feat: redesign Sidebar with hierarchical trees, starring, and collapsible sections
Replace flat app/route/agent lists with expandable tree navigation. Apps contain their routes and agents hierarchically. Add localStorage- backed starring with composite keys for uniqueness. Persist expand state to sessionStorage across page navigations. Add collapsible section headers, remove button on starred items, and parent app context labels. Create stub pages for /apps/:id, /agents/:id, /admin, /api-docs. Consolidate duplicated sidebar data into shared mock. Widen sidebar from 220px to 260px. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import styles from './LayoutSection.module.css'
|
||||
import { Sidebar } from '../../../design-system/layout/Sidebar/Sidebar'
|
||||
import type { SidebarApp } from '../../../design-system/layout/Sidebar/Sidebar'
|
||||
import { TopBar } from '../../../design-system/layout/TopBar/TopBar'
|
||||
|
||||
// ── DemoCard helper ──────────────────────────────────────────────────────────
|
||||
@@ -21,48 +22,42 @@ function DemoCard({ id, title, description, children }: DemoCardProps) {
|
||||
)
|
||||
}
|
||||
|
||||
// ── Sample data ───────────────────────────────────────────────────────────────
|
||||
// ── Sample data (hierarchical) ───────────────────────────────────────────────
|
||||
|
||||
const SAMPLE_APPS = [
|
||||
{ id: 'app1', name: 'cameleer-prod', agentCount: 3, health: 'live' as const, exchangeCount: 14320 },
|
||||
{ id: 'app2', name: 'cameleer-staging', agentCount: 2, health: 'stale' as const, exchangeCount: 871 },
|
||||
{ id: 'app3', name: 'cameleer-dev', agentCount: 1, health: 'dead' as const, exchangeCount: 42 },
|
||||
]
|
||||
|
||||
const SAMPLE_ROUTES = [
|
||||
{ id: 'r1', name: 'order-ingest', exchangeCount: 5421 },
|
||||
{ id: 'r2', name: 'payment-validate', exchangeCount: 3102 },
|
||||
{ id: 'r3', name: 'notify-customer', exchangeCount: 2201 },
|
||||
]
|
||||
|
||||
const SAMPLE_AGENTS = [
|
||||
const SAMPLE_APPS: SidebarApp[] = [
|
||||
{
|
||||
id: 'ag1',
|
||||
name: 'agent-prod-1',
|
||||
service: 'camel-core',
|
||||
version: 'v3.2.1',
|
||||
tps: '42 tps',
|
||||
lastSeen: '1m ago',
|
||||
status: 'live' as const,
|
||||
id: 'app1',
|
||||
name: 'cameleer-prod',
|
||||
health: 'live' as const,
|
||||
exchangeCount: 14320,
|
||||
routes: [
|
||||
{ id: 'r1', name: 'order-ingest', exchangeCount: 5421 },
|
||||
{ id: 'r2', name: 'payment-validate', exchangeCount: 3102 },
|
||||
],
|
||||
agents: [
|
||||
{ id: 'ag1', name: 'agent-prod-1', status: 'live' as const, tps: '42 tps' },
|
||||
{ id: 'ag2', name: 'agent-prod-2', status: 'live' as const, tps: '38 tps' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'ag2',
|
||||
name: 'agent-prod-2',
|
||||
service: 'camel-core',
|
||||
version: 'v3.2.1',
|
||||
tps: '38 tps',
|
||||
lastSeen: '2m ago',
|
||||
status: 'live' as const,
|
||||
errorRate: '0.4%',
|
||||
id: 'app2',
|
||||
name: 'cameleer-staging',
|
||||
health: 'stale' as const,
|
||||
exchangeCount: 871,
|
||||
routes: [
|
||||
{ id: 'r3', name: 'notify-customer', exchangeCount: 2201 },
|
||||
],
|
||||
agents: [
|
||||
{ id: 'ag3', name: 'agent-staging-1', status: 'stale' as const, tps: '5 tps' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'ag3',
|
||||
name: 'agent-staging-1',
|
||||
service: 'camel-core',
|
||||
version: 'v3.1.9',
|
||||
tps: '5 tps',
|
||||
lastSeen: '8m ago',
|
||||
status: 'stale' as const,
|
||||
id: 'app3',
|
||||
name: 'cameleer-dev',
|
||||
health: 'dead' as const,
|
||||
exchangeCount: 42,
|
||||
routes: [],
|
||||
agents: [],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -89,9 +84,9 @@ export function LayoutSection() {
|
||||
<span style={{ fontWeight: 400, fontSize: 10, marginTop: 4 }}>Logo</span>
|
||||
<span style={{ fontWeight: 400, fontSize: 10 }}>Search</span>
|
||||
<span style={{ fontWeight: 400, fontSize: 10 }}>Navigation</span>
|
||||
<span style={{ fontWeight: 400, fontSize: 10 }}>Applications</span>
|
||||
<span style={{ fontWeight: 400, fontSize: 10 }}>Routes</span>
|
||||
<span style={{ fontWeight: 400, fontSize: 10 }}>Agents</span>
|
||||
<span style={{ fontWeight: 400, fontSize: 10 }}>Applications tree</span>
|
||||
<span style={{ fontWeight: 400, fontSize: 10 }}>Agents tree</span>
|
||||
<span style={{ fontWeight: 400, fontSize: 10 }}>Starred</span>
|
||||
</div>
|
||||
<div className={styles.shellDiagramMain}>
|
||||
<children> — page content rendered here
|
||||
@@ -104,14 +99,10 @@ export function LayoutSection() {
|
||||
<DemoCard
|
||||
id="sidebar"
|
||||
title="Sidebar"
|
||||
description="Navigation sidebar with app/route/agent sections, search filter, health dots, and exec counts."
|
||||
description="Navigation sidebar with hierarchical app/route/agent trees, starring, search filter, and bottom links."
|
||||
>
|
||||
<div className={styles.sidebarPreview}>
|
||||
<Sidebar
|
||||
apps={SAMPLE_APPS}
|
||||
routes={SAMPLE_ROUTES}
|
||||
agents={SAMPLE_AGENTS}
|
||||
/>
|
||||
<Sidebar apps={SAMPLE_APPS} />
|
||||
</div>
|
||||
</DemoCard>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user