summaryrefslogtreecommitdiff
path: root/internal/tui/common
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-03-09 23:01:38 +0200
committerPaul Buetow <paul@buetow.org>2026-03-09 23:01:38 +0200
commit227de0db390fec4e1327a7cab6be4c1268848695 (patch)
treef70ff9f3b23db47db0e0aeafa1bb1aad5abc71a8 /internal/tui/common
parentbcaa22111ac619e317f7adfd60a1fc6bd4db8d29 (diff)
tui: add reverse sorting for dashboard tables (task 364)
Diffstat (limited to 'internal/tui/common')
-rw-r--r--internal/tui/common/keys.go98
-rw-r--r--internal/tui/common/keys_test.go23
2 files changed, 74 insertions, 47 deletions
diff --git a/internal/tui/common/keys.go b/internal/tui/common/keys.go
index 87edec4..2e54a6d 100644
--- a/internal/tui/common/keys.go
+++ b/internal/tui/common/keys.go
@@ -10,29 +10,30 @@ type HelpSection struct {
// KeyMap groups all key bindings shared by TUI screens.
type KeyMap struct {
- Tab key.Binding
- ShiftTab key.Binding
- One key.Binding
- Two key.Binding
- Three key.Binding
- Four key.Binding
- Five key.Binding
- Six key.Binding
- Seven key.Binding
- Visualize key.Binding
- Metric key.Binding
- Sort key.Binding
- DirGroup key.Binding
- SelectPID key.Binding
- SelectTID key.Binding
- Probes key.Binding
- Filter key.Binding
- FilterUndo key.Binding
- Export key.Binding
- Quit key.Binding
- Enter key.Binding
- Esc key.Binding
- Refresh key.Binding
+ Tab key.Binding
+ ShiftTab key.Binding
+ One key.Binding
+ Two key.Binding
+ Three key.Binding
+ Four key.Binding
+ Five key.Binding
+ Six key.Binding
+ Seven key.Binding
+ Visualize key.Binding
+ Metric key.Binding
+ Sort key.Binding
+ ReverseSort key.Binding
+ DirGroup key.Binding
+ SelectPID key.Binding
+ SelectTID key.Binding
+ Probes key.Binding
+ Filter key.Binding
+ FilterUndo key.Binding
+ Export key.Binding
+ Quit key.Binding
+ Enter key.Binding
+ Esc key.Binding
+ Refresh key.Binding
}
// Keys contains the default shared key map.
@@ -41,29 +42,30 @@ var Keys = DefaultKeyMap()
// DefaultKeyMap builds the default key bindings used by models.
func DefaultKeyMap() KeyMap {
return KeyMap{
- Tab: key.NewBinding(key.WithKeys("tab"), key.WithHelp("tab", "next tab")),
- ShiftTab: key.NewBinding(key.WithKeys("shift+tab"), key.WithHelp("shift+tab", "prev tab")),
- One: key.NewBinding(key.WithKeys("1"), key.WithHelp("1", "flame")),
- Two: key.NewBinding(key.WithKeys("2"), key.WithHelp("2", "overview")),
- Three: key.NewBinding(key.WithKeys("3"), key.WithHelp("3", "syscalls")),
- Four: key.NewBinding(key.WithKeys("4"), key.WithHelp("4", "files")),
- Five: key.NewBinding(key.WithKeys("5"), key.WithHelp("5", "processes")),
- Six: key.NewBinding(key.WithKeys("6"), key.WithHelp("6", "lat+gaps")),
- Seven: key.NewBinding(key.WithKeys("7"), key.WithHelp("7", "stream")),
- Visualize: key.NewBinding(key.WithKeys("v"), key.WithHelp("v", "viz")),
- Metric: key.NewBinding(key.WithKeys("b"), key.WithHelp("b", "metric")),
- Sort: key.NewBinding(key.WithKeys("s"), key.WithHelp("s", "sort table")),
- DirGroup: key.NewBinding(key.WithKeys("d"), key.WithHelp("d", "dir group")),
- SelectPID: key.NewBinding(key.WithKeys("p"), key.WithHelp("p", "select pid")),
- SelectTID: key.NewBinding(key.WithKeys("t"), key.WithHelp("t", "select tid")),
- Probes: key.NewBinding(key.WithKeys("o"), key.WithHelp("o", "probes")),
- Filter: key.NewBinding(key.WithKeys("f"), key.WithHelp("f", "filter")),
- FilterUndo: key.NewBinding(key.WithKeys("F"), key.WithHelp("F", "undo filter")),
- Export: key.NewBinding(key.WithKeys("e"), key.WithHelp("e", "stream export")),
- Quit: key.NewBinding(key.WithKeys("q", "ctrl+c"), key.WithHelp("q", "quit")),
- Enter: key.NewBinding(key.WithKeys("enter"), key.WithHelp("enter", "select")),
- Esc: key.NewBinding(key.WithKeys("esc"), key.WithHelp("esc", "back")),
- Refresh: key.NewBinding(key.WithKeys("r"), key.WithHelp("r", "reset baseline")),
+ Tab: key.NewBinding(key.WithKeys("tab"), key.WithHelp("tab", "next tab")),
+ ShiftTab: key.NewBinding(key.WithKeys("shift+tab"), key.WithHelp("shift+tab", "prev tab")),
+ One: key.NewBinding(key.WithKeys("1"), key.WithHelp("1", "flame")),
+ Two: key.NewBinding(key.WithKeys("2"), key.WithHelp("2", "overview")),
+ Three: key.NewBinding(key.WithKeys("3"), key.WithHelp("3", "syscalls")),
+ Four: key.NewBinding(key.WithKeys("4"), key.WithHelp("4", "files")),
+ Five: key.NewBinding(key.WithKeys("5"), key.WithHelp("5", "processes")),
+ Six: key.NewBinding(key.WithKeys("6"), key.WithHelp("6", "lat+gaps")),
+ Seven: key.NewBinding(key.WithKeys("7"), key.WithHelp("7", "stream")),
+ Visualize: key.NewBinding(key.WithKeys("v"), key.WithHelp("v", "viz")),
+ Metric: key.NewBinding(key.WithKeys("b"), key.WithHelp("b", "metric")),
+ Sort: key.NewBinding(key.WithKeys("s"), key.WithHelp("s", "sort table")),
+ ReverseSort: key.NewBinding(key.WithKeys("S"), key.WithHelp("S", "reverse sort")),
+ DirGroup: key.NewBinding(key.WithKeys("d"), key.WithHelp("d", "dir group")),
+ SelectPID: key.NewBinding(key.WithKeys("p"), key.WithHelp("p", "select pid")),
+ SelectTID: key.NewBinding(key.WithKeys("t"), key.WithHelp("t", "select tid")),
+ Probes: key.NewBinding(key.WithKeys("o"), key.WithHelp("o", "probes")),
+ Filter: key.NewBinding(key.WithKeys("f"), key.WithHelp("f", "filter")),
+ FilterUndo: key.NewBinding(key.WithKeys("F"), key.WithHelp("F", "undo filter")),
+ Export: key.NewBinding(key.WithKeys("e"), key.WithHelp("e", "stream export")),
+ Quit: key.NewBinding(key.WithKeys("q", "ctrl+c"), key.WithHelp("q", "quit")),
+ Enter: key.NewBinding(key.WithKeys("enter"), key.WithHelp("enter", "select")),
+ Esc: key.NewBinding(key.WithKeys("esc"), key.WithHelp("esc", "back")),
+ Refresh: key.NewBinding(key.WithKeys("r"), key.WithHelp("r", "reset baseline")),
}
}
@@ -97,6 +99,7 @@ func (k KeyMap) DashboardStatusHelpSections() []HelpSection {
k.Visualize,
k.Metric,
k.Sort,
+ k.ReverseSort,
k.Filter,
k.FilterUndo,
k.SelectPID,
@@ -113,6 +116,7 @@ func (k KeyMap) DashboardStatusHelpSections() []HelpSection {
k.Visualize,
k.Metric,
k.Sort,
+ k.ReverseSort,
helpTextBinding("space", "stream pause"),
helpTextBinding("enter", "selected filter"),
helpTextBinding("esc", "stream undo filter"),
@@ -142,7 +146,7 @@ func (k KeyMap) DashboardFullHelp() [][]key.Binding {
controls = append(controls, k.Export)
}
controls = append(controls, k.DirGroup, k.SelectPID, k.SelectTID, k.Probes, k.Refresh, k.Quit)
- controls = append(controls, k.Visualize, k.Metric, k.Sort, k.Filter, k.FilterUndo)
+ controls = append(controls, k.Visualize, k.Metric, k.Sort, k.ReverseSort, k.Filter, k.FilterUndo)
return [][]key.Binding{
{k.One, k.Two, k.Three, k.Four, k.Five, k.Six, k.Seven},
diff --git a/internal/tui/common/keys_test.go b/internal/tui/common/keys_test.go
index 8d34285..2c48603 100644
--- a/internal/tui/common/keys_test.go
+++ b/internal/tui/common/keys_test.go
@@ -43,6 +43,10 @@ func TestDefaultKeyMapIncludesDirGroupBinding(t *testing.T) {
if sortHelp.Key != "s" || sortHelp.Desc != "sort table" {
t.Fatalf("unexpected sort binding help: key=%q desc=%q", sortHelp.Key, sortHelp.Desc)
}
+ reverseSortHelp := keys.ReverseSort.Help()
+ if reverseSortHelp.Key != "S" || reverseSortHelp.Desc != "reverse sort" {
+ t.Fatalf("unexpected reverse sort binding help: key=%q desc=%q", reverseSortHelp.Key, reverseSortHelp.Desc)
+ }
undoHelp := keys.FilterUndo.Help()
if undoHelp.Key != "F" || undoHelp.Desc != "undo filter" {
@@ -156,6 +160,18 @@ func TestDashboardFullHelpIncludesDirGroupBinding(t *testing.T) {
found = false
for _, binding := range groups[1] {
help := binding.Help()
+ if help.Key == "S" && help.Desc == "reverse sort" {
+ found = true
+ break
+ }
+ }
+ if !found {
+ t.Fatalf("expected reverse sort binding in dashboard full help controls")
+ }
+
+ found = false
+ for _, binding := range groups[1] {
+ help := binding.Help()
if help.Key == "F" && help.Desc == "undo filter" {
found = true
break
@@ -174,6 +190,7 @@ func TestDashboardStatusHelpIncludesProbesBinding(t *testing.T) {
foundOne := false
foundUndo := false
foundSort := false
+ foundReverseSort := false
for _, binding := range short {
help := binding.Help()
if help.Key == "o" && help.Desc == "probes" {
@@ -191,6 +208,9 @@ func TestDashboardStatusHelpIncludesProbesBinding(t *testing.T) {
if help.Key == "s" && help.Desc == "sort table" {
foundSort = true
}
+ if help.Key == "S" && help.Desc == "reverse sort" {
+ foundReverseSort = true
+ }
}
if !found {
t.Fatalf("expected probes binding in dashboard short help")
@@ -207,4 +227,7 @@ func TestDashboardStatusHelpIncludesProbesBinding(t *testing.T) {
if !foundSort {
t.Fatalf("expected sort binding in dashboard short help")
}
+ if !foundReverseSort {
+ t.Fatalf("expected reverse sort binding in dashboard short help")
+ }
}