Skip to content

feat(editor): consistent schema gestures, SQL formatter, undo-friendly inserts#3

Merged
BorisTyshkevich merged 5 commits into
mainfrom
feat/editor-ux
Jun 20, 2026
Merged

feat(editor): consistent schema gestures, SQL formatter, undo-friendly inserts#3
BorisTyshkevich merged 5 commits into
mainfrom
feat/editor-ux

Conversation

@BorisTyshkevich

Copy link
Copy Markdown
Collaborator

A batch of editor/schema UX improvements.

Schema tree — consistent click model

Previously column single-click inserted the name, so a double-click pasted it twice (while tables inserted once on double-click). Now uniform:

single-click double-click shift-click
database expand insert db (cursor) SHOW CREATE DATABASE db (top line)
table expand SELECT * FROM db.table LIMIT 100 (top line) SHOW CREATE db.table (top line)
column (nothing) col (cursor) col::type (cursor)
  • "top line" = prepended as a new first line (doesn't replace existing content).
  • SHOW CREATE is used without TABLE so it covers tables/MVs/dictionaries.

Editor — real undo/redo for programmatic inserts

Programmatic edits (drag, double-click insert, format, Tab) now go through execCommand('insertText') with a manual-splice fallback, so they land on the native undo stack — ⌘Z / ⌘⇧Z work for them, not just for typing. New insertTopLine / replaceEditor helpers.

Format query (⌘⇧F)

Runs SELECT formatQuery(<editor SQL>) on the server and replaces the editor with the formatted output; failures surface via a toast.

Shortcuts

  • Removed ⌘T / ⌘W interception — the browser keeps its native new-tab/close-tab; the + and × buttons still create/close tabs.
  • Added to the shortcuts modal: Format query (⌘⇧F), Undo (⌘Z), Redo (⌘⇧Z).

Verification

In-browser (Chrome) against the built bundle: each gesture inserts the right text; execCommand('undo') reverts a programmatic insert (undo works); shortcuts modal shows the new list. npm test → 346 pass; editor/schema/shortcuts 100%, app.js within its gate.

🤖 Generated with Claude Code

https://claude.ai/code/session_01QennTvGKAtJZrv9EpQagef

Isolator acm and others added 5 commits June 20, 2026 11:42
…serts

Schema tree (consistent click model; was: column single-click inserted, so a
double-click pasted twice):
- single-click = expand (db/table) / nothing (column)
- double-click = insert — db: name (cursor); table: `SELECT * FROM db.t LIMIT 100`
  (prepended as a top line, not replacing); column: name (cursor)
- shift-click = db: `SHOW CREATE DATABASE db`; table: `SHOW CREATE db.t`
  (ClickHouse SHOW CREATE handles table/MV/dictionary); column: `col::type`
  (top-line for the statements, cursor for identifiers)

Editor:
- programmatic edits now go through execCommand('insertText') (with a manual-
  splice fallback), so drag/double-click/format inserts join the native undo
  stack — ⌘Z / ⌘⇧Z work for them, not just typing. New `insertTopLine` +
  `replaceEditor` helpers; Tab-insert routed through the same path.

Format query: new ⌘⇧F → `SELECT formatQuery(<editor sql>)` on the server,
replaces the editor with the result (errors surface via a toast).

Shortcuts: drop ⌘T/⌘W (let the browser keep new-tab/close-tab; the +/× buttons
remain); add Format, Undo, Redo to the modal list.

Verified in-browser: every gesture inserts the right text; execCommand('undo')
reverts a programmatic insert; shortcuts modal shows the new list. 346 tests
pass; editor/schema/shortcuts at 100%, app.js within gate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QennTvGKAtJZrv9EpQagef
⌘⇧F / Ctrl+Shift+F collides with browser find/Lens muscle memory (Ctrl+Shift+F
is Google Lens "search page" on Chrome Win/Linux). Rebind Format to
⌘/Ctrl+Shift+Enter — it pairs with Run (⌘/Ctrl+Enter), and Shift+Enter has no
browser default on macOS, Windows, or Linux. The Enter handler now branches on
Shift (format when signed in, else run). Shortcuts modal updated to ⌘⇧↵.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QennTvGKAtJZrv9EpQagef
The shortcuts modal now has a "Schema tree" section listing the click /
double-click / shift-click gestures (expand, insert, insert DDL/col::type),
reusing the existing row+chip styling under a small divider+subheading — so the
gestures are discoverable next to the keyboard shortcuts. Terse by design; the
per-row tooltips still carry the detail.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QennTvGKAtJZrv9EpQagef
…Query)

Shift-click on a table/db now fetches the real DDL via SHOW CREATE and pretty-
prints it through formatQuery(), inserting the formatted CREATE statement as a
top line — instead of inserting the literal "SHOW CREATE …" command. Two server
round-trips by design (show + format); if formatting fails it falls back to the
raw DDL, and a SHOW CREATE failure surfaces via a toast. New `insertCreate`
action; schema shift-click handlers call it ('db.table' for tables,
'DATABASE db' for databases).

352 tests pass; schema 100%, app.js within gate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QennTvGKAtJZrv9EpQagef
A share link carries the SQL in the URL hash (#<base64>). When the recipient
wasn't signed in, the OAuth redirect to the IdP dropped the hash (redirect_uri is
path-only and fragments don't round-trip), and the in-memory tab was wiped by the
full-page navigation — so they landed on a blank /sql after signing in.

bootstrap now stashes the decoded query in sessionStorage (`oauth_shared_sql`),
which survives the same-tab redirect like oauth_state/verifier, and restores it
when the hash is gone, clearing it once consumed on a signed-in render.

Verified in-browser: not-signed-in load stashes the query + shows login; the
post-redirect load (no hash, signed in) restores it into the editor and clears
the stash. 353 tests pass; main.js at 100%.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QennTvGKAtJZrv9EpQagef
@BorisTyshkevich BorisTyshkevich merged commit d3c5027 into main Jun 20, 2026
2 checks passed
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