Skip to content

Commit 932960c

Browse files
authored
Merge pull request #3521 from dgageot/worktree-board-299a81ea0ca8bb29
feat(board): align TUI card colors with web board status palette
2 parents 1e94365 + ac449ff commit 932960c

2 files changed

Lines changed: 64 additions & 8 deletions

File tree

pkg/board/tui/view.go

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -344,11 +344,12 @@ func busyCount(cards []*board.Card) int {
344344
func (m *model) renderCard(card *board.Card, colInnerWidth int, selected bool) string {
345345
textWidth := max(colInnerWidth-4, 1) // card border + padding
346346

347-
// Cards carry their project's accent color on the border and badge, so
348-
// each project's work is recognizable at a glance.
347+
// Like the web board, a card's border carries its status color; the
348+
// project badge keeps the project's accent so its work is still
349+
// recognizable at a glance.
349350
accent := m.projectColor(card.Project)
350351
titleStyle := styles.BaseStyle
351-
borderColor := accent
352+
borderColor := statusColor(card.Status)
352353
if selected {
353354
titleStyle = styles.HighlightWhiteStyle
354355
borderColor = styles.BorderPrimary
@@ -390,19 +391,37 @@ func splitTitle(title string, width int) (string, string) {
390391
return toolcommon.TruncateText(line1, width), ""
391392
}
392393

394+
// statusColor matches the web board's card tinting: starting/loading/
395+
// attaching=blue, running=orange, paused=white, error=red, waiting=green.
396+
func statusColor(status board.CardStatus) color.Color {
397+
switch status {
398+
case board.StatusStarting, board.StatusLoading, board.StatusAttaching:
399+
return styles.Info
400+
case board.StatusRunning:
401+
return styles.Warning
402+
case board.StatusPaused:
403+
return styles.White
404+
case board.StatusError:
405+
return styles.Error
406+
default: // waiting
407+
return styles.Success
408+
}
409+
}
410+
393411
func (m *model) renderStatus(status board.CardStatus, width int) string {
412+
style := styles.BaseStyle.Foreground(statusColor(status))
394413
spinner := spinnerFrames[m.frame%len(spinnerFrames)]
395414
switch status {
396415
case board.StatusStarting, board.StatusLoading, board.StatusAttaching:
397-
return styles.WarningStyle.Render(toolcommon.TruncateText(spinner+" "+string(status), width))
416+
return style.Render(toolcommon.TruncateText(spinner+" "+string(status), width))
398417
case board.StatusRunning:
399-
return styles.InfoStyle.Render(toolcommon.TruncateText(spinner+" running", width))
418+
return style.Render(toolcommon.TruncateText(spinner+" running", width))
400419
case board.StatusPaused:
401-
return styles.WarningStyle.Render(toolcommon.TruncateText("∥ paused", width))
420+
return style.Render(toolcommon.TruncateText("∥ paused", width))
402421
case board.StatusError:
403-
return styles.ErrorStyle.Render(toolcommon.TruncateText("✗ failed", width))
422+
return style.Render(toolcommon.TruncateText("✗ failed", width))
404423
default: // waiting
405-
return styles.SuccessStyle.Render(toolcommon.TruncateText("● ready", width))
424+
return style.Render(toolcommon.TruncateText("● ready", width))
406425
}
407426
}
408427

pkg/board/tui/view_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package tui
2+
3+
import (
4+
"image/color"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
9+
"github.com/docker/docker-agent/pkg/board"
10+
"github.com/docker/docker-agent/pkg/tui/styles"
11+
)
12+
13+
// TestStatusColor pins the status→color contract shared with the web board:
14+
// starting/loading/attaching=blue, running=orange, waiting=green,
15+
// paused=white, error=red.
16+
func TestStatusColor(t *testing.T) {
17+
// Theme colors are only bound after ApplyTheme; not parallel because it
18+
// mutates package-level style state.
19+
styles.ApplyThemeRef(styles.DefaultThemeRef)
20+
21+
tests := []struct {
22+
status board.CardStatus
23+
want color.Color
24+
}{
25+
{board.StatusStarting, styles.Info},
26+
{board.StatusLoading, styles.Info},
27+
{board.StatusAttaching, styles.Info},
28+
{board.StatusRunning, styles.Warning},
29+
{board.StatusPaused, styles.White},
30+
{board.StatusError, styles.Error},
31+
{board.StatusWaiting, styles.Success},
32+
{board.CardStatus("unknown"), styles.Success}, // falls back to waiting
33+
}
34+
for _, test := range tests {
35+
assert.Equal(t, test.want, statusColor(test.status), "status %q", test.status)
36+
}
37+
}

0 commit comments

Comments
 (0)