[agent-pipeline] pipe-20260330021427-v9fb round-1
This commit is contained in:
@@ -165,7 +165,7 @@ const TEST_TABLE_COLUMNS: ColumnInfo[] = [
|
||||
columnName: "id",
|
||||
columnLabel: "ID",
|
||||
dataType: "integer",
|
||||
webType: "number",
|
||||
web_type: "number",
|
||||
widgetType: "number",
|
||||
inputType: "auto",
|
||||
isNullable: "N",
|
||||
@@ -180,7 +180,7 @@ const TEST_TABLE_COLUMNS: ColumnInfo[] = [
|
||||
columnName: "user_name",
|
||||
columnLabel: "사용자명",
|
||||
dataType: "character varying",
|
||||
webType: "text",
|
||||
web_type: "text",
|
||||
widgetType: "text",
|
||||
inputType: "direct",
|
||||
isNullable: "N",
|
||||
@@ -195,7 +195,7 @@ const TEST_TABLE_COLUMNS: ColumnInfo[] = [
|
||||
columnName: "email",
|
||||
columnLabel: "이메일",
|
||||
dataType: "character varying",
|
||||
webType: "email",
|
||||
web_type: "email",
|
||||
widgetType: "email",
|
||||
inputType: "direct",
|
||||
isNullable: "N",
|
||||
@@ -210,7 +210,7 @@ const TEST_TABLE_COLUMNS: ColumnInfo[] = [
|
||||
columnName: "age",
|
||||
columnLabel: "나이",
|
||||
dataType: "integer",
|
||||
webType: "number",
|
||||
web_type: "number",
|
||||
widgetType: "number",
|
||||
inputType: "direct",
|
||||
isNullable: "Y",
|
||||
@@ -224,7 +224,7 @@ const TEST_TABLE_COLUMNS: ColumnInfo[] = [
|
||||
columnName: "birth_date",
|
||||
columnLabel: "생년월일",
|
||||
dataType: "date",
|
||||
webType: "date",
|
||||
web_type: "date",
|
||||
widgetType: "date",
|
||||
inputType: "direct",
|
||||
isNullable: "Y",
|
||||
@@ -238,7 +238,7 @@ const TEST_TABLE_COLUMNS: ColumnInfo[] = [
|
||||
columnName: "phone",
|
||||
columnLabel: "전화번호",
|
||||
dataType: "character varying",
|
||||
webType: "tel",
|
||||
web_type: "tel",
|
||||
widgetType: "tel",
|
||||
inputType: "direct",
|
||||
isNullable: "Y",
|
||||
|
||||
@@ -10,7 +10,7 @@ export async function GET(request: NextRequest) {
|
||||
const codeLayouts = LayoutRegistry.getAllLayouts().map((layout) => ({
|
||||
id: layout.id,
|
||||
name: layout.name,
|
||||
nameEng: layout.name_eng,
|
||||
name_eng: layout.name_eng,
|
||||
description: layout.description,
|
||||
category: layout.category,
|
||||
type: "code", // 코드로 생성된 레이아웃
|
||||
|
||||
@@ -106,7 +106,7 @@ export const LayoutFormModal: React.FC<LayoutFormModalProps> = ({ open, onOpenCh
|
||||
const [step, setStep] = useState<"basic" | "template" | "advanced">("basic");
|
||||
const [formData, setFormData] = useState({
|
||||
name: "",
|
||||
nameEng: "",
|
||||
name_eng: "",
|
||||
description: "",
|
||||
category: "" as LayoutCategory | "",
|
||||
zones: 2,
|
||||
@@ -124,7 +124,7 @@ export const LayoutFormModal: React.FC<LayoutFormModalProps> = ({ open, onOpenCh
|
||||
setStep("basic");
|
||||
setFormData({
|
||||
name: "",
|
||||
nameEng: "",
|
||||
name_eng: "",
|
||||
description: "",
|
||||
category: "",
|
||||
zones: 2,
|
||||
@@ -290,8 +290,8 @@ export const LayoutFormModal: React.FC<LayoutFormModalProps> = ({ open, onOpenCh
|
||||
<Input
|
||||
id="nameEng"
|
||||
placeholder="예: Sidebar, Dashboard, CardGrid"
|
||||
value={formData.nameEng}
|
||||
onChange={(e) => setFormData((prev) => ({ ...prev, nameEng: e.target.value }))}
|
||||
value={formData.name_eng}
|
||||
onChange={(e) => setFormData((prev) => ({ ...prev, name_eng: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -119,7 +119,7 @@ export const WebTypeInput: React.FC<WebTypeInputProps> = ({
|
||||
if (column.columnName === "manager_name" || webType === "entity") {
|
||||
console.log("🔍 Entity 필드 디버깅:", {
|
||||
columnName: column.columnName,
|
||||
webType: webType,
|
||||
web_type: webType,
|
||||
tableName: tableName,
|
||||
effectiveTableName: effectiveTableName,
|
||||
referenceTable: column.referenceTable,
|
||||
|
||||
+1
-1
@@ -120,7 +120,7 @@ const ActionConditionBuilder: React.FC<ActionConditionBuilderProps> = ({
|
||||
columnName: col.columnName,
|
||||
connectionId: col.connectionId,
|
||||
inputType: col.inputType,
|
||||
webType: col.webType,
|
||||
web_type: col.webType,
|
||||
})),
|
||||
);
|
||||
console.log("🔍 ActionConditionBuilder - 코드 타입 컬럼들:", codeFields);
|
||||
|
||||
+2
-2
@@ -86,7 +86,7 @@ const ControlConditionStep: React.FC<ControlConditionStepProps> = ({ state, acti
|
||||
columnName: col.columnName,
|
||||
connectionId: col.connectionId,
|
||||
inputType: col.inputType,
|
||||
webType: col.webType,
|
||||
web_type: col.webType,
|
||||
})),
|
||||
);
|
||||
console.log("🔍 코드 타입 컬럼들:", codeColumns);
|
||||
@@ -288,7 +288,7 @@ const ControlConditionStep: React.FC<ControlConditionStepProps> = ({ state, acti
|
||||
conditionField: condition.field,
|
||||
selectedField: selectedField,
|
||||
selectedFieldKeys: selectedField ? Object.keys(selectedField) : [],
|
||||
webType: selectedField?.webType,
|
||||
web_type: selectedField?.webType,
|
||||
inputType: selectedField?.inputType,
|
||||
connectionId: selectedField?.connectionId,
|
||||
dataType: selectedField?.dataType,
|
||||
|
||||
@@ -1308,7 +1308,7 @@ export default function ScreenDesigner({
|
||||
columnName: col.columnName,
|
||||
columnLabel: col.columnLabel,
|
||||
dataType: col.dataType === "string" ? "varchar" : col.dataType === "number" ? "numeric" : col.dataType,
|
||||
webType: col.dataType === "number" ? "number" : "text",
|
||||
web_type: col.dataType === "number" ? "number" : "text",
|
||||
input_type: "text",
|
||||
widgetType: col.dataType === "number" ? "number" : "text",
|
||||
isNullable: "YES",
|
||||
@@ -1399,7 +1399,7 @@ export default function ScreenDesigner({
|
||||
columnName: col.column_name,
|
||||
columnLabel: col.display_name || col.column_label || col.column_name,
|
||||
dataType: col.data_type || col.db_type,
|
||||
webType: col.web_type,
|
||||
web_type: col.web_type,
|
||||
input_type: inputType,
|
||||
inputType: inputType,
|
||||
widgetType,
|
||||
@@ -1484,7 +1484,7 @@ export default function ScreenDesigner({
|
||||
columnName: col.column_name,
|
||||
columnLabel: col.display_name || col.column_label || col.column_name,
|
||||
dataType: col.data_type || col.db_type,
|
||||
webType: col.web_type,
|
||||
web_type: col.web_type,
|
||||
input_type: inputType,
|
||||
inputType: inputType,
|
||||
widgetType,
|
||||
@@ -3279,7 +3279,7 @@ export default function ScreenDesigner({
|
||||
|
||||
console.log("🧩 컴포넌트 드롭:", {
|
||||
componentName: component.name,
|
||||
webType: component.webType,
|
||||
web_type: component.webType,
|
||||
rawPosition: { x: dropX, y: dropY },
|
||||
boundedPosition: { x: boundedX, y: boundedY },
|
||||
snappedPosition,
|
||||
@@ -3289,10 +3289,10 @@ export default function ScreenDesigner({
|
||||
console.log("🔍 ScreenDesigner handleComponentDrop:", {
|
||||
componentName: component.name,
|
||||
componentId: component.id,
|
||||
webType: component.webType,
|
||||
web_type: component.webType,
|
||||
category: component.category,
|
||||
defaultConfig: component.defaultConfig,
|
||||
defaultSize: component.defaultSize,
|
||||
default_config: component.defaultConfig,
|
||||
default_size: component.defaultSize,
|
||||
});
|
||||
|
||||
// 컴포넌트별 gridColumns 설정 및 크기 계산
|
||||
@@ -3395,7 +3395,7 @@ export default function ScreenDesigner({
|
||||
console.log("🎨 최종 컴포넌트 크기:", {
|
||||
componentId: component.id,
|
||||
componentName: component.name,
|
||||
defaultSize: component.defaultSize,
|
||||
default_size: component.defaultSize,
|
||||
finalSize: componentSize,
|
||||
gridColumns,
|
||||
});
|
||||
@@ -3465,7 +3465,7 @@ export default function ScreenDesigner({
|
||||
layerId: activeLayerIdRef.current || 1, // 🆕 현재 활성 레이어에 추가 (ref 사용)
|
||||
componentConfig: {
|
||||
type: component.id, // 새 컴포넌트 시스템의 ID 사용
|
||||
webType: component.webType, // 웹타입 정보 추가
|
||||
web_type: component.webType, // 웹타입 정보 추가
|
||||
...enhancedDefaultConfig,
|
||||
},
|
||||
webTypeConfig: getDefaultWebTypeConfig(component.webType),
|
||||
|
||||
@@ -488,7 +488,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD
|
||||
tableName,
|
||||
columnName: "id",
|
||||
columnLabel: "ID",
|
||||
webType: "number" as WebType,
|
||||
web_type: "number" as WebType,
|
||||
dataType: "BIGINT",
|
||||
isNullable: "NO",
|
||||
},
|
||||
@@ -496,7 +496,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD
|
||||
tableName,
|
||||
columnName: "name",
|
||||
columnLabel: "이름",
|
||||
webType: "text" as WebType,
|
||||
web_type: "text" as WebType,
|
||||
dataType: "VARCHAR",
|
||||
isNullable: "NO",
|
||||
},
|
||||
@@ -504,7 +504,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD
|
||||
tableName,
|
||||
columnName: "description",
|
||||
columnLabel: "설명",
|
||||
webType: "textarea" as WebType,
|
||||
web_type: "textarea" as WebType,
|
||||
dataType: "TEXT",
|
||||
isNullable: "YES",
|
||||
},
|
||||
@@ -512,7 +512,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD
|
||||
tableName,
|
||||
columnName: "created_date",
|
||||
columnLabel: "생성일",
|
||||
webType: "date" as WebType,
|
||||
web_type: "date" as WebType,
|
||||
dataType: "TIMESTAMP",
|
||||
isNullable: "NO",
|
||||
},
|
||||
@@ -520,7 +520,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD
|
||||
tableName,
|
||||
columnName: "updated_date",
|
||||
columnLabel: "수정일",
|
||||
webType: "date" as WebType,
|
||||
web_type: "date" as WebType,
|
||||
dataType: "TIMESTAMP",
|
||||
isNullable: "YES",
|
||||
},
|
||||
|
||||
@@ -949,7 +949,7 @@ function TableColumnAccordion({
|
||||
try {
|
||||
const settings: ColumnSettings = {
|
||||
columnLabel: columns.find(c => c.column_name === editingJoin.columnName)?.display_name || editingJoin.columnName,
|
||||
webType: "entity",
|
||||
web_type: "entity",
|
||||
detailSettings: JSON.stringify({}),
|
||||
codeCategory: "",
|
||||
codeValue: "",
|
||||
@@ -2063,7 +2063,7 @@ function OverviewTab({
|
||||
gridColumns: 4,
|
||||
componentConfig: {
|
||||
type: "text-input",
|
||||
webType: "text-input",
|
||||
web_type: "text-input",
|
||||
placeholder: `${newColumn}을(를) 입력하세요`,
|
||||
},
|
||||
webTypeConfig: {},
|
||||
|
||||
@@ -70,7 +70,7 @@ export default function SimpleScreenDesigner({ selectedScreen, onBackToList }: S
|
||||
size: { width: 200, height: 80 },
|
||||
title: `새 ${type}`,
|
||||
...(type === "widget" && {
|
||||
webType: "text" as const,
|
||||
web_type: "text" as const,
|
||||
label: "라벨",
|
||||
placeholder: "입력하세요",
|
||||
}),
|
||||
|
||||
@@ -62,8 +62,8 @@ export function ComponentsPanel({
|
||||
description: "드롭다운, 콤보박스, 라디오, 체크박스 등 다양한 선택 모드 지원",
|
||||
category: "input" as ComponentCategory,
|
||||
tags: ["select", "dropdown", "combobox", "v2"],
|
||||
defaultSize: { width: 300, height: 40 },
|
||||
defaultConfig: {
|
||||
default_size: { width: 300, height: 40 },
|
||||
default_config: {
|
||||
mode: "dropdown",
|
||||
source: "static",
|
||||
multiple: false,
|
||||
@@ -79,7 +79,7 @@ export function ComponentsPanel({
|
||||
description: "행 단위로 데이터를 추가/수정/삭제",
|
||||
category: "data" as ComponentCategory,
|
||||
tags: ["repeater", "table", "modal", "button", "v2", "v2"],
|
||||
defaultSize: { width: 600, height: 300 },
|
||||
default_size: { width: 600, height: 300 },
|
||||
},
|
||||
{
|
||||
id: "v2-bom-tree",
|
||||
@@ -87,7 +87,7 @@ export function ComponentsPanel({
|
||||
description: "BOM 구성을 계층 트리 형태로 조회",
|
||||
category: "data" as ComponentCategory,
|
||||
tags: ["bom", "tree", "계층", "제조", "v2"],
|
||||
defaultSize: { width: 900, height: 600 },
|
||||
default_size: { width: 900, height: 600 },
|
||||
},
|
||||
{
|
||||
id: "v2-bom-item-editor",
|
||||
@@ -95,7 +95,7 @@ export function ComponentsPanel({
|
||||
description: "BOM 하위 품목을 트리 구조로 추가/편집/삭제",
|
||||
category: "data" as ComponentCategory,
|
||||
tags: ["bom", "tree", "편집", "하위품목", "제조", "v2"],
|
||||
defaultSize: { width: 900, height: 400 },
|
||||
default_size: { width: 900, height: 400 },
|
||||
},
|
||||
] as unknown as ComponentDefinition[],
|
||||
[],
|
||||
|
||||
@@ -1091,7 +1091,7 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||
type: "component" as const,
|
||||
component_config: {
|
||||
type: "button-primary",
|
||||
webType: "button",
|
||||
web_type: "button",
|
||||
...anyComp.component_config,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -44,7 +44,7 @@ export interface TemplateComponent {
|
||||
description: string;
|
||||
category: "table" | "button" | "form" | "layout" | "chart" | "status" | "file" | "area";
|
||||
icon: React.ReactNode;
|
||||
defaultSize: { width: number; height: number };
|
||||
default_size: { width: number; height: number };
|
||||
components: Array<{
|
||||
type: "widget" | "container" | "datatable" | "file" | "area";
|
||||
widgetType?: string;
|
||||
@@ -93,7 +93,7 @@ const convertTemplateStandardToComponent = (template: TemplateStandard): Templat
|
||||
description: template.description || "",
|
||||
category: template.category as TemplateComponent["category"],
|
||||
icon: getIconByName(template.icon_name),
|
||||
defaultSize: template.default_size || { width: 300, height: 200 },
|
||||
default_size: template.default_size || { width: 300, height: 200 },
|
||||
components: template.layout_config?.components || [],
|
||||
};
|
||||
};
|
||||
@@ -107,7 +107,7 @@ const fallbackTemplates: TemplateComponent[] = [
|
||||
description: "컬럼 설정, 필터링, 페이지네이션이 포함된 완전한 데이터 테이블",
|
||||
category: "table",
|
||||
icon: <Table className="h-4 w-4" />,
|
||||
defaultSize: { width: 1000, height: 680 },
|
||||
default_size: { width:1000, height: 680 },
|
||||
components: [
|
||||
{
|
||||
type: "datatable",
|
||||
@@ -133,7 +133,7 @@ const fallbackTemplates: TemplateComponent[] = [
|
||||
description: "컴포넌트들을 그룹화할 수 있는 기본 박스 형태의 영역",
|
||||
category: "area",
|
||||
icon: <Square className="h-4 w-4" />,
|
||||
defaultSize: { width: 400, height: 300 },
|
||||
default_size: { width:400, height: 300 },
|
||||
components: [
|
||||
{
|
||||
type: "area",
|
||||
@@ -171,7 +171,7 @@ const fallbackTemplates: TemplateComponent[] = [
|
||||
description: "그림자와 둥근 모서리가 있는 카드 형태의 영역",
|
||||
category: "area",
|
||||
icon: <CreditCard className="h-4 w-4" />,
|
||||
defaultSize: { width: 400, height: 300 },
|
||||
default_size: { width:400, height: 300 },
|
||||
components: [
|
||||
{
|
||||
type: "area",
|
||||
@@ -209,7 +209,7 @@ const fallbackTemplates: TemplateComponent[] = [
|
||||
description: "제목 헤더가 포함된 패널 형태의 영역",
|
||||
category: "area",
|
||||
icon: <Layout className="h-4 w-4" />,
|
||||
defaultSize: { width: 500, height: 400 },
|
||||
default_size: { width:500, height: 400 },
|
||||
components: [
|
||||
{
|
||||
type: "area",
|
||||
@@ -237,7 +237,7 @@ const fallbackTemplates: TemplateComponent[] = [
|
||||
description: "내부 컴포넌트들을 격자 형태로 배치하는 영역",
|
||||
category: "area",
|
||||
icon: <Grid3x3 className="h-4 w-4" />,
|
||||
defaultSize: { width: 600, height: 400 },
|
||||
default_size: { width:600, height: 400 },
|
||||
components: [
|
||||
{
|
||||
type: "area",
|
||||
@@ -281,7 +281,7 @@ const fallbackTemplates: TemplateComponent[] = [
|
||||
description: "내부 컴포넌트들을 가로로 나란히 배치하는 영역",
|
||||
category: "area",
|
||||
icon: <Columns className="h-4 w-4" />,
|
||||
defaultSize: { width: 600, height: 200 },
|
||||
default_size: { width:600, height: 200 },
|
||||
components: [
|
||||
{
|
||||
type: "area",
|
||||
@@ -312,7 +312,7 @@ const fallbackTemplates: TemplateComponent[] = [
|
||||
description: "내부 컴포넌트들을 세로로 순차 배치하는 영역",
|
||||
category: "area",
|
||||
icon: <Rows className="h-4 w-4" />,
|
||||
defaultSize: { width: 300, height: 500 },
|
||||
default_size: { width:300, height: 500 },
|
||||
components: [
|
||||
{
|
||||
type: "area",
|
||||
@@ -343,7 +343,7 @@ const fallbackTemplates: TemplateComponent[] = [
|
||||
description: "사이드바와 메인 컨텐츠 영역으로 구분된 레이아웃",
|
||||
category: "area",
|
||||
icon: <SidebarOpen className="h-4 w-4" />,
|
||||
defaultSize: { width: 700, height: 400 },
|
||||
default_size: { width:700, height: 400 },
|
||||
components: [
|
||||
{
|
||||
type: "area",
|
||||
@@ -372,7 +372,7 @@ const fallbackTemplates: TemplateComponent[] = [
|
||||
description: "탭으로 구분된 여러 컨텐츠 영역을 제공하는 레이아웃",
|
||||
category: "area",
|
||||
icon: <Folder className="h-4 w-4" />,
|
||||
defaultSize: { width: 600, height: 400 },
|
||||
default_size: { width:600, height: 400 },
|
||||
components: [
|
||||
{
|
||||
type: "area",
|
||||
@@ -400,7 +400,7 @@ const fallbackTemplates: TemplateComponent[] = [
|
||||
// description: "접고 펼칠 수 있는 섹션들로 구성된 영역",
|
||||
// category: "area",
|
||||
// icon: <ChevronDown className="h-4 w-4" />,
|
||||
// defaultSize: { width: 500, height: 600 },
|
||||
// default_size: { width: 500, height: 600 },
|
||||
// components: [
|
||||
// {
|
||||
// type: "area",
|
||||
@@ -584,7 +584,7 @@ export const TemplatesPanel: React.FC<TemplatesPanelProps> = ({ onDragStart }) =
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center space-x-2 text-xs text-muted-foreground/70">
|
||||
<span className="bg-primary/10 px-3 py-1 rounded-full font-medium text-primary">
|
||||
{template.defaultSize.width}×{template.defaultSize.height}
|
||||
{template.default_size.width}×{template.default_size.height}
|
||||
</span>
|
||||
</div>
|
||||
<span className="text-xs font-medium text-primary capitalize bg-primary/5 px-3 py-1 rounded-full border border-primary/20">
|
||||
|
||||
@@ -50,7 +50,7 @@ export const numberingRuleTemplate = {
|
||||
description: "코드 자동 채번 규칙 설정",
|
||||
category: "admin" as const,
|
||||
icon: Hash,
|
||||
defaultSize: { width: 1200, height: 800 },
|
||||
default_size: { width: 1200, height: 800 },
|
||||
components: [
|
||||
{
|
||||
type: "numbering-rule" as const,
|
||||
|
||||
@@ -44,7 +44,7 @@ export const RatingWidget: React.FC<RatingWidgetProps> = ({
|
||||
|
||||
setCurrentRating(rating);
|
||||
onChange?.(rating);
|
||||
onEvent?.("change", { value: rating, webType: "rating" });
|
||||
onEvent?.("change", { value: rating, web_type: "rating" });
|
||||
};
|
||||
|
||||
const handleStarHover = (rating: number) => {
|
||||
|
||||
@@ -192,7 +192,7 @@ interface ColumnInfo {
|
||||
label?: string;
|
||||
dataType?: string;
|
||||
inputType?: string;
|
||||
webType?: string;
|
||||
web_type?: string;
|
||||
categoryCode?: string;
|
||||
}
|
||||
|
||||
@@ -290,7 +290,7 @@ export const V2AggregationWidgetConfigPanel: React.FC<V2AggregationWidgetConfigP
|
||||
// 숫자형 컬럼만
|
||||
const numericColumns = useMemo(() => {
|
||||
return columns.filter((col) => {
|
||||
const inputType = (col.inputType || col.webType || "").toLowerCase();
|
||||
const inputType = (col.inputType || col.web_type || "").toLowerCase();
|
||||
return inputType === "number" || inputType === "decimal" || inputType === "integer" ||
|
||||
inputType === "float" || inputType === "currency" || inputType === "percent";
|
||||
});
|
||||
@@ -337,12 +337,12 @@ export const V2AggregationWidgetConfigPanel: React.FC<V2AggregationWidgetConfigP
|
||||
label: col.displayName || col.columnLabel || col.column_label || col.label || col.columnName || col.column_name,
|
||||
dataType: col.dataType || col.data_type,
|
||||
inputType: col.inputType || col.input_type,
|
||||
webType: col.webType || col.web_type,
|
||||
web_type: col.webType || col.web_type,
|
||||
categoryCode: col.categoryCode || col.category_code,
|
||||
}));
|
||||
setColumns(mapped);
|
||||
const categoryCols = mapped.filter(
|
||||
(c: ColumnInfo) => c.inputType === "category" || c.webType === "category"
|
||||
(c: ColumnInfo) => c.inputType === "category" || c.web_type === "category"
|
||||
);
|
||||
if (categoryCols.length > 0) loadCategoryOptions(categoryCols);
|
||||
} else {
|
||||
@@ -428,7 +428,7 @@ export const V2AggregationWidgetConfigPanel: React.FC<V2AggregationWidgetConfigP
|
||||
|
||||
const isCategoryColumn = useCallback((columnName: string) => {
|
||||
const col = columns.find((c) => c.columnName === columnName);
|
||||
return col?.inputType === "category" || col?.webType === "category";
|
||||
return col?.inputType === "category" || col?.web_type === "category";
|
||||
}, [columns]);
|
||||
|
||||
// ─── 집계 항목 CRUD ───
|
||||
@@ -896,7 +896,7 @@ export const V2AggregationWidgetConfigPanel: React.FC<V2AggregationWidgetConfigP
|
||||
onValueChange={(value) => {
|
||||
updateFilter(filter.id, { columnName: value, staticValue: "" });
|
||||
const col = columns.find((c) => c.columnName === value);
|
||||
if (col && (col.inputType === "category" || col.webType === "category")) {
|
||||
if (col && (col.inputType === "category" || col.web_type === "category")) {
|
||||
loadCategoryOptions([col]);
|
||||
}
|
||||
}}
|
||||
|
||||
@@ -41,12 +41,12 @@ const v2ComponentDefinitions: ComponentDefinition[] = [
|
||||
name: "통합 입력",
|
||||
description: "텍스트, 숫자, 비밀번호, 슬라이더, 컬러 등 다양한 입력 타입을 지원하는 통합 컴포넌트",
|
||||
category: ComponentCategory.V2,
|
||||
webType: "text" as WebType,
|
||||
web_type: "text" as WebType,
|
||||
component: V2Input as any,
|
||||
tags: ["input", "text", "number", "password", "slider", "color", "v2"],
|
||||
defaultSize: { width: 200, height: 40 },
|
||||
configPanel: V2InputConfigPanel as any,
|
||||
defaultConfig: {
|
||||
default_size: { width: 200, height: 40 },
|
||||
config_panel: V2InputConfigPanel as any,
|
||||
default_config: {
|
||||
inputType: "text",
|
||||
format: "none",
|
||||
placeholder: "",
|
||||
@@ -57,12 +57,12 @@ const v2ComponentDefinitions: ComponentDefinition[] = [
|
||||
name: "통합 선택",
|
||||
description: "드롭다운, 라디오, 체크박스, 태그, 토글 등 다양한 선택 방식을 지원하는 통합 컴포넌트",
|
||||
category: ComponentCategory.V2,
|
||||
webType: "select" as WebType,
|
||||
web_type: "select" as WebType,
|
||||
component: V2Select as any,
|
||||
tags: ["select", "dropdown", "radio", "checkbox", "toggle", "v2"],
|
||||
defaultSize: { width: 200, height: 40 },
|
||||
configPanel: V2SelectConfigPanel as any,
|
||||
defaultConfig: {
|
||||
default_size: { width: 200, height: 40 },
|
||||
config_panel: V2SelectConfigPanel as any,
|
||||
default_config: {
|
||||
mode: "dropdown",
|
||||
source: "static",
|
||||
options: [],
|
||||
@@ -73,12 +73,12 @@ const v2ComponentDefinitions: ComponentDefinition[] = [
|
||||
name: "통합 날짜",
|
||||
description: "날짜, 시간, 날짜시간, 날짜 범위 등을 지원하는 통합 컴포넌트",
|
||||
category: ComponentCategory.V2,
|
||||
webType: "date" as WebType,
|
||||
web_type: "date" as WebType,
|
||||
component: V2Date as any,
|
||||
tags: ["date", "time", "datetime", "datepicker", "v2"],
|
||||
defaultSize: { width: 200, height: 40 },
|
||||
configPanel: V2DateConfigPanel as any,
|
||||
defaultConfig: {
|
||||
default_size: { width: 200, height: 40 },
|
||||
config_panel: V2DateConfigPanel as any,
|
||||
default_config: {
|
||||
dateType: "date",
|
||||
format: "YYYY-MM-DD",
|
||||
},
|
||||
@@ -88,12 +88,12 @@ const v2ComponentDefinitions: ComponentDefinition[] = [
|
||||
name: "통합 목록",
|
||||
description: "테이블, 카드, 칸반, 리스트 등 다양한 데이터 표시 방식을 지원하는 통합 컴포넌트",
|
||||
category: ComponentCategory.V2,
|
||||
webType: "list" as WebType,
|
||||
web_type: "list" as WebType,
|
||||
component: V2List as any,
|
||||
tags: ["list", "table", "card", "kanban", "data", "v2"],
|
||||
defaultSize: { width: 600, height: 400 },
|
||||
configPanel: V2ListConfigPanel as any,
|
||||
defaultConfig: {
|
||||
default_size: { width: 600, height: 400 },
|
||||
config_panel: V2ListConfigPanel as any,
|
||||
default_config: {
|
||||
viewMode: "table",
|
||||
source: "static",
|
||||
columns: [],
|
||||
@@ -106,12 +106,12 @@ const v2ComponentDefinitions: ComponentDefinition[] = [
|
||||
name: "통합 레이아웃",
|
||||
description: "그리드, 분할 패널, 플렉스 등 다양한 레이아웃 구조를 지원하는 통합 컴포넌트",
|
||||
category: ComponentCategory.V2,
|
||||
webType: "container" as WebType,
|
||||
web_type: "container" as WebType,
|
||||
component: V2Layout as any,
|
||||
tags: ["layout", "grid", "split", "flex", "container", "v2"],
|
||||
defaultSize: { width: 400, height: 300 },
|
||||
configPanel: V2LayoutConfigPanel as any,
|
||||
defaultConfig: {
|
||||
default_size: { width: 400, height: 300 },
|
||||
config_panel: V2LayoutConfigPanel as any,
|
||||
default_config: {
|
||||
layoutType: "grid",
|
||||
columns: 2,
|
||||
gap: "16",
|
||||
@@ -123,12 +123,12 @@ const v2ComponentDefinitions: ComponentDefinition[] = [
|
||||
name: "통합 그룹",
|
||||
description: "탭, 아코디언, 섹션, 모달 등 그룹 요소를 지원하는 통합 컴포넌트",
|
||||
category: ComponentCategory.V2,
|
||||
webType: "group" as WebType,
|
||||
web_type: "group" as WebType,
|
||||
component: V2Group as any,
|
||||
tags: ["group", "tabs", "accordion", "section", "modal", "v2"],
|
||||
defaultSize: { width: 400, height: 300 },
|
||||
configPanel: V2GroupConfigPanel as any,
|
||||
defaultConfig: {
|
||||
default_size: { width: 400, height: 300 },
|
||||
config_panel: V2GroupConfigPanel as any,
|
||||
default_config: {
|
||||
groupType: "section",
|
||||
title: "",
|
||||
collapsible: false,
|
||||
@@ -140,12 +140,12 @@ const v2ComponentDefinitions: ComponentDefinition[] = [
|
||||
name: "통합 미디어",
|
||||
description: "이미지, 비디오, 오디오, 파일 업로드 등을 지원하는 통합 컴포넌트",
|
||||
category: ComponentCategory.V2,
|
||||
webType: "file" as WebType,
|
||||
web_type: "file" as WebType,
|
||||
component: V2Media as any,
|
||||
tags: ["media", "image", "video", "audio", "file", "upload", "v2"],
|
||||
defaultSize: { width: 300, height: 200 },
|
||||
configPanel: V2MediaConfigPanel as any,
|
||||
defaultConfig: {
|
||||
default_size: { width: 300, height: 200 },
|
||||
config_panel: V2MediaConfigPanel as any,
|
||||
default_config: {
|
||||
mediaType: "image",
|
||||
multiple: false,
|
||||
preview: true,
|
||||
@@ -156,12 +156,12 @@ const v2ComponentDefinitions: ComponentDefinition[] = [
|
||||
name: "통합 비즈니스",
|
||||
description: "플로우, 랙, 채번규칙 등 비즈니스 기능을 지원하는 통합 컴포넌트",
|
||||
category: ComponentCategory.V2,
|
||||
webType: "custom" as WebType,
|
||||
web_type: "custom" as WebType,
|
||||
component: V2Biz as any,
|
||||
tags: ["business", "flow", "rack", "numbering", "category", "v2"],
|
||||
defaultSize: { width: 500, height: 400 },
|
||||
configPanel: V2BizConfigPanel as any,
|
||||
defaultConfig: {
|
||||
default_size: { width: 500, height: 400 },
|
||||
config_panel: V2BizConfigPanel as any,
|
||||
default_config: {
|
||||
bizType: "flow",
|
||||
},
|
||||
},
|
||||
@@ -170,12 +170,12 @@ const v2ComponentDefinitions: ComponentDefinition[] = [
|
||||
name: "통합 계층",
|
||||
description: "트리, 조직도, BOM, 연쇄 선택박스 등 계층 구조를 지원하는 통합 컴포넌트",
|
||||
category: ComponentCategory.V2,
|
||||
webType: "tree" as WebType,
|
||||
web_type: "tree" as WebType,
|
||||
component: V2Hierarchy as any,
|
||||
tags: ["hierarchy", "tree", "org-chart", "bom", "cascading", "v2"],
|
||||
defaultSize: { width: 400, height: 400 },
|
||||
configPanel: V2HierarchyConfigPanel as any,
|
||||
defaultConfig: {
|
||||
default_size: { width: 400, height: 400 },
|
||||
config_panel: V2HierarchyConfigPanel as any,
|
||||
default_config: {
|
||||
hierarchyType: "tree",
|
||||
viewMode: "tree",
|
||||
dataSource: "static",
|
||||
@@ -186,12 +186,12 @@ const v2ComponentDefinitions: ComponentDefinition[] = [
|
||||
name: "통합 반복",
|
||||
description: "인라인 테이블, 모달, 버튼 등 다양한 반복 데이터 관리를 지원하는 통합 컴포넌트",
|
||||
category: ComponentCategory.V2,
|
||||
webType: "entity" as WebType,
|
||||
web_type: "entity" as WebType,
|
||||
component: V2Repeater as any,
|
||||
tags: ["repeater", "table", "modal", "button", "data", "v2"],
|
||||
defaultSize: { width: 600, height: 300 },
|
||||
configPanel: V2RepeaterConfigPanel as any,
|
||||
defaultConfig: {
|
||||
default_size: { width: 600, height: 300 },
|
||||
config_panel: V2RepeaterConfigPanel as any,
|
||||
default_config: {
|
||||
renderMode: "inline",
|
||||
dataSource: {
|
||||
tableName: "",
|
||||
|
||||
@@ -1076,7 +1076,7 @@ export const RepeaterConfigPanel: React.FC<RepeaterConfigPanelProps> = ({
|
||||
columnName: column.columnName,
|
||||
input_type: col.input_type,
|
||||
inputType: col.inputType,
|
||||
webType: col.webType,
|
||||
web_type: col.webType,
|
||||
widgetType: col.widgetType,
|
||||
finalType: fieldType,
|
||||
});
|
||||
|
||||
@@ -150,7 +150,7 @@ export const entityJoinApi = {
|
||||
tableName: string,
|
||||
columnName: string,
|
||||
settings: {
|
||||
webType: string;
|
||||
web_type: string;
|
||||
referenceTable?: string;
|
||||
referenceColumn?: string;
|
||||
displayColumn?: string;
|
||||
|
||||
@@ -102,7 +102,7 @@ export interface ColumnInfo {
|
||||
displayName: string;
|
||||
dataType: string;
|
||||
dbType: string;
|
||||
webType: string;
|
||||
web_type: string;
|
||||
isNullable: boolean;
|
||||
isPrimaryKey: boolean;
|
||||
defaultValue?: string;
|
||||
@@ -203,7 +203,7 @@ export const getColumnsFromConnection = async (connectionId: number, tableName:
|
||||
return {
|
||||
...col,
|
||||
columnName: columnName,
|
||||
webType: isCodeColumn ? "code" : col.web_type || mapDataTypeToWebType(col.data_type),
|
||||
web_type: isCodeColumn ? "code" : col.web_type || mapDataTypeToWebType(col.data_type),
|
||||
codeCategory: isCodeColumn ? inferCodeCategory(columnName) : col.code_category,
|
||||
};
|
||||
})
|
||||
@@ -248,7 +248,7 @@ export const getColumnsFromConnection = async (connectionId: number, tableName:
|
||||
displayName: col.column_comment || col.display_name || columnName,
|
||||
dataType: dataType,
|
||||
dbType: dataType,
|
||||
webType: isCodeColumn ? "code" : mapDataTypeToWebType(dataType),
|
||||
web_type: isCodeColumn ? "code" : mapDataTypeToWebType(dataType),
|
||||
isNullable: col.is_nullable === "YES",
|
||||
columnDefault: col.column_default,
|
||||
description: col.column_comment || col.description,
|
||||
@@ -298,7 +298,7 @@ const getMockColumnsForTable = (tableName: string): ColumnInfo[] => {
|
||||
columnName: "id",
|
||||
displayName: "ID",
|
||||
dataType: "NUMBER",
|
||||
webType: "number",
|
||||
web_type: "number",
|
||||
isNullable: false,
|
||||
isPrimaryKey: true,
|
||||
columnComment: "고유 식별자",
|
||||
@@ -307,7 +307,7 @@ const getMockColumnsForTable = (tableName: string): ColumnInfo[] => {
|
||||
columnName: "name",
|
||||
displayName: "이름",
|
||||
dataType: "VARCHAR",
|
||||
webType: "text",
|
||||
web_type: "text",
|
||||
isNullable: false,
|
||||
isPrimaryKey: false,
|
||||
columnComment: "이름",
|
||||
@@ -316,7 +316,7 @@ const getMockColumnsForTable = (tableName: string): ColumnInfo[] => {
|
||||
columnName: "status",
|
||||
displayName: "상태",
|
||||
dataType: "VARCHAR",
|
||||
webType: "code",
|
||||
web_type: "code",
|
||||
isNullable: true,
|
||||
isPrimaryKey: false,
|
||||
columnComment: "상태 코드",
|
||||
@@ -326,7 +326,7 @@ const getMockColumnsForTable = (tableName: string): ColumnInfo[] => {
|
||||
columnName: "created_date",
|
||||
displayName: "생성일시",
|
||||
dataType: "TIMESTAMP",
|
||||
webType: "datetime",
|
||||
web_type: "datetime",
|
||||
isNullable: true,
|
||||
isPrimaryKey: false,
|
||||
columnComment: "생성일시",
|
||||
@@ -335,7 +335,7 @@ const getMockColumnsForTable = (tableName: string): ColumnInfo[] => {
|
||||
columnName: "updated_date",
|
||||
displayName: "수정일시",
|
||||
dataType: "TIMESTAMP",
|
||||
webType: "datetime",
|
||||
web_type: "datetime",
|
||||
isNullable: true,
|
||||
isPrimaryKey: false,
|
||||
columnComment: "수정일시",
|
||||
@@ -348,7 +348,7 @@ const getMockColumnsForTable = (tableName: string): ColumnInfo[] => {
|
||||
columnName: "email",
|
||||
displayName: "이메일",
|
||||
dataType: "VARCHAR",
|
||||
webType: "email",
|
||||
web_type: "email",
|
||||
isNullable: true,
|
||||
isPrimaryKey: false,
|
||||
columnComment: "이메일 주소",
|
||||
@@ -360,7 +360,7 @@ const getMockColumnsForTable = (tableName: string): ColumnInfo[] => {
|
||||
columnName: "price",
|
||||
displayName: "가격",
|
||||
dataType: "DECIMAL",
|
||||
webType: "decimal",
|
||||
web_type: "decimal",
|
||||
isNullable: true,
|
||||
isPrimaryKey: false,
|
||||
columnComment: "상품 가격",
|
||||
|
||||
@@ -544,7 +544,7 @@ export const tableTypeApi = {
|
||||
detailSettings?: Record<string, any>,
|
||||
): Promise<void> => {
|
||||
await apiClient.put(`/table-management/tables/${tableName}/columns/${columnName}/web-type`, {
|
||||
webType,
|
||||
web_type: webType,
|
||||
detailSettings,
|
||||
});
|
||||
},
|
||||
|
||||
@@ -208,7 +208,7 @@ export class ComponentRegistry {
|
||||
count,
|
||||
})),
|
||||
by_web_type: Array.from(webTypeMap.entries()).map(([webType, count]) => ({
|
||||
webType,
|
||||
web_type: webType,
|
||||
count,
|
||||
})),
|
||||
byAuthor: Array.from(authorMap.entries()).map(([author, count]) => ({
|
||||
@@ -414,7 +414,7 @@ Hot Reload 제어 (비동기):
|
||||
// React 컴포넌트는 직렬화할 수 없으므로 제외
|
||||
component: definition.component.name,
|
||||
renderer: definition.renderer?.name,
|
||||
configPanel: definition.config_panel?.name,
|
||||
config_panel: definition.config_panel?.name,
|
||||
},
|
||||
})),
|
||||
};
|
||||
|
||||
@@ -523,7 +523,7 @@ export const DynamicComponentRenderer: React.FC<DynamicComponentRendererProps> =
|
||||
tableName,
|
||||
columnName,
|
||||
inputType: "category",
|
||||
webType: "category",
|
||||
web_type: "category",
|
||||
};
|
||||
|
||||
const catStyle = catNeedsExternalHorizLabel
|
||||
|
||||
@@ -64,7 +64,7 @@ export const DynamicWebTypeRenderer: React.FC<DynamicComponentProps> = ({
|
||||
return {
|
||||
...props,
|
||||
webTypeConfig: mergedConfig,
|
||||
webType: webType,
|
||||
web_type: webType,
|
||||
onEvent: onEvent,
|
||||
};
|
||||
}, [props, mergedConfig, webType, onEvent]);
|
||||
|
||||
@@ -256,7 +256,7 @@ export class WebTypeRegistry {
|
||||
...def,
|
||||
// 함수/컴포넌트는 제외하고 메타데이터만 내보내기
|
||||
component: def.component.name || "Unknown",
|
||||
configPanel: def.configPanel.name || "Unknown",
|
||||
config_panel: def.configPanel.name || "Unknown",
|
||||
},
|
||||
]),
|
||||
),
|
||||
|
||||
@@ -1138,7 +1138,7 @@ export const SplitPanelLayoutConfigPanel: React.FC<SplitPanelLayoutConfigPanelPr
|
||||
columnName: col.column_name,
|
||||
columnLabel: col.display_name || col.column_label || col.column_name,
|
||||
dataType: col.data_type,
|
||||
webType: col.web_type,
|
||||
web_type: col.web_type,
|
||||
input_type: col.input_type,
|
||||
widgetType: col.widget_type || col.web_type,
|
||||
isNullable: col.is_nullable,
|
||||
|
||||
@@ -1182,7 +1182,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
cached.columns.forEach((col: any) => {
|
||||
labels[col.column_name] = col.display_name || col.comment || col.column_name;
|
||||
meta[col.column_name] = {
|
||||
webType: col.web_type,
|
||||
web_type: col.web_type,
|
||||
codeCategory: col.code_category,
|
||||
inputType: inputTypeMap[col.column_name], // 캐시된 inputType 사용!
|
||||
};
|
||||
@@ -1214,7 +1214,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
columns.forEach((col: any) => {
|
||||
labels[col.column_name] = col.display_name || col.comment || col.column_name;
|
||||
meta[col.column_name] = {
|
||||
webType: col.web_type,
|
||||
web_type: col.web_type,
|
||||
codeCategory: col.code_category,
|
||||
inputType: inputTypeMap[col.column_name],
|
||||
};
|
||||
|
||||
@@ -541,7 +541,7 @@ export const TableListConfigPanel: React.FC<TableListConfigPanelProps> = ({
|
||||
columnName: column.columnName,
|
||||
found: !!tableColumn,
|
||||
inputType: tableColumn?.input_type,
|
||||
webType: tableColumn?.web_type,
|
||||
web_type: tableColumn?.web_type,
|
||||
});
|
||||
|
||||
// 엔티티 타입인 경우 isEntityJoin 플래그 설정 (input_type 또는 web_type 확인)
|
||||
|
||||
@@ -3032,7 +3032,7 @@ PopComponentRegistry.registerComponent({
|
||||
category: "action",
|
||||
icon: "MousePointerClick",
|
||||
component: PopButtonComponent,
|
||||
configPanel: PopButtonConfigPanel,
|
||||
config_panel: PopButtonConfigPanel,
|
||||
preview: PopButtonPreviewComponent,
|
||||
defaultProps: {
|
||||
label: "버튼",
|
||||
|
||||
@@ -37,7 +37,7 @@ PopComponentRegistry.registerComponent({
|
||||
category: "display",
|
||||
icon: "LayoutGrid",
|
||||
component: PopCardListV2Component,
|
||||
configPanel: PopCardListV2ConfigPanel,
|
||||
config_panel: PopCardListV2ConfigPanel,
|
||||
preview: PopCardListV2PreviewComponent,
|
||||
defaultProps: defaultConfig,
|
||||
connectionMeta: {
|
||||
|
||||
@@ -55,7 +55,7 @@ PopComponentRegistry.registerComponent({
|
||||
category: "display",
|
||||
icon: "LayoutGrid",
|
||||
component: PopCardListComponent,
|
||||
configPanel: PopCardListConfigPanel,
|
||||
config_panel: PopCardListConfigPanel,
|
||||
preview: PopCardListPreviewComponent,
|
||||
defaultProps: defaultConfig,
|
||||
connectionMeta: {
|
||||
|
||||
@@ -19,7 +19,7 @@ PopComponentRegistry.registerComponent({
|
||||
category: "display",
|
||||
icon: "BarChart3",
|
||||
component: PopDashboardComponent,
|
||||
configPanel: PopDashboardConfigPanel,
|
||||
config_panel: PopDashboardConfigPanel,
|
||||
preview: PopDashboardPreviewComponent,
|
||||
defaultProps: {
|
||||
items: [],
|
||||
|
||||
@@ -57,7 +57,7 @@ PopComponentRegistry.registerComponent({
|
||||
category: "input",
|
||||
icon: "TextCursorInput",
|
||||
component: PopFieldComponent,
|
||||
configPanel: PopFieldConfigPanel,
|
||||
config_panel: PopFieldConfigPanel,
|
||||
preview: PopFieldPreviewComponent,
|
||||
defaultProps: DEFAULT_FIELD_CONFIG,
|
||||
connectionMeta: {
|
||||
|
||||
@@ -971,7 +971,7 @@ PopComponentRegistry.registerComponent({
|
||||
category: "action",
|
||||
icon: "MousePointer",
|
||||
component: PopIconComponent,
|
||||
configPanel: PopIconConfigPanel,
|
||||
config_panel: PopIconConfigPanel,
|
||||
preview: PopIconPreviewComponent,
|
||||
defaultProps: {
|
||||
iconType: "quick",
|
||||
|
||||
@@ -319,7 +319,7 @@ PopComponentRegistry.registerComponent({
|
||||
category: "action",
|
||||
icon: "UserCircle",
|
||||
component: PopProfileComponent,
|
||||
configPanel: PopProfileConfigPanel,
|
||||
config_panel: PopProfileConfigPanel,
|
||||
preview: PopProfilePreview,
|
||||
defaultProps: {
|
||||
avatarSize: "md",
|
||||
|
||||
@@ -678,7 +678,7 @@ PopComponentRegistry.registerComponent({
|
||||
category: "input",
|
||||
icon: "ScanLine",
|
||||
component: PopScannerComponent,
|
||||
configPanel: PopScannerConfigPanel,
|
||||
config_panel: PopScannerConfigPanel,
|
||||
preview: PopScannerPreview,
|
||||
defaultProps: DEFAULT_SCANNER_CONFIG,
|
||||
connectionMeta: {
|
||||
|
||||
@@ -31,7 +31,7 @@ PopComponentRegistry.registerComponent({
|
||||
category: "input",
|
||||
icon: "Search",
|
||||
component: PopSearchComponent,
|
||||
configPanel: PopSearchConfigPanel,
|
||||
config_panel: PopSearchConfigPanel,
|
||||
preview: PopSearchPreviewComponent,
|
||||
defaultProps: DEFAULT_SEARCH_CONFIG,
|
||||
connectionMeta: {
|
||||
|
||||
@@ -52,7 +52,7 @@ PopComponentRegistry.registerComponent({
|
||||
category: "display",
|
||||
icon: "BarChart3",
|
||||
component: PopStatusBarComponent,
|
||||
configPanel: PopStatusBarConfigPanel,
|
||||
config_panel: PopStatusBarConfigPanel,
|
||||
preview: PopStatusBarPreviewComponent,
|
||||
defaultProps: DEFAULT_STATUS_BAR_CONFIG,
|
||||
connectionMeta: {
|
||||
|
||||
@@ -30,7 +30,7 @@ PopComponentRegistry.registerComponent({
|
||||
category: "display",
|
||||
icon: "List",
|
||||
component: PopStringListComponent,
|
||||
configPanel: PopStringListConfigPanel,
|
||||
config_panel: PopStringListConfigPanel,
|
||||
preview: PopStringListPreviewComponent,
|
||||
defaultProps: defaultConfig,
|
||||
connectionMeta: {
|
||||
|
||||
@@ -836,7 +836,7 @@ PopComponentRegistry.registerComponent({
|
||||
category: "display",
|
||||
icon: "FileText",
|
||||
component: PopTextComponent,
|
||||
configPanel: PopTextConfigPanel,
|
||||
config_panel: PopTextConfigPanel,
|
||||
preview: PopTextPreviewComponent,
|
||||
defaultProps: { textType: "text", fontSize: "base" },
|
||||
touchOptimized: true,
|
||||
|
||||
@@ -19,7 +19,7 @@ PopComponentRegistry.registerComponent({
|
||||
category: "display",
|
||||
icon: "ClipboardCheck",
|
||||
component: PopWorkDetailComponent,
|
||||
configPanel: PopWorkDetailConfigPanel,
|
||||
config_panel: PopWorkDetailConfigPanel,
|
||||
preview: PopWorkDetailPreviewComponent,
|
||||
defaultProps: defaultConfig,
|
||||
connectionMeta: {
|
||||
|
||||
@@ -15,9 +15,9 @@ export interface WebTypeDefinition {
|
||||
/** 렌더링 컴포넌트 */
|
||||
component: React.ComponentType<any>;
|
||||
/** 설정 패널 컴포넌트 */
|
||||
configPanel: React.ComponentType<WebTypeConfigPanelProps>;
|
||||
config_panel: React.ComponentType<WebTypeConfigPanelProps>;
|
||||
/** 기본 설정값 */
|
||||
defaultConfig: Record<string, any>;
|
||||
default_config: Record<string, any>;
|
||||
/** 활성화 상태 */
|
||||
isActive: boolean;
|
||||
/** 아이콘 (선택사항) */
|
||||
@@ -41,7 +41,7 @@ export interface ButtonActionDefinition {
|
||||
/** 핸들러 함수 */
|
||||
handler: (context: ButtonActionContext) => void | Promise<void>;
|
||||
/** 기본 설정값 */
|
||||
defaultConfig: Record<string, any>;
|
||||
default_config: Record<string, any>;
|
||||
/** 활성화 상태 */
|
||||
isActive: boolean;
|
||||
/** 아이콘 (선택사항) */
|
||||
@@ -136,7 +136,7 @@ export type ButtonActionCategory = "save" | "delete" | "navigate" | "export" | "
|
||||
*/
|
||||
export interface DynamicComponentProps {
|
||||
/** 웹타입 ID */
|
||||
webType: string;
|
||||
web_type: string;
|
||||
/** 컴포넌트 속성 */
|
||||
props: Record<string, any>;
|
||||
/** 컴포넌트 설정 */
|
||||
|
||||
@@ -356,7 +356,7 @@ export const DynamicComponentConfigPanel: React.FC<ComponentConfigPanelProps> =
|
||||
columnName: col.columnName || col.column_name,
|
||||
columnLabel: col.displayName || col.columnLabel || col.column_label || col.columnName || col.column_name,
|
||||
dataType: col.dataType || col.data_type || col.dbType,
|
||||
webType: col.webType || col.web_type,
|
||||
web_type: col.webType || col.web_type,
|
||||
input_type: col.inputType || col.input_type,
|
||||
widgetType: col.widgetType || col.widget_type || col.webType || col.web_type,
|
||||
isNullable: col.isNullable || col.is_nullable,
|
||||
|
||||
@@ -191,7 +191,7 @@ export function convertV2ToLegacy(v2Layout: LayoutV2 | null): LegacyLayoutData |
|
||||
hidden: overrides.hidden,
|
||||
codeCategory: overrides.codeCategory,
|
||||
inputType: overrides.inputType,
|
||||
webType: overrides.webType,
|
||||
web_type: overrides.webType,
|
||||
autoFill: overrides.autoFill,
|
||||
style: overrides.style || {},
|
||||
webTypeConfig: overrides.webTypeConfig || {},
|
||||
|
||||
@@ -247,7 +247,7 @@ export function createV2ConfigFromColumn(column: {
|
||||
|
||||
const componentConfig: Record<string, any> = {
|
||||
...mapping.config,
|
||||
webType: column.widgetType, // 원본 웹타입 보존
|
||||
web_type: column.widgetType, // 원본 웹타입 보존
|
||||
// DB의 input_type이 있으면 사용, 없으면 매핑에서 가져온 값 유지
|
||||
inputType: column.inputType || mapping.config.inputType || "text",
|
||||
placeholder: parsedDetailSettings.placeholder || column.columnLabel || column.columnName,
|
||||
|
||||
@@ -95,7 +95,7 @@ export class APIIntegrationTestSuite {
|
||||
displayName: col.displayName,
|
||||
dataType: col.dataType,
|
||||
dbType: col.dbType,
|
||||
webType: isWebType(col.webType) ? (col.webType as WebType) : "text",
|
||||
web_type: isWebType(col.webType) ? (col.webType as WebType) : "text",
|
||||
inputType: col.inputType || "direct",
|
||||
detailSettings: col.detailSettings ? JSON.parse(col.detailSettings) : {},
|
||||
description: col.description || "",
|
||||
|
||||
@@ -329,7 +329,7 @@ export class TypeSafetyTestSuite {
|
||||
displayName: "사용자명",
|
||||
dataType: "varchar",
|
||||
dbType: "character varying(100)",
|
||||
webType: "text", // string 타입 (백엔드)
|
||||
web_type: "text", // string 타입 (백엔드)
|
||||
inputType: "direct",
|
||||
detailSettings: JSON.stringify({ maxLength: 100 }),
|
||||
description: "사용자의 이름을 저장하는 컬럼",
|
||||
@@ -345,7 +345,7 @@ export class TypeSafetyTestSuite {
|
||||
displayName: backendColumnInfo.displayName,
|
||||
dataType: backendColumnInfo.dataType,
|
||||
dbType: backendColumnInfo.dbType,
|
||||
webType: isWebType(backendColumnInfo.webType) ? (backendColumnInfo.webType as WebType) : "text", // 안전한 타입 변환
|
||||
web_type: isWebType(backendColumnInfo.webType) ? (backendColumnInfo.webType as WebType) : "text", // 안전한 타입 변환
|
||||
inputType: backendColumnInfo.inputType,
|
||||
detailSettings: JSON.parse(backendColumnInfo.detailSettings || "{}"),
|
||||
description: backendColumnInfo.description,
|
||||
|
||||
Reference in New Issue
Block a user