diff --git a/internal/tui/panel.go b/internal/tui/panel.go index 55a3291..4d90525 100644 --- a/internal/tui/panel.go +++ b/internal/tui/panel.go @@ -6,7 +6,7 @@ import ( "github.com/charmbracelet/lipgloss" ) -func (m Model) titledPanelH(title, content string, width, height, scrollOffset int, focused bool) string { +func (m Model) titledPanelH(title, content, footer string, width, height, scrollOffset int, focused bool) string { if height <= 0 { return m.titledPanel(title, content, width, focused) } @@ -40,7 +40,13 @@ func (m Model) titledPanelH(title, content string, width, height, scrollOffset i inner := contentStyle.Render(content) contentLines := strings.Split(inner, "\n") - bodyH := height - 2 + var footerLines []string + if footer != "" { + footerRendered := contentStyle.Render(footer) + footerLines = strings.Split(footerRendered, "\n") + } + + bodyH := height - 2 - len(footerLines) if bodyH < 1 { bodyH = 1 } @@ -58,13 +64,21 @@ func (m Model) titledPanelH(title, content string, width, height, scrollOffset i } visible := contentLines[scrollOffset:end] + borderLine := func(line string) string { + return bc.Render("│") + line + strings.Repeat(" ", max(0, innerW-lipgloss.Width(line))) + bc.Render("│") + } + emptyLine := borderLine(strings.Repeat(" ", innerW)) + var lines []string lines = append(lines, top) for _, line := range visible { - lines = append(lines, bc.Render("│")+line+strings.Repeat(" ", max(0, innerW-lipgloss.Width(line)))+bc.Render("│")) + lines = append(lines, borderLine(line)) } - for len(lines) < height-1 { - lines = append(lines, bc.Render("│")+strings.Repeat(" ", innerW)+bc.Render("│")) + for len(lines) < height-1-len(footerLines) { + lines = append(lines, emptyLine) + } + for _, line := range footerLines { + lines = append(lines, borderLine(line)) } lines = append(lines, bottom) diff --git a/internal/tui/view_dashboard.go b/internal/tui/view_dashboard.go index 6b81089..bdcde86 100644 --- a/internal/tui/view_dashboard.go +++ b/internal/tui/view_dashboard.go @@ -192,7 +192,8 @@ func (m Model) viewMonitorsLayout() string { } monHeight := lipgloss.Height(monPanel) detail := m.viewDetailInline(detailW-2, monHeight) - detailPanel := m.zones.Mark("panel-detail", m.titledPanelH(title, detail, detailW, monHeight, m.detailScrollOffset, m.focusedPanel == panelDetail)) + footer := m.detailFooter(detailW - 2) + detailPanel := m.zones.Mark("panel-detail", m.titledPanelH(title, detail, footer, detailW, monHeight, m.detailScrollOffset, m.focusedPanel == panelDetail)) topParts = append(topParts, detailPanel) } diff --git a/internal/tui/view_detail_inline.go b/internal/tui/view_detail_inline.go index ca5cc33..5c1ab94 100644 --- a/internal/tui/view_detail_inline.go +++ b/internal/tui/view_detail_inline.go @@ -143,8 +143,6 @@ func (m Model) viewDetailSidebar(site models.Site, hist monitor.SiteHistory, wid b.WriteString(" " + label.Render("No state changes") + "\n") } - b.WriteString("\n " + m.detailKeys() + "\n") - return lipgloss.NewStyle().Width(width).MaxWidth(width).Render(b.String()) } @@ -216,6 +214,33 @@ func (m Model) detailKeys() string { return m.st.subtleStyle.Render("[e] Edit [h] History [s] SLA [Esc] Back") } +func (m Model) detailFooter(width int) string { + label := m.st.subtleStyle + var lines []string + + switch m.detailMode { + case detailSLA: + var keys []string + for i, p := range slaPeriods { + k := fmt.Sprintf("[%s] %s", p.key, p.label) + if i == m.slaPeriodIdx { + keys = append(keys, m.st.titleStyle.Render(k)) + } else { + keys = append(keys, label.Render(k)) + } + } + lines = append(lines, " "+strings.Join(keys, " ")) + lines = append(lines, " "+label.Render("[Esc] Back")) + case detailHistory: + lines = append(lines, " "+label.Render("[Esc] Back")) + default: + lines = append(lines, " "+m.detailKeys()) + } + + content := strings.Join(lines, "\n") + return lipgloss.NewStyle().Width(width).MaxWidth(width).Render(content) +} + func (m Model) fmtStatusWord(status string) string { switch status { case "DOWN", "SSL EXP": @@ -292,20 +317,6 @@ func (m Model) viewSLASidebar(width, _ int) string { } } - b.WriteString("\n") - - var keys []string - for i, p := range slaPeriods { - k := fmt.Sprintf("[%s] %s", p.key, p.label) - if i == m.slaPeriodIdx { - keys = append(keys, m.st.titleStyle.Render(k)) - } else { - keys = append(keys, label.Render(k)) - } - } - b.WriteString(" " + strings.Join(keys, " ") + "\n") - b.WriteString(" " + label.Render("[Esc] Back") + "\n") - return lipgloss.NewStyle().Width(width).MaxWidth(width).Render(b.String()) } @@ -368,7 +379,6 @@ func (m Model) viewHistorySidebar(width, _ int) string { statParts = append(statParts, "avg "+fmtDuration(avg)) } b.WriteString(" " + label.Render(strings.Join(statParts, " │ ")) + "\n") - b.WriteString(" " + label.Render("[Esc] Back") + "\n") return lipgloss.NewStyle().Width(width).MaxWidth(width).Render(b.String()) }