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
11 changes: 11 additions & 0 deletions apple/TablePro/Core/SchemaTracking/StructureChangeManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -873,10 +873,21 @@ final class StructureChangeManager: ObservableObject, ChangeManaging {
}
}
tableOptions = TableOptionsDraft(original: writtenOptions, isAutoIncrementConfirmed: isAutoIncrementConfirmed)
adoptWrittenDefinitions()
discardChanges()
return true
}

// The written definitions stand in until the re-read lands, so a renamed or new definition keeps its id, its
// selection and the name the re-read is matched by.
private func adoptWrittenDefinitions() {
currentColumns = workingColumns.filter { !isPendingDeletion(.column($0.id)) }
currentIndexes = workingIndexes.filter { !isPendingDeletion(.index($0.id)) }
currentForeignKeys = workingForeignKeys.filter { !isPendingDeletion(.foreignKey($0.id)) }
currentCheckConstraints = workingCheckConstraints.filter { !isPendingDeletion(.checkConstraint($0.id)) }
currentPrimaryKey = workingPrimaryKey
}

// MARK: - Undo/Redo Operations

func undo() {
Expand Down
28 changes: 27 additions & 1 deletion apple/TablePro/Views/Main/MainContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,14 @@ struct MainContentView: View {
await coordinator.loadInspectorRowValues(tabId: tabId, rowID: rowID)
})
.background {
if let model = coordinator.activeGridModel {
if let editor = coordinator.activeStructureEditor {
StructureSelectionWatcher(
editor: editor,
onAttach: { scheduleInspectorUpdate() },
onChange: { rowsChanged in handleGridSelectionChange(rowsChanged: rowsChanged) }
)
.id(ObjectIdentifier(editor))
} else if let model = coordinator.activeGridModel {
GridSelectionWatcher(
model: model,
onAttach: { scheduleInspectorUpdate() },
Expand Down Expand Up @@ -552,6 +559,25 @@ struct MainContentView: View {
}

// No view of this window observes a session whose Structure view is not on screen, yet Discard and Save change it there.
// The selection moves between four grids, and the window reads only the one holding it.
private struct StructureSelectionWatcher: View {
@ObservedObject var editor: StructureDefinitionEditor
let onAttach: () -> Void
let onChange: (_ rowsChanged: Bool) -> Void

var body: some View {
let model = editor.focusedModel ?? editor.adapter(for: .columns).model
Color.clear
.frame(width: 0, height: 0)
.accessibilityHidden(true)
.background {
GridSelectionWatcher(model: model, onAttach: onAttach, onChange: onChange)
.id(ObjectIdentifier(model))
}
.onChange(of: editor.focusedSection) { _ in onChange(true) }
}
}

private struct StructureChangeWatcher: View {
@ObservedObject var session: StructureEditingSession
let onChange: () -> Void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,38 @@ struct StructureDefinitionEditorTests {
#expect(editor.inspectorTarget == .entity(.columns, status))
}

@Test("A saved rename and a saved new column keep their ids and the selection through the re-read")
func saveKeepsRenamedAndNewDefinitions() async throws {
let editor = makeEditor()
let status = id(of: "status", in: editor)
editor.commitInspectorField(section: .columns, id: status, field: 0, value: "phase")
editor.manager.addNewColumn()
let added = try #require(editor.manager.workingColumns.last).id
editor.commitInspectorField(section: .columns, id: added, field: 0, value: "note")
editor.adapter(for: .columns).select(entity: added)
let hold = try #require(editor.manager.holdForSave())

#expect(editor.manager.releaseHold(hold, written: true))
try await waitUntil { editor.adapter(for: .columns).model.configuration.isEditable }
#expect(editor.inspectorTarget == .entity(.columns, added))

editor.manager.loadSchema(
tableName: "orders",
columns: ["id", "customer_id", "phase", "note"].map {
ColumnInfo(name: $0, dataType: "INT", isNullable: true, isPrimaryKey: $0 == "id",
defaultValue: nil, extra: nil, charset: nil, collation: nil, comment: nil)
},
indexes: [IndexInfo(name: "orders_pkey", columns: ["id"], isUnique: true, isPrimary: true, type: "BTREE")],
foreignKeys: [],
primaryKey: ["id"]
)
try await waitUntil { editor.adapter(for: .columns).rowCount == 4 }

#expect(id(of: "phase", in: editor) == status)
#expect(id(of: "note", in: editor) == added)
#expect(editor.inspectorTarget == .entity(.columns, added))
}

@Test("A save's hold closes the grids and its end opens them again")
func saveHoldTogglesEditing() async throws {
let editor = makeEditor()
Expand Down
Loading