docs: 다양한 문서 및 가이드 업데이트
- 여러 문서의 내용을 업데이트하여 최신 정보를 반영하였습니다. - 컴포넌트 개발 가이드와 관련된 문서의 목차를 재구성하고, V2 및 Zod 레이아웃 시스템에 대한 내용을 추가하였습니다. - 화면 컴포넌트 개발 가이드를 개선하여 핵심 원칙과 패턴을 명확히 설명하였습니다. - 불필요한 문서 및 가이드를 삭제하고, 통합된 가이드를 통해 개발자들이 쉽게 참고할 수 있도록 하였습니다.
This commit is contained in:
@@ -43,26 +43,26 @@ export function ComponentsPanel({
|
||||
return components;
|
||||
}, []);
|
||||
|
||||
// Unified 컴포넌트 정의 (새로운 통합 컴포넌트 시스템)
|
||||
// 입력 컴포넌트(unified-input, unified-select, unified-date)는 테이블 컬럼 드래그 시 자동 생성되므로 숨김
|
||||
const unifiedComponents = useMemo(
|
||||
// V2 컴포넌트 정의 (새로운 통합 컴포넌트 시스템)
|
||||
// 입력 컴포넌트(v2-input, v2-select, v2-date)는 테이블 컬럼 드래그 시 자동 생성되므로 숨김
|
||||
const v2Components = useMemo(
|
||||
() =>
|
||||
[
|
||||
// unified-input: 테이블 컬럼 드래그 시 자동 생성되므로 숨김 처리
|
||||
// unified-select: 테이블 컬럼 드래그 시 자동 생성되므로 숨김 처리
|
||||
// unified-date: 테이블 컬럼 드래그 시 자동 생성되므로 숨김 처리
|
||||
// unified-layout: 중첩 드래그앤드롭 기능 미구현으로 숨김 처리
|
||||
// unified-group: 중첩 드래그앤드롭 기능 미구현으로 숨김 처리
|
||||
// unified-list: table-list, card-display로 분리하여 숨김 처리
|
||||
// unified-media 제거 - 테이블 컬럼의 image/file 입력 타입으로 사용
|
||||
// unified-biz 제거 - 개별 컴포넌트(flow-widget, rack-structure, numbering-rule)로 직접 표시
|
||||
// unified-hierarchy 제거 - 현재 미사용
|
||||
// v2-input: 테이블 컬럼 드래그 시 자동 생성되므로 숨김 처리
|
||||
// v2-select: 테이블 컬럼 드래그 시 자동 생성되므로 숨김 처리
|
||||
// v2-date: 테이블 컬럼 드래그 시 자동 생성되므로 숨김 처리
|
||||
// v2-layout: 중첩 드래그앤드롭 기능 미구현으로 숨김 처리
|
||||
// v2-group: 중첩 드래그앤드롭 기능 미구현으로 숨김 처리
|
||||
// v2-list: table-list, card-display로 분리하여 숨김 처리
|
||||
// v2-media 제거 - 테이블 컬럼의 image/file 입력 타입으로 사용
|
||||
// v2-biz 제거 - 개별 컴포넌트(flow-widget, rack-structure, numbering-rule)로 직접 표시
|
||||
// v2-hierarchy 제거 - 현재 미사용
|
||||
{
|
||||
id: "v2-unified-repeater",
|
||||
id: "v2-repeater",
|
||||
name: "리피터 그리드",
|
||||
description: "행 단위로 데이터를 추가/수정/삭제",
|
||||
category: "data" as ComponentCategory,
|
||||
tags: ["repeater", "table", "modal", "button", "unified", "v2"],
|
||||
tags: ["repeater", "table", "modal", "button", "v2", "v2"],
|
||||
defaultSize: { width: 600, height: 300 },
|
||||
},
|
||||
] as ComponentDefinition[],
|
||||
@@ -78,24 +78,24 @@ export function ComponentsPanel({
|
||||
"number-input",
|
||||
"date-input",
|
||||
"textarea-basic",
|
||||
// Unified 컴포넌트로 대체됨
|
||||
"image-widget", // → UnifiedMedia (image)
|
||||
"file-upload", // → UnifiedMedia (file)
|
||||
"entity-search-input", // → UnifiedSelect (entity 모드)
|
||||
"autocomplete-search-input", // → UnifiedSelect (autocomplete 모드)
|
||||
// V2 컴포넌트로 대체됨
|
||||
"image-widget", // → V2Media (image)
|
||||
"file-upload", // → V2Media (file)
|
||||
"entity-search-input", // → V2Select (entity 모드)
|
||||
"autocomplete-search-input", // → V2Select (autocomplete 모드)
|
||||
// DataFlow 전용 (일반 화면에서 불필요)
|
||||
"mail-recipient-selector",
|
||||
// 현재 사용 안함
|
||||
"repeater-field-group",
|
||||
// unified-repeater로 통합됨
|
||||
"simple-repeater-table", // → unified-repeater (inline 모드)
|
||||
"modal-repeater-table", // → unified-repeater (modal 모드)
|
||||
// v2-repeater로 통합됨
|
||||
"simple-repeater-table", // → v2-repeater (inline 모드)
|
||||
"modal-repeater-table", // → v2-repeater (modal 모드)
|
||||
// 특수 업무용 컴포넌트 (일반 화면에서 불필요)
|
||||
"tax-invoice-list", // 세금계산서 전용
|
||||
"customer-item-mapping", // 고객-품목 매핑 전용
|
||||
// card-display는 별도 컴포넌트로 유지
|
||||
// unified-media로 통합됨
|
||||
"image-display", // → unified-media (image)
|
||||
// v2-media로 통합됨
|
||||
"image-display", // → v2-media (image)
|
||||
// 공통코드관리로 통합 예정
|
||||
"category-manager", // → 공통코드관리 기능으로 통합 예정
|
||||
// 분할 패널 정리 (split-panel-layout v1 유지)
|
||||
@@ -106,12 +106,12 @@ export function ComponentsPanel({
|
||||
"conditional-container", // 조건부 컨테이너
|
||||
"universal-form-modal", // 범용 폼 모달
|
||||
// 통합 미디어 (테이블 컬럼 입력 타입으로 사용)
|
||||
"unified-media", // → 테이블 컬럼의 image/file 입력 타입으로 사용
|
||||
"v2-media", // → 테이블 컬럼의 image/file 입력 타입으로 사용
|
||||
// 플로우 위젯 숨김 처리
|
||||
"flow-widget",
|
||||
// 선택 항목 상세입력 - 기존 컴포넌트 조합으로 대체 가능
|
||||
"selected-items-detail-input",
|
||||
// 연관 데이터 버튼 - unified-repeater로 대체 가능
|
||||
// 연관 데이터 버튼 - v2-repeater로 대체 가능
|
||||
"related-data-buttons",
|
||||
// ===== V2로 대체된 기존 컴포넌트 (v2 버전만 사용) =====
|
||||
"button-primary", // → v2-button-primary
|
||||
@@ -126,7 +126,7 @@ export function ComponentsPanel({
|
||||
"section-card", // → v2-section-card
|
||||
"location-swap-selector", // → v2-location-swap-selector
|
||||
"rack-structure", // → v2-rack-structure
|
||||
"unified-repeater", // → v2-unified-repeater (아래 unifiedComponents에서 별도 처리)
|
||||
"v2-repeater", // → v2-repeater (아래 v2Components에서 별도 처리)
|
||||
"repeat-container", // → v2-repeat-container
|
||||
"repeat-screen-modal", // → v2-repeat-screen-modal
|
||||
"pivot-grid", // → v2-pivot-grid
|
||||
@@ -146,9 +146,9 @@ export function ComponentsPanel({
|
||||
utility: allComponents.filter(
|
||||
(c) => c.category === ComponentCategory.UTILITY && !hiddenComponents.includes(c.id),
|
||||
),
|
||||
unified: unifiedComponents,
|
||||
v2: v2Components,
|
||||
};
|
||||
}, [allComponents, unifiedComponents]);
|
||||
}, [allComponents, v2Components]);
|
||||
|
||||
// 카테고리별 검색 필터링
|
||||
const getFilteredComponents = (category: keyof typeof componentsByCategory) => {
|
||||
@@ -322,7 +322,7 @@ export function ComponentsPanel({
|
||||
<TabsContent value="components" className="mt-0 flex-1 space-y-2 overflow-y-auto">
|
||||
{(() => {
|
||||
const allFilteredComponents = [
|
||||
...getFilteredComponents("unified"),
|
||||
...getFilteredComponents("v2"),
|
||||
...getFilteredComponents("action"),
|
||||
...getFilteredComponents("display"),
|
||||
...getFilteredComponents("data"),
|
||||
|
||||
@@ -22,8 +22,8 @@ import { FileComponentConfigPanel } from "./FileComponentConfigPanel";
|
||||
import { WebTypeConfigPanel } from "./WebTypeConfigPanel";
|
||||
import { isFileComponent } from "@/lib/utils/componentTypeUtils";
|
||||
import { BaseInputType, getBaseInputType, getDetailTypes, DetailTypeOption } from "@/types/input-type-mapping";
|
||||
import { ConditionalConfigPanel } from "@/components/unified/ConditionalConfigPanel";
|
||||
import { ConditionalConfig } from "@/types/unified-components";
|
||||
import { ConditionalConfigPanel } from "@/components/v2/ConditionalConfigPanel";
|
||||
import { ConditionalConfig } from "@/types/v2-components";
|
||||
|
||||
// 새로운 컴포넌트 설정 패널들 import
|
||||
import { ButtonConfigPanel as NewButtonConfigPanel } from "../config-panels/ButtonConfigPanel";
|
||||
|
||||
@@ -61,10 +61,10 @@ import { DynamicComponentConfigPanel } from "@/lib/utils/getComponentConfigPanel
|
||||
import StyleEditor from "../StyleEditor";
|
||||
import { Slider } from "@/components/ui/slider";
|
||||
import { Zap } from "lucide-react";
|
||||
import { ConditionalConfigPanel } from "@/components/unified/ConditionalConfigPanel";
|
||||
import { ConditionalConfig } from "@/types/unified-components";
|
||||
import { ConditionalConfigPanel } from "@/components/v2/ConditionalConfigPanel";
|
||||
import { ConditionalConfig } from "@/types/v2-components";
|
||||
|
||||
interface UnifiedPropertiesPanelProps {
|
||||
interface V2PropertiesPanelProps {
|
||||
selectedComponent?: ComponentData;
|
||||
tables: TableInfo[];
|
||||
onUpdateProperty: (componentId: string, path: string, value: any) => void;
|
||||
@@ -83,7 +83,7 @@ interface UnifiedPropertiesPanelProps {
|
||||
currentScreenCompanyCode?: string;
|
||||
}
|
||||
|
||||
export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
|
||||
export const V2PropertiesPanel: React.FC<V2PropertiesPanelProps> = ({
|
||||
selectedComponent,
|
||||
tables,
|
||||
onUpdateProperty,
|
||||
@@ -204,27 +204,27 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
|
||||
selectedComponent.componentConfig?.id ||
|
||||
(selectedComponent.type === "component" ? selectedComponent.id : null); // 🆕 독립 컴포넌트 (table-search-widget 등)
|
||||
|
||||
// 🆕 Unified 컴포넌트 직접 감지 및 설정 패널 렌더링
|
||||
if (componentId?.startsWith("unified-")) {
|
||||
const unifiedConfigPanels: Record<string, React.FC<{ config: any; onChange: (config: any) => void }>> = {
|
||||
"unified-input": require("@/components/unified/config-panels/UnifiedInputConfigPanel").UnifiedInputConfigPanel,
|
||||
"unified-select": require("@/components/unified/config-panels/UnifiedSelectConfigPanel")
|
||||
.UnifiedSelectConfigPanel,
|
||||
"unified-date": require("@/components/unified/config-panels/UnifiedDateConfigPanel").UnifiedDateConfigPanel,
|
||||
"unified-list": require("@/components/unified/config-panels/UnifiedListConfigPanel").UnifiedListConfigPanel,
|
||||
"unified-layout": require("@/components/unified/config-panels/UnifiedLayoutConfigPanel")
|
||||
.UnifiedLayoutConfigPanel,
|
||||
"unified-group": require("@/components/unified/config-panels/UnifiedGroupConfigPanel").UnifiedGroupConfigPanel,
|
||||
"unified-media": require("@/components/unified/config-panels/UnifiedMediaConfigPanel").UnifiedMediaConfigPanel,
|
||||
"unified-biz": require("@/components/unified/config-panels/UnifiedBizConfigPanel").UnifiedBizConfigPanel,
|
||||
"unified-hierarchy": require("@/components/unified/config-panels/UnifiedHierarchyConfigPanel")
|
||||
.UnifiedHierarchyConfigPanel,
|
||||
// 🆕 V2 컴포넌트 직접 감지 및 설정 패널 렌더링
|
||||
if (componentId?.startsWith("v2-")) {
|
||||
const v2ConfigPanels: Record<string, React.FC<{ config: any; onChange: (config: any) => void }>> = {
|
||||
"v2-input": require("@/components/v2/config-panels/V2InputConfigPanel").V2InputConfigPanel,
|
||||
"v2-select": require("@/components/v2/config-panels/V2SelectConfigPanel")
|
||||
.V2SelectConfigPanel,
|
||||
"v2-date": require("@/components/v2/config-panels/V2DateConfigPanel").V2DateConfigPanel,
|
||||
"v2-list": require("@/components/v2/config-panels/V2ListConfigPanel").V2ListConfigPanel,
|
||||
"v2-layout": require("@/components/v2/config-panels/V2LayoutConfigPanel")
|
||||
.V2LayoutConfigPanel,
|
||||
"v2-group": require("@/components/v2/config-panels/V2GroupConfigPanel").V2GroupConfigPanel,
|
||||
"v2-media": require("@/components/v2/config-panels/V2MediaConfigPanel").V2MediaConfigPanel,
|
||||
"v2-biz": require("@/components/v2/config-panels/V2BizConfigPanel").V2BizConfigPanel,
|
||||
"v2-hierarchy": require("@/components/v2/config-panels/V2HierarchyConfigPanel")
|
||||
.V2HierarchyConfigPanel,
|
||||
};
|
||||
|
||||
const UnifiedConfigPanel = unifiedConfigPanels[componentId];
|
||||
if (UnifiedConfigPanel) {
|
||||
const V2ConfigPanel = v2ConfigPanels[componentId];
|
||||
if (V2ConfigPanel) {
|
||||
const currentConfig = selectedComponent.componentConfig || {};
|
||||
const handleUnifiedConfigChange = (newConfig: any) => {
|
||||
const handleV2ConfigChange = (newConfig: any) => {
|
||||
onUpdateProperty(selectedComponent.id, "componentConfig", { ...currentConfig, ...newConfig });
|
||||
};
|
||||
|
||||
@@ -236,16 +236,16 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
|
||||
|
||||
// 컴포넌트별 추가 props
|
||||
const extraProps: Record<string, any> = {};
|
||||
if (componentId === "unified-select") {
|
||||
if (componentId === "v2-select") {
|
||||
extraProps.inputType = inputType;
|
||||
}
|
||||
if (componentId === "unified-list") {
|
||||
if (componentId === "v2-list") {
|
||||
extraProps.currentTableName = currentTableName;
|
||||
}
|
||||
|
||||
return (
|
||||
<div key={selectedComponent.id} className="space-y-4">
|
||||
<UnifiedConfigPanel config={currentConfig} onChange={handleUnifiedConfigChange} {...extraProps} />
|
||||
<V2ConfigPanel config={currentConfig} onChange={handleV2ConfigChange} {...extraProps} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -685,16 +685,16 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
|
||||
"entity-search-input",
|
||||
"autocomplete-search-input",
|
||||
// 새로운 통합 입력 컴포넌트
|
||||
"unified-input",
|
||||
"unified-select",
|
||||
"unified-entity-select",
|
||||
"unified-checkbox",
|
||||
"unified-radio",
|
||||
"unified-textarea",
|
||||
"unified-date",
|
||||
"unified-datetime",
|
||||
"unified-time",
|
||||
"unified-file",
|
||||
"v2-input",
|
||||
"v2-select",
|
||||
"v2-entity-select",
|
||||
"v2-checkbox",
|
||||
"v2-radio",
|
||||
"v2-textarea",
|
||||
"v2-date",
|
||||
"v2-datetime",
|
||||
"v2-time",
|
||||
"v2-file",
|
||||
];
|
||||
|
||||
// 현재 컴포넌트가 입력 필드인지 확인
|
||||
@@ -942,10 +942,10 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
|
||||
);
|
||||
}
|
||||
|
||||
// 🆕 3.5. Unified 컴포넌트 - 반드시 다른 체크보다 먼저 처리
|
||||
const unifiedComponentType =
|
||||
// 🆕 3.5. V2 컴포넌트 - 반드시 다른 체크보다 먼저 처리
|
||||
const v2ComponentType =
|
||||
(selectedComponent as any).componentType || selectedComponent.componentConfig?.type || "";
|
||||
if (unifiedComponentType.startsWith("unified-")) {
|
||||
if (v2ComponentType.startsWith("v2-")) {
|
||||
const configPanel = renderComponentConfigPanel();
|
||||
if (configPanel) {
|
||||
return <div className="space-y-4">{configPanel}</div>;
|
||||
@@ -1232,7 +1232,7 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
|
||||
console.log("✅ [renderDetailTab] 일반 위젯 렌더링 시작");
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
{console.log("🔍 [UnifiedPropertiesPanel] widget.webType:", widget.webType, "widget:", widget)}
|
||||
{console.log("🔍 [V2PropertiesPanel] widget.webType:", widget.webType, "widget:", widget)}
|
||||
{/* WebType 선택 (있는 경우만) */}
|
||||
{widget.webType && (
|
||||
<div>
|
||||
@@ -1442,7 +1442,7 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
|
||||
?.filter((c) => {
|
||||
// 자기 자신 제외
|
||||
if (c.id === selectedComponent.id) return false;
|
||||
// widget 타입 또는 component 타입 (Unified 컴포넌트 포함)
|
||||
// widget 타입 또는 component 타입 (V2 컴포넌트 포함)
|
||||
return c.type === "widget" || c.type === "component";
|
||||
})
|
||||
.map((c) => {
|
||||
@@ -1453,7 +1453,7 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
|
||||
// 정적 옵션 추출 (select, dropdown, radio, entity 등)
|
||||
let options: Array<{ value: string; label: string }> | undefined;
|
||||
|
||||
// Unified 컴포넌트의 경우
|
||||
// V2 컴포넌트의 경우
|
||||
if (config.options && Array.isArray(config.options)) {
|
||||
options = config.options;
|
||||
}
|
||||
@@ -1529,4 +1529,4 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default UnifiedPropertiesPanel;
|
||||
export default V2PropertiesPanel;
|
||||
Reference in New Issue
Block a user