@@ -32,6 +32,7 @@ struct DataBrowserView: View {
3232 @State private var goToPageInput = " "
3333 @State private var searchText = " "
3434 @State private var activeSearchText = " "
35+ @State private var searchTask : Task < Void , Never > ?
3536 @State private var filters : [ TableFilter ] = [ ]
3637 @State private var filterLogicMode : FilterLogicMode = . and
3738 @State private var showFilterSheet = false
@@ -100,7 +101,7 @@ struct DataBrowserView: View {
100101 var body : some View {
101102 searchableContent
102103 . toolbar { topToolbar }
103- . toolbar ( rows. isEmpty ? . hidden : . visible, for: . bottomBar)
104+ . toolbar ( rows. isEmpty && !hasActiveSearch && !hasActiveFilters ? . hidden : . visible, for: . bottomBar)
104105 . toolbar { paginationToolbar }
105106 . task { await loadData ( isInitial: true ) }
106107 . sheet ( isPresented: $showInsertSheet) { insertSheet }
@@ -250,7 +251,7 @@ struct DataBrowserView: View {
250251 ForEach ( ExportFormat . allCases) { format in
251252 Button ( format. rawValue) {
252253 let text = ClipboardExporter . exportRow (
253- columns: columns, row: rows [ index ] ,
254+ columns: columns, row: row ,
254255 format: format, tableName: table. name
255256 )
256257 ClipboardExporter . copyToClipboard ( text)
@@ -260,17 +261,17 @@ struct DataBrowserView: View {
260261 if !foreignKeys. isEmpty {
261262 let rowFKs = foreignKeys. filter { fk in
262263 guard let colIndex = columns. firstIndex ( where: { $0. name == fk. column } ) ,
263- colIndex < rows [ index ] . count,
264- rows [ index ] [ colIndex] != nil else { return false }
264+ colIndex < row . count,
265+ row [ colIndex] != nil else { return false }
265266 return true
266267 }
267268 if !rowFKs. isEmpty {
268269 Divider ( )
269270 ForEach ( rowFKs, id: \. name) { fk in
270271 Button {
271272 if let colIndex = columns. firstIndex ( where: { $0. name == fk. column } ) ,
272- colIndex < rows [ index ] . count,
273- let value = rows [ index ] [ colIndex] {
273+ colIndex < row . count,
274+ let value = row [ colIndex] {
274275 fkPreviewItem = FKPreviewItem ( fk: fk, value: value)
275276 }
276277 } label: {
@@ -283,7 +284,7 @@ struct DataBrowserView: View {
283284 . swipeActions ( edge: . trailing, allowsFullSwipe: false ) {
284285 if !isView && hasPrimaryKeys && !connection. safeModeLevel. blocksWrites {
285286 Button ( role: . destructive) {
286- deleteTarget = primaryKeyValues ( for: rows [ index ] )
287+ deleteTarget = primaryKeyValues ( for: row )
287288 showDeleteConfirmation = true
288289 } label: {
289290 Label ( " Delete " , systemImage: " trash " )
@@ -320,6 +321,7 @@ struct DataBrowserView: View {
320321 }
321322 } label: {
322323 Image ( systemName: " square.and.arrow.up " )
324+ . accessibilityLabel ( Text ( " Export " ) )
323325 }
324326 . disabled ( rows. isEmpty)
325327 }
@@ -344,6 +346,7 @@ struct DataBrowserView: View {
344346 Image ( systemName: sortState. isSorting
345347 ? " arrow.up.arrow.down.circle.fill "
346348 : " arrow.up.arrow.down.circle " )
349+ . accessibilityLabel ( Text ( " Sort " ) )
347350 }
348351 . disabled ( columns. isEmpty)
349352 }
@@ -352,6 +355,7 @@ struct DataBrowserView: View {
352355 Image ( systemName: hasActiveFilters
353356 ? " line.3.horizontal.decrease.circle.fill "
354357 : " line.3.horizontal.decrease.circle " )
358+ . accessibilityLabel ( Text ( " Filter " ) )
355359 }
356360 . badge ( activeFilterCount)
357361 }
@@ -360,12 +364,14 @@ struct DataBrowserView: View {
360364 StructureView ( table: table, session: session, databaseType: connection. type)
361365 } label: {
362366 Image ( systemName: " info.circle " )
367+ . accessibilityLabel ( Text ( " Table Structure " ) )
363368 }
364369 }
365370 if !isView && !connection. safeModeLevel. blocksWrites {
366371 ToolbarItem ( placement: . primaryAction) {
367372 Button { showInsertSheet = true } label: {
368373 Image ( systemName: " plus " )
374+ . accessibilityLabel ( Text ( " Insert Row " ) )
369375 }
370376 }
371377 }
@@ -452,9 +458,14 @@ struct DataBrowserView: View {
452458 do {
453459 let query : String
454460 if hasActiveSearch {
461+ let searchableColumns = columns. filter { col in
462+ let upper = col. typeName. uppercased ( )
463+ return !upper. contains ( " BLOB " ) && !upper. contains ( " BYTEA " ) && !upper. contains ( " BINARY " )
464+ && !upper. contains ( " VARBINARY " ) && !upper. contains ( " IMAGE " )
465+ }
455466 query = SQLBuilder . buildSearchSelect (
456467 table: table. name, type: connection. type,
457- searchText: activeSearchText, searchColumns: columns ,
468+ searchText: activeSearchText, searchColumns: searchableColumns ,
458469 filters: filters, logicMode: filterLogicMode,
459470 sortState: sortState,
460471 limit: pagination. pageSize, offset: pagination. currentOffset
@@ -511,9 +522,14 @@ struct DataBrowserView: View {
511522 do {
512523 let countQuery : String
513524 if hasActiveSearch {
525+ let searchableColumns = columns. filter { col in
526+ let upper = col. typeName. uppercased ( )
527+ return !upper. contains ( " BLOB " ) && !upper. contains ( " BYTEA " ) && !upper. contains ( " BINARY " )
528+ && !upper. contains ( " VARBINARY " ) && !upper. contains ( " IMAGE " )
529+ }
514530 countQuery = SQLBuilder . buildSearchCount (
515531 table: table. name, type: connection. type,
516- searchText: activeSearchText, searchColumns: columns ,
532+ searchText: activeSearchText, searchColumns: searchableColumns ,
517533 filters: filters, logicMode: filterLogicMode
518534 )
519535 } else if hasActiveFilters {
@@ -609,15 +625,17 @@ struct DataBrowserView: View {
609625 guard hasActiveSearch, !columns. isEmpty else { return }
610626 pagination. currentPage = 0
611627 pagination. totalRows = nil
612- Task { await loadData ( ) }
628+ searchTask? . cancel ( )
629+ searchTask = Task { await loadData ( ) }
613630 }
614631
615632 private func clearSearch( ) {
616633 searchText = " "
617634 activeSearchText = " "
618635 pagination. currentPage = 0
619636 pagination. totalRows = nil
620- Task { await loadData ( ) }
637+ searchTask? . cancel ( )
638+ searchTask = Task { await loadData ( ) }
621639 }
622640
623641 private func applyFilters( ) {
@@ -841,5 +859,6 @@ private struct RowCard: View {
841859 }
842860 }
843861 . padding ( . vertical, 2 )
862+ . accessibilityElement ( children: . combine)
844863 }
845864}
0 commit comments