Skip to content

Unify TUI windowing on pane.Window, drop the dashboard scrollWindow (closes #8)#10

Merged
kinncj merged 3 commits into
mainfrom
refactor/dashboard-panes
Jul 3, 2026
Merged

Unify TUI windowing on pane.Window, drop the dashboard scrollWindow (closes #8)#10
kinncj merged 3 commits into
mainfrom
refactor/dashboard-panes

Conversation

@kinncj

@kinncj kinncj commented Jul 3, 2026

Copy link
Copy Markdown
Owner

Closes #8.

What

The dashboard modals + detail view carried their own scrollWindow/keepSelVisible, a duplicate of the windowing the pane package already does. This routes them through a single shared pane.Window, deletes the dashboard copies, and removes the pane's Filterable/Sortable API that had no consumer.

Changes

  • pane.Window(m, lines, offset, sel, height) — one exported windowing routine (clamp + keep-selection-visible + themed ▲/▼ more · y/total affordance). Pane/Group and the dashboard both use it.
  • Dashboard detail.go + modal.go now call pane.Window; scrollWindow and keepSelVisible are deleted. Modals now show the same affordance as the top view.
  • Dropped the pane's Filterable/Sortable interfaces and the /-filter + sort-cycle code — nothing consumed them (the dashboard's own filter/sort idiom won). Recoverable from history if a future full-pane migration wants it.
  • The fleet-grid list keeps its own cursor-centering window (different behaviour — out of scope).

Not changed

No user-facing behaviour. Log/command/process filters and top sort work exactly as before.

Tests

  • New pane.Window tests (fit, overflow affordances, selection-stays-visible invariant).
  • Detail view verified via headless snapshot (affordance renders as ▼ more · 8/18).
  • Full suite green: 303 tests, go vet clean.

Copilot AI review requested due to automatic review settings July 3, 2026 15:44
@kinncj kinncj merged commit 0ee0fad into main Jul 3, 2026
13 checks passed
@kinncj kinncj deleted the refactor/dashboard-panes branch July 3, 2026 15:48

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR consolidates TUI viewport/windowing behavior by introducing a shared pane.Window helper and routing the dashboard modal/detail scrolling through it, while also removing the previously-unused Filterable/Sortable pane APIs.

Changes:

  • Added pane.Window(mode, lines, offset, sel, height) as a shared windowing routine with themed overflow affordances.
  • Updated dashboard modal + detail rendering to use pane.Window and deleted the dashboard’s duplicate scrollWindow/keepSelVisible helpers (and their dedicated test).
  • Removed unused pane filter/sort interfaces and related state/logic from pane.Pane, and trimmed associated tests.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
CHANGELOG.md Documents the Unreleased change to modal/detail scrolling + API removals.
app/internal/tui/pane/window.go Introduces the shared exported windowing helper and affordance rendering.
app/internal/tui/pane/window_test.go Adds unit tests for the new shared windowing helper.
app/internal/tui/pane/pane.go Removes filter/sort APIs and updates affordance rendering; still contains its own windowing path.
app/internal/tui/pane/pane_test.go Removes tests tied to the dropped filter/sort behavior and simplifies fake sources.
app/internal/tui/dashboard/modal.go Routes modal body windowing through pane.Window and deletes local helpers.
app/internal/tui/dashboard/detail.go Routes detail-body windowing through pane.Window.
app/internal/tui/dashboard/modal_selection_test.go Deletes tests for removed dashboard keepSelVisible helper.

Comment on lines +18 to +42
total := len(lines)
if height < 1 {
height = 1
}
if total <= height {
return append([]string(nil), lines...), 0
}
// Keep the selection clear of the row an affordance will overwrite, so the
// cursor never hides under a "▲/▼ more" marker.
if sel >= 0 {
if sel <= offset {
offset = sel - 1
} else if sel >= offset+height-1 {
offset = sel - height + 2
}
}
offset = clampOffset(offset, total, height)
out := append([]string(nil), lines[offset:offset+height]...)
if offset > 0 {
out[0] = affordanceLine(m, offset+1, total, true)
}
if offset+height < total {
out[len(out)-1] = affordanceLine(m, offset+height, total, false)
}
return out, offset
Comment on lines 11 to 15
// affordances. Capabilities are opt-in interfaces so a static panel gets neither
// filter nor sort.
package pane

import (
Comment thread CHANGELOG.md
and the dashboard's duplicate `scrollWindow`/`keepSelVisible` are gone — one windowing
implementation for the whole TUI, so the modals show the same `▲/▼ more · y/total`
affordance as the top view. The pane's unused `Filterable`/`Sortable` API was dropped;
the dashboard keeps its own filter/sort idiom. No user-facing change (closes #8).
t.Fatalf("sel %d sits on the bottom ▼more row (off=%d)", sel, off)
}
}
}
Comment on lines 242 to 246
out := append([]string(nil), lines[offset:offset+height]...)
out = p.markCursor(m, out, offset)
if offset > 0 {
out[0] = p.affordance(m, offset, offset+1, total, true)
out[0] = affordanceLine(m, offset+1, total, true)
}
kinncj added a commit that referenced this pull request Jul 3, 2026
)

Fix the height==1 edge-overwrite bug (viewports <3 rows now show content, not a lone marker), route Pane.window through the shared Window so the cursor is never overwritten at a scrolled edge, and fix stale docs. Addresses the #10 review.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate dashboard modal bodies onto pane.Group (delete the 2nd scrollWindow)

2 participants