diff --git a/internal/tui/panel.go b/internal/tui/panel.go index 6935334..a8480f1 100644 --- a/internal/tui/panel.go +++ b/internal/tui/panel.go @@ -6,6 +6,18 @@ import ( "github.com/charmbracelet/lipgloss" ) +func (m Model) titledPanelH(title, content string, width, height int, focused bool) string { + s := m.titledPanel(title, content, width, focused) + if height <= 0 { + return s + } + lines := strings.Split(s, "\n") + if len(lines) <= height { + return s + } + return strings.Join(lines[:height-1], "\n") + "\n" + lines[len(lines)-1] +} + func (m Model) titledPanel(title, content string, width int, focused bool) string { borderColor := m.theme.Border titleColor := m.theme.Muted diff --git a/internal/tui/update_test.go b/internal/tui/update_test.go index d98d564..9d8aae0 100644 --- a/internal/tui/update_test.go +++ b/internal/tui/update_test.go @@ -142,7 +142,7 @@ func TestDetailLoad_CachesAndViewDoesNoIO(t *testing.T) { } for i := 0; i < 3; i++ { - _ = m.viewDetailInline(80) + _ = m.viewDetailInline(80, 30) } if ms.stateChangeCalls != 1 { t.Errorf("View performed DB IO: store hit %d times (want 1, from the Cmd only)", ms.stateChangeCalls) diff --git a/internal/tui/view_dashboard.go b/internal/tui/view_dashboard.go index 5999fbb..24fd8eb 100644 --- a/internal/tui/view_dashboard.go +++ b/internal/tui/view_dashboard.go @@ -190,8 +190,9 @@ func (m Model) viewMonitorsLayout() string { case detailHistory: title = "History · " + title } - detail := m.viewDetailInline(detailW - 2) - detailPanel := m.zones.Mark("panel-detail", m.titledPanel(title, detail, detailW, m.focusedPanel == panelDetail)) + monHeight := lipgloss.Height(monPanel) + detail := m.viewDetailInline(detailW-2, monHeight) + detailPanel := m.zones.Mark("panel-detail", m.titledPanelH(title, detail, detailW, monHeight, m.focusedPanel == panelDetail)) topParts = append(topParts, detailPanel) } diff --git a/internal/tui/view_detail_inline.go b/internal/tui/view_detail_inline.go index dbb4127..22e5834 100644 --- a/internal/tui/view_detail_inline.go +++ b/internal/tui/view_detail_inline.go @@ -10,23 +10,23 @@ import ( "github.com/charmbracelet/lipgloss" ) -func (m Model) viewDetailInline(width int) string { +func (m Model) viewDetailInline(width, height int) string { if m.cursor >= len(m.sites) { return "" } switch m.detailMode { case detailSLA: - return m.viewSLASidebar(width) + return m.viewSLASidebar(width, height) case detailHistory: - return m.viewHistorySidebar(width) + return m.viewHistorySidebar(width, height) default: site := m.sites[m.cursor] hist, _ := m.engine.GetHistory(site.ID) - return m.viewDetailSidebar(site, hist, width) + return m.viewDetailSidebar(site, hist, width, height) } } -func (m Model) viewDetailSidebar(site models.Site, hist monitor.SiteHistory, width int) string { +func (m Model) viewDetailSidebar(site models.Site, hist monitor.SiteHistory, width, _ int) string { dot := m.st.subtleStyle.Render(" · ") label := m.st.subtleStyle var b strings.Builder @@ -235,7 +235,7 @@ func (m Model) fmtStatusWord(status string) string { } } -func (m Model) viewSLASidebar(width int) string { +func (m Model) viewSLASidebar(width, height int) string { var b strings.Builder label := m.st.subtleStyle innerW := width - 4 @@ -277,7 +277,21 @@ func (m Model) viewSLASidebar(width int) string { if dayBarW < 10 { dayBarW = 10 } - for _, day := range m.slaDailyBreakdown { + slaChrome := 14 + if r.OutageCount > 0 { + slaChrome += 3 + } + maxDaily := len(m.slaDailyBreakdown) + if height > 0 && height-slaChrome < maxDaily { + maxDaily = height - slaChrome + if maxDaily < 1 { + maxDaily = 1 + } + } + for i, day := range m.slaDailyBreakdown { + if i >= maxDaily { + break + } dateStr := day.Date.Format("Jan 02") dayBar := m.uptimeBar(day.UptimePct, dayBarW) pctStr := fmtPct(day.UptimePct) + "%" @@ -309,7 +323,7 @@ func (m Model) viewSLASidebar(width int) string { return lipgloss.NewStyle().Width(width).MaxWidth(width).Render(b.String()) } -func (m Model) viewHistorySidebar(width int) string { +func (m Model) viewHistorySidebar(width, _ int) string { var b strings.Builder label := m.st.subtleStyle innerW := width - 4