에디터 정리 및 버그 수정
CI / test (push) Failing after 13m50s
CI / pr_and_merge (push) Has been cancelled

This commit is contained in:
2025-12-01 13:34:16 +09:00
parent 5f541e9524
commit 6ad731b6e2
76 changed files with 1348 additions and 29 deletions
+59 -4
View File
@@ -116,6 +116,13 @@ export interface ButtonBlockProps {
strokeColorCustom?: string;
// 버튼 텍스트 색상 커스텀 값
textColorCustom?: string;
// 폼 컨트롤러에서 Submit 버튼 매핑 시 사용할 수 있는 전송 키 (name 역할)
formFieldName?: string;
imageSrc?: string;
imageAlt?: string;
imageSourceType?: "asset" | "externalUrl";
imageAssetId?: string | null;
imagePlacement?: "left" | "right" | "top" | "bottom";
}
// 이미지 블록 속성
@@ -768,12 +775,22 @@ export interface EditorState {
redo: () => void;
removeBlock: (id: string) => void;
duplicateBlock: (id: string) => void;
resetHistory: () => void;
}
// 간단한 ID 생성기 (추후 uuid 라이브러리로 교체 가능)
let idCounter = 0;
const createId = () => `blk_${Date.now()}_${idCounter++}`;
// undo/redo 를 위한 히스토리 유틸리티: 상태 변경 전에 현재 blocks 스냅샷을 history 에 쌓고 future 는 비운다.
const pushHistoryImpl = (set: any, get: any) => {
const { blocks } = get() as EditorState;
set((state: EditorState) => ({
history: [...state.history, blocks],
future: [],
}));
};
const getNextFormFieldName = (blocks: Block[], prefix: string): string => {
const regex = new RegExp(`^${prefix}-(\\d+)$`);
let max = 0;
@@ -795,7 +812,16 @@ const getNextFormFieldName = (blocks: Block[], prefix: string): string => {
// 에디터 스토어 생성 함수 (테스트 및 앱에서 공유 사용)
// set/get 은 zustand 내부 구현에 의해 주입되므로, 여기서는 any 로 완화해 사용한다.
const createEditorState = (set: any, get: any): EditorState => ({
const createEditorState = (set: any, get: any): EditorState => {
const pushHistory = () => {
const { blocks } = get() as EditorState;
set((state: EditorState) => ({
history: [...state.history, blocks],
future: [],
}));
};
return {
blocks: [],
selectedBlockId: null,
selectedListItemId: null,
@@ -860,11 +886,10 @@ const createEditorState = (set: any, get: any): EditorState => ({
columnId,
};
pushHistoryImpl(set, get);
set((state: EditorState) => ({
blocks: [...state.blocks, newBlock],
selectedBlockId: id,
history: [...state.history, blocks],
future: [],
}));
},
@@ -887,6 +912,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
createId,
});
pushHistoryImpl(set, get);
set((state: EditorState) => {
let baseBlocks = state.blocks as Block[];
if (replacingSectionId) {
@@ -928,6 +954,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
createId,
});
pushHistoryImpl(set, get);
set((state: EditorState) => {
let baseBlocks = state.blocks as Block[];
if (replacingSectionId) {
@@ -964,6 +991,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
createId,
});
pushHistoryImpl(set, get);
set((state: EditorState) => {
let baseBlocks = state.blocks as Block[];
if (replacingSectionId) {
@@ -1000,6 +1028,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
createId,
});
pushHistoryImpl(set, get);
set((state: EditorState) => {
let baseBlocks = state.blocks as Block[];
if (replacingSectionId) {
@@ -1036,6 +1065,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
createId,
});
pushHistoryImpl(set, get);
set((state: EditorState) => {
let baseBlocks = state.blocks as Block[];
if (replacingSectionId) {
@@ -1072,6 +1102,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
createId,
});
pushHistoryImpl(set, get);
set((state: EditorState) => {
let baseBlocks = state.blocks as Block[];
if (replacingSectionId) {
@@ -1108,6 +1139,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
createId,
});
pushHistoryImpl(set, get);
set((state: EditorState) => {
let baseBlocks = state.blocks as Block[];
if (replacingSectionId) {
@@ -1144,6 +1176,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
createId,
});
pushHistoryImpl(set, get);
set((state: EditorState) => {
let baseBlocks = state.blocks as Block[];
if (replacingSectionId) {
@@ -1180,6 +1213,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
createId,
});
pushHistoryImpl(set, get);
set((state: EditorState) => {
let baseBlocks = state.blocks as Block[];
if (replacingSectionId) {
@@ -1233,6 +1267,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
columnId,
};
pushHistoryImpl(set, get);
set((state: EditorState) => ({
blocks: [...state.blocks, newBlock],
selectedBlockId: id,
@@ -1279,6 +1314,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
columnId,
};
pushHistoryImpl(set, get);
set((state: EditorState) => ({
blocks: [...state.blocks, newBlock],
selectedBlockId: id,
@@ -1318,6 +1354,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
columnId: null,
};
pushHistoryImpl(set, get);
set((state: EditorState) => ({
blocks: [...state.blocks, newBlock],
selectedBlockId: id,
@@ -1359,6 +1396,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
columnId: null,
};
pushHistoryImpl(set, get);
set((state: EditorState) => ({
blocks: [...state.blocks, newBlock],
selectedBlockId: id,
@@ -1401,6 +1439,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
columnId: null,
};
pushHistoryImpl(set, get);
set((state: EditorState) => ({
blocks: [...state.blocks, newBlock],
selectedBlockId: id,
@@ -1443,6 +1482,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
columnId: null,
};
pushHistoryImpl(set, get);
set((state: EditorState) => ({
blocks: [...state.blocks, newBlock],
selectedBlockId: id,
@@ -1483,6 +1523,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
columnId,
};
pushHistoryImpl(set, get);
set((state: EditorState) => ({
blocks: [...state.blocks, newBlock],
selectedBlockId: id,
@@ -1530,6 +1571,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
columnId,
};
pushHistoryImpl(set, get);
set((state: EditorState) => ({
blocks: [...state.blocks, newBlock],
selectedBlockId: id,
@@ -1556,6 +1598,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
columnId: null,
};
pushHistoryImpl(set, get);
set((state: EditorState) => ({
blocks: [...state.blocks, newBlock],
selectedBlockId: id,
@@ -1606,6 +1649,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
columnId: null,
};
pushHistoryImpl(set, get);
set((state: EditorState) => ({
blocks: [...state.blocks, newBlock],
selectedBlockId: id,
@@ -1660,6 +1704,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
columnId,
};
pushHistoryImpl(set, get);
set((state: EditorState) => ({
blocks: [...state.blocks, newBlock],
selectedBlockId: id,
@@ -1668,6 +1713,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
// 특정 블록의 속성을 부분 업데이트 (텍스트/버튼 공통 사용)
updateBlock: (id, partial) => {
pushHistoryImpl(set, get);
set((state: EditorState) => ({
blocks: state.blocks.map((block: Block) =>
block.id === id
@@ -1816,6 +1862,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
},
replaceBlocks: (blocks) => {
pushHistoryImpl(set, get);
set({
blocks,
selectedBlockId: blocks.length > 0 ? blocks[0].id : null,
@@ -1823,6 +1870,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
},
reorderBlocks: (activeId, overId) => {
pushHistoryImpl(set, get);
set((state: EditorState) => {
const current = state.blocks;
const oldIndex = current.findIndex((b: Block) => b.id === activeId);
@@ -1840,6 +1888,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
});
},
moveBlock: (id, sectionId, columnId) => {
pushHistoryImpl(set, get);
set((state: EditorState) => ({
blocks: state.blocks.map((block: Block) =>
block.id === id
@@ -1853,6 +1902,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
}));
},
removeBlock: (id) => {
pushHistoryImpl(set, get);
set((state: EditorState) => {
const current = state.blocks;
const index = current.findIndex((b) => b.id === id);
@@ -1884,6 +1934,7 @@ const createEditorState = (set: any, get: any): EditorState => ({
});
},
duplicateBlock: (id) => {
pushHistoryImpl(set, get);
set((state: EditorState) => {
const current = state.blocks;
const index = current.findIndex((b) => b.id === id);
@@ -1939,7 +1990,11 @@ const createEditorState = (set: any, get: any): EditorState => ({
future: nextFuture,
}));
},
});
resetHistory: () => {
set({ history: [], future: [] });
},
};
};
// React 컴포넌트에서 사용하는 전역 훅 스토어
export const useEditorStore = create<EditorState>()(createEditorState);