design(site): collapsible sidebar navigation for deployment & AI settings#25450
Draft
tracyjohnsonux wants to merge 44 commits into
Draft
design(site): collapsible sidebar navigation for deployment & AI settings#25450tracyjohnsonux wants to merge 44 commits into
tracyjohnsonux wants to merge 44 commits into
Conversation
…ttings Replaces the flat-list deployment settings sidebar with a new grouped accordion navigation system. Each section (General, Infrastructure, Authentication, AI Settings, AI Governance) has an icon header with expand/collapse behavior — only one section open at a time. The sidebar right edge is draggable to resize. Dragging below a threshold snaps it to an icon-only collapsed view (56px). Width is persisted to localStorage. A 3px hover-glow line on the resize handle uses a CSS gradient mask that fades at both ends for a softer visual effect. New components: - CollapsibleSidebar: resizable nav wrapper with context - SidebarAccordion: icon+label header with Radix Collapsible content - SidebarResizeHandle: drag handle with gradient glow - useSidebarResize: width state, drag logic, snap, localStorage Also adds blank stub pages for AI Settings sub-routes (Usage Stats, Models, Providers, Keys) and AI Governance sub-routes (Access & Speed, Settings, Analytics, Data Controls).
- Remove breadcrumb bar from deployment settings layout - Make layout full-width: sidebar flush-left with 24px padding matching main nav alignment - Reset button styles on accordion triggers (bg-transparent border-none) since Tailwind preflight is disabled - Center content area within its column via max-w + mx-auto
- Simplify to two-state model: expanded (240px) or collapsed (56px) with no in-between widths. Eliminates weird partial-width states. - Move resize handle outside nav overflow area so it's never clipped and the hover glow line aligns exactly on the 1px border. - Position handle with -right-1 to center on the border line. - Match collapsed icon button padding (px-3 py-2) to expanded button so icons stay at the same vertical position in both states. - Use same size-4 icons in both states for consistent alignment. - Persist collapsed/expanded state (not raw width) to localStorage. - Remove transition on outer wrapper for instant width changes during drag — no more clunky pause at snap boundaries. - Content area top padding reduced to 24px (pt-6) from 40px.
- Resize glow line is now a 300px segment centered on the cursor (150px above, 150px below) using a dynamic CSS mask gradient that updates on mousemove. Creates a spotlight effect instead of a full-height line. - Icons left-align with the Coder logo: nav pl-6 (24px) matches navbar px-6, buttons have zero left padding so icon left edges sit at exactly 24px from viewport edge in both states. - Collapsed buttons use the same py-2 and size-4 icon as expanded buttons for consistent vertical rhythm.
- Replace mask:none with a fully transparent gradient on mouseleave so the opacity transition fades smoothly without the full-line flash (the previous approach unmasked the entire line for one frame before the opacity transition kicked in). - Control opacity via explicit state (hovered) instead of CSS group-hover to keep mask and opacity in sync. - Add -ml-px to sidebar icons to compensate for lucide SVG viewBox inset (~1.3px stroke padding) so the visible icon edges align with the Coder logo's left edge.
…g area - Restore px-3 py-2 on both collapsed and expanded accordion buttons so vertical spacing is identical in both states. - Adjust nav pl from pl-6 to pl-3: nav-pl(12) + button-px(12) = 24px matching the navbar px-6 so icons align with the Coder logo. - Remove the -ml-px hack — no longer needed with correct padding math. - Widen resize handle hit area from w-2 (8px) to w-4 (16px) giving 8px of buffer on each side of the border line.
Increase collapsed width from 56px to 64px so the icon has equal space on both sides. Icon center is at 32px (nav-pl 12 + btn-px 12 + half icon 8), so width = 64 centers it exactly.
In collapsed mode, clicking a section icon now navigates to the first page in that section (e.g. clicking the gear icon goes to /deployment/overview). This triggers a route change which expands the sidebar and opens the correct accordion section. Adds an optional href prop to SidebarAccordion. When provided and the sidebar is collapsed, the icon renders as a Link instead of a toggle button.
…ment The collapsed Link/button elements lacked w-full, so they shrank to content width and the px-3 padding didn't align icons to the same 24px left edge as the expanded state. Adding w-full ensures the elements stretch to fill the nav width, keeping the icon at nav-pl(12) + px-3(12) = 24px from sidebar left in both states.
- Clicking a collapsed sidebar icon now expands the sidebar AND navigates to the section's first page. Added expand() to the sidebar context, called from the accordion's collapsed Link/button. - Remove requestAnimationFrame from drag handler — binary snap doesn't need throttling. Direct pointermove → setState is instant. - Use data-sidebar-container attribute to find the outer wrapper for drag offset calculation (handle is outside nav element). - Add mt-0 to all stub page h1 elements to reset browser-default top margin (preflight is off). - Moved transition-[width] to the outer wrapper div so the width change animates on the container, not the inner nav.
The expanded button was 40px tall (py-2 + text-sm line-height 24px) while the collapsed button was only 32px (py-2 + icon 16px). Adding an explicit h-10 (40px) to all three button/link variants ensures icons stay at the same vertical position when toggling between expanded and collapsed states.
Replace w-full + px-3 on collapsed buttons with w-10 h-10 justify-center so the hover background wraps tightly around the icon as a 40x40 rounded square. The icon center stays at 32px from sidebar left (matching the expanded state).
Track a dragging state that keeps the glow line visible even when the cursor leaves the handle area. During drag, a global pointermove listener updates the glow position and opacity is bumped to 0.7 (vs 0.4 on hover). On pointerup everything resets cleanly.
Remove the ::before/::after stripe bars on .navbar-stripe-devel and .navbar-stripe-rc. The CSS variable definitions are kept in case they're referenced elsewhere.
Apply text-content-primary to the section icon when its accordion is open, matching the label text treatment. Applies to all three states: expanded button, collapsed link, and collapsed button.
Add an 'active' prop to SidebarAccordion that reflects whether the section owns the current route (via activeSection). The icon and label use this for text-content-primary highlighting instead of the 'open' prop which only tracks accordion expansion. This fixes collapsed mode where no accordion is visually open but the active section's icon should still be highlighted.
Restore right padding on the nav (pl-3 → px-3) so the expanded button has equal 12px space on both sides before the border line.
The first 15px of drag movement tracks the cursor 1:1 so the grab feels immediate. After that, the width snaps to expanded (240px) or collapsed (64px) based on the snap threshold. - Track live pixel width during drag via dragWidth state. - Disable CSS transition while dragging so the 1:1 tracking doesn't fight the animation. Re-enable on pointerup so the final snap animates smoothly. - Expose 'dragging' boolean from the hook for the container to conditionally apply the transition class.
Replace React state updates on every pointermove with direct container.style.width writes. This eliminates the stutter caused by React reconciliation on each mouse event. During drag: - CSS transition is disabled (container.style.transition = 'none') - Width tracks the cursor 1:1, clamped between 64px and 240px - Zero React re-renders happen On pointerup: - CSS transition is restored - Width snaps to 64px or 240px based on the snap threshold - React state syncs once for collapsed/expanded
The inner nav now always renders at w-[240px] (full expanded width) so its text and icons never reflow during drag. The outer container has overflow-hidden and its width is what changes — content simply gets cropped as the container shrinks, then snaps to the collapsed icon-only view on release.
…llapsed The 1px right border was on the inner nav (always 240px wide), so it got clipped by overflow-hidden when the container shrank to 64px. Moving the border to the outer container keeps it at the visible right edge in both states.
Any drag movement now completes the transition: drag left from expanded → collapse, drag right from collapsed → expand. No minimum distance threshold — just direction. A click without movement toggles the state. Removed the SNAP_THRESHOLD constant since it's no longer needed.
Movement under 3px is treated as a click (toggles collapsed state). Movement >= 3px starts the drag — the container width tracks the cursor 1:1 and snaps on release based on direction. This prevents accidental state toggles from tiny mouse jitters during a click.
Resize handle now extends 8px left of the border line but only 3px right into the content area. Clicking in the content area no longer accidentally toggles the sidebar.
Revert handle to w-4 -right-2 (8px each side of border) so it's grabbable from both sides. The glow line is now absolutely positioned at left:7px within the 16px handle, placing the 2px line exactly on the 1px border instead of centered in the hit area.
The handle was inside the overflow-hidden div, clipping its right half so it wasn't grabbable from the content side. Now the outer wrapper (no overflow clipping) holds both the clipping container and the handle as siblings. The handle extends 8px on each side of the border without being clipped.
…rsor Remove the gradient mask approach. The glow is now a plain 150px tall, 2px wide rounded bar absolutely positioned at the cursor's Y coordinate. No gradient, no mask — just a simple bar that follows the mouse.
Shows a small uppercase 'Deployment' label above the accordion buttons in expanded mode. Hidden when collapsed to icon-only. Uses text-content-disabled as the tertiary content color.
Only kill the CSS transition when actual dragging starts (past the 3px dead zone). For clicks, never touch container.style — just toggle React state and let the existing CSS transition on the container animate the width change smoothly. This eliminates the weird line artifacts on click.
Keep the bar's last Y position on mouseleave instead of clearing it to null. The opacity transition fades it out in place, avoiding the flash caused by the bar jumping to top:-50 for one frame.
Replace the 100px cursor-following bar with a simple full-height line that appears on hover and stays during drag. Removed all mouseY tracking and gradient logic.
Replaces the stub AISettingsUsageStatsPage with a full mock matching the design comp: - 'AI usage' header with subtitle - Groups/Users tabs - Search input with date range - Table with Name, Costs, Input/output, Cache read/write columns - 4 mock group rows with avatars and token badges - Pagination controls with page numbers - Rename sidebar label from 'Usage Stats' to 'Usage'
Providers page with mock data: - Table with Name, Base URL, User keys columns - 4 providers (Anthropic, OpenAI, AWS Bedrock, Vercel AI Gateway) - Check/X icons for user key status, chevron-right for drill-in - + Add provider button, pagination Sidebar icon updates: - Infrastructure: Container → HardDrive - Authentication: KeyRound → UserLock - AI Settings: Sparkles → Settings2 - AI Governance: Scale → ShieldCheck Sidebar label: 'Usage Stats' → 'Usage'
New page at /deployment/ai-settings/providers/add matching the design comp: - Back to providers link - 'Add a provider' header with subtitle - Form card with API key, Base URL, Icon picker fields - Key policy section with 3 toggle switches (Central API key, Allow user API keys, Use central key as fallback) - Cancel and Add Provider action buttons - Route registered under ai-settings/providers/add
Models page at /deployment/ai-settings/models matching the design: - Table with Name, Model cost, Session share, Context limit, Status - 4 mock models: Opus 4.6 Max (active/default), claude-sonnet-4-6 (active), anthropic.claude-opus-4-6-v1 (stale), GPT 5.4 (disabled) - Status column with colored dot + label + detail text - Provider icon avatars, chevron-right for drill-in - Pagination controls
…g to match design spec Cherry-picked from #24541
- Admin dropdown: Deployment, Organizations, AI, Logs, Healthcheck - New /ai route with CollapsibleSidebar layout - AI sidebar: AI Governance, Providers, Models, Spend (top-level) + Agents accordion - Routes point to real AgentSettings*Page components from main - Removed AI Settings/Governance from Deployment sidebar - Fixed lucide-react icon names for v1 (Icon suffix)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Design/UX iteration — new collapsible sidebar navigation for deployment settings, plus a standalone AI admin section. Frontend only, no backend changes.
What changed
Collapsible sidebar system (
site/src/components/Sidebar/)overflow-hidden, preventing content reflowcollapsed,expand(),toggle()Deployment sidebar (
/deployment)/ai)AI section (
/ai) — new top-level areaAgentSettings*Pagecomponents (not stubs)Admin dropdown
Mock pages
Other