드래그 앤 드롭 기능 개선 및 Unified 컴포넌트 매핑 추가: ScreenDesigner, TabsWidget, DynamicComponentRenderer에서 드래그 앤 드롭 시 컴포넌트의 위치와 크기를 최적화하고, Unified 컴포넌트에 대한 매핑 로직을 추가하여 사용자 경험을 향상시켰습니다. 또한, ButtonConfigPanel에서 컴포넌트가 없는 경우 방어 처리 로직을 추가하여 안정성을 높였습니다.
This commit is contained in:
@@ -7,6 +7,18 @@ import React from "react";
|
||||
// 컴포넌트별 ConfigPanel 동적 import 맵
|
||||
// 모든 ConfigPanel이 있는 컴포넌트를 여기에 등록해야 슬롯/중첩 컴포넌트에서 전용 설정 패널이 표시됨
|
||||
const CONFIG_PANEL_MAP: Record<string, () => Promise<any>> = {
|
||||
// ========== Unified 컴포넌트 ==========
|
||||
"unified-input": () => import("@/components/unified/config-panels/UnifiedInputConfigPanel"),
|
||||
"unified-select": () => import("@/components/unified/config-panels/UnifiedSelectConfigPanel"),
|
||||
"unified-date": () => import("@/components/unified/config-panels/UnifiedDateConfigPanel"),
|
||||
"unified-list": () => import("@/components/unified/config-panels/UnifiedListConfigPanel"),
|
||||
"unified-media": () => import("@/components/unified/config-panels/UnifiedMediaConfigPanel"),
|
||||
"unified-biz": () => import("@/components/unified/config-panels/UnifiedBizConfigPanel"),
|
||||
"unified-group": () => import("@/components/unified/config-panels/UnifiedGroupConfigPanel"),
|
||||
"unified-hierarchy": () => import("@/components/unified/config-panels/UnifiedHierarchyConfigPanel"),
|
||||
"unified-layout": () => import("@/components/unified/config-panels/UnifiedLayoutConfigPanel"),
|
||||
"unified-repeater": () => import("@/components/unified/config-panels/UnifiedRepeaterConfigPanel"),
|
||||
|
||||
// ========== 기본 입력 컴포넌트 ==========
|
||||
"text-input": () => import("@/lib/registry/components/text-input/TextInputConfigPanel"),
|
||||
"number-input": () => import("@/lib/registry/components/number-input/NumberInputConfigPanel"),
|
||||
@@ -116,21 +128,37 @@ export async function getComponentConfigPanel(componentId: string): Promise<Reac
|
||||
|
||||
// 모듈에서 ConfigPanel 컴포넌트 추출
|
||||
// 1차: PascalCase 변환된 이름으로 찾기 (예: text-input -> TextInputConfigPanel)
|
||||
// 2차: 특수 export명들 fallback
|
||||
// 3차: default export
|
||||
// 2차: v2- 접두사 제거 후 PascalCase 이름으로 찾기 (예: v2-table-list -> TableListConfigPanel)
|
||||
// 3차: 특수 export명들 fallback
|
||||
// 4차: default export
|
||||
const pascalCaseName = `${toPascalCase(componentId)}ConfigPanel`;
|
||||
// v2- 접두사가 있는 경우 접두사를 제거한 이름도 시도
|
||||
const baseComponentId = componentId.startsWith("v2-") ? componentId.slice(3) : componentId;
|
||||
const basePascalCaseName = `${toPascalCase(baseComponentId)}ConfigPanel`;
|
||||
|
||||
const ConfigPanelComponent =
|
||||
module[pascalCaseName] ||
|
||||
module[basePascalCaseName] ||
|
||||
// 특수 export명들
|
||||
module.RepeaterConfigPanel ||
|
||||
module.FlowWidgetConfigPanel ||
|
||||
module.CustomerItemMappingConfigPanel ||
|
||||
module.SelectedItemsDetailInputConfigPanel ||
|
||||
module.ButtonConfigPanel ||
|
||||
module.TableListConfigPanel ||
|
||||
module.SectionCardConfigPanel ||
|
||||
module.SectionPaperConfigPanel ||
|
||||
module.TabsConfigPanel ||
|
||||
module.UnifiedRepeaterConfigPanel ||
|
||||
module.UnifiedInputConfigPanel ||
|
||||
module.UnifiedSelectConfigPanel ||
|
||||
module.UnifiedDateConfigPanel ||
|
||||
module.UnifiedListConfigPanel ||
|
||||
module.UnifiedMediaConfigPanel ||
|
||||
module.UnifiedBizConfigPanel ||
|
||||
module.UnifiedGroupConfigPanel ||
|
||||
module.UnifiedHierarchyConfigPanel ||
|
||||
module.UnifiedLayoutConfigPanel ||
|
||||
module.RepeatContainerConfigPanel ||
|
||||
module.ScreenSplitPanelConfigPanel ||
|
||||
module.SimpleRepeaterTableConfigPanel ||
|
||||
@@ -491,6 +519,20 @@ export const DynamicComponentConfigPanel: React.FC<ComponentConfigPanelProps> =
|
||||
return <ConfigPanelComponent config={config} onConfigChange={onChange} />;
|
||||
}
|
||||
|
||||
// 🆕 Unified 컴포넌트들은 전용 props 사용
|
||||
if (componentId.startsWith("unified-")) {
|
||||
return (
|
||||
<ConfigPanelComponent
|
||||
config={config}
|
||||
onChange={onChange}
|
||||
menuObjid={menuObjid}
|
||||
inputType={currentComponent?.inputType || config?.inputType}
|
||||
screenTableName={screenTableName}
|
||||
tableColumns={selectedTableColumns}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// entity-search-input은 currentComponent 정보 필요 (참조 테이블 자동 로드용)
|
||||
// 그리고 allComponents 필요 (연쇄관계 부모 필드 선택용)
|
||||
if (componentId === "entity-search-input") {
|
||||
@@ -520,6 +562,50 @@ export const DynamicComponentConfigPanel: React.FC<ComponentConfigPanelProps> =
|
||||
);
|
||||
}
|
||||
|
||||
// 🆕 ButtonConfigPanel은 component와 onUpdateProperty를 사용
|
||||
if (componentId === "button-primary" || componentId === "v2-button-primary") {
|
||||
// currentComponent가 있으면 그것을 사용, 없으면 config에서 component 구조 생성
|
||||
const componentForButton = currentComponent || {
|
||||
id: "temp",
|
||||
type: "component",
|
||||
componentType: componentId,
|
||||
componentConfig: config,
|
||||
};
|
||||
|
||||
return (
|
||||
<ConfigPanelComponent
|
||||
component={componentForButton}
|
||||
onUpdateProperty={(path: string, value: any) => {
|
||||
// path가 componentConfig로 시작하면 내부 경로 추출
|
||||
if (path.startsWith("componentConfig.")) {
|
||||
const configPath = path.replace("componentConfig.", "");
|
||||
const pathParts = configPath.split(".");
|
||||
|
||||
// 중첩된 경로 처리 - 현재 config를 기반으로 새 config 생성
|
||||
const currentConfig = componentForButton.componentConfig || {};
|
||||
const newConfig = JSON.parse(JSON.stringify(currentConfig)); // deep clone
|
||||
let current: any = newConfig;
|
||||
for (let i = 0; i < pathParts.length - 1; i++) {
|
||||
if (!current[pathParts[i]]) {
|
||||
current[pathParts[i]] = {};
|
||||
}
|
||||
current = current[pathParts[i]];
|
||||
}
|
||||
current[pathParts[pathParts.length - 1]] = value;
|
||||
|
||||
onChange(newConfig);
|
||||
} else {
|
||||
// 직접 config 속성 변경
|
||||
const currentConfig = componentForButton.componentConfig || {};
|
||||
onChange({ ...currentConfig, [path]: value });
|
||||
}
|
||||
}}
|
||||
allComponents={allComponents}
|
||||
currentTableName={screenTableName}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<ConfigPanelComponent
|
||||
config={config}
|
||||
|
||||
Reference in New Issue
Block a user