feat(web): comprehensive dashboard control panel with 13 data panels (#931)
* feat(dashboard): comprehensive control panel with expand/collapse
- Add 13 panels: Convoys, Polecats, Sessions, Activity, Mail, Merge Queue,
Escalations, Rigs, Dogs, System Health, Open Issues, Hooks, Queues
- Add Mayor status banner and Summary/Alerts section
- Implement instant client-side expand/collapse (no page reload)
- Add responsive grid layout for different window sizes
- Parallel data fetching for faster load times
- Color-coded mail by sender, chronological ordering
- Full titles visible in expanded views (no truncation)
- Auto-refresh every 10 seconds via HTMX
* fix(web): update tests and lint for dashboard control panel
- Update MockConvoyFetcher with 11 new interface methods
- Update MockConvoyFetcherWithErrors with matching methods
- Update test assertions for new template structure:
- Section headers ("Gas Town Convoys" -> "Convoys")
- Work status badges (badge-green, badge-yellow, badge-red)
- CI/merge status display text
- Empty state messages ("No active convoys")
- Fix linting: explicit _, _ = for fmt.Sscanf returns
Tests and linting now pass with the new dashboard features.
* perf(web): add timeouts and error logging to dashboard
Performance and reliability improvements:
- Add 8-second overall fetch timeout to prevent stuck requests
- Add per-command timeouts: 5s for bd/sqlite3, 10s for gh, 2s for tmux
- Add helper functions runCmd() and runBdCmd() with context timeout
- Add error logging for all 14 fetch operations
- Handler now returns partial data if timeout occurs
This addresses slow loading and "stuck" dashboard issues by ensuring
commands cannot hang indefinitely.
This commit is contained in:
@@ -54,13 +54,8 @@ func TestConvoyTemplate_RendersConvoyList(t *testing.T) {
|
||||
t.Error("Template should contain convoy ID hq-cv-def")
|
||||
}
|
||||
|
||||
// Check titles are rendered
|
||||
if !strings.Contains(output, "Feature X") {
|
||||
t.Error("Template should contain title 'Feature X'")
|
||||
}
|
||||
if !strings.Contains(output, "Bugfix Y") {
|
||||
t.Error("Template should contain title 'Bugfix Y'")
|
||||
}
|
||||
// The simplified dashboard no longer shows convoy titles in the table,
|
||||
// only the convoy IDs. Titles are shown in expanded view.
|
||||
}
|
||||
|
||||
func TestConvoyTemplate_LastActivityColors(t *testing.T) {
|
||||
@@ -184,14 +179,16 @@ func TestConvoyTemplate_StatusIndicators(t *testing.T) {
|
||||
data := ConvoyData{
|
||||
Convoys: []ConvoyRow{
|
||||
{
|
||||
ID: "hq-cv-open",
|
||||
Title: "Open Convoy",
|
||||
Status: "open",
|
||||
ID: "hq-cv-active",
|
||||
Title: "Active Convoy",
|
||||
Status: "open",
|
||||
WorkStatus: "active",
|
||||
},
|
||||
{
|
||||
ID: "hq-cv-closed",
|
||||
Title: "Closed Convoy",
|
||||
Status: "closed",
|
||||
ID: "hq-cv-stuck",
|
||||
Title: "Stuck Convoy",
|
||||
Status: "open",
|
||||
WorkStatus: "stuck",
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -204,12 +201,12 @@ func TestConvoyTemplate_StatusIndicators(t *testing.T) {
|
||||
|
||||
output := buf.String()
|
||||
|
||||
// Check status indicators
|
||||
if !strings.Contains(output, "status-open") {
|
||||
t.Error("Template should contain status-open class")
|
||||
// Check work status badges are rendered (replaced status-open/closed classes)
|
||||
if !strings.Contains(output, "badge-green") {
|
||||
t.Error("Template should contain badge-green class for active status")
|
||||
}
|
||||
if !strings.Contains(output, "status-closed") {
|
||||
t.Error("Template should contain status-closed class")
|
||||
if !strings.Contains(output, "badge-red") {
|
||||
t.Error("Template should contain badge-red class for stuck status")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,7 +229,7 @@ func TestConvoyTemplate_EmptyState(t *testing.T) {
|
||||
output := buf.String()
|
||||
|
||||
// Check for empty state message
|
||||
if !strings.Contains(output, "No convoys") {
|
||||
if !strings.Contains(output, "No active convoys") {
|
||||
t.Error("Template should show empty state message when no convoys")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user