- 레거시 컴포넌트를 제거하고, V2 및 Unified 컴포넌트 전용 Zod 스키마와 기본값 레지스트리를 통합 관리합니다. - V2 컴포넌트와 Unified 컴포넌트의 overrides 스키마를 정의하고, 기본값과의 병합 로직을 추가하였습니다. - 레이아웃 조회 시 V2 테이블을 우선적으로 조회하고, 없을 경우 V1 테이블을 조회하도록 개선하였습니다. - 관련된 테스트 계획 및 에러 처리 계획을 수립하여 안정성을 높였습니다.
141 lines
3.6 KiB
TypeScript
141 lines
3.6 KiB
TypeScript
/**
|
|
* V2 레이아웃 변환 유틸리티
|
|
*
|
|
* 기존 LayoutData ↔ V2 LayoutData 변환
|
|
*/
|
|
|
|
import {
|
|
ComponentV2,
|
|
LayoutV2,
|
|
getComponentUrl,
|
|
getComponentTypeFromUrl,
|
|
getDefaultsByUrl,
|
|
mergeComponentConfig,
|
|
extractCustomConfig
|
|
} from "@/lib/schemas/componentConfig";
|
|
|
|
// 기존 ComponentData 타입 (간략화)
|
|
interface LegacyComponentData {
|
|
id: string;
|
|
componentType?: string;
|
|
widgetType?: string;
|
|
type?: string;
|
|
position?: { x: number; y: number };
|
|
size?: { width: number; height: number };
|
|
componentConfig?: Record<string, any>;
|
|
[key: string]: any;
|
|
}
|
|
|
|
interface LegacyLayoutData {
|
|
components: LegacyComponentData[];
|
|
gridSettings?: any;
|
|
screenResolution?: any;
|
|
metadata?: any;
|
|
}
|
|
|
|
// ============================================
|
|
// V2 → Legacy 변환 (로드 시)
|
|
// ============================================
|
|
export function convertV2ToLegacy(v2Layout: LayoutV2 | null): LegacyLayoutData | null {
|
|
if (!v2Layout || !v2Layout.components) {
|
|
return null;
|
|
}
|
|
|
|
const components: LegacyComponentData[] = v2Layout.components.map((comp) => {
|
|
const componentType = getComponentTypeFromUrl(comp.url);
|
|
const defaults = getDefaultsByUrl(comp.url);
|
|
const mergedConfig = mergeComponentConfig(defaults, comp.overrides);
|
|
|
|
return {
|
|
id: comp.id,
|
|
componentType: componentType,
|
|
widgetType: componentType,
|
|
type: "component",
|
|
position: comp.position,
|
|
size: comp.size,
|
|
componentConfig: mergedConfig,
|
|
// 기존 구조 호환을 위한 추가 필드
|
|
label: mergedConfig.label || componentType,
|
|
style: {},
|
|
parentId: null,
|
|
gridColumns: 12,
|
|
gridRowIndex: 0,
|
|
};
|
|
});
|
|
|
|
return {
|
|
components,
|
|
gridSettings: v2Layout.gridSettings || {
|
|
enabled: true,
|
|
size: 20,
|
|
color: "#d1d5db",
|
|
opacity: 0.5,
|
|
snapToGrid: true,
|
|
columns: 12,
|
|
gap: 16,
|
|
padding: 16,
|
|
},
|
|
screenResolution: v2Layout.screenResolution || {
|
|
width: 1920,
|
|
height: 1080,
|
|
},
|
|
};
|
|
}
|
|
|
|
// ============================================
|
|
// Legacy → V2 변환 (저장 시)
|
|
// ============================================
|
|
export function convertLegacyToV2(legacyLayout: LegacyLayoutData): LayoutV2 {
|
|
const components: ComponentV2[] = legacyLayout.components.map((comp, index) => {
|
|
// 컴포넌트 타입 결정
|
|
const componentType = comp.componentType || comp.widgetType || comp.type || "unknown";
|
|
const url = getComponentUrl(componentType);
|
|
|
|
// 기본값 가져오기
|
|
const defaults = getDefaultsByUrl(url);
|
|
|
|
// 현재 설정에서 차이값만 추출
|
|
const fullConfig = comp.componentConfig || {};
|
|
const overrides = extractCustomConfig(fullConfig, defaults);
|
|
|
|
return {
|
|
id: comp.id,
|
|
url: url,
|
|
position: comp.position || { x: 0, y: 0 },
|
|
size: comp.size || { width: 100, height: 100 },
|
|
displayOrder: index,
|
|
overrides: overrides,
|
|
};
|
|
});
|
|
|
|
return {
|
|
version: "2.0",
|
|
components,
|
|
updatedAt: new Date().toISOString(),
|
|
};
|
|
}
|
|
|
|
// ============================================
|
|
// V2 레이아웃 유효성 검사
|
|
// ============================================
|
|
export function isValidV2Layout(data: any): data is LayoutV2 {
|
|
return (
|
|
data &&
|
|
typeof data === "object" &&
|
|
data.version === "2.0" &&
|
|
Array.isArray(data.components)
|
|
);
|
|
}
|
|
|
|
// ============================================
|
|
// 기존 레이아웃인지 확인
|
|
// ============================================
|
|
export function isLegacyLayout(data: any): boolean {
|
|
return (
|
|
data &&
|
|
typeof data === "object" &&
|
|
Array.isArray(data.components) &&
|
|
data.version !== "2.0"
|
|
);
|
|
}
|