chore(tui): visual polish — detail sections, column headers, alert detail (#37)
## Summary Bundled remaining UX polish items from the screenshot review. ### Changes **Detail panel sections (#5)** - Fields grouped into ENDPOINT, TIMING, HTTP, CONFIG sections with subtle headers - Matches existing PROBE RESULTS and STATE CHANGES section pattern - Cleaner visual hierarchy without box-drawing clutter **Omit unconfigured fields (#6)** - Timeout hidden when 0 (unconfigured) - Method hidden when default GET - AcceptedCodes shows "200-299" explicitly when empty **Column header (#7)** - `LATENCY` → `LAT` (design short, never truncate — htop/btop pattern) **Alert detail view (#8)** - `i` key on Alerts tab opens full detail panel - Shows: type, health status, last sent time, send/fail counts, last error - Full config key:value pairs (untruncated) - Keybinding: `[i/Esc] Back [e] Edit [t] Test [q] Quit` ### Files (3) - `internal/tui/tab_sites.go` — section headers, field omission, LAT header - `internal/tui/tab_alerts.go` — viewAlertDetailPanel() - `internal/tui/tui.go` — stateAlertDetail, key handler, render routing Reviewed-on: lerko/uptop#37
This commit was merged in pull request #37.
This commit is contained in:
+28
-11
@@ -2,10 +2,11 @@ package tui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gitea.lerkolabs.com/lerko/uptop/internal/models"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"gitea.lerkolabs.com/lerko/uptop/internal/models"
|
||||
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/charmbracelet/huh"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
@@ -40,19 +41,19 @@ func fmtMaintType(t string) string {
|
||||
return maintStyle.Render("maintenance")
|
||||
}
|
||||
|
||||
func fmtMaintMonitor(monitorID int, sites []models.Site) string {
|
||||
func fmtMaintMonitorW(monitorID int, sites []models.Site, maxW int) string {
|
||||
if monitorID == 0 {
|
||||
return "All"
|
||||
}
|
||||
for _, s := range sites {
|
||||
if s.ID == monitorID {
|
||||
return limitStr(s.Name, 18)
|
||||
return limitStr(s.Name, maxW)
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("#%d", monitorID)
|
||||
}
|
||||
|
||||
func fmtMaintTime(t time.Time) string {
|
||||
func fmtMaintTime(t time.Time, colW int) string {
|
||||
if t.IsZero() {
|
||||
return subtleStyle.Render("—")
|
||||
}
|
||||
@@ -60,7 +61,10 @@ func fmtMaintTime(t time.Time) string {
|
||||
if t.Year() == now.Year() && t.YearDay() == now.YearDay() {
|
||||
return t.Format("15:04")
|
||||
}
|
||||
return t.Format("15:04 Jan 02")
|
||||
if colW >= 14 {
|
||||
return t.Format("15:04 Jan 02")
|
||||
}
|
||||
return t.Format("Jan 02")
|
||||
}
|
||||
|
||||
func (m Model) isMonitorInMaintenance(monitorID int) bool {
|
||||
@@ -92,8 +96,21 @@ func (m Model) viewMaintTab() string {
|
||||
return "\n No maintenance windows or incidents. Press [n] to create one."
|
||||
}
|
||||
|
||||
var headers []string
|
||||
var widths []int
|
||||
if m.isWide() {
|
||||
headers = []string{"#", "TITLE", "TYPE", "MONITORS", "STATUS", "STARTED", "ENDS"}
|
||||
widths = []int{4, 24, 14, 22, 12, 16, 16}
|
||||
} else {
|
||||
headers = []string{"#", "TITLE", "TYPE", "MON", "ST", "START", "ENDS"}
|
||||
widths = []int{4, 14, 13, 14, 11, 14, 14}
|
||||
}
|
||||
titleW := widths[1]
|
||||
monW := widths[3]
|
||||
timeW := widths[5]
|
||||
|
||||
return m.renderTable(
|
||||
[]string{"#", "TITLE", "TYPE", "MONITORS", "STATUS", "STARTED", "ENDS"},
|
||||
headers,
|
||||
len(m.maintenanceWindows),
|
||||
func(start, end int) [][]string {
|
||||
var rows [][]string
|
||||
@@ -102,17 +119,17 @@ func (m Model) viewMaintTab() string {
|
||||
mw := m.maintenanceWindows[i]
|
||||
rows = append(rows, []string{
|
||||
strconv.Itoa(i + 1),
|
||||
m.zones.Mark(fmt.Sprintf("maint-%d", i), limitStr(mw.Title, 24)),
|
||||
m.zones.Mark(fmt.Sprintf("maint-%d", i), limitStr(mw.Title, titleW-2)),
|
||||
fmtMaintType(mw.Type),
|
||||
fmtMaintMonitor(mw.MonitorID, allSites),
|
||||
fmtMaintMonitorW(mw.MonitorID, allSites, monW-2),
|
||||
fmtMaintStatus(mw),
|
||||
fmtMaintTime(mw.StartTime),
|
||||
fmtMaintTime(mw.EndTime),
|
||||
fmtMaintTime(mw.StartTime, timeW),
|
||||
fmtMaintTime(mw.EndTime, timeW),
|
||||
})
|
||||
}
|
||||
return rows
|
||||
},
|
||||
[]int{6, 0, 14, 20, 12, 16, 16},
|
||||
widths,
|
||||
nil,
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user