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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- The results status bar has a divider above it and balanced left and right margins, and its loading spinner matches the size of the other controls. (#1569)
- Custom keyboard shortcuts now work on non-US keyboard layouts, and shifted symbols like Cmd+[ record correctly.
- The Keyboard settings list is grouped by where shortcuts act (Editor, Data Grid, Navigation, Connections), and each changed shortcut has its own reset button.
- Conflict detection now checks live macOS system shortcuts and the editor's built-in commands, and lets the same key serve the editor and the data grid because focus decides which one runs.
Expand All @@ -31,6 +32,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- Pagination and other status bar buttons no longer get blocked by the window resize zone in the bottom-right corner. (#1569)
- VoiceOver now reads clear labels for the Columns button, Filters toggle, and loading indicators in the results status bar. (#1569)
- The custom rows-per-page popover now points at the page-size menu instead of the center of the pagination controls. (#1569)
- DynamoDB AWS Profile auth now reads `~/.aws/config` as well as `~/.aws/credentials` and supports `credential_process`, matching the AWS CLI. Profiles defined only in `~/.aws/config`, including SSO and credential-process profiles, no longer fail with "profile not found". (#1567)
- Query result columns now follow the order in the SELECT. Adding or removing a column no longer leaves new columns stuck at the end of the grid. (#1565)
- JSON file import works again. It failed to load in 0.48.0.
Expand Down
59 changes: 59 additions & 0 deletions TablePro/Models/Query/StatusBarSnapshot.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//
// StatusBarSnapshot.swift
// TablePro
//

import Foundation

struct StatusBarSnapshot: Equatable {
let tabId: UUID?
let tabType: TabType?
let hasRows: Bool
let hasColumns: Bool
let rowCount: Int
let hasTableName: Bool
let pagination: PaginationState
let statusMessage: String?

init(
tabId: UUID?,
tabType: TabType?,
hasRows: Bool,
hasColumns: Bool,
rowCount: Int,
hasTableName: Bool,
pagination: PaginationState,
statusMessage: String?
) {
self.tabId = tabId
self.tabType = tabType
self.hasRows = hasRows
self.hasColumns = hasColumns
self.rowCount = rowCount
self.hasTableName = hasTableName
self.pagination = pagination
self.statusMessage = statusMessage
}

init(tab: QueryTab?, tableRows: TableRows?) {
self.init(
tabId: tab?.id,
tabType: tab?.tabType,
hasRows: !(tableRows?.rows.isEmpty ?? true),
hasColumns: !(tableRows?.columns.isEmpty ?? true),
rowCount: tableRows?.rows.count ?? 0,
hasTableName: tab?.tableContext.tableName != nil,
pagination: tab?.pagination ?? PaginationState(),
statusMessage: tab?.execution.statusMessage
)
}

var showsPaginationControls: Bool {
if let total = pagination.totalRowCount, total > 0 { return true }
return isPagedWithUnknownTotal
}

var isPagedWithUnknownTotal: Bool {
pagination.currentPage > 1 || rowCount >= pagination.pageSize
}
}
11 changes: 8 additions & 3 deletions TablePro/Views/Components/PaginationControlsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ struct PaginationControlsView: View {
pageSizeMenu
navigationCluster
}
.popover(isPresented: $showCustomPopover, arrowEdge: .top) {
customPageSizePopover
}
}

// MARK: - Page Size Menu
Expand Down Expand Up @@ -62,6 +59,13 @@ struct PaginationControlsView: View {
.controlSize(.small)
.help(String(localized: "Rows per page"))
.accessibilityLabel(String(localized: "Rows per page"))
.overlay(alignment: .bottom) {
Color.clear
.frame(width: 0, height: 0)
.popover(isPresented: $showCustomPopover, arrowEdge: .top) {
customPageSizePopover
}
}
}

private var pageSizeBinding: Binding<Int> {
Expand Down Expand Up @@ -96,6 +100,7 @@ struct PaginationControlsView: View {
if pagination.isLoading {
ProgressView()
.controlSize(.small)
.accessibilityLabel(String(localized: "Loading page"))
}

navButton(
Expand Down
39 changes: 23 additions & 16 deletions TablePro/Views/Main/Child/MainEditorContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@ struct MainEditorContentView: View {
}

if tab.display.explainText == nil {
Divider()
statusBar(tab: tab)
}
}
Expand Down Expand Up @@ -744,25 +745,31 @@ struct MainEditorContentView: View {
return MainStatusBarView(
snapshot: StatusBarSnapshot(tab: tab, tableRows: resolvedRows),
filterState: tab.filterState,
hiddenColumns: tab.columnLayout.hiddenColumns,
allColumns: coordinator.columnsForVisibilityPicker(for: tab, resultColumns: resolvedRows.columns),
selectedRowIndices: selectionState.indices,
viewMode: resultsViewModeBinding(for: tab),
onFirstPage: onFirstPage,
onPreviousPage: onPreviousPage,
onNextPage: onNextPage,
onLastPage: onLastPage,
onPageSizeChange: onPageSizeChange,
onShowAll: onShowAll,
onGoToPage: onGoToPage,
onToggleColumn: { coordinator.toggleColumnVisibility($0) },
onShowAllColumns: { coordinator.showAllColumns() },
onHideAllColumns: { coordinator.hideAllColumns($0) },
paginationCallbacks: PaginationCallbacks(
onFirst: onFirstPage,
onPrevious: onPreviousPage,
onNext: onNextPage,
onLast: onLastPage,
onPageSizeChange: onPageSizeChange,
onShowAll: onShowAll,
onGoToPage: onGoToPage
),
columnState: StatusBarColumnState(
hidden: tab.columnLayout.hiddenColumns,
all: coordinator.columnsForVisibilityPicker(for: tab, resultColumns: resolvedRows.columns),
onToggle: { coordinator.toggleColumnVisibility($0) },
onShowAll: { coordinator.showAllColumns() },
onHideAll: { coordinator.hideAllColumns($0) }
),
structureState: StatusBarStructureState(
footer: coordinator.structureFooterState,
onAdd: { coordinator.structureActions?.addRow?() },
onRemove: { coordinator.structureActions?.removeRow?() }
),
onToggleFilters: { coordinator.toggleFilterPanel() },
onFetchAll: { coordinator.fetchAllRows() },
structureFooterState: coordinator.structureFooterState,
onStructureAdd: { coordinator.structureActions?.addRow?() },
onStructureRemove: { coordinator.structureActions?.removeRow?() }
onFetchAll: { coordinator.fetchAllRows() }
)
}

Expand Down
Loading
Loading