mirror of
https://github.com/usestrix/strix.git
synced 2026-10-04 02:33:47 +00:00
fix(tui): keep sidebar panels inside the terminal height
This commit is contained in:
parent
701c22b8a9
commit
1a680f4aa3
3 changed files with 64 additions and 2 deletions
|
|
@ -220,6 +220,8 @@ func (m *Model) revealPanel(panel sidebarPanel) {
|
|||
|
||||
func (m *Model) clickPanel(rect panelRect, x, y int) bool {
|
||||
switch {
|
||||
case rect.height <= 1 && !m.panelShrunk(rect.panel):
|
||||
m.togglePanelZoom(rect.panel)
|
||||
case rect.height <= 1:
|
||||
m.revealPanel(rect.panel)
|
||||
case y-rect.top != 1:
|
||||
|
|
|
|||
|
|
@ -230,3 +230,45 @@ func TestScrollbarHitTestFollowsPanelState(t *testing.T) {
|
|||
t.Fatalf("collapsed panel still reports a scrollbar")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSidebarFitsShortTerminal(t *testing.T) {
|
||||
m := panelsModel(t)
|
||||
m.height = 19
|
||||
m.snapshot.Connections = m.snapshot.Connections[:1]
|
||||
m.resizeViewport()
|
||||
_, sidebarWidth, _, _ := m.layout()
|
||||
rects := m.sidebarPanels()
|
||||
last := rects[len(rects)-1]
|
||||
if last.top+last.height > m.height {
|
||||
t.Fatalf("panels run past the screen: %+v (height %d)", rects, m.height)
|
||||
}
|
||||
if got := lipgloss.Height(m.sidebarView(sidebarWidth, m.height)); got > m.height {
|
||||
t.Fatalf("sidebar renders %d rows on a %d-row terminal", got, m.height)
|
||||
}
|
||||
squeezed, ok := m.panelAt(last.top)
|
||||
if !ok || squeezed.panel != panelStats || squeezed.height != 1 {
|
||||
t.Fatalf("expected the stats panel squeezed to its header, got %+v", squeezed)
|
||||
}
|
||||
m = click(t, m, m.width-6, last.top)
|
||||
if m.zoomedPanel != panelStats {
|
||||
t.Fatalf("clicking a squeezed header should zoom it, zoomed=%v", m.zoomedPanel)
|
||||
}
|
||||
statsHeight, _, _, _ := m.sidebarHeights()
|
||||
if statsHeight < 4 {
|
||||
t.Fatalf("zoomed stats panel still has no room: %d", statsHeight)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStatsPanelKeepsAssignedHeight(t *testing.T) {
|
||||
m := panelsModel(t)
|
||||
m.snapshot.Model = strings.Repeat("openrouter/some-vendor/a-very-long-model-name ", 12)
|
||||
m.resizeViewport()
|
||||
_, sidebarWidth, _, _ := m.layout()
|
||||
statsHeight, _, _, _ := m.sidebarHeights()
|
||||
if statsHeight != 15 {
|
||||
t.Fatalf("stats panel should hit its cap, got %d", statsHeight)
|
||||
}
|
||||
if got := lipgloss.Height(m.sidebarView(sidebarWidth, m.height)); got != m.height {
|
||||
t.Fatalf("sidebar renders %d rows, want %d", got, m.height)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -582,7 +582,7 @@ func (m Model) sidebarView(width, height int) string {
|
|||
}
|
||||
stats := ""
|
||||
if statsHeight > 1 {
|
||||
stats = m.statsView()
|
||||
stats = fixedPanelBody(lipgloss.NewStyle().Width(width-4).Render(m.statsView()), width-4, statsHeight-3)
|
||||
}
|
||||
parts = append(parts, m.panelBox(panelStats, stats, width, statsHeight, false))
|
||||
return lipgloss.JoinVertical(lipgloss.Left, parts...)
|
||||
|
|
@ -603,7 +603,25 @@ func (m Model) sidebarHeights() (statsHeight, vulnHeight, mcpHeight, agentHeight
|
|||
if len(m.snapshot.Connections) > 0 {
|
||||
mcpHeight = m.panelHeight(panelMcp, min(9, len(m.snapshot.Connections)+3))
|
||||
}
|
||||
agentHeight = m.panelHeight(panelAgents, 3)
|
||||
agentHeight = m.panelHeight(panelAgents, 4)
|
||||
squeezable := []*int{&statsHeight, &mcpHeight, &vulnHeight}
|
||||
for _, h := range squeezable {
|
||||
over := m.viewerHeight() + statsHeight + vulnHeight + mcpHeight + agentHeight - m.height
|
||||
if over <= 0 {
|
||||
break
|
||||
}
|
||||
if *h > 4 {
|
||||
*h -= min(over, *h-4)
|
||||
}
|
||||
}
|
||||
for _, h := range squeezable {
|
||||
if m.viewerHeight()+statsHeight+vulnHeight+mcpHeight+agentHeight <= m.height {
|
||||
break
|
||||
}
|
||||
if *h > 1 {
|
||||
*h = 1
|
||||
}
|
||||
}
|
||||
spare := max(0, m.height-m.viewerHeight()-statsHeight-vulnHeight-mcpHeight-agentHeight)
|
||||
switch {
|
||||
case m.zoomedPanel == panelFindings && vulnHeight > 1:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue