fix(tui): apply log filter to full log list, not viewport window

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.
This commit is contained in:
2026-06-12 14:30:48 -04:00
parent 49f419896c
commit 6df9b52033
4 changed files with 22 additions and 13 deletions
+1 -1
View File
@@ -104,7 +104,7 @@ func (m *Model) refreshLive() {
ordered = filterSites(ordered, m.filterText) ordered = filterSites(ordered, m.filterText)
} }
m.sites = ordered m.sites = ordered
m.logViewport.SetContent(strings.Join(m.engine.GetLogs(), "\n")) m.refreshLogContent()
if m.currentTab == 0 && m.selectedID != 0 { if m.currentTab == 0 && m.selectedID != 0 {
for i, s := range m.sites { for i, s := range m.sites {
+18 -12
View File
@@ -82,18 +82,15 @@ func (m Model) renderLogLine(line string) string {
return fmt.Sprintf(" %s %s", tag, msg) return fmt.Sprintf(" %s %s", tag, msg)
} }
func (m Model) viewLogsTab() string { // refreshLogContent rebuilds the log viewport from the full engine log list,
content := m.logViewport.View() // filtering before windowing so the entry count and "(n hidden)" reflect all
if strings.TrimSpace(content) == "" || content == "Waiting for logs..." { // logs, not just the visible viewport slice.
return m.emptyState("No log entries yet.", "Logs appear as monitors run checks") func (m *Model) refreshLogContent() {
}
lines := strings.Split(content, "\n")
var rendered []string var rendered []string
total := 0 total := 0
shown := 0 shown := 0
for _, line := range lines { for _, line := range m.engine.GetLogs() {
if strings.TrimSpace(line) == "" { if strings.TrimSpace(line) == "" {
continue continue
} }
@@ -106,18 +103,27 @@ func (m Model) viewLogsTab() string {
rendered = append(rendered, m.renderLogLine(line)) rendered = append(rendered, m.renderLogLine(line))
} }
m.logTotal = total
m.logShown = shown
m.logViewport.SetContent(strings.Join(rendered, "\n"))
}
func (m Model) viewLogsTab() string {
if m.logTotal == 0 {
return m.emptyState("No log entries yet.", "Logs appear as monitors run checks")
}
filterLabel := "All" filterLabel := "All"
if m.logFilterImportant { if m.logFilterImportant {
filterLabel = "Important" filterLabel = "Important"
} }
header := m.st.subtleStyle.Render(fmt.Sprintf( header := m.st.subtleStyle.Render(fmt.Sprintf(
" %d entries Filter: %s", shown, filterLabel)) " %d entries Filter: %s", m.logShown, filterLabel))
if m.logFilterImportant && shown < total { if m.logFilterImportant && m.logShown < m.logTotal {
header += m.st.subtleStyle.Render(fmt.Sprintf(" (%d hidden)", total-shown)) header += m.st.subtleStyle.Render(fmt.Sprintf(" (%d hidden)", m.logTotal-m.logShown))
} }
m.logViewport.SetContent(strings.Join(rendered, "\n"))
return "\n" + header + "\n\n" + m.logViewport.View() return "\n" + header + "\n\n" + m.logViewport.View()
} }
+2
View File
@@ -121,6 +121,8 @@ type Model struct {
logViewport viewport.Model logViewport viewport.Model
logFilterImportant bool logFilterImportant bool
logTotal int
logShown int
historyViewport viewport.Model historyViewport viewport.Model
historyChanges []models.StateChange historyChanges []models.StateChange
+1
View File
@@ -527,6 +527,7 @@ func (m *Model) handleDashboardKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
case "f": case "f":
if m.state == stateLogs { if m.state == stateLogs {
m.logFilterImportant = !m.logFilterImportant m.logFilterImportant = !m.logFilterImportant
m.refreshLogContent()
return m, nil return m, nil
} }
case "tab": case "tab":