swarm ui: the agents page is separate cards, not one big agents card
The filter bar is a card of its own, holding the + agent button and the refresh picker; the hives card and each agent card sit beside it.
This commit is contained in:
parent
70901115a2
commit
6e5dc3dd30
2 changed files with 78 additions and 44 deletions
|
|
@ -1,6 +1,6 @@
|
|||
/* The folded hives card over the agents. */
|
||||
.ui-agents-hives {
|
||||
margin-block-end: 1em;
|
||||
margin-block-end: 0.5em;
|
||||
}
|
||||
/* The roster's refresh picker, at the top right of the open card. */
|
||||
.ui-hives-refresh {
|
||||
|
|
|
|||
|
|
@ -18,8 +18,10 @@
|
|||
// natural home for the action that populates it. The form itself
|
||||
// (`CreateAgentForm`) mounts inside a `Dialog` here, not its own route.
|
||||
//
|
||||
// The roster is one column of cards, each opening in place into its details
|
||||
// (mara: "one column of expandable cards"). This file owns the page's own
|
||||
// The page is a column of separate cards: the hives card, a filter card (with
|
||||
// the "+ agent" button and the refresh picker), then one card per agent, each
|
||||
// opening in place into its details (mara: "one column of expandable cards";
|
||||
// the agents are not wrapped in one big card). This file owns the page's own
|
||||
// state and the filter fields only — `AgentRow` and friends live in
|
||||
// `AgentTypes.ts`, the wanted-state control in `WantedMenu.tsx`, the actions
|
||||
// on an agent (declare a state, link an account) in `AgentActions.tsx`, the
|
||||
|
|
@ -34,7 +36,6 @@ import { FRESHNESS, type AgentRow } from "../../agent/AgentTypes.js";
|
|||
import { Button } from "../../ui/button/Button.js";
|
||||
import { Dialog } from "../../ui/dialog/Dialog.js";
|
||||
import { FilterableView } from "../../ui/filterable-view/FilterableView.js";
|
||||
import { Panel } from "../../ui/panel/Panel.js";
|
||||
import { HivesCard } from "./HivesCard.js";
|
||||
import {
|
||||
RefreshIntervalPicker,
|
||||
|
|
@ -128,43 +129,39 @@ export function AgentsPage() {
|
|||
<div class="ui-agents-hives">
|
||||
<HivesCard />
|
||||
</div>
|
||||
<Panel
|
||||
title="agents"
|
||||
icon="👥"
|
||||
actions={
|
||||
<>
|
||||
<Button variant="primary" onClick={() => setCreateOpen(true)}>
|
||||
+ agent
|
||||
</Button>
|
||||
<RefreshIntervalPicker
|
||||
id="agents-refresh"
|
||||
value={intervalMs}
|
||||
onChange={setIntervalMs}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
>
|
||||
{error ? (
|
||||
<ApiErrorPanel
|
||||
context="failed to load the agent roster"
|
||||
problem={error}
|
||||
/>
|
||||
) : null}
|
||||
{!error && rows === null ? <p>loading…</p> : null}
|
||||
{rows ? (
|
||||
<FilterableView
|
||||
view="cards"
|
||||
columns={FIELDS}
|
||||
rows={rows}
|
||||
rowKey={(a) => a.name}
|
||||
storageKey="swarm-ui:agents:table-filters"
|
||||
emptyMessage="no agents yet — the swarm-wide identity store has no agents registered on any hive"
|
||||
// Each card gets its live row from `rows` on every render, so an
|
||||
// opened card follows a refresh or a state change made inside it.
|
||||
renderCard={(a) => <AgentCard row={a} actions={actions} />}
|
||||
/>
|
||||
) : null}
|
||||
</Panel>
|
||||
{error ? (
|
||||
<ApiErrorPanel
|
||||
context="failed to load the agent roster"
|
||||
problem={error}
|
||||
/>
|
||||
) : null}
|
||||
{!error && rows === null ? <p>loading…</p> : null}
|
||||
{rows ? (
|
||||
<FilterableView
|
||||
view="cards"
|
||||
standalone
|
||||
barActions={
|
||||
<>
|
||||
<Button variant="primary" onClick={() => setCreateOpen(true)}>
|
||||
+ agent
|
||||
</Button>
|
||||
<RefreshIntervalPicker
|
||||
id="agents-refresh"
|
||||
value={intervalMs}
|
||||
onChange={setIntervalMs}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
columns={FIELDS}
|
||||
rows={rows}
|
||||
rowKey={(a) => a.name}
|
||||
storageKey="swarm-ui:agents:table-filters"
|
||||
emptyMessage="no agents yet — the swarm-wide identity store has no agents registered on any hive"
|
||||
// Each card gets its live row from `rows` on every render, so an
|
||||
// opened card follows a refresh or a state change made inside it.
|
||||
renderCard={(a) => <AgentCard row={a} actions={actions} />}
|
||||
/>
|
||||
) : null}
|
||||
<Dialog
|
||||
open={createOpen}
|
||||
onClose={() => setCreateOpen(false)}
|
||||
|
|
|
|||
Loading…
Reference in a new issue