Delete confirmation dialog used wrong magic numbers for entity kind
mapping — maintenance windows showed as "alert", settings deletions
showed as "monitor". Now uses tab/section constants to match correctly.
Also: consistent [q/Esc] Back across all views (detail inline, logs,
SLA, history headers), extract detailKeys(), remove dead maxSections
variable, add nodes empty state hint, use models.Status constants in
siteOrder, delete orphaned theme.png.
- Click Alerts/Nodes/Users sub-tabs in settings to switch sections
- Click STATUS/NAME/LATENCY column headers to sort (click again
to reverse direction)
- Logs panel show/hide: [l] toggles sidebar visibility, click
focused panel to hide. Monitors expand to full width when hidden.
- Logs full-screen: Enter when focused on logs opens scrollable
full-screen log view with severity tags, filter toggle [f],
and live updates
Introduced models.LogEntry{Message, CreatedAt} to replace raw strings
in the log pipeline. Timestamps are now formatted at render time, not
baked into stored messages.
- Engine: appendLog stores LogEntry with time.Now()
- Store: LoadLogs returns []LogEntry, selects created_at from DB
- Store: strips legacy [HH:MM] prefix from pre-refactor DB entries
- TUI: sidebar shows "MM/DD HH:MM" from CreatedAt
- TUI: full log view shows "MM/DD HH:MM" from CreatedAt
- SaveLog still receives plain message string (DB handles timestamp)
Replace full viewLogsTab with compact sidebar renderer for the 70/30
monitors split. Single-char severity icons (▼▲◆●·), truncated messages,
no header chrome. Renders directly from engine logs without viewport.
viewLogsTab filtered logViewport.View() — the visible window — so the
entry count showed the window size and hidden lines reappeared while
scrolling. Filter and render now happen at content-set time from
engine.GetLogs(); the view only reads stored counts.
applyTheme mutated ~18 package-global lipgloss styles while every SSH
session's tea.Program read them concurrently from its own goroutine.
Pressing T or opening a new connection raced other sessions' View and
bled themes across users.
Styles now live in an immutable per-Model struct built by newStyles;
free formatter helpers that consumed the globals became Model methods.
Logs were dumping all lines directly, pushing the dashboard
footer off screen. Now uses logViewport with proper height
accounting so footer stays visible and scrolling works.
- Extract divider() and emptyState() helpers to format.go
- All empty states now use bordered box with accent color
- Detail and alert detail panels get header/section dividers
- SLA label width 14→16 to match detail/alert panels
- Logs key hints moved from content to dashboard footer
- History/SLA panels use shared divider helper