swarm-ui: fill create-agent's empty column with an explanatory panel
mara's follow-up on the field-alignment fix: narrowing the form panel left a lot of bare space next to it, and asked for something that fills it while helping a new user understand what the page does. Adds a second panel beside the form (stacks under it on a narrow viewport) explaining the job chain '/api/agents' actually queues: an authelia identity, then a forge config repo — no container exists yet after this page, and deploying one onto the chosen hive is a separate step that isn't wired up server-side.
This commit is contained in:
parent
f14fc154cc
commit
fc65811d9f
2 changed files with 99 additions and 54 deletions
|
|
@ -1,21 +1,42 @@
|
||||||
/* <CreateAgentPage> — the create-agent form. Input/button chrome now
|
/* <CreateAgentPage> — the create-agent form. Input/button chrome now
|
||||||
comes from the shared `ui/` form kit (`TextField`/`SelectField`/
|
comes from the shared `ui/` form kit (`TextField`/`SelectField`/
|
||||||
`Button`); this file only owns the page's own layout + copy. Column,
|
`Button`); this file only owns the page's own layout + copy. Column,
|
||||||
not row: with a second field (hive) added, a row layout put fields of
|
not row inside the form itself: with a second field (hive) added, a
|
||||||
different natural widths on one baseline and looked misaligned —
|
row layout put fields of different natural widths on one baseline and
|
||||||
mara: "make it a col". Reuses the same base16 slots (../theme.css)
|
looked misaligned — mara: "make it a col". Reuses the same base16
|
||||||
every other component draws from.
|
slots (../theme.css) every other component draws from.
|
||||||
|
|
||||||
`.create-agent-page` caps the panel's own width: `Panel` has no width
|
`.create-agent-page` caps the whole layout's width: `Panel` has no
|
||||||
opinion of its own, so left unconstrained it filled `.shell-body`'s
|
width opinion of its own, so left unconstrained a single form panel
|
||||||
full 60em column — a lot of bare panel to the right of a ~16em-wide
|
filled `.shell-body`'s full 60em column — a lot of bare panel to the
|
||||||
form, the "weird empty space" mara flagged alongside the field
|
right of a ~16em-wide form, the "weird empty space" mara flagged
|
||||||
misalignment. 24em roughly matches the fields' own 16em cap
|
alongside the original field misalignment. The follow-up ask was to
|
||||||
(../ui/form-field/FormField.css) plus the panel's 1em body padding on
|
fill that space with something that explains the page rather than
|
||||||
each side and a little breathing room, so the panel reads as sized to
|
just narrowing it further — `.create-agent-layout` puts the form
|
||||||
its content instead of to the page column. */
|
beside a second, explanatory panel instead. `.create-agent-form-col`
|
||||||
|
keeps the same ~24em cap the single-panel version had (fields' own
|
||||||
|
16em cap, ../ui/form-field/FormField.css, plus body padding and a
|
||||||
|
little breathing room); `.create-agent-info-col` takes the rest of
|
||||||
|
the row and wraps under the form on a narrow viewport (`flex-wrap`,
|
||||||
|
no separate media query needed). */
|
||||||
.create-agent-page {
|
.create-agent-page {
|
||||||
max-width: 24em;
|
max-width: 44em;
|
||||||
|
}
|
||||||
|
.create-agent-layout {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 1.5em;
|
||||||
|
}
|
||||||
|
.create-agent-form-col {
|
||||||
|
flex: 0 1 24em;
|
||||||
|
}
|
||||||
|
.create-agent-info-col {
|
||||||
|
flex: 1 1 16em;
|
||||||
|
}
|
||||||
|
.create-agent-info-glyph {
|
||||||
|
margin: 0 0 0.5em;
|
||||||
|
font-size: 2em;
|
||||||
}
|
}
|
||||||
.create-agent-intro {
|
.create-agent-intro {
|
||||||
margin: 0 0 1.5em;
|
margin: 0 0 1.5em;
|
||||||
|
|
|
||||||
|
|
@ -126,47 +126,71 @@ export function CreateAgentPage() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="create-agent-page">
|
<div class="create-agent-page">
|
||||||
<Panel title="create agent">
|
<div class="create-agent-layout">
|
||||||
<p class="create-agent-intro">
|
<div class="create-agent-form-col">
|
||||||
Create a new agent's swarm-level identity. This only queues the job — check{' '}
|
<Panel title="create agent">
|
||||||
<Link href="/jobs">jobs</Link> to watch it settle.
|
<p class="create-agent-intro">
|
||||||
</p>
|
Create a new agent's swarm-level identity. This only queues the job — check{' '}
|
||||||
{hivesError && <ApiErrorPanel context="failed to load the hive list" problem={hivesError} />}
|
<Link href="/jobs">jobs</Link> to watch it settle.
|
||||||
<form class="create-agent-form" onSubmit={submit}>
|
</p>
|
||||||
<TextField
|
{hivesError && (
|
||||||
id="agent-name"
|
<ApiErrorPanel context="failed to load the hive list" problem={hivesError} />
|
||||||
label="agent name"
|
)}
|
||||||
value={name}
|
<form class="create-agent-form" onSubmit={submit}>
|
||||||
pattern={NAME_PATTERN}
|
<TextField
|
||||||
title="1-63 chars: lowercase letters, digits, hyphens"
|
id="agent-name"
|
||||||
required
|
label="agent name"
|
||||||
onInput={setName}
|
value={name}
|
||||||
/>
|
pattern={NAME_PATTERN}
|
||||||
<SelectField
|
title="1-63 chars: lowercase letters, digits, hyphens"
|
||||||
id="agent-hive"
|
required
|
||||||
label="hive"
|
onInput={setName}
|
||||||
value={hive}
|
/>
|
||||||
onChange={setHive}
|
<SelectField
|
||||||
options={hiveOptions}
|
id="agent-hive"
|
||||||
required
|
label="hive"
|
||||||
disabled={!hivesReady}
|
value={hive}
|
||||||
placeholder={
|
onChange={setHive}
|
||||||
!hives ? 'loading…' : hives.length === 0 ? 'no hives configured' : 'select a hive'
|
options={hiveOptions}
|
||||||
}
|
required
|
||||||
/>
|
disabled={!hivesReady}
|
||||||
<Button variant="primary" type="submit" disabled={result.status === 'submitting' || !hivesReady}>
|
placeholder={
|
||||||
{result.status === 'submitting' ? 'creating…' : 'create'}
|
!hives ? 'loading…' : hives.length === 0 ? 'no hives configured' : 'select a hive'
|
||||||
</Button>
|
}
|
||||||
</form>
|
/>
|
||||||
{result.status === 'done' && (
|
<Button
|
||||||
<p class="create-agent-result create-agent-result-ok">
|
variant="primary"
|
||||||
queued as job node #{result.nodeId} — <Link href="/jobs">watch it in jobs</Link>
|
type="submit"
|
||||||
</p>
|
disabled={result.status === 'submitting' || !hivesReady}
|
||||||
)}
|
>
|
||||||
{result.status === 'error' && (
|
{result.status === 'submitting' ? 'creating…' : 'create'}
|
||||||
<ApiErrorPanel context="failed to queue" problem={result.problem} />
|
</Button>
|
||||||
)}
|
</form>
|
||||||
</Panel>
|
{result.status === 'done' && (
|
||||||
|
<p class="create-agent-result create-agent-result-ok">
|
||||||
|
queued as job node #{result.nodeId} — <Link href="/jobs">watch it in jobs</Link>
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
{result.status === 'error' && (
|
||||||
|
<ApiErrorPanel context="failed to queue" problem={result.problem} />
|
||||||
|
)}
|
||||||
|
</Panel>
|
||||||
|
</div>
|
||||||
|
<div class="create-agent-info-col">
|
||||||
|
<Panel title="what this creates">
|
||||||
|
<p class="create-agent-info-glyph" aria-hidden="true">
|
||||||
|
🪪
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
This queues a small chain of jobs, not a running agent: first an authelia identity
|
||||||
|
at the swarm level, then a config repo on the forge with the operator added as a
|
||||||
|
collaborator. It reserves everything an agent needs before any container exists —
|
||||||
|
actually deploying one onto the hive you pick above is a separate step that isn't
|
||||||
|
wired up yet.
|
||||||
|
</p>
|
||||||
|
</Panel>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue