diff --git a/internal/tui/panel.go b/internal/tui/panel.go new file mode 100644 index 0000000..586af54 --- /dev/null +++ b/internal/tui/panel.go @@ -0,0 +1,52 @@ +package tui + +import ( + "strings" + + "github.com/charmbracelet/lipgloss" +) + +func (m Model) titledPanel(title, content string, width int, focused bool) string { + borderColor := m.theme.Border + titleColor := m.theme.Muted + if focused { + borderColor = m.theme.Accent + titleColor = m.theme.Accent + } + + bc := lipgloss.NewStyle().Foreground(borderColor) + tc := lipgloss.NewStyle().Foreground(titleColor).Bold(true) + + innerW := width - 2 + if innerW < 10 { + innerW = 10 + } + + titleRendered := tc.Render(" " + title + " ") + titleLen := len([]rune(title)) + 2 + fillLen := innerW - titleLen - 1 + if fillLen < 0 { + fillLen = 0 + } + + top := bc.Render("╭─") + titleRendered + bc.Render(strings.Repeat("─", fillLen)+"╮") + + contentStyle := lipgloss.NewStyle().Width(innerW).MaxWidth(innerW) + inner := contentStyle.Render(content) + + var lines []string + lines = append(lines, top) + for _, line := range strings.Split(inner, "\n") { + lines = append(lines, bc.Render("│")+line+strings.Repeat(" ", max(0, innerW-lipgloss.Width(line)))+bc.Render("│")) + } + lines = append(lines, bc.Render("╰"+strings.Repeat("─", innerW)+"╯")) + + return strings.Join(lines, "\n") +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} diff --git a/internal/tui/table_helpers.go b/internal/tui/table_helpers.go index e2dd5d8..0fd36ee 100644 --- a/internal/tui/table_helpers.go +++ b/internal/tui/table_helpers.go @@ -52,8 +52,7 @@ func (m Model) renderTable(headers []string, items int, buildRows func(start, en } t := table.New(). - Border(lipgloss.RoundedBorder()). - BorderStyle(m.st.tableBorderStyle). + Border(lipgloss.HiddenBorder()). Width(tableWidth). Headers(headers...). Rows(rows...). @@ -94,5 +93,5 @@ func (m Model) renderTable(headers []string, items int, buildRows func(start, en return base }) - return "\n" + t.Render() + return t.Render() } diff --git a/internal/tui/view_dashboard.go b/internal/tui/view_dashboard.go index c2a2fb8..d5d1a92 100644 --- a/internal/tui/view_dashboard.go +++ b/internal/tui/view_dashboard.go @@ -157,35 +157,38 @@ func (m Model) viewDashboard() string { availW := m.termWidth - chromePadH leftW := availW * 70 / 100 rightW := availW - leftW - m.contentWidth = leftW + m.contentWidth = leftW - 2 monitors := m.viewSitesTab() - left := lipgloss.NewStyle().Width(leftW).Render(monitors) - sidebarBorder := lipgloss.NewStyle(). - Border(lipgloss.RoundedBorder()). - BorderForeground(m.theme.Border). - BorderLeft(false). - BorderBottom(false) - innerW := rightW - 2 - if innerW < 10 { - innerW = 10 - } - sidebar := m.viewLogsSidebar(innerW, m.maxTableRows) - right := sidebarBorder.Render(sidebar) - top := lipgloss.JoinHorizontal(lipgloss.Top, left, right) + monPanel := m.titledPanel("Monitors", monitors, leftW, !m.detailOpen) + sidebarContent := m.viewLogsSidebar(rightW-2, m.maxTableRows) + logPanel := m.titledPanel("Logs", sidebarContent, rightW, false) + top := lipgloss.JoinHorizontal(lipgloss.Top, monPanel, logPanel) if m.detailOpen { - detail := m.viewDetailInline(availW) - content = top + "\n" + detail + site := "" + if m.cursor < len(m.sites) { + site = m.sites[m.cursor].Name + } + detail := m.viewDetailInline(availW - 2) + detailPanel := m.titledPanel(site, detail, availW, true) + content = top + "\n" + detailPanel } else { content = top } } else { - m.contentWidth = m.termWidth + m.contentWidth = m.termWidth - 2 monitors := m.viewSitesTab() + availW := m.termWidth - chromePadH + monPanel := m.titledPanel("Monitors", monitors, availW, !m.detailOpen) if m.detailOpen { - detail := m.viewDetailInline(m.termWidth - chromePadH) - content = monitors + "\n" + detail + site := "" + if m.cursor < len(m.sites) { + site = m.sites[m.cursor].Name + } + detail := m.viewDetailInline(availW - 2) + detailPanel := m.titledPanel(site, detail, availW, true) + content = monPanel + "\n" + detailPanel } else { - content = monitors + content = monPanel } } case tabMaint: diff --git a/internal/tui/view_detail_inline.go b/internal/tui/view_detail_inline.go index c28ea29..da962c5 100644 --- a/internal/tui/view_detail_inline.go +++ b/internal/tui/view_detail_inline.go @@ -18,15 +18,6 @@ func (m Model) viewDetailInline(width int) string { var b strings.Builder - title := m.st.titleStyle.Render(site.Name) - b.WriteString(" " + title + "\n") - - divW := width - 4 - if divW < 20 { - divW = 20 - } - b.WriteString(" " + m.st.subtleStyle.Render(strings.Repeat("─", divW)) + "\n") - status := m.fmtStatus(site.Status, site.Paused, m.isMonitorInMaintenance(site.ID)) latency := m.fmtLatency(site.Latency) uptime := m.fmtUptime(hist.Statuses)