diff --git a/ui/src/components/LayoutShell.tsx b/ui/src/components/LayoutShell.tsx index 2827f7ff..6cf5a5bd 100644 --- a/ui/src/components/LayoutShell.tsx +++ b/ui/src/components/LayoutShell.tsx @@ -108,23 +108,30 @@ function LayoutContent() { const sidebarApps: SidebarApp[] = useMemo(() => { if (!catalog) return []; - return catalog.map((app: any) => ({ - id: app.appId, - name: app.appId, - health: app.health as 'live' | 'stale' | 'dead', - exchangeCount: app.exchangeCount, - routes: (app.routes || []).map((r: any) => ({ - id: r.routeId, - name: r.routeId, - exchangeCount: r.exchangeCount, - })), - agents: (app.agents || []).map((a: any) => ({ - id: a.id, - name: a.name, - status: a.status as 'live' | 'stale' | 'dead', - tps: a.tps, - })), - })); + const cmp = (a: string, b: string) => a.localeCompare(b); + return [...catalog] + .sort((a: any, b: any) => cmp(a.appId, b.appId)) + .map((app: any) => ({ + id: app.appId, + name: app.appId, + health: app.health as 'live' | 'stale' | 'dead', + exchangeCount: app.exchangeCount, + routes: [...(app.routes || [])] + .sort((a: any, b: any) => cmp(a.routeId, b.routeId)) + .map((r: any) => ({ + id: r.routeId, + name: r.routeId, + exchangeCount: r.exchangeCount, + })), + agents: [...(app.agents || [])] + .sort((a: any, b: any) => cmp(a.name, b.name)) + .map((a: any) => ({ + id: a.id, + name: a.name, + status: a.status as 'live' | 'stale' | 'dead', + tps: a.tps, + })), + })); }, [catalog]); const catalogData = useMemo(