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,4 @@
|
||||
import { useState } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import styles from './AgentHealth.module.css'
|
||||
|
||||
// Layout
|
||||
@@ -18,21 +17,7 @@ import { Card } from '../../design-system/primitives/Card/Card'
|
||||
|
||||
// Mock data
|
||||
import { agents } from '../../mocks/agents'
|
||||
import { routes } from '../../mocks/routes'
|
||||
|
||||
// ─── Sidebar data (shared) ────────────────────────────────────────────────────
|
||||
const APPS = [
|
||||
{ id: 'order-service', name: 'order-service', agentCount: 2, health: 'live' as const, exchangeCount: 1433 },
|
||||
{ id: 'payment-svc', name: 'payment-svc', agentCount: 1, health: 'live' as const, exchangeCount: 912 },
|
||||
{ id: 'shipment-tracker', name: 'shipment-tracker', agentCount: 2, health: 'live' as const, exchangeCount: 471 },
|
||||
{ id: 'notification-hub', name: 'notification-hub', agentCount: 1, health: 'stale' as const, exchangeCount: 128 },
|
||||
]
|
||||
|
||||
const SIDEBAR_ROUTES = routes.slice(0, 3).map((r) => ({
|
||||
id: r.id,
|
||||
name: r.name,
|
||||
exchangeCount: r.exchangeCount,
|
||||
}))
|
||||
import { SIDEBAR_APPS } from '../../mocks/sidebar'
|
||||
|
||||
// ─── Build trend data for each agent ─────────────────────────────────────────
|
||||
function buildAgentTrendSeries(agentId: string) {
|
||||
@@ -68,16 +53,8 @@ const totalActiveRoutes = agents.reduce((sum, a) => sum + a.activeRoutes, 0)
|
||||
|
||||
// ─── AgentHealth page ─────────────────────────────────────────────────────────
|
||||
export function AgentHealth() {
|
||||
const navigate = useNavigate()
|
||||
const [activeItem, setActiveItem] = useState('agents')
|
||||
const [expandedAgent, setExpandedAgent] = useState<string | null>(null)
|
||||
|
||||
function handleItemClick(id: string) {
|
||||
setActiveItem(id)
|
||||
const route = routes.find((r) => r.id === id)
|
||||
if (route) navigate(`/routes/${id}`)
|
||||
}
|
||||
|
||||
function toggleAgent(id: string) {
|
||||
setExpandedAgent((prev) => (prev === id ? null : id))
|
||||
}
|
||||
@@ -85,13 +62,7 @@ export function AgentHealth() {
|
||||
return (
|
||||
<AppShell
|
||||
sidebar={
|
||||
<Sidebar
|
||||
apps={APPS}
|
||||
routes={SIDEBAR_ROUTES}
|
||||
agents={agents}
|
||||
activeItem={activeItem}
|
||||
onItemClick={handleItemClick}
|
||||
/>
|
||||
<Sidebar apps={SIDEBAR_APPS} />
|
||||
}
|
||||
>
|
||||
{/* Top bar */}
|
||||
|
||||
Reference in New Issue
Block a user