Skip to content

feat(ui): header user menu (hidden logout) + export/import saved queries#10

Merged
BorisTyshkevich merged 2 commits into
mainfrom
feat/user-menu-saved-io
Jun 21, 2026
Merged

feat(ui): header user menu (hidden logout) + export/import saved queries#10
BorisTyshkevich merged 2 commits into
mainfrom
feat/user-menu-saved-io

Conversation

@BorisTyshkevich

Copy link
Copy Markdown
Collaborator

What

Two additions from the design handoff (Altinity Play), both verified live on antalya.

1. Hide logout behind a header user control

The header showed the full email plus a standalone Log Out button — heavy and easy to mis-click. Replaced with a compact short-name + chevron control (btyshkevich ▾, the email local-part) that opens a dropdown:

  • identity row (full email)
  • red Log out item — signs out immediately (no confirm dialog)
  • closes on Esc / outside-click

2. Export / Import of saved queries

Saved queries live only in localStorage — no backup, no portability. Added a pinned Export / Import row at the bottom of the Saved panel.

  • Export → downloads all saved queries as JSON ({format, version, exportedAt, queries}). Disabled when the list is empty.
  • Import → reads a JSON file and merges + dedupes: skip exact name+SQL duplicates, update on id-match, add the rest. Reports Added N · updated N · skipped N. Validates format/version and reports a toast on malformed input.

Layering / tests

New pure logic at 100% per-file coverage:

  • core/format.jsuserShortName(email)
  • core/saved-io.js (new) — buildExportDoc / parseImportDoc / mergeSaved
  • state.jsimportSaved (persist via injected save + genId seams)

FileReader is injected through createApp(env) like the other side-effect seams. npm test green, coverage gate held (406 tests).

Verification

Deployed to antalya /sql and checked in-browser: short-name menu opens → email + red Log out, Esc closes; Export downloads sql-browser-queries-<date>.json and toasts Exported 1 query.

🤖 Generated with Claude Code

https://claude.ai/code/session_01QennTvGKAtJZrv9EpQagef

Isolator acm and others added 2 commits June 21, 2026 19:36
…ries

Header: replace the standalone email + "Log Out" button with a compact
short-name control (email local-part + chevron) that opens a dropdown
holding the full email and a red Log out item. Esc / outside-click close it;
Log out signs out immediately (no confirm), per design handoff.

Saved panel: pinned Export / Import row. Export downloads all saved queries
as JSON ({format,version,exportedAt,queries}); Import merges + dedupes
(skip exact name+SQL dups, update on id-match, add the rest) and reports
"Added N · updated N · skipped N".

New pure modules carry the logic at 100% coverage:
- core/format.js: userShortName(email)
- core/saved-io.js: buildExportDoc / parseImportDoc / mergeSaved
- state.js: importSaved (persists via injected save + genId seams)
FileReader is injected through createApp(env) like the other side-effects.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QennTvGKAtJZrv9EpQagef
It was position:sticky; bottom:0, so it stayed glued to the viewport bottom
over a scrolling list. Drop sticky — margin-top:auto still sinks it to the
bottom when the list is short, but a long list now scrolls it out of view.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QennTvGKAtJZrv9EpQagef
@BorisTyshkevich BorisTyshkevich merged commit 983ceb1 into main Jun 21, 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