From fbb81ffb40c6a3ad3f44a22632567a0cf0520ab7 Mon Sep 17 00:00:00 2001 From: proxyctl coordinator Date: Fri, 17 Jul 2026 20:48:58 +0800 Subject: [PATCH] chore: complete Operations Console ticket --- .../issues/02-operations-console-dashboard.md | 26 +++++++++---------- internal/tui/dashboard_view.go | 3 +-- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/.scratch/tui-redesign/issues/02-operations-console-dashboard.md b/.scratch/tui-redesign/issues/02-operations-console-dashboard.md index 8f6bc71..5b2e3fe 100644 --- a/.scratch/tui-redesign/issues/02-operations-console-dashboard.md +++ b/.scratch/tui-redesign/issues/02-operations-console-dashboard.md @@ -4,17 +4,17 @@ **Blocked by:** 01 — Build the responsive TUI foundation. -**Status:** ready-for-agent +**Status:** done -- [ ] The header shows a compact proxyctl identity, the Active Profile, and counts for the current Target states. -- [ ] Available Targets appear in stable product order by default. -- [ ] A contextual action reveals unavailable Targets and their detection evidence without changing product order. -- [ ] Each Target row combines a standard Unicode/ASCII-safe symbol, explicit state text, and semantic styling. -- [ ] The selected Target details prioritize state, evidence, affected scope, permissions, ownership/restoration implications, and restart risk. -- [ ] Wide terminals show Target list and details panes side by side; narrow terminals stack the same regions. -- [ ] Tab changes pane focus, the focused pane is visible without relying only on color, and arrows navigate within the focused pane. -- [ ] Long Target lists and details remain reachable through list/viewport scrolling. -- [ ] The footer shows only actions valid for the current focus and state. -- [ ] Resizing preserves selection by Target identity rather than fragile row position. -- [ ] Complete-Model tests cover every Target state, unavailable visibility, long content, focus, scrolling, and wide/narrow rendering. -- [ ] Production rendering is rewritten from the spec; prototype branch `prototype/tui-operations-console` commit `364f28d` is reference material only and is not copied into production. +- [x] The header shows a compact proxyctl identity, the Active Profile, and counts for the current Target states. +- [x] Available Targets appear in stable product order by default. +- [x] A contextual action reveals unavailable Targets and their detection evidence without changing product order. +- [x] Each Target row combines a standard Unicode/ASCII-safe symbol, explicit state text, and semantic styling. +- [x] The selected Target details prioritize state, evidence, affected scope, permissions, ownership/restoration implications, and restart risk. +- [x] Wide terminals show Target list and details panes side by side; narrow terminals stack the same regions. +- [x] Tab changes pane focus, the focused pane is visible without relying only on color, and arrows navigate within the focused pane. +- [x] Long Target lists and details remain reachable through list/viewport scrolling. +- [x] The footer shows only actions valid for the current focus and state. +- [x] Resizing preserves selection by Target identity rather than fragile row position. +- [x] Complete-Model tests cover every Target state, unavailable visibility, long content, focus, scrolling, and wide/narrow rendering. +- [x] Production rendering is rewritten from the spec; prototype branch `prototype/tui-operations-console` commit `364f28d` is reference material only and is not copied into production. diff --git a/internal/tui/dashboard_view.go b/internal/tui/dashboard_view.go index cd2f080..1221699 100644 --- a/internal/tui/dashboard_view.go +++ b/internal/tui/dashboard_view.go @@ -46,7 +46,7 @@ func (p terminalPresentation) renderTargetListPane(state dashboardRenderState, w bodyHeight := max(1, height-2) lines := make([]string, 0, len(state.catalog.items)) selectedIndex := state.catalog.index(state.selectedTargetID) - for i, item := range state.catalog.items { + for _, item := range state.catalog.items { cursor := " " if item.ID == state.selectedTargetID { cursor = "> " @@ -55,7 +55,6 @@ func (p terminalPresentation) renderTargetListPane(state dashboardRenderState, w (!state.profileTransition && state.progressTarget == "" && state.applying && item.ID == state.selectedTargetID) badge := p.targetBadge(item, applying) lines = append(lines, cursor+badge+" "+item.Description.Name) - _ = i } if len(lines) == 0 { lines = append(lines, "No Targets are currently Available.")