v2.10.1 43db1bb

status.go RawHistoryFolder

1package components
2
3import (
4	"strings"
5
6	"github.com/bnema/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	StatusPaused
23	StatusRestarting
24	StatusExited
25	StatusUnknown
26)
27
28// StatusConfig holds configuration for status rendering.
29type StatusConfig struct {
30	Status  Status
31	Label   string
32	Icon    string
33	Style   lipgloss.Style
34	Badge   bool // If true, render as a badge with background
35	Compact bool // If true, render icon only
36}
37
38// DefaultStatusConfigs provides default configurations for each status type.
39var DefaultStatusConfigs = map[Status]StatusConfig{
40	StatusSuccess: {
41		Icon:  styles.IconSuccess,
42		Style: styles.Theme.Success,
43	},
44	StatusError: {
45		Icon:  styles.IconError,
46		Style: styles.Theme.Error,
47	},
48	StatusWarning: {
49		Icon:  styles.IconWarning,
50		Style: styles.Theme.Warning,
51	},
52	StatusInfo: {
53		Icon:  styles.IconInfo,
54		Style: styles.Theme.Info,
55	},
56	StatusPending: {
57		Icon:  styles.IconPending,
58		Style: styles.Theme.Muted,
59	},
60	StatusRunning: {
61		Icon:  styles.IconRunning,
62		Style: styles.Theme.Success,
63	},
64	StatusStopped: {
65		Icon:  styles.IconStopped,
66		Style: styles.Theme.Error,
67	},
68	StatusPaused: {
69		Icon:  styles.IconPaused,
70		Style: styles.Theme.Warning,
71	},
72	StatusRestarting: {
73		Icon:  styles.IconRestarting,
74		Style: styles.Theme.Warning,
75	},
76	StatusExited: {
77		Icon:  styles.IconExited,
78		Style: styles.Theme.Error,
79	},
80	StatusUnknown: {
81		Icon:  styles.IconUnknown,
82		Style: styles.Theme.Muted,
83	},
84}
85
86// RenderStatus renders a status with icon and optional label.
87func RenderStatus(status Status, label string) string {
88	config := DefaultStatusConfigs[status]
89	if label == "" {
90		return config.Style.Render(config.Icon)
91	}
92	return config.Style.Render(config.Icon + " " + label)
93}
94
95// RenderStatusBadge renders a status as a compact icon badge with background.
96// It displays only the icon (no label) for minimal width in table columns.
97func RenderStatusBadge(status Status) string {
98	config := DefaultStatusConfigs[status]
99	var badgeStyle lipgloss.Style
100	switch status {
101	case StatusSuccess, StatusRunning:
102		badgeStyle = styles.Theme.BadgeSuccess
103	case StatusError, StatusStopped, StatusExited:
104		badgeStyle = styles.Theme.BadgeError
105	case StatusWarning, StatusPaused, StatusRestarting:
106		badgeStyle = styles.Theme.BadgeWarning
107	case StatusPending:
108		badgeStyle = styles.Theme.BadgePending
109	case StatusUnknown:
110		badgeStyle = styles.Theme.Muted
111	default:
112		badgeStyle = styles.Theme.BadgeInfo
113	}
114	return badgeStyle.Render(config.Icon)
115}
116
117// ParseStatus converts a string status to Status type.
118func ParseStatus(s string) Status {
119	switch strings.ToLower(s) {
120	case "success", "ok", "active", "healthy":
121		return StatusSuccess
122	case "error", "failed", "unhealthy":
123		return StatusError
124	case "warning", "degraded":
125		return StatusWarning
126	case "info":
127		return StatusInfo
128	case "pending", "starting", "waiting", "created":
129		return StatusPending
130	case "running", "up":
131		return StatusRunning
132	case "stopped", "down":
133		return StatusStopped
134	case "paused":
135		return StatusPaused
136	case "restarting":
137		return StatusRestarting
138	case "exited", "dead":
139		return StatusExited
140	case "unknown":
141		return StatusUnknown
142	default:
143		return StatusUnknown
144	}
145}
146
147// StatusIndicator is a simple status indicator component.
148type StatusIndicator struct {
149	Status Status
150	Label  string
151	Badge  bool
152}
153
154// NewStatusIndicator creates a new status indicator.
155func NewStatusIndicator(status Status, label string) StatusIndicator {
156	return StatusIndicator{
157		Status: status,
158		Label:  label,
159		Badge:  false,
160	}
161}
162
163// NewStatusBadge creates a new status badge (with background).
164func NewStatusBadge(status Status, label string) StatusIndicator {
165	return StatusIndicator{
166		Status: status,
167		Label:  label,
168		Badge:  true,
169	}
170}
171
172// View renders the status indicator.
173func (s StatusIndicator) View() string {
174	if s.Badge {
175		return RenderStatusBadge(s.Status)
176	}
177	return RenderStatus(s.Status, s.Label)
178}
179
180// ContainerStatusIndicator renders container status with appropriate styling.
181func ContainerStatusIndicator(status string) string {
182	parsed := ParseStatus(status)
183	return RenderStatus(parsed, status)
184}
185
186// ContainerStatusBadge renders container status as a badge.
187func ContainerStatusBadge(status string) string {
188	parsed := ParseStatus(status)
189	return RenderStatusBadge(parsed)
190}

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 7

Tags 106

↑↓ moveenter openesc close