dashboard-v2 frontend: node column + clickable pills on storage tabs
Build with clawstor cache / Cargo build (clawstor-cached) (pull_request) Failing after 3s

All storage rows now carry a 'node' field from the aggregator.
Adds a small green-pill component that renders the source node
name; click drills into that node's detail page.

Also fixes the TS interfaces to match the new backend shape
(node field added to Blob/Tag/Ref/Snapshot/RefTracking types).
This commit is contained in:
Omar Sobh
2026-07-14 16:44:06 -07:00
parent 1211f0d891
commit b672037e42
5 changed files with 48 additions and 10 deletions
+21 -4
View File
@@ -37,8 +37,9 @@ function BlobsList() {
<>
{err && <ErrorBox msg={err} />}
<Table
headers={['blob-id', 'size', 'chunks']}
headers={['node', 'blob-id', 'size', 'chunks']}
rows={rows.map((r) => [
<NodePill key="n" node={r.node} />,
<span key="hex" className="font-mono text-xs">
{r.blob_id_hex.slice(0, 24)}
</span>,
@@ -68,8 +69,9 @@ function TagsList() {
/>
{err && <ErrorBox msg={err} />}
<Table
headers={['key', 'blob-id']}
headers={['node', 'key', 'blob-id']}
rows={rows.map((r) => [
<NodePill key="n" node={r.node} />,
<span key="k" className="font-mono text-sm">
{r.key}
</span>,
@@ -93,8 +95,9 @@ function RefsList() {
<>
{err && <ErrorBox msg={err} />}
<Table
headers={['fingerprint', 'blob-id']}
headers={['node', 'fingerprint', 'blob-id']}
rows={rows.map((r) => [
<NodePill key="n" node={r.node} />,
<span key="fp" className="font-mono text-xs">
{r.fingerprint_hex.slice(0, 24)}
</span>,
@@ -118,8 +121,9 @@ function SnapshotsList() {
<>
{err && <ErrorBox msg={err} />}
<Table
headers={['name', 'created', 'blobs', 'json size']}
headers={['node', 'name', 'created', 'blobs', 'json size']}
rows={rows.map((r) => [
<NodePill key="node" node={r.node} />,
<span key="n" className="font-mono text-sm">
{r.name}
</span>,
@@ -190,3 +194,16 @@ function ErrorBox({ msg }: { msg: string }) {
</div>
);
}
/// Small pill badge for the originating node — clickable to
/// drill into that node's detail page.
function NodePill({ node }: { node: string }) {
return (
<a
href={`#/nodes/${node}`}
className="inline-block rounded bg-slate-800 text-emerald-300 text-xs font-mono px-2 py-0.5 hover:bg-slate-700"
>
{node}
</a>
);
}