fix(sidebar): check preselected tables and apply default options in the export sheet - #1897
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 486f54afb4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| databaseItems = [item].normalizingOptionValues( | ||
| optionColumnCount: currentOptionColumnCount, | ||
| defaultOptionValues: currentDefaultOptionValues |
There was a problem hiding this comment.
Avoid enabling SQL export before schema names are loaded
When exporting from a schema-scoped connection such as PostgreSQL or Oracle before loadDatabaseItems() finishes, this normalization makes the instant sidebar rows exportable even though they were built just above with databaseName = connection.database; the SQL export path treats databaseName as the schema qualifier, while the later metadata path replaces it with the actual schema. A fast click on Export can therefore generate or query database.table instead of schema.table, or fail on a missing relation. Keep these rows disabled until schema-qualified items are loaded, or initialize them from table.schema.
Useful? React with 👍 / 👎.
Problem
Select tables in the sidebar, right-click, Export. If the last-used export format has per-table option columns (SQL: Structure/Drop/Data, MQL: Drop/Indexes/Data), the sheet opens with each preselected row's main checkbox unchecked while its option toggles look enabled. Worse, those tables are excluded from the export ("N skipped (no options)") and the Export button stays disabled.
Root cause
A preselected
ExportTableItemis created withisSelected: truebut an emptyoptionValuesarray, and the three readers of that array disagree on what empty means:genericCheckboxStatetreats it as uncheckedgetfalls back totrueisTableExportabletreats it as not exportableThe invariant (a selected table has materialized, at-least-one-true option values) had no owner. It was patched lazily in three scattered view-layer spots, none of which runs on the preselection path:
resetOptionValuesfires on format change before the table list is populated, and the other two heals only run on direct user interaction.Fix
One pure function now owns the invariant:
ExportTableItem.normalized(forOptionColumnCount:defaultOptionValues:). It fixes a wrong-shaped array for any row and re-applies plugin defaults when a selected row has no option enabled, and never touches a deliberate partial selection.ExportDialognormalizes at bothdatabaseItemsassignments (instant sidebar populate and async reload), which fixes the reported bug for every format that declares option columns, current and future.optionValuestoo (priorRowSnapshots()replacingcurrentSelectionState()), fixing a latent bug where an option toggled while the list was still loading got silently reset.ExportTableTreeViewdrops its three divergent heals and calls the same function;ensureOptionValuesis deleted, the option toggle's silentreturn truefallback becameoptionValues[safe:] ?? column.defaultValue. Clicking a mixed row checkbox still checks all options.Row and database IDs are preserved by the normalization helpers, so SwiftUI list identity is unaffected.
Tests
9 new swift-testing cases in
ExportModelsTests, including a direct regression test that reproduces the preselection shape (selected, empty option values) and asserts the two properties that were broken: the main-checkbox precondition and exportability.No UI automation added: no deterministic export-sheet UI test exists today, and the decision logic now lives entirely in tested pure functions, leaving only thin SwiftUI wiring in the dialog.
Notes
CSV/JSON/XLSX are unaffected (zero option columns makes normalization a no-op). Query-results export mode is untouched.
docs/features/import-export.mdxalready documents the defaults this fix restores, so no docs change.