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,
|
LayoutGrid, Clock, AlertTriangle, GitBranch, Layers, Code2, Wand2,
|
||||||
ListChecks, Download, BarChart3, Rocket, BookOpen, MessageSquare,
|
ListChecks, Download, BarChart3, Rocket, BookOpen, MessageSquare,
|
||||||
Settings, Pin, PinOff,
|
Settings, Pin, PinOff,
|
||||||
|
Zap, Database, HelpCircle,
|
||||||
} from 'lucide-react'
|
} from 'lucide-react'
|
||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
import { useUserPreferencesStore } from '@/store/userPreferencesStore'
|
import { useUserPreferencesStore } from '@/store/userPreferencesStore'
|
||||||
@@ -62,6 +63,57 @@ export function Sidebar() {
|
|||||||
|
|
||||||
/* ── Navigation data ──────────────────────────────── */
|
/* ── 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[] = [
|
const sections: NavSection[] = [
|
||||||
{
|
{
|
||||||
title: 'RESOLVE',
|
title: 'RESOLVE',
|
||||||
@@ -102,8 +154,6 @@ export function Sidebar() {
|
|||||||
]
|
]
|
||||||
|
|
||||||
const footerItems: NavEntry[] = [
|
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' },
|
{ href: '/account', icon: Settings, label: 'Account', shortLabel: 'Acct' },
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -167,7 +217,7 @@ export function Sidebar() {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={key}
|
key={key}
|
||||||
className="relative"
|
className="relative w-full"
|
||||||
onMouseEnter={() => hasChildren && !sidebarPinned ? openFlyout(key) : undefined}
|
onMouseEnter={() => hasChildren && !sidebarPinned ? openFlyout(key) : undefined}
|
||||||
onMouseLeave={() => hasChildren && !sidebarPinned ? closeFlyout() : 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 (
|
return (
|
||||||
<nav
|
<nav
|
||||||
ref={sidebarRef}
|
ref={sidebarRef}
|
||||||
className="sidebar flex flex-col items-center"
|
className="sidebar flex flex-col items-center h-full"
|
||||||
style={{ background: '#0f1118', borderRight: '1px solid #1e2130' }}
|
style={{ background: '#0f1118', borderRight: '1px solid #1e2130', minHeight: '100vh' }}
|
||||||
onWheel={handleWheel}
|
onWheel={handleWheel}
|
||||||
>
|
>
|
||||||
{/* Nav sections */}
|
{/* Grouped nav items */}
|
||||||
<div className="flex flex-col items-center w-full px-1.5 py-2 space-y-0.5">
|
<div className="flex flex-col items-center w-full px-1.5 pt-3 space-y-1">
|
||||||
{sections.map((section, si) => (
|
{railGroups.map((item, i) => (
|
||||||
<div key={section.title} className="w-full">
|
<div key={`rail-${i}`} data-flyout-key={`rail-${i}`}>
|
||||||
{si > 0 && (
|
{renderRailItem(item, `rail-${i}-inner`)}
|
||||||
<div className="mx-3 my-2" style={{ borderTop: '1px solid #1e2130' }} />
|
|
||||||
)}
|
|
||||||
{section.items.map((item, ii) => renderRailItemWithRef(item, `${si}-${ii}`))}
|
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex-1" />
|
<div className="flex-1" />
|
||||||
|
|
||||||
{/* Footer */}
|
{/* Footer: Account + Pin */}
|
||||||
<div className="flex flex-col items-center w-full px-1.5 py-2 space-y-0.5" style={{ borderTop: '1px solid #1e2130' }}>
|
<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) => (
|
{footerItems.map((item, i) => (
|
||||||
<div key={`footer-${i}`} data-flyout-key={`footer-${i}`}>
|
<div key={`footer-${i}`} data-flyout-key={`footer-${i}`}>
|
||||||
{renderRailItem(item, `footer-${i}-inner`)}
|
{renderRailItem(item, `footer-${i}-inner`)}
|
||||||
|
|||||||
Reference in New Issue
Block a user