Skip to content

fix(sidebar): use grouped form layout in favorite edit dialogs#1809

Merged
datlechin merged 2 commits into
mainfrom
fix/favorite-dialog-layout
Jul 3, 2026
Merged

fix(sidebar): use grouped form layout in favorite edit dialogs#1809
datlechin merged 2 commits into
mainfrom
fix/favorite-dialog-layout

Conversation

@datlechin

Copy link
Copy Markdown
Member

Problem

The New Favorite / Edit Favorite sheet rendered with a large empty region on the left, labels pushed to mid-dialog, and fields crushed against the right edge.

Root cause

The form used .formStyle(.columns), which lays out one shared trailing-aligned label column for the whole form. The dialog put the ~90-character ";;" hint sentence (and the keyword error text) into the label slot of an empty LabeledContent. That single row inflated the shared label column, which right-aligned every short label toward the center and squeezed the value column into a narrow strip. The same anti-pattern was copy-pasted into LinkedFavoriteMetadataDialog.

Changes

  • Rebuilt both dialogs on the repo-standard sheet shape (title row, Divider, Form with .formStyle(.grouped), Divider, bottom-right Cancel/primary row). This matches the 24 existing .grouped form sites, Apple's grouped-form guidance (WWDC22 10052, Food Truck sample), and HIG rules for sheets, text fields, and toggles.
  • The Query editor is now a full-width TextEditor in its own section (minHeight 180, monospaced), with the ";;" hint as a real section footer.
  • Keyword validation shows inline directly under the Keyword field. Global is a checkbox (HIG: do not replace a checkbox with a switch) with a visible "Available in all connections" caption instead of a hover tooltip.
  • Extracted the duplicated keyword validation from both view structs into SQLFavoriteEditValidation.swift (SQLFavoriteKeywordValidator pure classifier plus SQLFavoriteKeywordField with an injectable availability check). This also fixes a latent race: an in-flight availability check could overwrite the result of a newer synchronous validation. Every validate call now invalidates stale checks.
  • Removed a latent perf issue: isValid trimmed the full query string (up to 500KB) on every body evaluation. It now uses a short-circuiting blank check. The 500KB save cap is unchanged.
  • CreateDatabaseSheet keeps .formStyle(.columns) on purpose: all its labels are short and it is not affected.

Tests

  • New SQLFavoriteEditValidationTests: classifier table (empty, space, unavailable, reserved-keyword shadow), warning-allows-save vs error-blocks-save semantics, keyword trimming, and a deterministic stale-response race test using gated AsyncStreams.
  • No UI automation added: TableProUITests has no harness for driving a .sheet(item:) dialog and no storage-injection seam, so the keyword-validation flow cannot run deterministically against the live SQLite-backed store. The extracted logic carries the coverage instead.
  • swiftlint lint --strict clean on all changed files.

Follow-up

The screenshots in docs/features/favorites.mdx (sql-favorite-create.png, sql-favorite-create-dark.png) show the old layout and need recapturing. The page text stays accurate.

@datlechin datlechin force-pushed the fix/favorite-dialog-layout branch from b729c6a to 4214695 Compare July 3, 2026 17:52
Signed-off-by: Ngô Quốc Đạt <datlechin@gmail.com>
@datlechin datlechin merged commit 83d9bc5 into main Jul 3, 2026
2 checks passed
@datlechin datlechin deleted the fix/favorite-dialog-layout branch July 3, 2026 18:00
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