diff options
| author | Paul Buetow <paul@buetow.org> | 2026-02-24 17:27:10 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-02-24 17:27:10 +0200 |
| commit | da8ddf1cf415f1754c3fe71f3f342327ad00e91e (patch) | |
| tree | af3ba70015cf7db4bfd3a2adcb9334417740e4f3 /internal/tui | |
| parent | 2ae0b33c9f196634eaa55bd6997d1feae9147385 (diff) | |
tui: add toggle to disable snapshot export file writes
Diffstat (limited to 'internal/tui')
| -rw-r--r-- | internal/tui/common/keys.go | 15 | ||||
| -rw-r--r-- | internal/tui/tui.go | 13 | ||||
| -rw-r--r-- | internal/tui/tui_test.go | 37 |
3 files changed, 60 insertions, 5 deletions
diff --git a/internal/tui/common/keys.go b/internal/tui/common/keys.go index 0f9c54d..1111def 100644 --- a/internal/tui/common/keys.go +++ b/internal/tui/common/keys.go @@ -45,14 +45,25 @@ func DefaultKeyMap() KeyMap { // DashboardShortHelp returns compact bindings for dashboard help bars. func (k KeyMap) DashboardShortHelp() []key.Binding { - return []key.Binding{k.Tab, k.ShiftTab, k.Export, k.Help, k.Quit} + bindings := []key.Binding{k.Tab, k.ShiftTab} + if help := k.Export.Help(); help.Key != "" || help.Desc != "" { + bindings = append(bindings, k.Export) + } + bindings = append(bindings, k.Help, k.Quit) + return bindings } // DashboardFullHelp returns grouped bindings for dashboard overlays. func (k KeyMap) DashboardFullHelp() [][]key.Binding { + controls := []key.Binding{k.Tab, k.ShiftTab} + if help := k.Export.Help(); help.Key != "" || help.Desc != "" { + controls = append(controls, k.Export) + } + controls = append(controls, k.Refresh, k.Help, k.Quit) + return [][]key.Binding{ {k.One, k.Two, k.Three, k.Four, k.Five, k.Six}, - {k.Tab, k.ShiftTab, k.Export, k.Refresh, k.Help, k.Quit}, + controls, { key.NewBinding(key.WithKeys("left/right"), key.WithHelp("left/right", "tab")), key.NewBinding(key.WithKeys("h/l"), key.WithHelp("h/l", "tab")), diff --git a/internal/tui/tui.go b/internal/tui/tui.go index 143cf02..4433172 100644 --- a/internal/tui/tui.go +++ b/internal/tui/tui.go @@ -99,13 +99,17 @@ func NewModel(initialPID int, startTrace TraceStarter) Model { if startTrace == nil { startTrace = defaultTraceStarter } + keys := Keys + if !flags.Get().TUIExportEnable { + keys.Export = key.NewBinding() + } model := Model{ screen: ScreenPIDPicker, pidPicker: pidpicker.New(), - dashboard: dashboardui.NewModel(lateBoundDashboardSource{}), + dashboard: dashboardui.NewModelWithConfig(lateBoundDashboardSource{}, 1000, keys), exporter: tuiexport.NewModel(), - keys: Keys, + keys: keys, spin: spin, startTrace: startTrace, } @@ -151,7 +155,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { if !m.exporter.Visible() && m.showHelp { return m, nil } - if m.screen == ScreenDashboard && !m.attaching && m.lastErr == nil && key.Matches(msg, m.keys.Export) && !m.exporter.Visible() { + if flags.Get().TUIExportEnable && m.screen == ScreenDashboard && !m.attaching && m.lastErr == nil && key.Matches(msg, m.keys.Export) && !m.exporter.Visible() { m.exporter = m.exporter.Open() return m, nil } @@ -299,6 +303,9 @@ func (m Model) View() string { func runExportCmd(option tuiexport.Option, snap *statsengine.Snapshot) tea.Cmd { return func() tea.Msg { + if !flags.Get().TUIExportEnable { + return tuiexport.FailedMsg{Err: errors.New("tui export is disabled by -tuiExport=false")} + } switch option { case tuiexport.OptionCSV: path, err := exportSnapshotCSV(snap) diff --git a/internal/tui/tui_test.go b/internal/tui/tui_test.go index fd7adfa..e69ff9b 100644 --- a/internal/tui/tui_test.go +++ b/internal/tui/tui_test.go @@ -192,6 +192,9 @@ func TestDashboardRefreshPicksLateBoundSource(t *testing.T) { } func TestExportKeyOpensModalOnDashboard(t *testing.T) { + flags.SetTUIExportEnable(true) + t.Cleanup(func() { flags.SetTUIExportEnable(true) }) + m := NewModel(-1, func(context.Context) error { return nil }) m.screen = ScreenDashboard m.attaching = false @@ -203,6 +206,21 @@ func TestExportKeyOpensModalOnDashboard(t *testing.T) { } } +func TestExportKeyIgnoredWhenExportDisabled(t *testing.T) { + flags.SetTUIExportEnable(false) + t.Cleanup(func() { flags.SetTUIExportEnable(true) }) + + m := NewModel(-1, func(context.Context) error { return nil }) + m.screen = ScreenDashboard + m.attaching = false + + next, _ := m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'e'}}) + updated := next.(Model) + if updated.exporter.Visible() { + t.Fatalf("expected export modal to remain closed when export is disabled") + } +} + func TestRunExportCmdCSVWritesFile(t *testing.T) { dir := t.TempDir() prev, err := os.Getwd() @@ -292,6 +310,9 @@ func TestHelpOverlayUsesPickerBindingsOnPickerScreen(t *testing.T) { } func TestHelpToggleDoesNotBreakExportModalInput(t *testing.T) { + flags.SetTUIExportEnable(true) + t.Cleanup(func() { flags.SetTUIExportEnable(true) }) + m := NewModel(-1, func(context.Context) error { return nil }) m.screen = ScreenDashboard @@ -314,6 +335,22 @@ func TestHelpToggleDoesNotBreakExportModalInput(t *testing.T) { } } +func TestHelpOverlayHidesExportBindingWhenExportDisabled(t *testing.T) { + flags.SetTUIExportEnable(false) + t.Cleanup(func() { flags.SetTUIExportEnable(true) }) + + m := NewModel(-1, func(context.Context) error { return nil }) + m.screen = ScreenDashboard + m.showHelp = true + m.width = 100 + m.height = 30 + + out := m.View() + if strings.Contains(out, "e export") { + t.Fatalf("did not expect export shortcut in help overlay when export is disabled") + } +} + func TestExportModalStillAllowsDashboardStatsUpdates(t *testing.T) { m := NewModel(-1, func(context.Context) error { return nil }) m.screen = ScreenDashboard |
