refactor: strip AppShell+Sidebar wrappers from all page components
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,6 @@
|
||||
import { useNavigate, useLocation } from 'react-router-dom'
|
||||
import { AppShell } from '../../design-system/layout/AppShell/AppShell'
|
||||
import { Sidebar } from '../../design-system/layout/Sidebar/Sidebar'
|
||||
import { TopBar } from '../../design-system/layout/TopBar/TopBar'
|
||||
import { Tabs } from '../../design-system/composites/Tabs/Tabs'
|
||||
import { SIDEBAR_APPS } from '../../mocks/sidebar'
|
||||
import styles from './Admin.module.css'
|
||||
import type { ReactNode } from 'react'
|
||||
|
||||
@@ -23,7 +20,7 @@ export function AdminLayout({ title, children }: AdminLayoutProps) {
|
||||
const location = useLocation()
|
||||
|
||||
return (
|
||||
<AppShell sidebar={<Sidebar apps={SIDEBAR_APPS} />}>
|
||||
<>
|
||||
<TopBar
|
||||
breadcrumb={[
|
||||
{ label: 'Admin', href: '/admin' },
|
||||
@@ -40,6 +37,6 @@ export function AdminLayout({ title, children }: AdminLayoutProps) {
|
||||
<div className={styles.adminContent}>
|
||||
{children}
|
||||
</div>
|
||||
</AppShell>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@ import { ChevronRight } from 'lucide-react'
|
||||
import styles from './AgentHealth.module.css'
|
||||
|
||||
// Layout
|
||||
import { AppShell } from '../../design-system/layout/AppShell/AppShell'
|
||||
import { Sidebar } from '../../design-system/layout/Sidebar/Sidebar'
|
||||
import { TopBar } from '../../design-system/layout/TopBar/TopBar'
|
||||
|
||||
// Composites
|
||||
@@ -28,7 +26,6 @@ import { useGlobalFilters } from '../../design-system/providers/GlobalFilterProv
|
||||
|
||||
// Mock data
|
||||
import { agents, type AgentHealth as AgentHealthData } from '../../mocks/agents'
|
||||
import { SIDEBAR_APPS } from '../../mocks/sidebar'
|
||||
import { agentEvents } from '../../mocks/agentEvents'
|
||||
|
||||
// ── URL scope parsing ────────────────────────────────────────────────────────
|
||||
@@ -317,19 +314,7 @@ export function AgentHealth() {
|
||||
const isFullWidth = scope.level !== 'all'
|
||||
|
||||
return (
|
||||
<AppShell
|
||||
sidebar={<Sidebar apps={SIDEBAR_APPS} />}
|
||||
detail={
|
||||
selectedInstance ? (
|
||||
<DetailPanel
|
||||
open={panelOpen}
|
||||
onClose={() => setPanelOpen(false)}
|
||||
title={selectedInstance.name}
|
||||
tabs={detailTabs}
|
||||
/>
|
||||
) : undefined
|
||||
}
|
||||
>
|
||||
<>
|
||||
<TopBar
|
||||
breadcrumb={buildBreadcrumb(scope)}
|
||||
environment="PRODUCTION"
|
||||
@@ -454,6 +439,16 @@ export function AgentHealth() {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</AppShell>
|
||||
|
||||
{/* Detail panel (portals itself) */}
|
||||
{selectedInstance && (
|
||||
<DetailPanel
|
||||
open={panelOpen}
|
||||
onClose={() => setPanelOpen(false)}
|
||||
title={selectedInstance.name}
|
||||
tabs={detailTabs}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@ import { ChevronRight } from 'lucide-react'
|
||||
import styles from './AgentInstance.module.css'
|
||||
|
||||
// Layout
|
||||
import { AppShell } from '../../design-system/layout/AppShell/AppShell'
|
||||
import { Sidebar } from '../../design-system/layout/Sidebar/Sidebar'
|
||||
import { TopBar } from '../../design-system/layout/TopBar/TopBar'
|
||||
|
||||
// Composites
|
||||
@@ -28,7 +26,6 @@ import { useGlobalFilters } from '../../design-system/providers/GlobalFilterProv
|
||||
|
||||
// Data
|
||||
import { agents } from '../../mocks/agents'
|
||||
import { SIDEBAR_APPS } from '../../mocks/sidebar'
|
||||
import { agentEvents } from '../../mocks/agentEvents'
|
||||
|
||||
import { useState } from 'react'
|
||||
@@ -127,12 +124,12 @@ export function AgentInstance() {
|
||||
|
||||
if (!agent) {
|
||||
return (
|
||||
<AppShell sidebar={<Sidebar apps={SIDEBAR_APPS} />}>
|
||||
<>
|
||||
<TopBar breadcrumb={[{ label: 'Agents', href: '/agents' }, { label: 'Not Found' }]} environment="PRODUCTION" user={{ name: 'hendrik' }} />
|
||||
<div className={styles.content}>
|
||||
<div className={styles.notFound}>Agent instance not found.</div>
|
||||
</div>
|
||||
</AppShell>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -153,7 +150,7 @@ export function AgentInstance() {
|
||||
const statusColor = agent.status === 'live' ? 'success' : agent.status === 'stale' ? 'warning' : 'error'
|
||||
|
||||
return (
|
||||
<AppShell sidebar={<Sidebar apps={SIDEBAR_APPS} />}>
|
||||
<>
|
||||
<TopBar
|
||||
breadcrumb={[
|
||||
{ label: 'Applications', href: '/apps' },
|
||||
@@ -302,6 +299,6 @@ export function AgentInstance() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</AppShell>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
import { AppShell } from '../../design-system/layout/AppShell/AppShell'
|
||||
import { Sidebar } from '../../design-system/layout/Sidebar/Sidebar'
|
||||
import { TopBar } from '../../design-system/layout/TopBar/TopBar'
|
||||
import { EmptyState } from '../../design-system/primitives/EmptyState/EmptyState'
|
||||
import { SIDEBAR_APPS } from '../../mocks/sidebar'
|
||||
|
||||
export function ApiDocs() {
|
||||
return (
|
||||
<AppShell sidebar={<Sidebar apps={SIDEBAR_APPS} />}>
|
||||
<>
|
||||
<TopBar
|
||||
breadcrumb={[{ label: 'API Documentation' }]}
|
||||
environment="PRODUCTION"
|
||||
@@ -17,6 +14,6 @@ export function ApiDocs() {
|
||||
title="API Documentation"
|
||||
description="API documentation coming soon."
|
||||
/>
|
||||
</AppShell>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
import { useParams } from 'react-router-dom'
|
||||
import { AppShell } from '../../design-system/layout/AppShell/AppShell'
|
||||
import { Sidebar } from '../../design-system/layout/Sidebar/Sidebar'
|
||||
import { TopBar } from '../../design-system/layout/TopBar/TopBar'
|
||||
import { EmptyState } from '../../design-system/primitives/EmptyState/EmptyState'
|
||||
import { SIDEBAR_APPS } from '../../mocks/sidebar'
|
||||
|
||||
export function AppDetail() {
|
||||
const { id } = useParams<{ id: string }>()
|
||||
|
||||
return (
|
||||
<AppShell sidebar={<Sidebar apps={SIDEBAR_APPS} />}>
|
||||
<>
|
||||
<TopBar
|
||||
breadcrumb={[
|
||||
{ label: 'Applications', href: '/apps' },
|
||||
@@ -23,6 +20,6 @@ export function AppDetail() {
|
||||
title="Application Detail"
|
||||
description="Application detail view coming soon."
|
||||
/>
|
||||
</AppShell>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@ import { TrendingUp, TrendingDown, ArrowRight, ExternalLink, AlertTriangle } fro
|
||||
import styles from './Dashboard.module.css'
|
||||
|
||||
// Layout
|
||||
import { AppShell } from '../../design-system/layout/AppShell/AppShell'
|
||||
import { Sidebar } from '../../design-system/layout/Sidebar/Sidebar'
|
||||
import { TopBar } from '../../design-system/layout/TopBar/TopBar'
|
||||
|
||||
// Composites
|
||||
@@ -287,12 +285,67 @@ export function Dashboard() {
|
||||
const totalErrors = processorErrors.length + (hasExchangeError && processorErrors.length === 0 ? 1 : 0)
|
||||
|
||||
return (
|
||||
<AppShell
|
||||
sidebar={
|
||||
<Sidebar apps={SIDEBAR_APPS} />
|
||||
<>
|
||||
{/* Top bar */}
|
||||
<TopBar
|
||||
breadcrumb={
|
||||
routeId
|
||||
? [{ label: 'Applications', href: '/apps' }, { label: appId!, href: `/apps/${appId}` }, { label: routeId }]
|
||||
: appId
|
||||
? [{ label: 'Applications', href: '/apps' }, { label: appId }]
|
||||
: [{ label: 'Applications' }]
|
||||
}
|
||||
detail={
|
||||
selectedExchange ? (
|
||||
environment="PRODUCTION"
|
||||
user={{ name: 'hendrik' }}
|
||||
/>
|
||||
|
||||
{/* Scrollable content */}
|
||||
<div className={styles.content}>
|
||||
|
||||
{/* Health strip */}
|
||||
<KpiStrip items={kpiItems} />
|
||||
|
||||
{/* Exchanges table */}
|
||||
<div className={styles.tableSection}>
|
||||
<div className={styles.tableHeader}>
|
||||
<span className={styles.tableTitle}>Recent Exchanges</span>
|
||||
<div className={styles.tableRight}>
|
||||
<span className={styles.tableMeta}>
|
||||
{filteredExchanges.length.toLocaleString()} of {scopedExchanges.length.toLocaleString()} exchanges
|
||||
</span>
|
||||
<Badge label="LIVE" color="success" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DataTable
|
||||
columns={COLUMNS}
|
||||
data={filteredExchanges}
|
||||
onRowClick={handleRowClick}
|
||||
selectedId={selectedId}
|
||||
sortable
|
||||
flush
|
||||
fillHeight
|
||||
rowAccent={handleRowAccent}
|
||||
expandedContent={(row) =>
|
||||
row.errorMessage ? (
|
||||
<div className={styles.inlineError}>
|
||||
<span className={styles.inlineErrorIcon}><AlertTriangle size={14} /></span>
|
||||
<div>
|
||||
<div className={styles.inlineErrorText}>{row.errorMessage}</div>
|
||||
<div className={styles.inlineErrorHint}>Click to view full stack trace</div>
|
||||
</div>
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Shortcuts bar */}
|
||||
<ShortcutsBar shortcuts={SHORTCUTS} />
|
||||
|
||||
{/* Detail panel (portals itself) */}
|
||||
{selectedExchange && (
|
||||
<DetailPanel
|
||||
open={panelOpen}
|
||||
onClose={() => setPanelOpen(false)}
|
||||
@@ -384,66 +437,7 @@ export function Dashboard() {
|
||||
/>
|
||||
</div>
|
||||
</DetailPanel>
|
||||
) : undefined
|
||||
}
|
||||
>
|
||||
{/* Top bar */}
|
||||
<TopBar
|
||||
breadcrumb={
|
||||
routeId
|
||||
? [{ label: 'Applications', href: '/apps' }, { label: appId!, href: `/apps/${appId}` }, { label: routeId }]
|
||||
: appId
|
||||
? [{ label: 'Applications', href: '/apps' }, { label: appId }]
|
||||
: [{ label: 'Applications' }]
|
||||
}
|
||||
environment="PRODUCTION"
|
||||
user={{ name: 'hendrik' }}
|
||||
/>
|
||||
|
||||
{/* Scrollable content */}
|
||||
<div className={styles.content}>
|
||||
|
||||
{/* Health strip */}
|
||||
<KpiStrip items={kpiItems} />
|
||||
|
||||
{/* Exchanges table */}
|
||||
<div className={styles.tableSection}>
|
||||
<div className={styles.tableHeader}>
|
||||
<span className={styles.tableTitle}>Recent Exchanges</span>
|
||||
<div className={styles.tableRight}>
|
||||
<span className={styles.tableMeta}>
|
||||
{filteredExchanges.length.toLocaleString()} of {scopedExchanges.length.toLocaleString()} exchanges
|
||||
</span>
|
||||
<Badge label="LIVE" color="success" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DataTable
|
||||
columns={COLUMNS}
|
||||
data={filteredExchanges}
|
||||
onRowClick={handleRowClick}
|
||||
selectedId={selectedId}
|
||||
sortable
|
||||
flush
|
||||
fillHeight
|
||||
rowAccent={handleRowAccent}
|
||||
expandedContent={(row) =>
|
||||
row.errorMessage ? (
|
||||
<div className={styles.inlineError}>
|
||||
<span className={styles.inlineErrorIcon}><AlertTriangle size={14} /></span>
|
||||
<div>
|
||||
<div className={styles.inlineErrorText}>{row.errorMessage}</div>
|
||||
<div className={styles.inlineErrorHint}>Click to view full stack trace</div>
|
||||
</div>
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Shortcuts bar */}
|
||||
<ShortcutsBar shortcuts={SHORTCUTS} />
|
||||
</AppShell>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,8 +3,6 @@ import { useParams, useNavigate } from 'react-router-dom'
|
||||
import styles from './ExchangeDetail.module.css'
|
||||
|
||||
// Layout
|
||||
import { AppShell } from '../../design-system/layout/AppShell/AppShell'
|
||||
import { Sidebar } from '../../design-system/layout/Sidebar/Sidebar'
|
||||
import { TopBar } from '../../design-system/layout/TopBar/TopBar'
|
||||
|
||||
// Composites
|
||||
@@ -22,7 +20,7 @@ import { InfoCallout } from '../../design-system/primitives/InfoCallout/InfoCall
|
||||
|
||||
// Mock data
|
||||
import { exchanges } from '../../mocks/exchanges'
|
||||
import { SIDEBAR_APPS, buildRouteToAppMap } from '../../mocks/sidebar'
|
||||
import { buildRouteToAppMap } from '../../mocks/sidebar'
|
||||
|
||||
const ROUTE_TO_APP = buildRouteToAppMap()
|
||||
|
||||
@@ -196,11 +194,7 @@ export function ExchangeDetail() {
|
||||
// Not found state
|
||||
if (!exchange) {
|
||||
return (
|
||||
<AppShell
|
||||
sidebar={
|
||||
<Sidebar apps={SIDEBAR_APPS} />
|
||||
}
|
||||
>
|
||||
<>
|
||||
<TopBar
|
||||
breadcrumb={[
|
||||
{ label: 'Applications', href: '/apps' },
|
||||
@@ -213,7 +207,7 @@ export function ExchangeDetail() {
|
||||
<div className={styles.content}>
|
||||
<InfoCallout variant="warning">Exchange "{id}" not found in mock data.</InfoCallout>
|
||||
</div>
|
||||
</AppShell>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -229,11 +223,7 @@ export function ExchangeDetail() {
|
||||
const isSelectedFailed = selectedProc?.status === 'fail'
|
||||
|
||||
return (
|
||||
<AppShell
|
||||
sidebar={
|
||||
<Sidebar apps={SIDEBAR_APPS} />
|
||||
}
|
||||
>
|
||||
<>
|
||||
{/* Top bar */}
|
||||
<TopBar
|
||||
breadcrumb={[
|
||||
@@ -454,6 +444,6 @@ export function ExchangeDetail() {
|
||||
)}
|
||||
|
||||
</div>
|
||||
</AppShell>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,8 +3,6 @@ import { useNavigate, useParams } from 'react-router-dom'
|
||||
import styles from './Routes.module.css'
|
||||
|
||||
// Layout
|
||||
import { AppShell } from '../../design-system/layout/AppShell/AppShell'
|
||||
import { Sidebar } from '../../design-system/layout/Sidebar/Sidebar'
|
||||
import { TopBar } from '../../design-system/layout/TopBar/TopBar'
|
||||
|
||||
// Composites
|
||||
@@ -33,7 +31,7 @@ import {
|
||||
type RouteMetricRow,
|
||||
} from '../../mocks/metrics'
|
||||
import { routes } from '../../mocks/routes'
|
||||
import { SIDEBAR_APPS, buildRouteToAppMap } from '../../mocks/sidebar'
|
||||
import { buildRouteToAppMap } from '../../mocks/sidebar'
|
||||
|
||||
const ROUTE_TO_APP = buildRouteToAppMap()
|
||||
|
||||
@@ -410,7 +408,7 @@ export function Routes() {
|
||||
// ── Route detail view ───────────────────────────────────────────────────────
|
||||
if (routeId && appId && routeDef) {
|
||||
return (
|
||||
<AppShell sidebar={<Sidebar apps={SIDEBAR_APPS} />}>
|
||||
<>
|
||||
<TopBar
|
||||
breadcrumb={breadcrumb}
|
||||
environment="PRODUCTION"
|
||||
@@ -448,13 +446,13 @@ export function Routes() {
|
||||
<RouteFlow nodes={routeFlowNodes} />
|
||||
</div>
|
||||
</div>
|
||||
</AppShell>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
// ── Top level / Application level view ──────────────────────────────────────
|
||||
return (
|
||||
<AppShell sidebar={<Sidebar apps={SIDEBAR_APPS} />}>
|
||||
<>
|
||||
<TopBar
|
||||
breadcrumb={breadcrumb}
|
||||
environment="PRODUCTION"
|
||||
@@ -533,6 +531,6 @@ export function Routes() {
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</AppShell>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user