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
+7 -3
View File
@@ -32,13 +32,17 @@ export default function TaskOutput({ id, onDone }: { id: string; onDone?: (t: Ta
const running = !task || task.running
const failed = !!task && !task.running && (task.exit_code !== 0 || !!task.error)
const status = !task ? 'starting…' : task.running ? 'running…' : task.error ? `failed: ${task.error}` : task.exit_code === 0 ? 'finished' : `exited ${task.exit_code}`
const cancelled = task?.error === 'cancelled'
// how it ended is a badge, legible at a glance: nobody should have to read compose's output to learn a deploy failed
const verdict = !task || task.running ? '' : cancelled ? 'cancelled' : task.error ? 'failed' : task.exit_code === 0 ? 'finished' : `failed · exit ${task.exit_code}`
const status = !task ? 'starting…' : task.running ? 'running…' : task.error && !cancelled ? task.error : ''
return (
<div className={'task' + (running ? ' running' : failed ? ' failed' : ' done')}>
<div className={'task' + (running ? ' running' : cancelled ? ' done' : failed ? ' failed' : ' done')}>
<div className="logs-bar">
{running ? <Spinner /> : <span className={'dot ' + (failed ? 'bad' : 'ok')} />}
<span>{task?.title ?? '…'}</span>
<span className="muted">· {status}</span>
{verdict && <span className={'badge ' + (failed && !cancelled ? 'bad' : cancelled ? '' : 'ok')}>{verdict}</span>}
{status && <span className="muted">· {status}</span>}
<span className="spacer" />
{task?.running && <Btn className="btn" onClick={() => api.cancelTask(id)}>Cancel</Btn>}
</div>