v2.4.1 7c3b292

status.go RawHistoryFolder

1package components
2
3import (
4	"strings"
5
6	"gordon/internal/adapters/in/cli/ui/styles"
7
8	"github.com/charmbracelet/lipgloss"
9)
10
11// Status represents a status type for rendering.
12type Status int
13
14const (
15	StatusSuccess Status = iota
16	StatusError
17	StatusWarning
18	StatusInfo
19	StatusPending
20	StatusRunning
21	StatusStopped
22)
23
24// StatusConfig holds configuration for status rendering.
25type StatusConfig struct {
26	Status  Status
27	Label   string
28	Icon    string
29	Style   lipgloss.Style
30	Badge   bool // If true, render as a badge with background
31	Compact bool // If true, render icon only
32}
33
34// DefaultStatusConfigs provides default configurations for each status type.
35var DefaultStatusConfigs = map[Status]StatusConfig{
36	StatusSuccess: {
37		Icon:  styles.IconSuccess,
38		Style: styles.Theme.Success,
39	},
40	StatusError: {
41		Icon:  styles.IconError,
42		Style: styles.Theme.Error,
43	},
44	StatusWarning: {
45		Icon:  styles.IconWarning,
46		Style: styles.Theme.Warning,
47	},
48	StatusInfo: {
49		Icon:  styles.IconInfo,
50		Style: styles.Theme.Info,
51	},
52	StatusPending: {
53		Icon:  styles.IconPending,
54		Style: styles.Theme.Muted,
55	},
56	StatusRunning: {
57		Icon:  styles.IconSuccess,
58		Style: styles.Theme.Success,
59	},
60	StatusStopped: {
61		Icon:  styles.IconError,
62		Style: styles.Theme.Error,
63	},
64}
65
66// RenderStatus renders a status with icon and optional label.
67func RenderStatus(status Status, label string) string {
68	config := DefaultStatusConfigs[status]
69	if label == "" {
70		return config.Style.Render(config.Icon)
71	}
72	return config.Style.Render(config.Icon + " " + label)
73}
74
75// RenderStatusBadge renders a status as a badge with background.
76func RenderStatusBadge(status Status, label string) string {
77	var badgeStyle lipgloss.Style
78	switch status {
79	case StatusSuccess, StatusRunning:
80		badgeStyle = styles.Theme.BadgeSuccess
81	case StatusError, StatusStopped:
82		badgeStyle = styles.Theme.BadgeError
83	case StatusWarning:
84		badgeStyle = styles.Theme.BadgeWarning
85	case StatusPending:
86		badgeStyle = styles.Theme.BadgePending
87	default:
88		badgeStyle = styles.Theme.BadgeInfo
89	}
90	return badgeStyle.Render(label)
91}
92
93// ParseStatus converts a string status to Status type.
94func ParseStatus(s string) Status {
95	switch strings.ToLower(s) {
96	case "success", "ok", "active", "healthy":
97		return StatusSuccess
98	case "error", "failed", "unhealthy":
99		return StatusError
100	case "warning", "degraded":
101		return StatusWarning
102	case "info":
103		return StatusInfo
104	case "pending", "starting", "waiting":
105		return StatusPending
106	case "running", "up":
107		return StatusRunning
108	case "stopped", "down", "exited":
109		return StatusStopped
110	default:
111		return StatusInfo
112	}
113}
114
115// StatusIndicator is a simple status indicator component.
116type StatusIndicator struct {
117	Status Status
118	Label  string
119	Badge  bool
120}
121
122// NewStatusIndicator creates a new status indicator.
123func NewStatusIndicator(status Status, label string) StatusIndicator {
124	return StatusIndicator{
125		Status: status,
126		Label:  label,
127		Badge:  false,
128	}
129}
130
131// NewStatusBadge creates a new status badge (with background).
132func NewStatusBadge(status Status, label string) StatusIndicator {
133	return StatusIndicator{
134		Status: status,
135		Label:  label,
136		Badge:  true,
137	}
138}
139
140// View renders the status indicator.
141func (s StatusIndicator) View() string {
142	if s.Badge {
143		return RenderStatusBadge(s.Status, s.Label)
144	}
145	return RenderStatus(s.Status, s.Label)
146}
147
148// ContainerStatusIndicator renders container status with appropriate styling.
149func ContainerStatusIndicator(status string) string {
150	parsed := ParseStatus(status)
151	return RenderStatus(parsed, status)
152}
153
154// ContainerStatusBadge renders container status as a badge.
155func ContainerStatusBadge(status string) string {
156	parsed := ParseStatus(status)
157	return RenderStatusBadge(parsed, status)
158}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 106

↑↓ moveenter openesc close