feat(WEB): 3depth 메뉴 구조 지원 및 CEO 대시보드 개선
- 사이드바 메뉴 3depth 이상 지원 (재귀 컴포넌트) - menuTransform.ts: buildChildrenRecursive 함수 추가 - AuthenticatedLayout.tsx: findMenuRecursive + ancestorIds 배열로 경로 매칭 - Sidebar.tsx: depth별 스타일 (1depth: 아이콘+굵은텍스트, 2depth: 작은아이콘, 3depth: dot+작은텍스트) - CEO 대시보드 상세 모달 및 카드 관리 개선 - 폴더블 기기 레이아웃 가이드 문서 추가 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -192,8 +192,30 @@ interface ApiMenu {
|
||||
external_url: string | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 재귀적으로 자식 메뉴를 찾아서 트리 구조로 변환 (3depth 이상 지원)
|
||||
*/
|
||||
function buildChildrenRecursive(parentId: number, allMenus: ApiMenu[]): SerializableMenuItem[] {
|
||||
const children = allMenus
|
||||
.filter((menu) => menu.parent_id === parentId)
|
||||
.sort((a, b) => a.sort_order - b.sort_order)
|
||||
.map((menu) => {
|
||||
const grandChildren = buildChildrenRecursive(menu.id, allMenus);
|
||||
return {
|
||||
id: menu.id.toString(),
|
||||
label: menu.name,
|
||||
iconName: menu.icon || 'folder',
|
||||
path: menu.url || '#',
|
||||
children: grandChildren.length > 0 ? grandChildren : undefined,
|
||||
};
|
||||
});
|
||||
|
||||
return children;
|
||||
}
|
||||
|
||||
/**
|
||||
* API 메뉴 데이터를 SerializableMenuItem 구조로 변환 (localStorage 저장용)
|
||||
* 3depth 이상의 메뉴 구조 지원
|
||||
*/
|
||||
export function transformApiMenusToMenuItems(apiMenus: ApiMenu[]): SerializableMenuItem[] {
|
||||
if (!apiMenus || !Array.isArray(apiMenus)) {
|
||||
@@ -201,27 +223,19 @@ export function transformApiMenusToMenuItems(apiMenus: ApiMenu[]): SerializableM
|
||||
}
|
||||
|
||||
// parent_id가 null인 최상위 메뉴만 추출
|
||||
const parentMenus = apiMenus
|
||||
const rootMenus = apiMenus
|
||||
.filter((menu) => menu.parent_id === null)
|
||||
.sort((a, b) => a.sort_order - b.sort_order);
|
||||
|
||||
// 각 부모 메뉴에 대해 자식 메뉴 찾기
|
||||
const menuItems: SerializableMenuItem[] = parentMenus.map((parentMenu) => {
|
||||
const children = apiMenus
|
||||
.filter((menu) => menu.parent_id === parentMenu.id)
|
||||
.sort((a, b) => a.sort_order - b.sort_order)
|
||||
.map((childMenu) => ({
|
||||
id: childMenu.id.toString(),
|
||||
label: childMenu.name,
|
||||
iconName: childMenu.icon || 'folder', // 문자열로 저장
|
||||
path: childMenu.url || '#',
|
||||
}));
|
||||
// 각 루트 메뉴에 대해 재귀적으로 자식 메뉴 찾기
|
||||
const menuItems: SerializableMenuItem[] = rootMenus.map((rootMenu) => {
|
||||
const children = buildChildrenRecursive(rootMenu.id, apiMenus);
|
||||
|
||||
return {
|
||||
id: parentMenu.id.toString(),
|
||||
label: parentMenu.name,
|
||||
iconName: parentMenu.icon || 'folder', // 문자열로 저장
|
||||
path: parentMenu.url || '#',
|
||||
id: rootMenu.id.toString(),
|
||||
label: rootMenu.name,
|
||||
iconName: rootMenu.icon || 'folder',
|
||||
path: rootMenu.url || '#',
|
||||
children: children.length > 0 ? children : undefined,
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user