From b0031fe432baf40a39733db233706d211e81c06b Mon Sep 17 00:00:00 2001 From: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Date: Wed, 17 Jun 2026 02:37:07 -0700 Subject: [PATCH] fix(sidebar): keep filter text when opening a table from the filtered list --- CHANGELOG.md | 1 + .../SidebarContainerViewController.swift | 5 ++++ .../Views/SidebarSearchPersistenceTests.swift | 27 +++++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 TableProTests/Views/SidebarSearchPersistenceTests.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 6537bb4e5..de14b566e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- The sidebar filter no longer clears when you open a table from the filtered list. It only clears when you empty the field. (#1690) - DuckDB VARIANT columns now show their value as text instead of an empty cell. ## [0.51.1] - 2026-06-16 diff --git a/TablePro/Core/Services/Infrastructure/SidebarContainerViewController.swift b/TablePro/Core/Services/Infrastructure/SidebarContainerViewController.swift index c87ab23ab..a011f88df 100644 --- a/TablePro/Core/Services/Infrastructure/SidebarContainerViewController.swift +++ b/TablePro/Core/Services/Infrastructure/SidebarContainerViewController.swift @@ -131,9 +131,14 @@ extension SidebarContainerViewController: NSSearchFieldDelegate { } func searchFieldDidEndSearching(_ sender: NSSearchField) { + guard Self.shouldClearOnEndSearching(fieldValue: sender.stringValue) else { return } writeSearchText("") } + nonisolated static func shouldClearOnEndSearching(fieldValue: String) -> Bool { + fieldValue.isEmpty + } + func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool { guard commandSelector == #selector(NSResponder.moveDown(_:)) else { return false } view.window?.makeFirstResponder(hostingController.view) diff --git a/TableProTests/Views/SidebarSearchPersistenceTests.swift b/TableProTests/Views/SidebarSearchPersistenceTests.swift new file mode 100644 index 000000000..38e77803c --- /dev/null +++ b/TableProTests/Views/SidebarSearchPersistenceTests.swift @@ -0,0 +1,27 @@ +// +// SidebarSearchPersistenceTests.swift +// TableProTests +// +// Regression guard for #1690 where opening a table from a filtered sidebar +// cleared the active filter. searchFieldDidEndSearching fired on focus loss +// and wrote "" back over the persisted filter text. The filter must only be +// cleared when the field is actually empty (cancel button / explicit clear). +// + +import Foundation +import Testing + +@testable import TablePro + +@Suite("Sidebar search persistence on end editing") +struct SidebarSearchPersistenceTests { + @Test("keeps the filter when the field still has text and focus is lost") + func keepsFilterWhenFieldHasText() { + #expect(!SidebarContainerViewController.shouldClearOnEndSearching(fieldValue: "dp_")) + } + + @Test("clears the filter when the field is empty") + func clearsFilterWhenFieldEmpty() { + #expect(SidebarContainerViewController.shouldClearOnEndSearching(fieldValue: "")) + } +}