Convert portal shell from block-centered (max-width 1600px) layout to full-viewport fluid flexbox with collapsible sidebar: desktop push-mode (240px → 0), mobile overlay drawer with backdrop. Rename .content → .shell-content to avoid CSS collision with page-level classes. Override page-level max-width constraints when embedded in shell. Also replace native <select multiple> in query-tool with shared MultiSelect component for equipment and workcenter group filters, matching resource-status/history UX. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
5.6 KiB
5.6 KiB
1. Sidebar State Management (App.vue script)
- 1.1 Add
sidebarCollapsed,sidebarMobileOpen,isMobilerefs toApp.vue<script setup> - 1.2 Implement
toggleSidebar(),closeMobileSidebar(),checkViewport()functions - 1.3 Add
sessionStorageload/save for sidebar collapsed preference (portal-shell:sidebar-collapsed) - 1.4 Register
resizelistener inonMounted, clean up inonUnmounted - 1.5 Add Escape key handler to close mobile sidebar overlay
- 1.6 Add
closeMobileSidebar()call to existing route watcher for auto-close on navigation
2. Template Restructure (App.vue template)
- 2.1 Add
.shell-header-leftwrapper with hamburger toggle<button>(inline SVG,aria-label,aria-expanded) - 2.2 Add
:classbinding on.shellroot:{ 'sidebar-collapsed': sidebarCollapsed && !isMobile } - 2.3 Add
:classbindings on<aside class="sidebar">:sidebar--collapsed,sidebar--mobile-open,sidebar--mobile-closed - 2.4 Add
<Transition name="overlay-fade">wrapped<div class="sidebar-overlay">before<main>, shown whenisMobile && sidebarMobileOpen - 2.5 Rename
<section class="content">to<section class="shell-content">in the template
3. Shell CSS Rewrite (frontend/src/portal-shell/style.css)
- 3.1 Rename all
.contentselectors to.shell-contentthroughoutstyle.css(.content,.content .xxx-page, etc.) - 3.2
.shell: removemax-width: 1600px,padding: 20px,margin: 0 auto; adddisplay: flex; flex-direction: column - 3.3
.shell-header: removeborder-radius: 12px; adjustpaddingto12px 20px; addflex-shrink: 0 - 3.4 Add
.shell-header-leftstyles (flex, align-items center, gap 12px) - 3.5 Add
.sidebar-togglebutton styles (36x36, border/bg rgba white, hover, focus-visible outline) - 3.6
.shell-main: replacedisplay: grid; grid-template-columnswithdisplay: flex; flex: 1; overflow: hidden; remove legacygap: 12pxto prevent residual gutter when sidebar collapses - 3.7
.sidebar: rewrite towidth: 240px; min-width: 240px; border-right; overflow-y: auto; flex-shrink: 0; transition: width/min-width/padding 0.3s; white-space: nowrap— remove border-radius, border, sticky, height: fit-content - 3.8 Add
.sidebar--collapsedstyles:width: 0; min-width: 0; padding: 0; border-right: none; overflow: hidden - 3.9 Add
.sidebar--mobile-closedstyles: fixed position,transform: translateX(-100%), 280px width, z-index 40 - 3.10 Add
.sidebar--mobile-openstyles: fixed position,transform: translateX(0), box-shadow, z-index 40 - 3.11 Add
.sidebar-overlaystyles: fixed inset 0, z-index 35,background: rgba(0,0,0,0.4) - 3.12 Add
overlay-fadetransition classes (enter/leave opacity 0.3s) - 3.13
.shell-content: removeborder,border-radius: 10px,min-height: 70vh; addflex: 1; min-width: 0; overflow-y: auto; change background to#f5f7fa - 3.14 Bump
.health-popupz-index from30to50
4. Page-Level Overrides (frontend/src/portal-shell/style.css)
- 4.1 Add
.shell-content .resource-page, .shell-content .dashboard, .shell-content .qc-gate-page, .shell-content .job-query-page, .shell-content .excel-query-page, .shell-content .query-tool-page, .shell-content .tmtt-page, .shell-content .tables-pageoverride:max-width: none; min-height: auto - 4.2 Add
.shell-content .tables-page .containeroverride:max-width: none(tables module has max-width on inner.container, not on page wrapper) - 4.3 Add
.shell-content .resource-pageoverride:padding: 0(remove duplicate padding)
5. Responsive and Accessibility (frontend/src/portal-shell/style.css)
- 5.1 Simplify
@media (max-width: 900px)block — remove grid/sidebar rules (now JS-driven); keep header/content padding adjustments only - 5.2 Extend
@media (prefers-reduced-motion: reduce)to include.sidebar,.sidebar--mobile-*,.sidebar-overlay,.overlay-fade-*,.sidebar-toggle
6. CSS Variables Update (frontend/src/styles/tailwind.css)
- 6.1 Change
--portal-shell-max-widthfrom1600pxtonone - 6.2 Add
--portal-sidebar-width: 240pxand--shell-header-height: 56px - 6.3 Update
.u-content-shellutility: replacemax-widthwithwidth: 100%
7. Automated Tests
- 7.1 Create
frontend/tests/portal-shell-sidebar.test.jsusing existing Nodenode:testharness - 7.2 Test: desktop sidebar collapse — toggle sets
sidebarCollapsedto true, sidebar getssidebar--collapsedclass - 7.3 Test: mobile overlay close via backdrop — clicking overlay calls
closeMobileSidebar(),sidebarMobileOpenbecomes false - 7.4 Test: mobile overlay close via Escape — pressing Escape when overlay open closes sidebar
- 7.5 Test: sessionStorage persistence — collapsing sidebar writes to sessionStorage; mounting with stored value restores collapsed state
8. Manual Verification
- 8.1 Run
npm run build— confirm no build errors - 8.2 Test desktop: sidebar expanded → toggle collapse → toggle expand (smooth 300ms animation)
- 8.3 Test mobile (<= 900px): toggle opens overlay drawer with backdrop → tap backdrop closes → Escape closes
- 8.4 Test route navigation auto-closes mobile sidebar
- 8.5 Test health popup z-index: open health popup while mobile sidebar is open → popup stays on top
- 8.6 Test shell-registered page modules render fluid (no max-width centering) within the shell
- 8.7 Test
prefers-reduced-motion: all transitions disabled - 8.8 Verify tables module
.contentclass is not affected by shell.shell-contentstyles