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

### Added

- iOS: VoiceOver "Delete row" / "Delete group" / "Delete tag" custom actions on rows whose only deletion path was a swipe gesture
- iOS: empty Groups and Tags screens show a Create button so the action is reachable without opening the toolbar
- iOS: "No Results" empty state in Query Editor explains the query returned no rows
- iOS: iCloud sync runs every 30 minutes in the background via `BGAppRefreshTask` while the app is closed (gated by the iCloud Sync setting); iOS schedules the actual cadence based on usage and battery
- iOS: Cmd+F focuses the search field in Tables and Data Browser (iPad keyboard canonical)
- iOS: search text in Tables and Data Browser persists across process kill via `@SceneStorage` (per-window on iPad)
Expand Down
5 changes: 5 additions & 0 deletions TableProMobile/TableProMobile/Views/DataBrowserView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,11 @@ struct DataBrowserView: View {
.tint(.red)
}
}
.accessibilityAction(named: Text("Delete row")) {
guard !isView, viewModel.hasPrimaryKeys, !connection.safeModeLevel.blocksWrites else { return }
deleteTarget = viewModel.primaryKeyValues(for: row)
showDeleteConfirmation = true
}
}

@ViewBuilder
Expand Down
6 changes: 6 additions & 0 deletions TableProMobile/TableProMobile/Views/GroupManagementView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ struct GroupManagementView: View {
}
.tint(.red)
}
.accessibilityAction(named: Text("Delete group")) {
groupToDelete = group
}
}
.onMove { source, destination in
var sorted = appState.groups.sorted(by: { $0.sortOrder < $1.sortOrder })
Expand All @@ -62,6 +65,9 @@ struct GroupManagementView: View {
Label("No Groups", systemImage: "folder")
} description: {
Text("Create a group to organize your connections.")
} actions: {
Button("Create Group") { showingAddGroup = true }
.buttonStyle(.borderedProminent)
}
}
}
Expand Down
8 changes: 6 additions & 2 deletions TableProMobile/TableProMobile/Views/QueryEditorView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,12 @@ struct QueryEditorView: View {
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
} else if viewModel.legacyRows.isEmpty {
ContentUnavailableView("No Results", systemImage: "tray")
.frame(maxWidth: .infinity, maxHeight: .infinity)
ContentUnavailableView(
"No Results",
systemImage: "tray",
description: Text("The query returned no rows.")
)
.frame(maxWidth: .infinity, maxHeight: .infinity)
} else {
resultList
}
Expand Down
7 changes: 7 additions & 0 deletions TableProMobile/TableProMobile/Views/TagManagementView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ struct TagManagementView: View {
}
}
}
.accessibilityAction(named: Text("Delete tag")) {
guard !tag.isPreset else { return }
appState.deleteTag(tag.id)
}
}
}
.overlay {
Expand All @@ -55,6 +59,9 @@ struct TagManagementView: View {
Label("No Tags", systemImage: "tag")
} description: {
Text("Create a tag to organize your connections.")
} actions: {
Button("Create Tag") { showingAddTag = true }
.buttonStyle(.borderedProminent)
}
}
}
Expand Down
Loading