From 46d1271603a51e41cc0b27256b813983873d5bc8 Mon Sep 17 00:00:00 2001 From: iris Date: Mon, 24 Aug 2026 00:14:36 +0200 Subject: [PATCH] =?UTF-8?q?swarm-ui:=20agents=20page=20=E2=80=94=20explain?= =?UTF-8?q?er=20message=20when=20the=20roster=20is=20empty?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Table gains an optional emptyMessage prop, rendered as a single full-width row in place of a bare empty tbody; AgentsPage is the first consumer. Screenshot-verified against a mock server returning an empty roster. --- .../swarm-ui/src/pages/AgentsPage.tsx | 9 ++++++- .../packages/swarm-ui/src/ui/table/Table.css | 5 ++++ .../packages/swarm-ui/src/ui/table/Table.tsx | 27 ++++++++++++++----- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/frontend/packages/swarm-ui/src/pages/AgentsPage.tsx b/frontend/packages/swarm-ui/src/pages/AgentsPage.tsx index fe312ec1..bfcb22b7 100644 --- a/frontend/packages/swarm-ui/src/pages/AgentsPage.tsx +++ b/frontend/packages/swarm-ui/src/pages/AgentsPage.tsx @@ -115,7 +115,14 @@ export function AgentsPage() { > {error ? : null} {!error && rows === null ?

loading…

: null} - {rows ? a.name} /> : null} + {rows ? ( +
a.name} + emptyMessage="no agents yet — the swarm-wide identity store has no agents registered on any hive" + /> + ) : null} setCreateOpen(false)} label="create agent"> diff --git a/frontend/packages/swarm-ui/src/ui/table/Table.css b/frontend/packages/swarm-ui/src/ui/table/Table.css index 68407656..cec0a17c 100644 --- a/frontend/packages/swarm-ui/src/ui/table/Table.css +++ b/frontend/packages/swarm-ui/src/ui/table/Table.css @@ -21,3 +21,8 @@ .ui-table tr:last-child td { border-bottom: none; } +.ui-table-empty { + color: var(--muted); + text-align: center; + padding: 1.25em 0.75em; +} diff --git a/frontend/packages/swarm-ui/src/ui/table/Table.tsx b/frontend/packages/swarm-ui/src/ui/table/Table.tsx index e8e82c44..23c1739a 100644 --- a/frontend/packages/swarm-ui/src/ui/table/Table.tsx +++ b/frontend/packages/swarm-ui/src/ui/table/Table.tsx @@ -22,10 +22,17 @@ export function Table({ columns, rows, rowKey, + emptyMessage, }: { columns: TableColumn[]; rows: T[]; rowKey: (row: T) => string; + // Rendered as a single full-width row when `rows` is empty. Omit to + // leave a bare empty `` — a caller whose "no rows yet" is + // covered by its own loading/error state (rendered instead of the + // table entirely) has nothing useful to add here, so this stays + // opt-in rather than every table growing a mandatory default string. + emptyMessage?: ComponentChildren; }) { return (
@@ -38,13 +45,21 @@ export function Table({
- {rows.map((row) => ( - - {columns.map((c) => ( - - ))} + {rows.length === 0 && emptyMessage ? ( + + - ))} + ) : ( + rows.map((row) => ( + + {columns.map((c) => ( + + ))} + + )) + )}
{c.render(row)}
+ {emptyMessage} +
{c.render(row)}