From 67bae5640c36ea30edb602152a1cdbd9361ed5c2 Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Sat, 28 Mar 2026 14:45:08 +0100 Subject: [PATCH] =?UTF-8?q?refactor(ui):=20remove=20KPI=20strip=20from=20D?= =?UTF-8?q?ashboard=20=E2=80=94=20metrics=20now=20in=20tab=20bar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/src/pages/Dashboard/Dashboard.tsx | 100 +-------------------------- 1 file changed, 1 insertion(+), 99 deletions(-) diff --git a/ui/src/pages/Dashboard/Dashboard.tsx b/ui/src/pages/Dashboard/Dashboard.tsx index 49a5253d..6c4b3b26 100644 --- a/ui/src/pages/Dashboard/Dashboard.tsx +++ b/ui/src/pages/Dashboard/Dashboard.tsx @@ -4,17 +4,14 @@ import { AlertTriangle, X, Search } from 'lucide-react' import { DataTable, ShortcutsBar, - KpiStrip, StatusDot, MonoText, Badge, useGlobalFilters, } from '@cameleer/design-system' -import type { Column, KpiItem } from '@cameleer/design-system' +import type { Column } from '@cameleer/design-system' import { useSearchExecutions, - useExecutionStats, - useStatsTimeseries, } from '../../api/queries/executions' import type { ExecutionSummary } from '../../api/types' import styles from './Dashboard.module.css' @@ -199,16 +196,12 @@ export default function Dashboard() { const { timeRange, statusFilters } = useGlobalFilters() const timeFrom = timeRange.start.toISOString() const timeTo = timeRange.end.toISOString() - const timeWindowSeconds = (timeRange.end.getTime() - timeRange.start.getTime()) / 1000 - const handleSortChange = useCallback((key: string, dir: 'asc' | 'desc') => { setSortField(key) setSortDir(dir) }, []) // ─── API hooks ─────────────────────────────────────────────────────────── - const { data: stats } = useExecutionStats(timeFrom, timeTo, routeId, appId) - const { data: timeseries } = useStatsTimeseries(timeFrom, timeTo, routeId, appId) // Convert design-system status filters (lowercase) to API status param (uppercase) const statusParam = statusFilters.size > 0 ? [...statusFilters].map(s => s.toUpperCase()).join(',') @@ -236,94 +229,6 @@ export default function Dashboard() { [searchResult], ) - // ─── KPI items ─────────────────────────────────────────────────────────── - const totalCount = stats?.totalCount ?? 0 - const failedCount = stats?.failedCount ?? 0 - const successRate = totalCount > 0 ? ((totalCount - failedCount) / totalCount) * 100 : 100 - const throughput = timeWindowSeconds > 0 ? totalCount / timeWindowSeconds : 0 - - const prevTotal = stats?.prevTotalCount ?? 0 - const prevFailed = stats?.prevFailedCount ?? 0 - const exchangeTrend = prevTotal > 0 ? ((totalCount - prevTotal) / prevTotal) * 100 : 0 - const prevSuccessRate = prevTotal > 0 ? ((prevTotal - prevFailed) / prevTotal) * 100 : 100 - const successRateDelta = successRate - prevSuccessRate - const errorDelta = failedCount - prevFailed - - const sparkExchanges = useMemo( - () => (timeseries?.buckets || []).map((b: any) => b.totalCount as number), - [timeseries], - ) - const sparkErrors = useMemo( - () => (timeseries?.buckets || []).map((b: any) => b.failedCount as number), - [timeseries], - ) - const sparkLatency = useMemo( - () => (timeseries?.buckets || []).map((b: any) => b.p99DurationMs as number), - [timeseries], - ) - const sparkThroughput = useMemo( - () => - (timeseries?.buckets || []).map((b: any) => { - const bucketSeconds = timeWindowSeconds / Math.max((timeseries?.buckets || []).length, 1) - return bucketSeconds > 0 ? (b.totalCount as number) / bucketSeconds : 0 - }), - [timeseries, timeWindowSeconds], - ) - - const kpiItems: KpiItem[] = useMemo( - () => [ - { - label: 'Exchanges', - value: totalCount.toLocaleString(), - trend: { - label: `${exchangeTrend > 0 ? '\u2191' : exchangeTrend < 0 ? '\u2193' : '\u2192'} ${exchangeTrend > 0 ? '+' : ''}${exchangeTrend.toFixed(0)}%`, - variant: (exchangeTrend > 0 ? 'success' : exchangeTrend < 0 ? 'error' : 'muted') as 'success' | 'error' | 'muted', - }, - subtitle: `${successRate.toFixed(1)}% success rate`, - sparkline: sparkExchanges, - borderColor: 'var(--amber)', - }, - { - label: 'Success Rate', - value: `${successRate.toFixed(1)}%`, - trend: { - label: `${successRateDelta >= 0 ? '\u2191' : '\u2193'} ${successRateDelta >= 0 ? '+' : ''}${successRateDelta.toFixed(1)}%`, - variant: (successRateDelta >= 0 ? 'success' : 'error') as 'success' | 'error', - }, - subtitle: `${(totalCount - failedCount).toLocaleString()} ok / ${failedCount} error`, - borderColor: 'var(--success)', - }, - { - label: 'Errors', - value: failedCount, - trend: { - label: `${errorDelta > 0 ? '\u2191' : errorDelta < 0 ? '\u2193' : '\u2192'} ${errorDelta > 0 ? '+' : ''}${errorDelta}`, - variant: (errorDelta > 0 ? 'error' : errorDelta < 0 ? 'success' : 'muted') as 'success' | 'error' | 'muted', - }, - subtitle: `${failedCount} errors in selected period`, - sparkline: sparkErrors, - borderColor: 'var(--error)', - }, - { - label: 'Throughput', - value: `${throughput.toFixed(1)} msg/s`, - trend: { label: '\u2192', variant: 'muted' as const }, - subtitle: `${throughput.toFixed(1)} msg/s`, - sparkline: sparkThroughput, - borderColor: 'var(--running)', - }, - { - label: 'Latency p99', - value: `${(stats?.p99LatencyMs ?? 0).toLocaleString()} ms`, - trend: { label: '', variant: 'muted' as const }, - subtitle: `${(stats?.p99LatencyMs ?? 0).toLocaleString()}ms`, - sparkline: sparkLatency, - borderColor: 'var(--warning)', - }, - ], - [totalCount, failedCount, successRate, throughput, exchangeTrend, successRateDelta, errorDelta, sparkExchanges, sparkErrors, sparkLatency, sparkThroughput, stats?.p99LatencyMs], - ) - // ─── Table columns ────────────────────────────────────────────────────── const columns: Column[] = useMemo(() => buildBaseColumns(), []) @@ -344,9 +249,6 @@ export default function Dashboard() { <> {/* Scrollable content */}
- {/* KPI strip */} - - {/* Exchanges table */}