swarm-ui: page shell + layout primitives
Structural foundation split out of hyperhive#3118 per mara's steer: structure first so the real overview page (hive roster) and later routes (swarm-wide agent roster) land as content changes rather than each reinventing chrome + nav + a table/panel/chip shape. - <Shell>: header bar (branding) + nav row, wraps every route. Route list lives in Shell itself (one small SPA, one place to know its own nav). - ui/Panel, ui/StatusChip, ui/Table: the three primitives the overview page's actual scope (hive roster: name/domain/status, linking out to each hive's own dashboard) calls for, nothing speculative beyond that. Preact-native styling (plain CSS files imported via swarm-ui.css, no shadow DOM — this package renders into light DOM) — not @hive/shared's chrome.css, which is the old MPA dashboard's visual language. Same base16/Catppuccin color tokens via theme.css/colors.css so it still reads as hyperhive. npm run build (whole frontend workspace) + npm run typecheck both clean. Verified with a real headless-chromium screenshot against the built dist, not just source-reading. Fixes hyperhive#3211
This commit is contained in:
parent
75f99ecafb
commit
67eb0c660d
10 changed files with 224 additions and 29 deletions
43
frontend/packages/swarm-ui/src/ui/Table.tsx
Normal file
43
frontend/packages/swarm-ui/src/ui/Table.tsx
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
// <Table> — a generic column-defined table, the shape the hive roster
|
||||
// (name / domain / status chip, one row per hive) needs. Columns own
|
||||
// their own cell rendering rather than this component knowing about
|
||||
// any particular row shape, so it stays reusable for the swarm-wide
|
||||
// agent roster later without a rewrite.
|
||||
import type { ComponentChildren } from 'preact';
|
||||
|
||||
export interface TableColumn<T> {
|
||||
key: string;
|
||||
header: string;
|
||||
render: (row: T) => ComponentChildren;
|
||||
}
|
||||
|
||||
export function Table<T>({
|
||||
columns,
|
||||
rows,
|
||||
rowKey,
|
||||
}: {
|
||||
columns: TableColumn<T>[];
|
||||
rows: T[];
|
||||
rowKey: (row: T) => string;
|
||||
}) {
|
||||
return (
|
||||
<table class="ui-table">
|
||||
<thead>
|
||||
<tr>
|
||||
{columns.map((c) => (
|
||||
<th key={c.key}>{c.header}</th>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{rows.map((row) => (
|
||||
<tr key={rowKey(row)}>
|
||||
{columns.map((c) => (
|
||||
<td key={c.key}>{c.render(row)}</td>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
}
|
||||
Loading…
Reference in a new issue