ui: keep detail-page SSE swaps live after the first outerHTML replace
Pipeline fragment payload was a bare <div class=pipeline>, but the sse-swap=pipeline-N wrapper lived only in the page shell. The first outerHTML swap destroyed the wrapper, so every subsequent pipeline event had nothing to target — forcing a manual refresh. RenderPipelineString now emits the full <section id=pipeline-N sse-swap=... hx-swap=outerHTML> wrapper, used from both the shell and the orchestrator publish path. Also drop the red-bar styling from the empty DetailHold placeholder: the wrapper's detail-hold class was painting an unconditional red band between Pipeline and Actions whenever no hold was active.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package templates
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"vetting/internal/model"
|
||||
@@ -200,3 +201,24 @@ func TestBuildPipeline_PreStageRunning_WaitingReboot(t *testing.T) {
|
||||
t.Errorf("Booting = %q, want pending", nodes[idxBooting].State)
|
||||
}
|
||||
}
|
||||
|
||||
// TestRenderPipelineString_IncludesSection asserts the orchestrator-
|
||||
// published fragment carries the <section id=pipeline-N sse-swap=...
|
||||
// hx-swap=outerHTML> wrapper. Without this, the first outerHTML swap
|
||||
// would replace the section with a bare <div class=pipeline>, wiping
|
||||
// out the sse-swap attribute and freezing every subsequent pipeline
|
||||
// event until page reload.
|
||||
func TestRenderPipelineString_IncludesSection(t *testing.T) {
|
||||
run := &model.Run{ID: 42, State: model.StateSMART}
|
||||
html := RenderPipelineString(run, seedStages())
|
||||
for _, want := range []string{
|
||||
`id="pipeline-42"`,
|
||||
`sse-swap="pipeline-42"`,
|
||||
`hx-swap="outerHTML"`,
|
||||
`<h2>Pipeline</h2>`,
|
||||
} {
|
||||
if !strings.Contains(html, want) {
|
||||
t.Errorf("RenderPipelineString missing %q in:\n%s", want, html)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user