Skip to content

Commit fa8a795

Browse files
committed
feat(datagrid): redesign filter panel header and row actions
- Rename 'Unset' -> 'Clear': calls clearAppliedFilters() (keeps rows, returns to unfiltered); old clearFilterState() moved to 'Remove All Filters' in ... menu - Remove per-row Apply/Applied buttons; 'Apply Only This Filter' added to row context menu via rightMouseDown - Tri-state checkbox in header toggles all filter rows enabled/disabled at once
1 parent 947ccb0 commit fa8a795

3 files changed

Lines changed: 61 additions & 25 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1515
### Changed
1616

1717
- Switcher, menus, and alerts now use each database's own container name: Dataset for BigQuery, Keyspace for Cassandra and ScyllaDB. (#509)
18+
- Filter panel header "Unset" renamed to "Clear": it now keeps filter rows in place and only removes the applied state, returning the table to unfiltered results. Use "Remove All Filters" in the filter options menu to discard all filter rows at once.
19+
- Per-row Apply and Applied buttons removed from the filter panel; "Apply Only This Filter" is now in each row's right-click context menu.
20+
- A tri-state checkbox in the filter panel header toggles all filter rows enabled or disabled at once.
1821

1922
### Fixed
2023

TablePro/Views/Filter/FilterPanelView.swift

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,43 @@ struct FilterPanelView: View {
6767
.onPreferenceChange(FilterRowsHeightKey.self) { filterRowsHeight = $0 }
6868
}
6969

70+
private var allFiltersCheckboxImage: String {
71+
switch allFiltersEnabledState {
72+
case true: return "checkmark.square.fill"
73+
case false: return "square"
74+
case .none: return "minus.square.fill"
75+
}
76+
}
77+
78+
private var allFiltersEnabledState: Bool? {
79+
guard !filterState.filters.isEmpty else { return false }
80+
let enabledCount = filterState.filters.count { $0.isEnabled }
81+
if enabledCount == filterState.filters.count { return true }
82+
if enabledCount == 0 { return false }
83+
return nil
84+
}
85+
86+
private func toggleAllFiltersEnabled() {
87+
let allEnabled = filterState.filters.allSatisfy { $0.isEnabled }
88+
let newState = !allEnabled
89+
for filter in filterState.filters {
90+
var updated = filter
91+
updated.isEnabled = newState
92+
coordinator.updateFilter(updated)
93+
}
94+
}
95+
7096
private var filterHeader: some View {
7197
HStack(spacing: 8) {
98+
if !filterState.filters.isEmpty {
99+
Button(action: toggleAllFiltersEnabled) {
100+
Image(systemName: allFiltersCheckboxImage)
101+
.foregroundStyle(.primary)
102+
}
103+
.buttonStyle(.plain)
104+
.help(String(localized: "Enable or disable all filters"))
105+
}
106+
72107
Text("Filters")
73108
.font(.callout.weight(.medium))
74109

@@ -88,15 +123,15 @@ struct FilterPanelView: View {
88123

89124
filterOptionsMenu
90125

91-
Button("Unset") {
92-
coordinator.clearFilterState()
126+
Button("Clear") {
127+
coordinator.clearAppliedFilters()
93128
onUnset()
94129
coordinator.focusActiveGrid()
95130
}
96131
.buttonStyle(.bordered)
97132
.controlSize(.small)
98133
.disabled(!filterState.hasAppliedFilters)
99-
.help(String(localized: "Remove all filters and reload"))
134+
.help(String(localized: "Clear applied filters without removing filter rows"))
100135

101136
Button("Apply") {
102137
applyAllValidFilters()
@@ -172,6 +207,17 @@ struct FilterPanelView: View {
172207

173208
Divider()
174209

210+
Button(role: .destructive) {
211+
coordinator.clearFilterState()
212+
onUnset()
213+
coordinator.focusActiveGrid()
214+
} label: {
215+
Label(String(localized: "Remove All Filters"), systemImage: "xmark.circle")
216+
}
217+
.disabled(filterState.filters.isEmpty)
218+
219+
Divider()
220+
175221
Button {
176222
showSettingsPopover.toggle()
177223
} label: {
@@ -198,7 +244,6 @@ struct FilterPanelView: View {
198244
completions: completionItems(),
199245
enumValuesByColumn: enumValuesByColumn,
200246
rawSQLCompletionProvider: rawSQLCompletionProvider,
201-
isApplied: filterState.commit == .solo(filter.id),
202247
onAdd: {
203248
coordinator.addFilter(columns: columns, primaryKeyColumn: primaryKeyColumn)
204249
focusedFilterId = filterState.filters.last?.id

TablePro/Views/Filter/FilterRowView.swift

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ struct FilterRowView: View {
1111
let completions: [String]
1212
var enumValuesByColumn: [String: [String]] = [:]
1313
var rawSQLCompletionProvider: RawSQLFilterCompletionProvider?
14-
let isApplied: Bool
1514
let onAdd: () -> Void
1615
let onDuplicate: () -> Void
1716
let onRemove: () -> Void
@@ -160,28 +159,8 @@ struct FilterRowView: View {
160159
}
161160
}
162161

163-
@ViewBuilder
164-
private var soloApplyButton: some View {
165-
if isApplied {
166-
Button(String(localized: "Applied"), action: onApply)
167-
.buttonStyle(.borderedProminent)
168-
} else {
169-
Button(String(localized: "Apply"), action: onApply)
170-
.buttonStyle(.bordered)
171-
}
172-
}
173-
174162
private var rowButtons: some View {
175163
HStack(spacing: 4) {
176-
soloApplyButton
177-
.controlSize(.small)
178-
.disabled(!filter.isValid)
179-
.accessibilityLabel(String(localized: "Apply only this filter"))
180-
.accessibilityValue(isApplied ? String(localized: "Applied") : "")
181-
.help(isApplied
182-
? String(localized: "Filtering by only this row")
183-
: String(localized: "Filter by only this row"))
184-
185164
Button(action: onAdd) {
186165
Image(systemName: "plus")
187166
.frame(width: rowButtonGlyphSize, height: rowButtonGlyphSize)
@@ -204,6 +183,15 @@ struct FilterRowView: View {
204183

205184
@ViewBuilder
206185
private var rowContextMenu: some View {
186+
Button {
187+
onApply()
188+
} label: {
189+
Label(String(localized: "Apply Only This Filter"), systemImage: "checkmark.circle")
190+
}
191+
.disabled(!filter.isValid)
192+
193+
Divider()
194+
207195
Button {
208196
onAdd()
209197
} label: {

0 commit comments

Comments
 (0)