more code
This commit is contained in:
1 parent
f24fd63e9a
commit
ee72257c64
29 files changed
+5636
-440
No files matched your search
+11
-26
@@ -23,11 +23,11 @@ import {
|
||||
} from 'recharts'
|
||||
import { Activity, Ban, Gauge, RefreshCw, Timer } from 'lucide-react'
|
||||
|
||||
import { getDashboard } from '../../lib/api'
|
||||
import type { Dashboard as DashboardData, LogItem, UpstreamStat } from '../../lib/types'
|
||||
import { useApi } from '../../hooks/useApi'
|
||||
import { useAutoRefresh } from '../../hooks/useAutoRefresh'
|
||||
import { TIME_RANGES, useTimeRange } from '../../hooks/useTimeRange'
|
||||
import { getDashboard } from '../lib/api'
|
||||
import type { Dashboard as DashboardData, LogItem, UpstreamStat } from '../lib/types'
|
||||
import { useApi } from '../hooks/useApi'
|
||||
import { useAutoRefresh } from '../hooks/useAutoRefresh'
|
||||
import { TIME_RANGES, useTimeRange } from '../hooks/useTimeRange'
|
||||
import {
|
||||
formatClock,
|
||||
formatCompact,
|
||||
@@ -36,7 +36,7 @@ import {
|
||||
formatPercent,
|
||||
formatRate,
|
||||
formatUptime,
|
||||
} from '../../lib/format'
|
||||
} from '../lib/format'
|
||||
import { Badge, Button, Card, CardBody, EmptyState, Progress, StatCard, Table } from '../components/ui'
|
||||
import { HealthPill, PageError, PageHeader } from '../components/layout'
|
||||
|
||||
@@ -47,7 +47,6 @@ const QUERIES = '#38bdf8'
|
||||
const CACHED = '#34d399'
|
||||
const BLOCKED = '#f59e0b'
|
||||
const ERRORS = '#f87171'
|
||||
const TIP_BG = '#0f172a'
|
||||
|
||||
/** The parts of the dashboard payload that older daemons may not send. */
|
||||
type DashboardView = Partial<DashboardData> & {
|
||||
@@ -64,20 +63,6 @@ function view(data: DashboardData | null): DashboardView {
|
||||
return (data ?? {}) as DashboardView
|
||||
}
|
||||
|
||||
/** `useToast()` shape is the UI kit's business; this just needs a call. */
|
||||
type ToastLike = {
|
||||
success?: (message: string) => void
|
||||
error?: (message: string) => void
|
||||
toast?: (message: string) => void
|
||||
push?: (message: string) => void
|
||||
}
|
||||
|
||||
function notify(toast: unknown, kind: 'ok' | 'fail', message: string): void {
|
||||
const t = toast as ToastLike
|
||||
const fn = kind === 'ok' ? (t.success ?? t.toast ?? t.push) : (t.error ?? t.toast ?? t.push)
|
||||
fn?.call(t, message)
|
||||
}
|
||||
|
||||
type TipProps = {
|
||||
active?: boolean
|
||||
label?: number | string
|
||||
@@ -222,7 +207,7 @@ export default function Dashboard() {
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
icon={<RefreshCw size={14} />}
|
||||
icon={RefreshCw}
|
||||
onClick={refetch}
|
||||
loading={loading}
|
||||
>
|
||||
@@ -251,26 +236,26 @@ export default function Dashboard() {
|
||||
label="Queries / s"
|
||||
value={formatCompact(d.queries_per_sec ?? 0)}
|
||||
hint={`${formatNumber(d.queries_total ?? 0)} total`}
|
||||
icon={<Activity size={16} />}
|
||||
icon={Activity}
|
||||
/>
|
||||
<StatCard
|
||||
label="Cache hit rate"
|
||||
value={formatRate(hitRate)}
|
||||
hint="higher is better"
|
||||
icon={<Gauge size={16} />}
|
||||
icon={Gauge}
|
||||
tone={hitRate >= 0.7 ? 'ok' : hitRate >= 0.4 ? 'warn' : 'danger'}
|
||||
/>
|
||||
<StatCard
|
||||
label="Blocked"
|
||||
value={formatPercent(d.blocked_pct ?? 0)}
|
||||
hint={`${formatNumber(d.blocked_total ?? 0)} queries`}
|
||||
icon={<Ban size={16} />}
|
||||
icon={Ban}
|
||||
/>
|
||||
<StatCard
|
||||
label={latencyLabel}
|
||||
value={latencyValue != null ? formatMs(latencyValue) : '—'}
|
||||
hint={p99 != null ? 'from the server' : 'slowest upstream p95'}
|
||||
icon={<Timer size={16} />}
|
||||
icon={Timer}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in new issue
Block a user