diff --git a/frontend/components/layout/AppLayout.tsx b/frontend/components/layout/AppLayout.tsx index d2f13c79..f206b718 100644 --- a/frontend/components/layout/AppLayout.tsx +++ b/frontend/components/layout/AppLayout.tsx @@ -490,12 +490,12 @@ function AppLayoutInner({ children }: AppLayoutProps) { const menuObjid = parseInt((menu.objid || menu.id)?.toString() || "0"); - if (activeTab.type === "admin" && activeTab.adminUrl) { + if (activeTab?.type === "admin" && activeTab?.adminUrl) { return menu.url === activeTab.adminUrl; } - if (activeTab.type === "screen") { - if (activeTab.menuObjid != null && menuObjid === activeTab.menuObjid) return true; - if (activeTab.screenId != null && menu.screenId === activeTab.screenId) return true; + if (activeTab?.type === "screen") { + if (activeTab?.menuObjid != null && menuObjid === activeTab.menuObjid) return true; + if (activeTab?.screenId != null && menu.screenId === activeTab.screenId) return true; } return false; }, @@ -562,6 +562,34 @@ function AppLayoutInner({ children }: AppLayoutProps) { ); }; + const uiMenus = user ? convertMenuToUI(currentMenus, user as ExtendedUserInfo) : []; + + // 활성 탭에 해당하는 메뉴가 속한 부모 메뉴 자동 확장 (기존 확장 상태 유지, 추가만 함) + useEffect(() => { + if (!activeTab || uiMenus.length === 0) return; + + const toExpand: string[] = []; + for (const menu of uiMenus) { + if (menu.hasChildren && menu.children) { + const hasActiveChild = menu.children.some((child: any) => isMenuActive(child)); + if (hasActiveChild) toExpand.push(menu.id); + } + } + if (toExpand.length > 0) { + setExpandedMenus((prev) => { + const next = new Set(prev); + let changed = false; + toExpand.forEach((id) => { + if (!next.has(id)) { + next.add(id); + changed = true; + } + }); + return changed ? next : prev; + }); + } + }, [activeTab, uiMenus, isMenuActive]); + if (isPreviewMode) { return (
{children}
@@ -579,30 +607,6 @@ function AppLayoutInner({ children }: AppLayoutProps) { ); } - const uiMenus = convertMenuToUI(currentMenus, user as ExtendedUserInfo); - - // 활성 탭에 해당하는 메뉴가 속한 부모 메뉴 자동 확장 - useEffect(() => { - if (!activeTab || uiMenus.length === 0) return; - - const toExpand: string[] = []; - for (const menu of uiMenus) { - if (menu.hasChildren && menu.children) { - const hasActiveChild = menu.children.some((child: any) => isMenuActive(child)); - if (hasActiveChild && !expandedMenus.has(menu.id)) { - toExpand.push(menu.id); - } - } - } - if (toExpand.length > 0) { - setExpandedMenus((prev) => { - const next = new Set(prev); - toExpand.forEach((id) => next.add(id)); - return next; - }); - } - }, [activeTab, uiMenus, isMenuActive, expandedMenus]); - return (
{/* 모바일 헤더 */} diff --git a/frontend/lib/registry/components/v2-split-panel-layout/SplitPanelLayoutComponent.tsx b/frontend/lib/registry/components/v2-split-panel-layout/SplitPanelLayoutComponent.tsx index 28acdbe6..4527a85f 100644 --- a/frontend/lib/registry/components/v2-split-panel-layout/SplitPanelLayoutComponent.tsx +++ b/frontend/lib/registry/components/v2-split-panel-layout/SplitPanelLayoutComponent.tsx @@ -21,7 +21,7 @@ import { Move, FileSpreadsheet, List, - LayoutPanelRight, + PanelRight, } from "lucide-react"; import { dataApi } from "@/lib/api/data"; import { entityJoinApi } from "@/lib/api/entityJoin"; @@ -3972,7 +3972,7 @@ export const SplitPanelLayoutComponent: React.FC >
- + {/* 탭이 없으면 제목만, 있으면 탭으로 전환 (2px primary 밑줄 인디케이터) */} {(componentConfig.rightPanel?.additionalTabs?.length || 0) > 0 ? (