fix(ui): fit pipeline timeline without horizontal scroll
15 nodes (3 pre-stage + 11 stage + Completed) exceeded the 1280px main
container's usable width, producing a horizontal scrollbar under the
pipeline on the run page. Widen main to 1440px, tighten per-node min
widths, drop the scrollbar, and split camelCase labels so multi-word
stages ("WaitingReboot", "SpecValidate", "CPUStress") wrap onto two
lines instead of forcing node width.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"vetting/internal/model"
|
||||
@@ -250,6 +251,33 @@ func stageDuration(n PipelineNode) string {
|
||||
}
|
||||
}
|
||||
|
||||
// stageDisplayName turns the internal single-word state/stage identifier
|
||||
// into a human-readable label by inserting spaces before interior capital
|
||||
// letters. "WaitingReboot" → "Waiting Reboot", "SpecValidate" →
|
||||
// "Spec Validate", "CPUStress" → "CPU Stress". The space lets the
|
||||
// pipeline node wrap the label onto two lines on narrow layouts instead
|
||||
// of forcing horizontal scroll — single-word names ("Inventory",
|
||||
// "Completed") pass through unchanged.
|
||||
func stageDisplayName(name string) string {
|
||||
var b strings.Builder
|
||||
b.Grow(len(name) + 2)
|
||||
for i, r := range name {
|
||||
if i > 0 && r >= 'A' && r <= 'Z' {
|
||||
prev := rune(name[i-1])
|
||||
// Insert a space at every lower→upper boundary ("Spec|Validate")
|
||||
// and at upper→upper when the next char is lower ("CPU|Stress",
|
||||
// where we split before the S that starts a new word). This
|
||||
// keeps acronyms like "GPU"/"PSU" intact.
|
||||
if (prev >= 'a' && prev <= 'z') ||
|
||||
(prev >= 'A' && prev <= 'Z' && i+1 < len(name) && name[i+1] >= 'a' && name[i+1] <= 'z') {
|
||||
b.WriteByte(' ')
|
||||
}
|
||||
}
|
||||
b.WriteRune(r)
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// stageMarker returns the single-char glyph shown in the node's dot.
|
||||
// Dots stay colored-via-class; the glyph is redundant-but-helpful.
|
||||
func stageMarker(state string) string {
|
||||
@@ -277,7 +305,7 @@ templ Pipeline(nodes []PipelineNode) {
|
||||
}
|
||||
<div class={ "stage-node", "stage-node-" + n.State }>
|
||||
<div class={ "stage-dot", "stage-dot-" + n.State }>{ stageMarker(n.State) }</div>
|
||||
<div class="stage-name">{ n.Name }</div>
|
||||
<div class="stage-name">{ stageDisplayName(n.Name) }</div>
|
||||
<div class="stage-duration">{ stageDuration(n) }</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user