fix: restructure icon rail to 5 grouped items (Sentry-style)
Home, Work, Knowledge, Insights, Help — each with hover flyout showing sub-items. Sidebar now stretches to full viewport height. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import {
|
||||
LayoutGrid, Clock, AlertTriangle, GitBranch, Layers, Code2, Wand2,
|
||||
ListChecks, Download, BarChart3, Rocket, BookOpen, MessageSquare,
|
||||
Settings, Pin, PinOff,
|
||||
Zap, Database, HelpCircle,
|
||||
} from 'lucide-react'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { useUserPreferencesStore } from '@/store/userPreferencesStore'
|
||||
@@ -62,6 +63,57 @@ export function Sidebar() {
|
||||
|
||||
/* ── Navigation data ──────────────────────────────── */
|
||||
|
||||
/* ── Grouped nav: 5 top-level icons (Sentry-style) ── */
|
||||
|
||||
const railGroups: NavEntry[] = [
|
||||
{
|
||||
href: '/', icon: LayoutGrid, label: 'Home', shortLabel: 'Home',
|
||||
matchPaths: ['/'],
|
||||
},
|
||||
{
|
||||
href: '/sessions', icon: Zap, label: 'Work', shortLabel: 'Work',
|
||||
badge: (stats?.active_count || 0) + (stats?.escalation_count || 0) || undefined,
|
||||
matchPaths: ['/sessions', '/escalations', '/pilot'],
|
||||
children: [
|
||||
{ href: '/sessions', label: 'Active Sessions', count: stats?.active_count || undefined },
|
||||
{ href: '/escalations', label: 'Escalations', count: stats?.escalation_count || undefined },
|
||||
],
|
||||
},
|
||||
{
|
||||
href: '/trees', icon: Database, label: 'Knowledge', shortLabel: 'Know',
|
||||
badge: stats?.tree_counts.total || undefined,
|
||||
matchPaths: ['/trees', '/flows', '/my-trees', '/step-library', '/scripts', '/script-builder', '/review-queue'],
|
||||
children: [
|
||||
{ href: '/trees', label: 'All Flows', count: stats?.tree_counts.total || undefined },
|
||||
{ href: '/trees?type=troubleshooting', label: 'Troubleshooting', count: stats?.tree_counts.troubleshooting || undefined },
|
||||
{ href: '/trees?type=procedural', label: 'Projects', count: stats?.tree_counts.procedural || undefined },
|
||||
{ href: '/trees?type=maintenance', label: 'Maintenance', count: stats?.tree_counts.maintenance || undefined },
|
||||
{ href: '/step-library', label: 'Step Library' },
|
||||
{ href: '/scripts', label: 'Scripts' },
|
||||
{ href: '/script-builder', label: 'Script Builder' },
|
||||
{ href: '/review-queue', label: 'Review Queue' },
|
||||
],
|
||||
},
|
||||
{
|
||||
href: '/analytics', icon: BarChart3, label: 'Insights', shortLabel: 'Data',
|
||||
matchPaths: ['/analytics', '/shares'],
|
||||
children: [
|
||||
{ href: '/shares', label: 'Exports' },
|
||||
{ href: '/analytics', label: 'Analytics' },
|
||||
{ href: '/analytics/flowpilot', label: 'FlowPilot Analytics' },
|
||||
],
|
||||
},
|
||||
{
|
||||
href: '/guides', icon: HelpCircle, label: 'Help', shortLabel: 'Help',
|
||||
matchPaths: ['/guides', '/feedback'],
|
||||
children: [
|
||||
{ href: '/guides', label: 'User Guides' },
|
||||
{ href: '/feedback', label: 'Feedback' },
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
/* Pinned mode still uses the detailed section layout */
|
||||
const sections: NavSection[] = [
|
||||
{
|
||||
title: 'RESOLVE',
|
||||
@@ -102,8 +154,6 @@ export function Sidebar() {
|
||||
]
|
||||
|
||||
const footerItems: NavEntry[] = [
|
||||
{ href: '/guides', icon: BookOpen, label: 'User Guides', shortLabel: 'Guides' },
|
||||
{ href: '/feedback', icon: MessageSquare, label: 'Feedback', shortLabel: 'Feedbk' },
|
||||
{ href: '/account', icon: Settings, label: 'Account', shortLabel: 'Acct' },
|
||||
]
|
||||
|
||||
@@ -167,7 +217,7 @@ export function Sidebar() {
|
||||
return (
|
||||
<div
|
||||
key={key}
|
||||
className="relative"
|
||||
className="relative w-full"
|
||||
onMouseEnter={() => hasChildren && !sidebarPinned ? openFlyout(key) : undefined}
|
||||
onMouseLeave={() => hasChildren && !sidebarPinned ? closeFlyout() : undefined}
|
||||
>
|
||||
@@ -378,30 +428,27 @@ export function Sidebar() {
|
||||
)
|
||||
}
|
||||
|
||||
/* Icon Rail (default) */
|
||||
/* Icon Rail (default) — 5 grouped icons, Sentry-style */
|
||||
return (
|
||||
<nav
|
||||
ref={sidebarRef}
|
||||
className="sidebar flex flex-col items-center"
|
||||
style={{ background: '#0f1118', borderRight: '1px solid #1e2130' }}
|
||||
className="sidebar flex flex-col items-center h-full"
|
||||
style={{ background: '#0f1118', borderRight: '1px solid #1e2130', minHeight: '100vh' }}
|
||||
onWheel={handleWheel}
|
||||
>
|
||||
{/* Nav sections */}
|
||||
<div className="flex flex-col items-center w-full px-1.5 py-2 space-y-0.5">
|
||||
{sections.map((section, si) => (
|
||||
<div key={section.title} className="w-full">
|
||||
{si > 0 && (
|
||||
<div className="mx-3 my-2" style={{ borderTop: '1px solid #1e2130' }} />
|
||||
)}
|
||||
{section.items.map((item, ii) => renderRailItemWithRef(item, `${si}-${ii}`))}
|
||||
{/* Grouped nav items */}
|
||||
<div className="flex flex-col items-center w-full px-1.5 pt-3 space-y-1">
|
||||
{railGroups.map((item, i) => (
|
||||
<div key={`rail-${i}`} data-flyout-key={`rail-${i}`}>
|
||||
{renderRailItem(item, `rail-${i}-inner`)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="flex-1" />
|
||||
|
||||
{/* Footer */}
|
||||
<div className="flex flex-col items-center w-full px-1.5 py-2 space-y-0.5" style={{ borderTop: '1px solid #1e2130' }}>
|
||||
{/* Footer: Account + Pin */}
|
||||
<div className="flex flex-col items-center w-full px-1.5 pb-3 space-y-1" style={{ borderTop: '1px solid #1e2130' }}>
|
||||
{footerItems.map((item, i) => (
|
||||
<div key={`footer-${i}`} data-flyout-key={`footer-${i}`}>
|
||||
{renderRailItem(item, `footer-${i}-inner`)}
|
||||
|
||||
Reference in New Issue
Block a user