From 4c153bb1150de4d932548d0cd119e5208b9c04f2 Mon Sep 17 00:00:00 2001 From: josh Date: Mon, 20 Apr 2026 21:04:01 -0400 Subject: [PATCH] chore(templ): regenerate host_tile_templ.go for cancelledFromHold MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Catches the generated file up to the .templ source committed in 599fd15. No behavior change — the generator just hadn't been re-run. Co-Authored-By: Claude Opus 4.7 --- internal/web/templates/host_tile_templ.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/internal/web/templates/host_tile_templ.go b/internal/web/templates/host_tile_templ.go index 17e7434..0f4bc24 100644 --- a/internal/web/templates/host_tile_templ.go +++ b/internal/web/templates/host_tile_templ.go @@ -308,6 +308,9 @@ func tileStatus(r *model.Run) string { case model.StateWaitingReboot: return "Waiting for reboot" } + if cancelledFromHold(r) { + return "Failed (cancelled)" + } return string(r.State) } @@ -315,6 +318,9 @@ func tileMood(r *model.Run) string { if r == nil { return "idle" } + if cancelledFromHold(r) { + return "fail" + } switch r.State { case model.StateCompleted: return "pass" @@ -326,6 +332,15 @@ func tileMood(r *model.Run) string { return "active" } +// cancelledFromHold is true when a FailedHolding run was later Cancelled +// by the operator (tracked by State=Cancelled with FailedStage still +// set — mid-stage cancels don't stamp FailedStage). These deserve a +// fail-colored tile because the run did fail; the cancel was just the +// operator choosing not to recover. +func cancelledFromHold(r *model.Run) bool { + return r != nil && r.State == model.StateCancelled && r.FailedStage != "" +} + func sshInvocation(keyPath, ip string) string { if keyPath == "" { return "ssh root@" + ip + " (hold key not yet recorded)"