Skip to content

fix(sidebar): check preselected tables and apply default options in the export sheet - #1897

Merged
datlechin merged 1 commit into
mainfrom
fix/export-preselected-option-values
Jul 16, 2026
Merged

fix(sidebar): check preselected tables and apply default options in the export sheet#1897
datlechin merged 1 commit into
mainfrom
fix/export-preselected-option-values

Conversation

@datlechin

Copy link
Copy Markdown
Member

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 ExportTableItem is created with isSelected: true but an empty optionValues array, and the three readers of that array disagree on what empty means:

  • genericCheckboxState treats it as unchecked
  • the option toggle's get falls back to true
  • isTableExportable treats it as not exportable

The 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: resetOptionValues fires 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.

  • ExportDialog normalizes at both databaseItems assignments (instant sidebar populate and async reload), which fixes the reported bug for every format that declares option columns, current and future.
  • The reload snapshot now carries optionValues too (priorRowSnapshots() replacing currentSelectionState()), fixing a latent bug where an option toggled while the list was still loading got silently reset.
  • ExportTableTreeView drops its three divergent heals and calls the same function; ensureOptionValues is deleted, the option toggle's silent return true fallback became optionValues[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.mdx already documents the defaults this fix restores, so no docs change.

@datlechin
datlechin merged commit a77ce87 into main Jul 16, 2026
2 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +572 to +574
databaseItems = [item].normalizingOptionValues(
optionColumnCount: currentOptionColumnCount,
defaultOptionValues: currentDefaultOptionValues

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant