Skip to content

Commit e429eab

Browse files
authored
fix(datagrid): drive Cmd+F filter toggle from tab context and the View menu (#1360)
* fix(datagrid): drive Cmd+F filter toggle from tab context and the View menu * refactor(datagrid): extract Cmd+F route into a testable type
1 parent ff967c8 commit e429eab

6 files changed

Lines changed: 65 additions & 13 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1616
### Changed
1717

1818
- `Cmd+C` now copies the focused cell value when one row is selected and a cell has focus; with multiple rows selected, or when no cell is focused, it still copies row(s) as TSV. `Cmd+Shift+C` now always copies row(s) as TSV. "Copy with Headers" stays in the Edit menu and row context menu without a default shortcut (#1332)
19-
- `Cmd+F` toggles the data-grid filter panel when the grid is focused; the SQL editor's Find panel still opens with `Cmd+F` when the editor is focused. The old `Cmd+Shift+F` shortcut for filters is removed
19+
- `Cmd+F` toggles the filter panel when viewing a table, and opens the Find panel in the SQL editor. The old `Cmd+Shift+F` shortcut for filters is removed
2020

2121
### Fixed
2222

TablePro/Models/UI/KeyboardShortcutModels.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,7 @@ struct KeyboardSettings: Codable, Equatable {
499499
// View
500500
.toggleTableBrowser: KeyCombo(key: "0", command: true),
501501
.toggleInspector: KeyCombo(key: "i", command: true, option: true),
502+
.toggleFilters: KeyCombo(key: "f", command: true),
502503
.toggleHistory: KeyCombo(key: "y", command: true),
503504
.toggleResults: KeyCombo(key: "r", command: true, option: true),
504505
.previousResultTab: KeyCombo(key: "[", command: true, option: true),

TablePro/TableProApp.swift

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,23 @@ struct PasteboardCommands: Commands {
106106

107107
// MARK: - App Menu Commands
108108

109+
/// Where `Cmd+F` resolves in the current context. The data-grid filter lives in
110+
/// the View menu and the editor's Find lives in the Edit menu. Only the item
111+
/// matching the current route binds `Cmd+F`; the other drops it. Two items
112+
/// sharing one key equivalent makes SwiftUI dedupe the shortcut and AppKit bind
113+
/// it to the disabled item, so the live owner must be unique.
114+
enum CommandFRoute {
115+
case inspectorFilter
116+
case tableFilter
117+
case editorFind
118+
119+
static func resolve(isInspector: Bool, isTableTab: Bool) -> CommandFRoute {
120+
if isInspector { return .inspectorFilter }
121+
if isTableTab { return .tableFilter }
122+
return .editorFind
123+
}
124+
}
125+
109126
/// All menu commands extracted into a separate Commands struct so that AppState
110127
/// changes only re-evaluate the menu items — NOT the Scene body / WindowGroups.
111128
struct AppMenuCommands: Commands {
@@ -152,6 +169,10 @@ struct AppMenuCommands: Commands {
152169
NSApp.keyWindow?.windowController is InspectorWindowController
153170
}
154171

172+
private var commandFRoute: CommandFRoute {
173+
CommandFRoute.resolve(isInspector: keyWindowIsInspector, isTableTab: actions?.isTableTab == true)
174+
}
175+
155176
var body: some Commands {
156177
// Custom About window + Check for Updates + MCP status
157178
CommandGroup(replacing: .appInfo) {
@@ -468,16 +489,17 @@ struct AppMenuCommands: Commands {
468489
Divider()
469490

470491
Button(String(localized: "Find...")) {
471-
if keyWindowIsInspector {
492+
switch commandFRoute {
493+
case .inspectorFilter:
472494
NSApp.sendAction(#selector(InspectorViewController.toggleInspectorFilter(_:)), to: nil, from: nil)
473-
} else if NSApp.keyWindow?.firstResponder is KeyHandlingTableView,
474-
actions?.isTableTab == true {
475-
actions?.toggleFilterPanel()
476-
} else {
495+
case .editorFind:
477496
EditorEventRouter.shared.showFindPanelForKeyWindow()
497+
case .tableFilter:
498+
break
478499
}
479500
}
480-
.keyboardShortcut("f", modifiers: .command)
501+
.optionalKeyboardShortcut(commandFRoute == .tableFilter ? nil : KeyboardShortcut("f", modifiers: .command))
502+
.disabled(commandFRoute == .tableFilter)
481503

482504
Divider()
483505

@@ -521,8 +543,8 @@ struct AppMenuCommands: Commands {
521543
Button("Toggle Filters") {
522544
actions?.toggleFilterPanel()
523545
}
524-
.optionalKeyboardShortcut(shortcut(for: .toggleFilters))
525-
.disabled(!(actions?.isConnected ?? false) || !(actions?.isTableTab ?? false))
546+
.optionalKeyboardShortcut(commandFRoute == .tableFilter ? shortcut(for: .toggleFilters) : nil)
547+
.disabled(commandFRoute != .tableFilter || !(actions?.isConnected ?? false))
526548

527549
Button("Toggle History") {
528550
actions?.toggleHistoryPanel()
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//
2+
// CommandFRouteTests.swift
3+
// TableProTests
4+
//
5+
// Tests for CommandFRoute, which decides where Cmd+F resolves so exactly one
6+
// menu item owns the shortcut per context.
7+
//
8+
9+
@testable import TablePro
10+
import Testing
11+
12+
@Suite("CommandFRouteTests")
13+
struct CommandFRouteTests {
14+
@Test("Inspector window takes priority over tab type")
15+
func inspectorWins() {
16+
#expect(CommandFRoute.resolve(isInspector: true, isTableTab: true) == .inspectorFilter)
17+
#expect(CommandFRoute.resolve(isInspector: true, isTableTab: false) == .inspectorFilter)
18+
}
19+
20+
@Test("Table tab routes to the View-menu filter toggle")
21+
func tableTabFilters() {
22+
#expect(CommandFRoute.resolve(isInspector: false, isTableTab: true) == .tableFilter)
23+
}
24+
25+
@Test("Everything else routes to the editor Find panel")
26+
func otherwiseFinds() {
27+
#expect(CommandFRoute.resolve(isInspector: false, isTableTab: false) == .editorFind)
28+
}
29+
}

docs/features/filtering.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description: Filter table data with 18 operators, raw SQL, and saved presets
55

66
# Filtering
77

8-
Press `Cmd+F` with the data grid focused to open the filter panel. Type a raw SQL WHERE clause and press `Enter` to filter. Raw SQL is the default mode.
8+
Press `Cmd+F` while viewing a table to open the filter panel. Type a raw SQL WHERE clause and press `Enter` to filter. Raw SQL is the default mode.
99

1010
Each row has a column picker, operator, value field, and **+**/**** buttons. Multiple rows combine with **AND** or **OR** (toggle in the header). Click **Apply** or press `Enter` to activate. Click **Unset** to clear all.
1111

docs/features/keyboard-shortcuts.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ TablePro is keyboard-driven. Most actions have shortcuts, and most menu shortcut
7171

7272
| Action | Shortcut |
7373
|--------|----------|
74-
| Find (SQL editor focused) | `Cmd+F` |
74+
| Find (in SQL editor) | `Cmd+F` |
7575
| Find and replace | `Cmd+Option+F` |
7676
| Find next | `Cmd+G` |
7777
| Find previous | `Cmd+Shift+G` |
@@ -151,7 +151,7 @@ Inherits the standard `NSDocument` shortcuts.
151151
| Save | `Cmd+S` |
152152
| Save As | `Cmd+Shift+S` |
153153
| Revert to Saved | `Cmd+Option+S` |
154-
| Toggle filter bar | `Cmd+F` |
154+
| Toggle filter panel | `Cmd+F` |
155155
| Copy selected rows as TSV | `Cmd+C` |
156156
| Paste TSV as new rows | `Cmd+V` |
157157
| Add secondary sort column | `Shift+Click` column header |
@@ -255,7 +255,7 @@ Vim keys only apply in the SQL editor. The data grid and other panels keep their
255255

256256
| Action | Shortcut |
257257
|--------|----------|
258-
| Toggle filter panel (data grid focused) | `Cmd+F` |
258+
| Toggle filter panel (table tab) | `Cmd+F` |
259259
| Apply filters | `Enter` (in value field) |
260260

261261
## Table Structure

0 commit comments

Comments
 (0)