Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion internal/dashboard/ui/dist/assets/index-Ci1VGgVu.css

This file was deleted.

1 change: 1 addition & 0 deletions internal/dashboard/ui/dist/assets/index-MZFUSUjx.css

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions internal/dashboard/ui/dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<meta name="theme-color" content="#020617" />
<meta name="description" content="Swan Chain computing provider operations dashboard" />
<title>Swan Provider Console</title>
<script type="module" crossorigin src="/assets/index-l8iQ2u1V.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-Ci1VGgVu.css">
<script type="module" crossorigin src="/assets/index-BXEceZQg.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-MZFUSUjx.css">
</head>
<body>
<div id="root"></div>
Expand Down
36 changes: 19 additions & 17 deletions internal/dashboard/ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -229,23 +229,25 @@ function App() {
{activeView === 'overview' && (
<div className="space-y-6">
<section aria-labelledby="provider-health-heading">
<div className="mb-3">
<h2 id="provider-health-heading" className="text-xl font-semibold text-white">Provider overview</h2>
<p className="mt-1 text-sm text-slate-300">Current service health, traffic, and earnings.</p>
<div className="mb-3 flex flex-wrap items-center justify-between gap-x-4 gap-y-2">
<div className="min-w-0">
<h2 id="provider-health-heading" className="text-xl font-semibold text-white">Provider overview</h2>
<p className="mt-1 text-sm text-slate-300">Current service health, traffic, and earnings.</p>
</div>
<OperationalSummary
status={status}
metrics={metrics}
models={models}
loading={statusLoading || metricsLoading || modelsLoading}
dataIssues={[
{ label: 'connection', error: statusError },
{ label: 'metrics', error: metricsError },
{ label: 'models', error: modelsError },
{ label: 'request controls', error: requestMgmtError },
{ label: 'earnings', error: earningsError },
]}
/>
</div>
<OperationalSummary
status={status}
metrics={metrics}
models={models}
loading={statusLoading || metricsLoading || modelsLoading}
dataIssues={[
{ label: 'connection', error: statusError },
{ label: 'metrics', error: metricsError },
{ label: 'models', error: modelsError },
{ label: 'request controls', error: requestMgmtError },
{ label: 'earnings', error: earningsError },
]}
/>
<MetricsPanel
metrics={metrics}
loading={metricsLoading}
Expand Down Expand Up @@ -283,7 +285,6 @@ function App() {
/>
</div>
<div className="min-w-0 space-y-6">
<GPUPanel gpus={metrics?.gpu_metrics ?? []} loading={metricsLoading} error={metricsError} />
<section aria-labelledby="earnings-heading">
<div className="mb-3">
<h2 id="earnings-heading" className="text-xl font-semibold text-white">Earnings and traffic mix</h2>
Expand All @@ -294,6 +295,7 @@ function App() {
<ModelDistribution earnings={earnings} loading={earningsLoading && !earnings} error={earningsError} />
</div>
</section>
<GPUPanel gpus={metrics?.gpu_metrics ?? []} loading={metricsLoading} error={metricsError} />
</div>
</div>
</section>
Expand Down
26 changes: 16 additions & 10 deletions internal/dashboard/ui/src/components/OperationalSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,25 +92,31 @@ export function OperationalSummary({ status, metrics, models, dataIssues, loadin
}[severity];
const Icon = visual.Icon;

// A single row beside the page title rather than a full-width card below it.
// The banner earns its space when something is wrong; when every signal is
// healthy it was a paragraph saying so, pushing the actual figures down the
// page. Severity still carries its own colour and icon, the detail is kept in
// the title attribute rather than dropped, and anything non-healthy keeps the
// jump-to-operations action.
const detail = `${visual.title}. ${visual.copy}`;
return (
<div
role={severity === 'critical' ? 'alert' : 'status'}
className={`mb-4 flex flex-col gap-3 rounded-xl border px-4 py-3 sm:flex-row sm:items-center sm:justify-between ${visual.className}`}
title={detail}
className={`flex min-w-0 max-w-full items-center gap-2 rounded-lg border px-3 py-1.5 ${visual.className}`}
>
<div className="flex min-w-0 items-start gap-3">
<Icon aria-hidden="true" size={20} className={`mt-0.5 shrink-0 ${visual.iconClass}`} />
<div className="min-w-0">
<p className={`font-medium ${visual.titleClass}`}>{visual.title}</p>
<p className="mt-0.5 text-sm text-slate-300">{visual.copy}</p>
</div>
</div>
<Icon aria-hidden="true" size={16} className={`shrink-0 ${visual.iconClass}`} />
<p className={`min-w-0 truncate text-sm font-medium ${visual.titleClass}`}>
{visual.title}
{visual.copy && <span className="ml-2 font-normal text-slate-300">{visual.copy}</span>}
</p>
{severity !== 'healthy' && (
<button
type="button"
onClick={() => document.getElementById('operations-heading')?.scrollIntoView({ behavior: 'smooth' })}
className="inline-flex min-h-10 shrink-0 items-center justify-center gap-2 self-start rounded-lg border border-current/30 px-3 text-sm font-medium text-slate-200 hover:bg-white/5 focus:outline-none focus:ring-2 focus:ring-blue-400 sm:self-auto"
className="ml-1 inline-flex shrink-0 items-center gap-1 rounded-md border border-current/30 px-2 py-1 text-xs font-medium text-slate-200 hover:bg-white/5 focus:outline-none focus:ring-2 focus:ring-blue-400"
>
Review operations <ChevronDown aria-hidden="true" size={15} />
Review <ChevronDown aria-hidden="true" size={13} />
</button>
)}
</div>
Expand Down
Loading