Compare commits

1 Commits

Author SHA1 Message Date
lerko 83d9754c89 feat(tui): mouse click for settings sections, column sort, logs toggle
CI / test (pull_request) Successful in 1m50s
CI / lint (pull_request) Successful in 1m16s
CI / vulncheck (pull_request) Successful in 51s
- 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)
2026-06-28 11:34:34 -04:00
4 changed files with 2 additions and 72 deletions
-18
View File
@@ -5,7 +5,6 @@ import (
"strings"
"gitea.lerkolabs.com/lerkolabs/uptop/internal/models"
"github.com/charmbracelet/lipgloss"
)
type logSeverity int
@@ -73,23 +72,6 @@ func (m Model) renderLogLine(entry models.LogEntry) string {
return fmt.Sprintf(" %s %s %s", ts, tag, entry.Message)
}
func (m Model) viewLogsFullscreen() string {
header := m.st.subtleStyle.Render(" Logs") + "\n" + m.divider()
filterLabel := m.st.subtleStyle.Render("[f] All")
if m.logFilterImportant {
filterLabel = m.st.subtleStyle.Render("[f] Important only")
}
countLabel := m.st.subtleStyle.Render(fmt.Sprintf("%d/%d", m.logShown, m.logTotal))
footer := m.divider() + "\n " + m.st.subtleStyle.Render("[Esc] Back") + " " + filterLabel + " " + countLabel
m.logViewport.Width = m.termWidth - chromePadH
m.logViewport.Height = m.termHeight - 8
return lipgloss.NewStyle().Padding(1, 2).Render(
header + "\n" + m.logViewport.View() + "\n" + footer)
}
func (m *Model) refreshLogContent() {
var rendered []string
total := 0
-2
View File
@@ -197,7 +197,6 @@ type Model struct {
lastTabLoad time.Time // last dispatch of loadTabDataCmd (throttle)
tabSeq int // seq of the newest issued tab-data load
logsOpen bool
detailOpen bool
detailChanges []models.StateChange
detailChangesSiteID int
@@ -248,7 +247,6 @@ func InitialModel(ctx context.Context, isAdmin bool, s store.Store, eng *monitor
theme: theme,
themeIndex: themeIdx,
st: newStyles(theme),
logsOpen: true,
detailOpen: detailPref == "true",
demoMode: os.Getenv("UPTOP_DEMO") == "1",
version: version,
-48
View File
@@ -53,9 +53,6 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if m.state == stateFormSite || m.state == stateFormAlert || m.state == stateFormUser || m.state == stateFormMaint {
return m.handleFormMsg(msg)
}
if m.state == stateLogs {
return m.handleLogsFullscreen(msg)
}
switch msg := msg.(type) {
case tea.MouseMsg:
@@ -244,40 +241,6 @@ func (m *Model) testAlertCmd(id int, name string) tea.Cmd {
}
}
func (m *Model) handleLogsFullscreen(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.String() {
case "esc", "q":
m.state = stateDashboard
m.focusedPanel = panelLogs
case "ctrl+c":
return m, tea.Quit
case "f":
m.logFilterImportant = !m.logFilterImportant
m.refreshLogContent()
case "up", "k":
m.logViewport.ScrollUp(1)
case "down", "j":
m.logViewport.ScrollDown(1)
case "pgup":
m.logViewport.ScrollUp(m.logViewport.Height)
case "pgdown":
m.logViewport.ScrollDown(m.logViewport.Height)
}
case tea.MouseMsg:
switch msg.Button {
case tea.MouseButtonWheelUp:
m.logViewport.ScrollUp(3)
case tea.MouseButtonWheelDown:
m.logViewport.ScrollDown(3)
}
case tickMsg:
m.refreshLogContent()
}
return m, nil
}
func (m *Model) handleMouse(msg tea.MouseMsg) (tea.Model, tea.Cmd) {
if m.state == stateHistory {
switch msg.Button {
@@ -616,13 +579,10 @@ func (m *Model) handleDashboardKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
m.switchSettingsSection(m.settingsSection + 1)
case tabMonitors:
if m.focusedPanel == panelLogs {
m.logsOpen = false
m.focusedPanel = panelMonitors
} else {
m.logsOpen = true
m.focusedPanel = panelLogs
}
m.recalcLayout()
}
case "up", "k":
if m.currentTab == tabMonitors && m.focusedPanel == panelLogs {
@@ -658,12 +618,6 @@ func (m *Model) handleDashboardKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
case "n":
return m.handleNewItem()
case "enter":
if m.currentTab == tabMonitors && m.focusedPanel == panelLogs {
m.refreshLogContent()
m.logViewport.GotoTop()
m.state = stateLogs
return m, nil
}
if m.currentTab == tabMonitors && len(m.sites) > 0 {
m.state = stateDetail
return m, m.loadDetailCmd(m.sites[m.cursor].ID)
@@ -925,9 +879,7 @@ func (m *Model) handleClick(msg tea.MouseMsg) (tea.Model, tea.Cmd) {
m.focusedPanel = panelMonitors
} else if m.zones.Get("panel-logs").InBounds(msg) {
if m.focusedPanel == panelLogs {
m.logsOpen = false
m.focusedPanel = panelMonitors
m.recalcLayout()
} else {
m.focusedPanel = panelLogs
}
+2 -4
View File
@@ -92,8 +92,6 @@ func (m Model) View() string {
return ""
case stateDetail:
return m.zones.Scan(m.viewDetailPanel())
case stateLogs:
return m.viewLogsFullscreen()
case stateHistory:
return m.viewHistoryPanel()
case stateSLA:
@@ -154,7 +152,7 @@ func (m Model) viewDashboard() string {
var content string
switch m.currentTab {
case tabMonitors:
showSidebar := m.termWidth >= wideBreakpoint && m.logsOpen
showSidebar := m.termWidth >= wideBreakpoint
if showSidebar {
availW := m.termWidth - chromePadH
leftW := availW * 70 / 100
@@ -312,7 +310,7 @@ func (m Model) renderFooter(stats dashboardStats) string {
switch m.currentTab {
case tabMonitors:
if m.focusedPanel == panelLogs {
keys = "[↑/↓]Scroll [Enter]Expand [l/Esc]Back [T]Theme [q]Quit"
keys = "[↑/↓]Scroll [l/Esc]Back [T]Theme [q]Quit"
} else if m.detailOpen {
keys = "[i]Close [Enter]Expand [h]History [s]SLA [e]Edit [l]Logs [↑/↓]Select [T]Theme [q]Quit"
} else {