Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions TablePro.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,6 @@
5A867000D00000000 /* RedisDriver.tableplugin in Copy Plug-Ins */ = {isa = PBXBuildFile; fileRef = 5A867000100000000 /* RedisDriver.tableplugin */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
5A868000A00000000 /* TableProPluginKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A860000100000000 /* TableProPluginKit.framework */; };
5A868000D00000000 /* PostgreSQLDriver.tableplugin in Copy Plug-Ins */ = {isa = PBXBuildFile; fileRef = 5A868000100000000 /* PostgreSQLDriver.tableplugin */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
5ACE00012F4F000000000004 /* CodeEditSourceEditor in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F000000000002 /* CodeEditSourceEditor */; };
5ACE00012F4F000000000005 /* CodeEditLanguages in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F000000000003 /* CodeEditLanguages */; };
5ACE00012F4F000000000006 /* CodeEditTextView in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F000000000007 /* CodeEditTextView */; };
5ACE00012F4F00000000000A /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F000000000009 /* Sparkle */; };
5ACE00012F4F00000000000D /* MarkdownUI in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F00000000000C /* MarkdownUI */; };
5AEE5B362F5C9B7B00FA84D7 /* OracleNIO in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F00000000000F /* OracleNIO */; };
5A86A000A00000000 /* TableProPluginKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A860000100000000 /* TableProPluginKit.framework */; };
5A86A000D00000000 /* CSVExport.tableplugin in Copy Plug-Ins */ = {isa = PBXBuildFile; fileRef = 5A86A000100000000 /* CSVExport.tableplugin */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
5A86B000A00000000 /* TableProPluginKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A860000100000000 /* TableProPluginKit.framework */; };
Expand All @@ -40,6 +34,12 @@
5A86D000D00000000 /* XLSXExport.tableplugin in Copy Plug-Ins */ = {isa = PBXBuildFile; fileRef = 5A86D000100000000 /* XLSXExport.tableplugin */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
5A86E000A00000000 /* TableProPluginKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A860000100000000 /* TableProPluginKit.framework */; };
5A86E000D00000000 /* MQLExport.tableplugin in Copy Plug-Ins */ = {isa = PBXBuildFile; fileRef = 5A86E000100000000 /* MQLExport.tableplugin */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
5ACE00012F4F000000000004 /* CodeEditSourceEditor in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F000000000002 /* CodeEditSourceEditor */; };
5ACE00012F4F000000000005 /* CodeEditLanguages in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F000000000003 /* CodeEditLanguages */; };
5ACE00012F4F000000000006 /* CodeEditTextView in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F000000000007 /* CodeEditTextView */; };
5ACE00012F4F00000000000A /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F000000000009 /* Sparkle */; };
5ACE00012F4F00000000000D /* MarkdownUI in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F00000000000C /* MarkdownUI */; };
5AEE5B362F5C9B7B00FA84D7 /* OracleNIO in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F00000000000F /* OracleNIO */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "2640"
version = "1.7">
version = "1.8">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"
Expand Down
13 changes: 13 additions & 0 deletions TablePro/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,11 @@ struct ContentView: View {
schemaProvider: SchemaProviderRegistry.shared.provider(for: currentSession.connection.id)
)
}
.searchable(
text: sidebarSearchTextBinding(for: currentSession.connection.id),
placement: .sidebar,
prompt: "Filter"
)
.navigationSplitViewColumnWidth(min: 200, ideal: 250, max: 600)
} detail: {
// MARK: - Detail (Main workspace with optional right sidebar)
Expand Down Expand Up @@ -332,6 +337,14 @@ struct ContentView: View {
)
}

private func sidebarSearchTextBinding(for connectionId: UUID) -> Binding<String> {
let state = SharedSidebarState.forConnection(connectionId)
return Binding(
get: { state.searchText },
set: { state.searchText = $0 }
)
}

private var sessionTableOperationOptionsBinding: Binding<[String: TableOperationOptions]> {
createSessionBinding(
get: { $0.tableOperationOptions },
Expand Down
1 change: 1 addition & 0 deletions TablePro/Resources/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -1810,6 +1810,7 @@
}
},
"Clear table filter" : {
"extractionState" : "stale",
"localizations" : {
"vi" : {
"stringUnit" : {
Expand Down
55 changes: 1 addition & 54 deletions TablePro/Views/Sidebar/SidebarView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ import SwiftUI
/// Sidebar view displaying list of database tables
struct SidebarView: View {
@State private var viewModel: SidebarViewModel
/// Local search text for responsive typing; synced to/from shared state
@State private var localSearchText: String = ""
/// Debounce task for writing local search text to the shared state
@State private var searchSyncTask: Task<Void, Never>?

// Keep @Binding on the view for SwiftUI change tracking.
// The ViewModel stores the same bindings for write access.
Expand Down Expand Up @@ -56,7 +52,6 @@ struct SidebarView: View {
) {
_tables = tables
self.sidebarState = sidebarState
_localSearchText = State(initialValue: sidebarState.searchText)
_pendingTruncates = pendingTruncates
_pendingDeletes = pendingDeletes
let selectedBinding = Binding(
Expand Down Expand Up @@ -84,28 +79,11 @@ struct SidebarView: View {

var body: some View {
VStack(alignment: .leading, spacing: 0) {
if !tables.isEmpty {
searchField
}
content
}
.frame(minWidth: 280)
.onChange(of: localSearchText) { _, newValue in
viewModel.debouncedSearchText = newValue
searchSyncTask?.cancel()
searchSyncTask = Task { @MainActor in
try? await Task.sleep(nanoseconds: 150_000_000)
guard !Task.isCancelled else { return }
if sidebarState.searchText != newValue {
sidebarState.searchText = newValue
}
}
}
.onChange(of: sidebarState.searchText) { _, newValue in
if localSearchText != newValue {
localSearchText = newValue
viewModel.debouncedSearchText = newValue
}
viewModel.debouncedSearchText = newValue
}
.onChange(of: tables) { _, newTables in
let hasSession = DatabaseManager.shared.activeSessions[connectionId] != nil
Expand Down Expand Up @@ -135,37 +113,6 @@ struct SidebarView: View {
}
}

// MARK: - Search Field

private var searchField: some View {
HStack(spacing: 6) {
Image(systemName: "magnifyingglass")
.foregroundStyle(.secondary)
.font(.system(size: DesignConstants.FontSize.medium))

TextField("Filter", text: $localSearchText)
.textFieldStyle(.plain)
.font(.system(size: DesignConstants.FontSize.body))

if !localSearchText.isEmpty {
Button(action: { localSearchText = "" }) {
Image(systemName: "xmark.circle.fill")
.foregroundStyle(.secondary)
.font(.system(size: DesignConstants.FontSize.medium))
}
.buttonStyle(.plain)
.accessibilityLabel(String(localized: "Clear table filter"))
}
}
.padding(.horizontal, 8)
.padding(.vertical, DesignConstants.Spacing.xxs)
.background(Color(nsColor: .quaternaryLabelColor))
.cornerRadius(6)
.padding(.horizontal, 10)
.padding(.top, 8)
.padding(.bottom, 4)
}

// MARK: - Content States

@ViewBuilder
Expand Down