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

- Traditional Chinese (繁體中文) language in Settings > General with full UI translation
- An Add button in the table status bar inserts a new row at the end of the grid and starts editing it.

## [0.51.1] - 2026-06-16

Expand Down
3 changes: 2 additions & 1 deletion TablePro/Views/Main/Child/MainEditorContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,8 @@ struct MainEditorContentView: View {
onRemove: { coordinator.structureActions?.removeRow?() }
),
onToggleFilters: { coordinator.toggleFilterPanel() },
onFetchAll: { coordinator.fetchAllRows() }
onFetchAll: { coordinator.fetchAllRows() },
onAddRow: currentTabAllowsAddRow ? { onAddRow() } : nil
)
}

Expand Down
30 changes: 28 additions & 2 deletions TablePro/Views/Main/Child/MainStatusBarView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,27 @@ struct MainStatusBarView: View {
let structureState: StatusBarStructureState
let onToggleFilters: () -> Void
let onFetchAll: (() -> Void)?
let onAddRow: (() -> Void)?

@State private var showColumnPopover = false

private var isStructureMode: Bool { viewMode == .structure }
private var showsDataChrome: Bool { !isStructureMode }

static func showsAddRow(viewMode: ResultsViewMode, canAddRow: Bool) -> Bool {
viewMode == .data && canAddRow
}

private var filterToggleHelp: String {
let label = String(localized: "Toggle Filters")
guard let combo = AppSettingsManager.shared.keyboard.shortcut(for: .toggleFilters),
helpText(String(localized: "Toggle Filters"), shortcut: .toggleFilters)
}

private var addRowHelp: String {
helpText(String(localized: "Add Row"), shortcut: .addRow)
}

private func helpText(_ label: String, shortcut action: ShortcutAction) -> String {
guard let combo = AppSettingsManager.shared.keyboard.shortcut(for: action),
!combo.isCleared else {
return label
}
Expand Down Expand Up @@ -141,6 +153,20 @@ struct MainStatusBarView: View {
}

if showsDataChrome {
if Self.showsAddRow(viewMode: viewMode, canAddRow: onAddRow != nil), let onAddRow {
Button {
onAddRow()
} label: {
HStack(spacing: 4) {
Image(systemName: "plus")
Text("Add")
}
}
.controlSize(.small)
.help(addRowHelp)
.accessibilityLabel(String(localized: "Add Row"))
}

if snapshot.hasColumns {
Button {
showColumnPopover.toggle()
Expand Down
17 changes: 16 additions & 1 deletion TableProTests/Views/Main/MainStatusBarLayoutTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,23 @@ struct MainStatusBarLayoutTests {
onRemove: {}
),
onToggleFilters: {},
onFetchAll: nil
onFetchAll: nil,
onAddRow: nil
)
#expect(type(of: view.body) != Never.self)
}

@Test("Add Row button shows only in Data mode when adding is allowed")
func addRowVisibilityByMode() {
#expect(MainStatusBarView.showsAddRow(viewMode: .data, canAddRow: true))
#expect(!MainStatusBarView.showsAddRow(viewMode: .structure, canAddRow: true))
#expect(!MainStatusBarView.showsAddRow(viewMode: .json, canAddRow: true))
}

@Test("Add Row button is hidden when adding is not allowed")
func addRowHiddenWhenNotAllowed() {
#expect(!MainStatusBarView.showsAddRow(viewMode: .data, canAddRow: false))
#expect(!MainStatusBarView.showsAddRow(viewMode: .structure, canAddRow: false))
#expect(!MainStatusBarView.showsAddRow(viewMode: .json, canAddRow: false))
}
}
Loading