diff --git a/fe-user/src/components/Layout.tsx b/fe-user/src/components/Layout.tsx index b51fbae..69311f3 100644 --- a/fe-user/src/components/Layout.tsx +++ b/fe-user/src/components/Layout.tsx @@ -99,11 +99,19 @@ const USER_HIDDEN_KEYS = new Set([ ]) function filterForUser(nodes: MenuNode[]): MenuNode[] { + // Filter 2 tầng: hardcode USER_HIDDEN_KEYS (system-level, structural never-show) + // + dynamic isVisible (Mig 27 admin toggle qua MenuVisibilityPage). isVisible + // mặc định true, admin set false → ẩn khỏi sidebar eOffice. return nodes - .filter(n => !USER_HIDDEN_KEYS.has(n.key)) + .filter(n => !USER_HIDDEN_KEYS.has(n.key) && n.isVisible !== false) .map(n => ({ ...n, children: filterForUser(n.children) })) } +// Mig 27: ưu tiên displayLabel admin custom, fallback label gốc. +function effectiveLabel(n: { label: string; displayLabel?: string | null }): string { + return (n.displayLabel && n.displayLabel.trim()) || n.label +} + // Accordion state cho groups Ct_ (7 HĐ) + Pe_ (2 phiếu) — mỗi // family mutex độc lập. Auto-expand theo URL `?type=X` (Ct_ dùng route // /contracts|/my-contracts|/inbox, Pe_ dùng /purchase-evaluations). Group @@ -174,7 +182,7 @@ function MenuGroup({ node, depth }: { node: MenuNode; depth: number }) { > - {node.label} + {effectiveLabel(node)} @@ -236,7 +244,7 @@ function MenuLeaf({ node, depth }: { node: MenuNode; depth: number }) { )} > - {node.label} + {effectiveLabel(node)} ) } @@ -244,7 +252,7 @@ function MenuLeaf({ node, depth }: { node: MenuNode; depth: number }) { // Static entries prepended to the dynamic menu tree — these are user-app // specific (inbox + quick create) not backed by MenuItems DB rows. const USER_FIXED_TOP: MenuNode[] = [ - { key: '__inbox', label: 'Hộp thư', parentKey: null, order: 0, icon: 'Inbox', canRead: true, canCreate: true, canUpdate: true, canDelete: true, children: [] }, + { key: '__inbox', label: 'Hộp thư', parentKey: null, order: 0, icon: 'Inbox', canRead: true, canCreate: true, canUpdate: true, canDelete: true, isVisible: true, displayLabel: null, children: [] }, ] function staticResolvePath(key: string): string | null { @@ -268,7 +276,7 @@ function StaticLeaf({ node }: { node: MenuNode }) { } > - {node.label} + {effectiveLabel(node)} ) } diff --git a/fe-user/src/types/menu.ts b/fe-user/src/types/menu.ts index d5bed7a..43076f3 100644 --- a/fe-user/src/types/menu.ts +++ b/fe-user/src/types/menu.ts @@ -8,6 +8,8 @@ export type MenuNode = { canCreate: boolean canUpdate: boolean canDelete: boolean + isVisible: boolean + displayLabel: string | null children: MenuNode[] } @@ -17,6 +19,8 @@ export type MenuItem = { parentKey: string | null order: number icon: string | null + isVisible: boolean + displayLabel: string | null } export type Role = {