From 83d9754c89542dc0f3952bbdc2c10fe81ac0fcd1 Mon Sep 17 00:00:00 2001 From: Tyler Koenig Date: Sun, 28 Jun 2026 11:34:34 -0400 Subject: [PATCH] feat(tui): mouse click for settings sections, column sort, logs toggle - Click Alerts/Nodes/Users sub-tabs in settings to switch sections - Click STATUS/NAME/LATENCY column headers to sort (click again to reverse direction) - Click logs panel to toggle focus (click again to unfocus) --- internal/tui/tab_settings.go | 8 ++++++-- internal/tui/tab_sites.go | 10 +++++++++ internal/tui/update.go | 40 +++++++++++++++++++++++++++++++++++- 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/internal/tui/tab_settings.go b/internal/tui/tab_settings.go index c1d2f51..2b02929 100644 --- a/internal/tui/tab_settings.go +++ b/internal/tui/tab_settings.go @@ -1,6 +1,8 @@ package tui import ( + "fmt" + "github.com/charmbracelet/lipgloss" ) @@ -18,11 +20,13 @@ func (m Model) viewSettingsTab() string { var tabs []string for i, name := range sections { + var rendered string if i == m.settingsSection { - tabs = append(tabs, m.st.activeTab.Render(name)) + rendered = m.st.activeTab.Render(name) } else { - tabs = append(tabs, m.st.inactiveTab.Render(name)) + rendered = m.st.inactiveTab.Render(name) } + tabs = append(tabs, m.zones.Mark(fmt.Sprintf("section-%d", i), rendered)) } header := lipgloss.JoinHorizontal(lipgloss.Top, tabs...) diff --git a/internal/tui/tab_sites.go b/internal/tui/tab_sites.go index 8a65d29..45464a0 100644 --- a/internal/tui/tab_sites.go +++ b/internal/tui/tab_sites.go @@ -110,6 +110,11 @@ func (m Model) computeLayout() tableLayout { sortName: colName, sortLatency: colLatency, } + sortableKeys := map[colKey]string{ + colStatus: "sort-status", + colName: "sort-name", + colLatency: "sort-latency", + } if sortedKey, ok := sortColMap[m.sortColumn]; ok { arrow := "▼" if m.sortAsc { @@ -122,6 +127,11 @@ func (m Model) computeLayout() tableLayout { } } } + for i, k := range active { + if zoneID, ok := sortableKeys[k]; ok { + headers[i] = m.zones.Mark(zoneID, headers[i]) + } + } numCols := len(headers) borderOverhead := 2 + (numCols - 1) diff --git a/internal/tui/update.go b/internal/tui/update.go index be85437..35999c8 100644 --- a/internal/tui/update.go +++ b/internal/tui/update.go @@ -840,11 +840,49 @@ func (m *Model) handleClick(msg tea.MouseMsg) (tea.Model, tea.Cmd) { } } + if m.currentTab == tabSettings { + maxSec := 1 + if m.isAdmin { + maxSec = 2 + } + for i := 0; i <= maxSec; i++ { + if m.zones.Get(fmt.Sprintf("section-%d", i)).InBounds(msg) { + m.switchSettingsSection(i) + return m, nil + } + } + } + if m.currentTab == tabMonitors { + sortZones := []struct { + zone string + col int + }{ + {"sort-status", sortStatus}, + {"sort-name", sortName}, + {"sort-latency", sortLatency}, + } + for _, sz := range sortZones { + if m.zones.Get(sz.zone).InBounds(msg) { + if m.sortColumn == sz.col { + m.sortAsc = !m.sortAsc + } else { + m.sortColumn = sz.col + m.sortAsc = false + } + m.refreshLive() + return m, nil + } + } + if m.zones.Get("panel-monitors").InBounds(msg) { m.focusedPanel = panelMonitors } else if m.zones.Get("panel-logs").InBounds(msg) { - m.focusedPanel = panelLogs + if m.focusedPanel == panelLogs { + m.focusedPanel = panelMonitors + } else { + m.focusedPanel = panelLogs + } return m, nil } else if m.detailOpen && m.zones.Get("panel-detail").InBounds(msg) { m.focusedPanel = panelDetail