import { useSearchExecutions, useExecutionStats, useStatsTimeseries } from '../../api/queries/executions'; import { useExecutionSearch } from './use-execution-search'; import { StatCard } from '../../components/shared/StatCard'; import { Pagination } from '../../components/shared/Pagination'; import { SearchFilters } from './SearchFilters'; import { ResultsTable } from './ResultsTable'; import styles from './ExecutionExplorer.module.css'; function formatCompact(n: number): string { if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`; if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`; return n.toLocaleString(); } function pctChange(current: number, previous: number): { text: string; direction: 'up' | 'down' | 'neutral' } { if (previous === 0) return { text: 'no prior data', direction: 'neutral' }; const pct = ((current - previous) / previous) * 100; if (Math.abs(pct) < 0.5) return { text: '~0% vs yesterday', direction: 'neutral' }; const arrow = pct > 0 ? '\u2191' : '\u2193'; return { text: `${arrow} ${Math.abs(pct).toFixed(1)}% vs yesterday`, direction: pct > 0 ? 'up' : 'down' }; } export function ExecutionExplorer() { const { toSearchRequest, offset, limit, setOffset, live, toggleLive } = useExecutionSearch(); const searchRequest = toSearchRequest(); const { data, isLoading, isFetching } = useSearchExecutions(searchRequest, live); const timeFrom = searchRequest.timeFrom ?? undefined; const timeTo = searchRequest.timeTo ?? undefined; const { data: stats } = useExecutionStats(timeFrom, timeTo); const { data: timeseries } = useStatsTimeseries(timeFrom, timeTo); const sparkTotal = timeseries?.buckets.map((b) => b.totalCount) ?? []; const sparkFailed = timeseries?.buckets.map((b) => b.failedCount) ?? []; const sparkAvgDuration = timeseries?.buckets.map((b) => b.avgDurationMs) ?? []; const sparkP99 = timeseries?.buckets.map((b) => b.p99DurationMs) ?? []; const sparkActive = timeseries?.buckets.map((b) => b.activeCount) ?? []; const total = data?.total ?? 0; const results = data?.data ?? []; // Failure rate as percentage const failureRate = stats && stats.totalCount > 0 ? (stats.failedCount / stats.totalCount) * 100 : 0; const prevFailureRate = stats && stats.prevTotalCount > 0 ? (stats.prevFailedCount / stats.prevTotalCount) * 100 : 0; // Comparison vs yesterday const avgChange = stats ? pctChange(stats.avgDurationMs, stats.prevAvgDurationMs) : null; const failRateChange = stats ? pctChange(failureRate, prevFailureRate) : null; const p99Change = stats ? pctChange(stats.p99LatencyMs, stats.prevP99LatencyMs) : null; const showFrom = total > 0 ? offset + 1 : 0; const showTo = Math.min(offset + limit, total); return ( <> {/* Page Header */}

Route Explorer

Search and analyze route executions
{/* Stats Bar */}
{/* Filters */} {/* Results Header */}
Showing {showFrom}–{showTo} of {total.toLocaleString()} results {isFetching && !isLoading && ' · updating...'}
{/* Results Table */} {/* Pagination */} ); }