Stacks: Duplicate, Labels and Network in the form, task verdict badges, a short Where; Cancel really cancels

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Mitchell-Johnson
2026-09-20 13:12:54 -07:00
co-authored by Claude Fable 5.1
parent a229f2b597
commit 1e992ca1eb
8 changed files with 183 additions and 36 deletions
+36
View File
@@ -379,3 +379,39 @@ container can't be removed (409); a volume needs its name twice. A read-only tok
file is refused. Shaped, fleet and streamed sensor queries, `/metrics`, the ten alert
rules, terminal typing, the file editor's discard question and service deep links are
unchanged. No native browser dialogs anywhere.
## Quality of life — four chosen by Mitchell, ✅ built and verified 2026-09-20
1. ✅ **"Where" fits on a phone**: `…/stacks/core · 12 stacks` instead of the whole path (which
is still written out underneath). Two homes whose last two folders match fall back to the
full path. Measured at 390 px: no option is wider than the box.
2. ✅ **How a task ended is a badge**: green `finished`, red `failed · exit 1` with the box
outlined in red, grey `cancelled`. Verified on a deploy of an image that doesn't exist.
5. ✅ **Duplicate…** on a stack: the New stack dialog opened on a copy of its compose file,
named `<name>-copy`. The original's `.env` is copied **on the machine** (`env_from`), mode
600, its values never sent to the browser — checked: the secret is nowhere in the page.
Anything that would collide with what is running is named before you press Create
("a container called X already exists; port 18222 is already published by X") — for
every new stack, not only duplicates — and clears as you fix it. Disabled while the
original has unsaved edits. Verified: copy deployed beside the original, which never
stopped.
6. ✅ **The form has Labels and Network.** Labels one per line (`$`, quotes and spaces arrive
intact). Network: its own, the machine's (`host`, which turns Ports off), or **join** one
that already exists — written as an `external` network so compose doesn't make a second
one. Verified on the container: both labels, attached to the chosen network only.
Found while building them, ✅ fixed:
- **Cancel on a stack task cancelled nothing.** It killed the `sh` that ran compose, not
compose; and as compose still held the output pipe, the task stayed "running" and the
stack "busy" until compose finished by itself — for a deploy waiting on a health check,
minutes. Tasks now run in their own process group and the whole group is stopped (TERM,
then KILL after 4 s); for stacks deployed inside Dockhand, where the process is not the
task's child at all, the cancel goes into the container after it. Verified both ways:
ended in ~100 ms, compose gone, the stack free for the next action.
- **Phone: a stack's task output was squeezed to a line** under the buttons (the same fault
as the dialog: a scrolling column whose parts were allowed to shrink), which also put
Cancel out of reach. Detail panes keep their parts' heights; services, containers, stacks
and cron rechecked on both sizes.
- The Duplicate dialog and the stack page under it shared a React key, so the dialog
multiplied. An undeployed stack's dot was green ("0 of 0 running"); now neutral.