Files
vexplor/frontend/components/pop/designer/utils/legacyLoader.ts
SeongHyun Kim 320100c4e2 refactor: POP 그리드 시스템 명칭 통일 + Dead Code 제거
V5→V6 전환 과정에서 누적된 버전 접미사, 미사용 함수, 레거시 잔재를
정리하여 코드 관리성을 확보한다. 14개 파일 수정, 365줄 순감.
[타입 리네이밍] (14개 파일)
- PopLayoutDataV5 → PopLayoutData
- PopComponentDefinitionV5 → PopComponentDefinition
- PopGlobalSettingsV5 → PopGlobalSettings
- PopModeOverrideV5 → PopModeOverride
- createEmptyPopLayoutV5 → createEmptyLayout
- isV5Layout → isPopLayout
- addComponentToV5Layout → addComponentToLayout
- createComponentDefinitionV5 → createComponentDefinition
- 구 이름은 deprecated 별칭으로 유지 (하위 호환)
[Dead Code 삭제] (gridUtils.ts -350줄)
- getAdjustedBreakpoint, convertPositionToMode, isOutOfBounds,
  mouseToGridPosition, gridToPixelPosition, isValidPosition,
  clampPosition, autoLayoutComponents (전부 외부 사용 0건)
- needsReview + ReviewPanel/ReviewItem (항상 false, 미사용)
- getEffectiveComponentPosition export → 내부 함수로 전환
[레거시 로더 분리] (신규 legacyLoader.ts)
- convertV5LayoutToV6 → loadLegacyLayout (legacyLoader.ts)
- V5 변환 상수/함수를 gridUtils에서 분리
[주석 정리]
- "v5 그리드" → "POP 블록 그리드"
- "하위 호환용" → "뷰포트 프리셋" / "레이아웃 설정용"
- 파일 헤더, 섹션 구분, 함수 JSDoc 정리
기능 변경 0건. DB 변경 0건. 백엔드 변경 0건.
2026-03-13 16:39:51 +09:00

129 lines
3.7 KiB
TypeScript

// 레거시 레이아웃 로더
// DB에 저장된 V5(12칸) 좌표를 현재 블록 좌표로 변환한다.
// DB 데이터는 건드리지 않고, 로드 시 메모리에서만 변환.
import {
PopGridPosition,
PopLayoutData,
BLOCK_SIZE,
BLOCK_GAP,
BLOCK_PADDING,
getBlockColumns,
} from "../types/pop-layout";
const LEGACY_COLUMNS = 12;
const LEGACY_ROW_HEIGHT = 48;
const LEGACY_GAP = 16;
const DESIGN_WIDTH = 1024;
function isLegacyGridConfig(layout: PopLayoutData): boolean {
if (layout.gridConfig?.rowHeight === BLOCK_SIZE) return false;
const maxCol = Object.values(layout.components).reduce((max, comp) => {
const end = comp.position.col + comp.position.colSpan - 1;
return Math.max(max, end);
}, 0);
return maxCol <= LEGACY_COLUMNS;
}
function convertLegacyPosition(
pos: PopGridPosition,
targetColumns: number,
): PopGridPosition {
const colRatio = targetColumns / LEGACY_COLUMNS;
const rowRatio = (LEGACY_ROW_HEIGHT + LEGACY_GAP) / (BLOCK_SIZE + BLOCK_GAP);
const newCol = Math.max(1, Math.round((pos.col - 1) * colRatio) + 1);
let newColSpan = Math.max(1, Math.round(pos.colSpan * colRatio));
const newRowSpan = Math.max(1, Math.round(pos.rowSpan * rowRatio));
if (newCol + newColSpan - 1 > targetColumns) {
newColSpan = targetColumns - newCol + 1;
}
return { col: newCol, row: pos.row, colSpan: newColSpan, rowSpan: newRowSpan };
}
const BLOCK_GRID_CONFIG = {
rowHeight: BLOCK_SIZE,
gap: BLOCK_GAP,
padding: BLOCK_PADDING,
};
/**
* DB에서 로드한 레이아웃을 현재 블록 좌표로 변환한다.
*
* - 12칸 레거시 좌표 → 블록 좌표 변환
* - 이미 블록 좌표인 경우 → gridConfig만 보정
* - 구 모드별 overrides는 항상 제거 (리플로우가 대체)
*/
export function loadLegacyLayout(layout: PopLayoutData): PopLayoutData {
if (!isLegacyGridConfig(layout)) {
return {
...layout,
gridConfig: BLOCK_GRID_CONFIG,
overrides: undefined,
};
}
const blockColumns = getBlockColumns(DESIGN_WIDTH);
const rowGroups: Record<number, string[]> = {};
Object.entries(layout.components).forEach(([id, comp]) => {
const r = comp.position.row;
if (!rowGroups[r]) rowGroups[r] = [];
rowGroups[r].push(id);
});
const convertedPositions: Record<string, PopGridPosition> = {};
Object.entries(layout.components).forEach(([id, comp]) => {
convertedPositions[id] = convertLegacyPosition(comp.position, blockColumns);
});
const sortedRows = Object.keys(rowGroups).map(Number).sort((a, b) => a - b);
const rowMapping: Record<number, number> = {};
let currentRow = 1;
for (const legacyRow of sortedRows) {
rowMapping[legacyRow] = currentRow;
const maxSpan = Math.max(
...rowGroups[legacyRow].map(id => convertedPositions[id].rowSpan)
);
currentRow += maxSpan;
}
const newComponents = { ...layout.components };
Object.entries(newComponents).forEach(([id, comp]) => {
const converted = convertedPositions[id];
const mappedRow = rowMapping[comp.position.row] ?? converted.row;
newComponents[id] = {
...comp,
position: { ...converted, row: mappedRow },
};
});
const newModals = layout.modals?.map(modal => {
const modalComps = { ...modal.components };
Object.entries(modalComps).forEach(([id, comp]) => {
modalComps[id] = {
...comp,
position: convertLegacyPosition(comp.position, blockColumns),
};
});
return {
...modal,
gridConfig: BLOCK_GRID_CONFIG,
components: modalComps,
overrides: undefined,
};
});
return {
...layout,
gridConfig: BLOCK_GRID_CONFIG,
components: newComponents,
overrides: undefined,
modals: newModals,
};
}