Layout & Navigation
Layout system
A pluggable module that aggregates navigation from all frontend modules and provides an Admin Layout Manager for toggling visibility.
Overview
- Frontend module contributes a route for an Admin Layout Manager page.
- Aggregates
navItemsfrom all loaded frontend modules viaFrontendModuleLoader. - Supports role-based visibility through each item's
visiblepredicate. - Non-invasive: does not alter existing app behavior; simply adds layout tooling.
Backend
src/modules/layout/index.ts: declaresEnvSpecand installs a small health endpoint.- Health check:
GET /api/layout/health→{ ok: true, module: "layout", version: "1.0.0" }
Environment variables (backend)
FEATURE_LAYOUT: Enable/disable the Layout module (default: enabled).LAYOUT_DEFAULT: Default preset (e.g.,drawer-left,drawer-right,topbar-only).LAYOUT_SHOW_FOOTER: Whether to render a footer in the app shell (default:true).
Frontend
client/src/modules/layout/index.ts: registers route/admin/layout(rendered under the app base) and contributes a topbar nav item to/app/admin/layout.- Requires admin/owner: wrapped with
RequireAdminand usesisAuthenticatedWithSomeRole(["admin","owner"]). client/src/modules/layout/pages/AdminLayoutManager.tsx: loads modules, aggregatesnavItems, and lets admins toggle item visibility.
Navigation item contract
// client/src/modules/types.ts
export type FrontendModuleNavItem = {
to: string; // e.g. "/app/admin/layout"
label: string; // UI label
area?: string; // e.g. "topbar"
icon?: React.ReactNode; // optional icon
visible?: boolean | (() => boolean); // RBAC or custom conditions
};
Admin Layout Manager
Page component: client/src/modules/layout/pages/AdminLayoutManager.tsx
- Persists hidden items in
localStorageunder key"layout.hiddenNavItems". - Emits a
windowevent"layout:nav.changed"after changes so consumers can re-render navigation. - Respects each item's
visiblepredicate before presenting toggles.
// Toggle handler excerpt
function saveHidden(set: Set<string>) {
localStorage.setItem("layout.hiddenNavItems", JSON.stringify(Array.from(set)));
window.dispatchEvent(new Event("layout:nav.changed"));
}
Enable the module
# Backend/Frontend modules loader
MODULES_ENABLED=layout
# Optional (default is enabled)
FEATURE_LAYOUT=true
# Optional layout preferences
LAYOUT_DEFAULT=drawer-left
LAYOUT_SHOW_FOOTER=true
Restart the server. The backend exposes the health endpoint; the frontend adds the admin page and topbar item for admins.
Troubleshooting
- If the admin page doesn't show, ensure your user has
adminorownerrole. - Verify
MODULES_ENABLEDcontainslayoutandFEATURE_LAYOUTis not false. - Check console logs:
[frontend-modules][layout]and[modules][layout]in development.
Related
- Modules system — how modules are loaded and discovered.
- Auth & RBAC — roles required for accessing layout admin tools.