feat(run-page): tick the run-duration timer between SSE pushes
CI / Lint + build + test (push) Successful in 1m34s
Release / release (push) Has been cancelled

Adds a 1s client-side ticker that rewrites .run-duration text from a
data-started-at attribute, so the header timer on /runs/{id}
increments every second while the run is active. When an SSE swap
lands a fresh header the new server-rendered value seamlessly takes
over; when the run goes terminal the template drops the attribute
and the ticker silently skips the node, leaving the final elapsed in
place.

Other templ_*.go churn is cosmetic — regenerator versions differ
between CI and local and only the filename field in templ.Error
callsites changed.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-19 21:53:40 -04:00
parent 05ceb8e042
commit c545028903
9 changed files with 263 additions and 198 deletions
+7 -1
View File
@@ -4,6 +4,7 @@ import (
"bytes"
"context"
"fmt"
"time"
"vetting/internal/model"
"vetting/internal/store"
@@ -84,7 +85,12 @@ templ RunHeader(d RunPageData) {
<h1 class="run-header-name">{ fmt.Sprintf("Run #%d", d.Run.ID) }</h1>
<span class={ "run-status-badge", "run-status-" + tileMood(&d.Run) }>{ tileStatus(&d.Run) }</span>
<span class={ "run-profile-chip", "run-profile-" + profileChipValue(d.Run.Profile) }>{ profileChipValue(d.Run.Profile) }</span>
<span class="run-duration">{ runDuration(&d.Run) }</span>
<span
class="run-duration"
if !d.Run.State.IsTerminal() && !d.Run.StartedAt.IsZero() {
data-started-at={ d.Run.StartedAt.UTC().Format(time.RFC3339Nano) }
}
>{ runDuration(&d.Run) }</span>
if d.Run.FailedStage != "" {
<span class="run-failed-stage">failed at <strong>{ d.Run.FailedStage }</strong></span>
}