docs: 다양한 문서 및 가이드 업데이트

- 여러 문서의 내용을 업데이트하여 최신 정보를 반영하였습니다.
- 컴포넌트 개발 가이드와 관련된 문서의 목차를 재구성하고, V2 및 Zod 레이아웃 시스템에 대한 내용을 추가하였습니다.
- 화면 컴포넌트 개발 가이드를 개선하여 핵심 원칙과 패턴을 명확히 설명하였습니다.
- 불필요한 문서 및 가이드를 삭제하고, 통합된 가이드를 통해 개발자들이 쉽게 참고할 수 있도록 하였습니다.
This commit is contained in:
kjs
2026-01-28 17:36:19 +09:00
parent e0ee375f01
commit 95bef976a5
276 changed files with 2544 additions and 2495 deletions

View File

@@ -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"),

View File

@@ -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";

View File

@@ -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;