Summary
Redesign Saved Queries as a named Library with document-style file operations in the header.
Move the current Saved-panel Export/Import buttons into a top-header File ▾ menu, add a visible editable Library name, and track unsaved Library changes with a small dirty indicator.
JSON remains the canonical lossless round-trip format. SQL/Markdown export can be added as share/publish actions, but should not be treated as equivalent importable Library formats.
Motivation
Saved queries are currently browser-local and per-profile. Users need a clear way to back up, transfer, and share their query Library.
The current Export/Import controls are hidden at the bottom of the Saved pane and feel like secondary panel actions. File operations are really document-level actions, so they should live in the app header.
Current state
- Saved queries are persisted locally.
- JSON export/import exists through
buildExportDoc, parseImportDoc, and mergeSaved.
- The Saved pane renders bottom-pinned Export / Import controls.
- Import currently appends/merges; there is no explicit Replace vs Append choice.
- There is no Library name or Library dirty state.
Proposed UX
Header:
Altinity SQL Browser <host> | File ▾ My queries •
- File ▾ is the action menu.
- My queries is the editable Library name.
- • appears when the Library has unsaved file changes.
Sidebar:
The Saved tab should be renamed to Library, but saved-query rows and search can still use “saved queries” where clearer.
File menu
New Library
────────────
Save Library
Save JSON .json
────────────
Load from file
Replace…
Append…
────────────
N queries in Library
Share / publish section:
Share / publish
Download Markdown .md
Download SQL .sql
Behavior
Save JSON
- Downloads the whole Library as the existing JSON envelope.
- Keeps
id, name, description,sql, favorite, chart, and view.
- Filename derives from the Library name:
My queries.json
- sanitize invalid filename characters.
- Clears the Library dirty indicator once the download is started.
- If the Library is empty, disable the action or show
Nothing to save.
Replace…
- Opens a file picker for
.json.
- Validates the existing envelope:
- matching
format
- supported
version
- valid
queries[]
- max count limit preserved
- If the current Library is non-empty, show a confirmation dialog:
Replace Library?
<filename> contains N queries. Replacing will remove your current M saved queries.
Open editor tabs are unaffected.
[Cancel] [Replace]
- Replaces the saved-query Library with the file contents.
- The Library adopts the file base name.
- Existing open editor tabs are unaffected.
- Imported SQL is never auto-run.
- Clears the dirty indicator.
Append…
- Opens a file picker for
.json.
- Merges into the current Library using existing merge semantics:
- skip exact name+SQL duplicates
- update by matching id when content differs
- otherwise add
- Shows a result toast:
Added 6 · updated 2 · skipped 3
- Sets the Library dirty indicator.
New Library
- If the current Library is non-empty, confirm first:
Start a new Library?
This clears your current saved queries and starts an empty Untitled Library.
Open editor tabs are unaffected.
[Cancel] [New Library]
- Clears saved queries.
- Sets name to
Untitled Library.
- Clears the dirty indicator.
Rename Library
- Clicking the Library title enters inline edit.
- Enter commits.
- Escape cancels.
- Empty name falls back to
Untitled Library.
- Name is persisted separately from saved queries.
- Rename sets the dirty indicator because it affects the next saved file name/document identity.
Dirty indicator
Set dirty on:
- save or update saved query
- rename saved query
- delete saved query
- toggle favorite
- append import
- Library rename
Clear dirty on:
- Save JSON
- Replace
- New Library
Do not set Library dirty when editing an open query tab unless that edit is saved into the Library.
Out of scope for this issue
- Multiple simultaneously open Libraries.
- Server-side/account-backed Library sync.
- Conflict-resolution UI beyond the current merge behavior.
- Selecting a subset of queries for export/import.
Markdown / SQL download
Markdown and SQL should be handled as share/export features, not as canonical Library files.
- Download Markdown
- Download SQL
Markdown exports should include a title as a 3rd-level heading, a description as a paragraph, and a fenced SQL block. It is useful for GitHub, docs, PRs, Slack, and wikis, but it should be one-way because metadata like ids, chart config, result view, and exact favorite state are not reliably preserved.
SQL exports should include title and description in /* ... */ comment block followed by sql query. Add ; (semicolon) as a delimiter between sql statements.
Implementation notes
- Add
libraryName and libraryDirty to state.
- Add storage key for Library name.
- Add state operations:
renameLibrary
newLibrary
replaceLibrary
appendLibrary
markLibrarySaved
- Reuse existing JSON envelope:
buildExportDoc
parseImportDoc
mergeSaved
- Move export/import UI out of
saved-history.js.
- Remove
savedActions().
- Add a header File menu component.
- Update Saved tab label to
Library · N.
- Add tests for:
- Library name persistence
- dirty flag transitions
- Save JSON filename generation
- Replace confirmation path
- Append merge result
- invalid JSON import errors
- open tabs unaffected by Replace/New
Acceptance criteria
- Header shows
File ▾, editable Library name, and dirty dot.
- Saved panel no longer contains Export / Import buttons.
- File menu supports New Library, Save JSON, Replace, and Append.
- JSON Save round-trips existing saved-query metadata losslessly.
- Replace and New confirm before destructive changes.
- Append reports added/updated/skipped counts.
- Library name is persisted and used for the JSON filename.
- Dirty indicator behavior matches the rules above.
- Invalid/unsupported files show a clear error toast.
- Imported queries are never executed automatically.
Summary
Redesign Saved Queries as a named Library with document-style file operations in the header.
Move the current Saved-panel Export/Import buttons into a top-header File ▾ menu, add a visible editable Library name, and track unsaved Library changes with a small dirty indicator.
JSON remains the canonical lossless round-trip format. SQL/Markdown export can be added as share/publish actions, but should not be treated as equivalent importable Library formats.
Motivation
Saved queries are currently browser-local and per-profile. Users need a clear way to back up, transfer, and share their query Library.
The current Export/Import controls are hidden at the bottom of the Saved pane and feel like secondary panel actions. File operations are really document-level actions, so they should live in the app header.
Current state
buildExportDoc,parseImportDoc, andmergeSaved.Proposed UX
Header:
Sidebar:
The Saved tab should be renamed to Library, but saved-query rows and search can still use “saved queries” where clearer.
File menu
Share / publish section:
Behavior
Save JSON
id,name,description,sql,favorite,chart, andview.My queries.jsonNothing to save.Replace…
.json.formatversionqueries[]Append…
.json.New Library
Untitled Library.Rename Library
Untitled Library.Dirty indicator
Set dirty on:
Clear dirty on:
Do not set Library dirty when editing an open query tab unless that edit is saved into the Library.
Out of scope for this issue
Markdown / SQL download
Markdown and SQL should be handled as share/export features, not as canonical Library files.
Markdown exports should include a title as a 3rd-level heading, a description as a paragraph, and a fenced SQL block. It is useful for GitHub, docs, PRs, Slack, and wikis, but it should be one-way because metadata like ids, chart config, result view, and exact favorite state are not reliably preserved.
SQL exports should include title and description in /* ... */ comment block followed by sql query. Add ; (semicolon) as a delimiter between sql statements.
Implementation notes
libraryNameandlibraryDirtyto state.renameLibrarynewLibraryreplaceLibraryappendLibrarymarkLibrarySavedbuildExportDocparseImportDocmergeSavedsaved-history.js.savedActions().Library · N.Acceptance criteria
File ▾, editable Library name, and dirty dot.