2026-03-18 20:06:25 +01:00
|
|
|
import { useMemo, useCallback } from 'react'
|
|
|
|
|
import { Routes, Route, Navigate, useNavigate } from 'react-router-dom'
|
2026-03-18 10:06:41 +01:00
|
|
|
import { Dashboard } from './pages/Dashboard/Dashboard'
|
2026-03-19 15:29:27 +01:00
|
|
|
import { Routes as RoutesPage } from './pages/Routes/Routes'
|
2026-03-18 10:22:23 +01:00
|
|
|
import { ExchangeDetail } from './pages/ExchangeDetail/ExchangeDetail'
|
|
|
|
|
import { AgentHealth } from './pages/AgentHealth/AgentHealth'
|
feat: add AgentInstance detail page and improve AgentHealth
- New /agents/:appId/:instanceId page with process info, 3x2 charts
grid (CPU, memory, throughput, errors, threads, GC), application
log viewer with level filtering, and instance-scoped timeline
- AgentHealth now uses slide-in DetailPanel for quick instance preview
- Stat strip enhanced: colored StatusDot breakdowns, route ratio with
state-colored values, Groups renamed to Applications
- Unified page structure: stat strip → scope trail with inline badges
(removed duplicate section headers from both pages)
- StatCard value/detail props now accept ReactNode
- Log and timeline displayed side by side
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 10:51:13 +01:00
|
|
|
import { AgentInstance } from './pages/AgentInstance/AgentInstance'
|
2026-03-18 15:12:28 +01:00
|
|
|
import { Inventory } from './pages/Inventory/Inventory'
|
2026-03-18 23:04:28 +01:00
|
|
|
import { AuditLog } from './pages/Admin/AuditLog/AuditLog'
|
|
|
|
|
import { OidcConfig } from './pages/Admin/OidcConfig/OidcConfig'
|
|
|
|
|
import { UserManagement } from './pages/Admin/UserManagement/UserManagement'
|
2026-03-18 17:50:41 +01:00
|
|
|
import { ApiDocs } from './pages/ApiDocs/ApiDocs'
|
2026-03-18 10:06:41 +01:00
|
|
|
|
2026-03-18 20:06:25 +01:00
|
|
|
import { CommandPalette } from './design-system/composites/CommandPalette/CommandPalette'
|
|
|
|
|
import type { SearchResult } from './design-system/composites/CommandPalette/types'
|
|
|
|
|
import { useCommandPalette } from './design-system/providers/CommandPaletteProvider'
|
|
|
|
|
import { useGlobalFilters } from './design-system/providers/GlobalFilterProvider'
|
|
|
|
|
import { buildSearchData } from './mocks/searchData'
|
|
|
|
|
import { exchanges } from './mocks/exchanges'
|
|
|
|
|
import { routes } from './mocks/routes'
|
|
|
|
|
import { agents } from './mocks/agents'
|
refactor: unify /apps routing with application and route filtering
- Table columns: Status, Route, Application, Started (yyyy-mm-dd hh:mm:ss),
Duration, Agent (removed Order ID and Customer)
- /apps shows all exchanges, /apps/:id filters by application,
/apps/:id/:routeId filters by application and route
- Route paths changed from /routes/:id to /apps/:appId/:routeId across
sidebar, search, breadcrumbs, metrics, and exchange detail
- Added buildRouteToAppMap utility for route→application lookup
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 12:39:45 +01:00
|
|
|
import { SIDEBAR_APPS, buildRouteToAppMap } from './mocks/sidebar'
|
|
|
|
|
|
|
|
|
|
const routeToApp = buildRouteToAppMap()
|
2026-03-18 20:06:25 +01:00
|
|
|
|
|
|
|
|
/** Compute which sidebar path to reveal for a given search result */
|
|
|
|
|
function computeSidebarRevealPath(result: SearchResult): string | undefined {
|
|
|
|
|
if (!result.path) return undefined
|
|
|
|
|
|
|
|
|
|
if (result.category === 'application') {
|
|
|
|
|
return result.path
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (result.category === 'route') {
|
|
|
|
|
return result.path
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (result.category === 'agent') {
|
|
|
|
|
return result.path
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (result.category === 'exchange') {
|
|
|
|
|
const exchange = exchanges.find((e) => e.id === result.id)
|
|
|
|
|
if (exchange) {
|
refactor: unify /apps routing with application and route filtering
- Table columns: Status, Route, Application, Started (yyyy-mm-dd hh:mm:ss),
Duration, Agent (removed Order ID and Customer)
- /apps shows all exchanges, /apps/:id filters by application,
/apps/:id/:routeId filters by application and route
- Route paths changed from /routes/:id to /apps/:appId/:routeId across
sidebar, search, breadcrumbs, metrics, and exchange detail
- Added buildRouteToAppMap utility for route→application lookup
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 12:39:45 +01:00
|
|
|
const appId = routeToApp.get(exchange.route)
|
|
|
|
|
if (appId) return `/apps/${appId}/${exchange.route}`
|
2026-03-18 20:06:25 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result.path
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-18 09:07:31 +01:00
|
|
|
export default function App() {
|
2026-03-18 20:06:25 +01:00
|
|
|
const navigate = useNavigate()
|
|
|
|
|
const { open: paletteOpen, setOpen } = useCommandPalette()
|
|
|
|
|
const { isInTimeRange, statusFilters } = useGlobalFilters()
|
|
|
|
|
|
|
|
|
|
const filteredSearchData = useMemo(() => {
|
|
|
|
|
// Filter exchanges by time range and status
|
|
|
|
|
let filteredExchanges = exchanges.filter((e) => isInTimeRange(e.timestamp))
|
|
|
|
|
if (statusFilters.size > 0) {
|
|
|
|
|
filteredExchanges = filteredExchanges.filter((e) => statusFilters.has(e.status))
|
|
|
|
|
}
|
|
|
|
|
return buildSearchData(filteredExchanges, routes, agents)
|
|
|
|
|
}, [isInTimeRange, statusFilters])
|
|
|
|
|
|
|
|
|
|
const handleSelect = useCallback(
|
|
|
|
|
(result: SearchResult) => {
|
|
|
|
|
if (result.path) {
|
|
|
|
|
const sidebarReveal = computeSidebarRevealPath(result)
|
|
|
|
|
navigate(result.path, { state: sidebarReveal ? { sidebarReveal } : undefined })
|
|
|
|
|
}
|
|
|
|
|
setOpen(false)
|
|
|
|
|
},
|
|
|
|
|
[navigate, setOpen],
|
|
|
|
|
)
|
|
|
|
|
|
2026-03-18 10:06:41 +01:00
|
|
|
return (
|
2026-03-18 20:06:25 +01:00
|
|
|
<>
|
|
|
|
|
<Routes>
|
|
|
|
|
<Route path="/" element={<Navigate to="/apps" replace />} />
|
|
|
|
|
<Route path="/apps" element={<Dashboard />} />
|
|
|
|
|
<Route path="/apps/:id" element={<Dashboard />} />
|
refactor: unify /apps routing with application and route filtering
- Table columns: Status, Route, Application, Started (yyyy-mm-dd hh:mm:ss),
Duration, Agent (removed Order ID and Customer)
- /apps shows all exchanges, /apps/:id filters by application,
/apps/:id/:routeId filters by application and route
- Route paths changed from /routes/:id to /apps/:appId/:routeId across
sidebar, search, breadcrumbs, metrics, and exchange detail
- Added buildRouteToAppMap utility for route→application lookup
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 12:39:45 +01:00
|
|
|
<Route path="/apps/:id/:routeId" element={<Dashboard />} />
|
2026-03-19 15:29:27 +01:00
|
|
|
<Route path="/routes" element={<RoutesPage />} />
|
|
|
|
|
<Route path="/routes/:appId" element={<RoutesPage />} />
|
|
|
|
|
<Route path="/routes/:appId/:routeId" element={<RoutesPage />} />
|
2026-03-18 20:06:25 +01:00
|
|
|
<Route path="/exchanges/:id" element={<ExchangeDetail />} />
|
feat: add AgentInstance detail page and improve AgentHealth
- New /agents/:appId/:instanceId page with process info, 3x2 charts
grid (CPU, memory, throughput, errors, threads, GC), application
log viewer with level filtering, and instance-scoped timeline
- AgentHealth now uses slide-in DetailPanel for quick instance preview
- Stat strip enhanced: colored StatusDot breakdowns, route ratio with
state-colored values, Groups renamed to Applications
- Unified page structure: stat strip → scope trail with inline badges
(removed duplicate section headers from both pages)
- StatCard value/detail props now accept ReactNode
- Log and timeline displayed side by side
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 10:51:13 +01:00
|
|
|
<Route path="/agents/:appId/:instanceId" element={<AgentInstance />} />
|
2026-03-18 20:06:25 +01:00
|
|
|
<Route path="/agents/*" element={<AgentHealth />} />
|
2026-03-18 23:04:28 +01:00
|
|
|
<Route path="/admin" element={<Navigate to="/admin/rbac" replace />} />
|
|
|
|
|
<Route path="/admin/audit" element={<AuditLog />} />
|
|
|
|
|
<Route path="/admin/oidc" element={<OidcConfig />} />
|
|
|
|
|
<Route path="/admin/rbac" element={<UserManagement />} />
|
2026-03-18 20:06:25 +01:00
|
|
|
<Route path="/api-docs" element={<ApiDocs />} />
|
|
|
|
|
<Route path="/inventory" element={<Inventory />} />
|
|
|
|
|
</Routes>
|
|
|
|
|
<CommandPalette
|
|
|
|
|
open={paletteOpen}
|
|
|
|
|
onClose={() => setOpen(false)}
|
|
|
|
|
onOpen={() => setOpen(true)}
|
|
|
|
|
data={filteredSearchData}
|
|
|
|
|
onSelect={handleSelect}
|
|
|
|
|
/>
|
|
|
|
|
</>
|
2026-03-18 10:06:41 +01:00
|
|
|
)
|
2026-03-18 09:03:33 +01:00
|
|
|
}
|