Altinity / Altinity/altinity-sql-browser

Add documentation search UI to the Reference drawer

Aperta
#422 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

enhancement
Lingua principale
TypeScript
Stelle
8
Fork
2
Merge medio
1h 34m
PR unite (30g)
6

Descrizione

Parent design: #420
Depends on: #421

Purpose

Add the user-facing documentation search experience to the existing persistent Reference drawer, using the SchemaCatalogService.docSearch() API from #421.

This issue owns drawer chrome, search submission, result rendering, focus and keyboard behavior, stale-response suppression, Back-stack snapshots, responsive layout, accessibility, and regression coverage. It must not execute SQL or duplicate catalog ranking/normalization logic.

Header design

Add a persistent search form to the Reference drawer header:

Reference   [ Search functions, engines, types, settings… ] [Search]   ×

Requirements:

  • Keep “Reference” visible as the drawer title.
  • Keep the close button as the rightmost control.
  • The search form survives every body-state replacement.
  • The input grows to use available width.
  • At narrow drawer widths, allow the title/close row and search form to wrap onto two rows.
  • Never shrink the close target or make the search input unusably narrow.

Use semantic controls:

<form role="search" aria-label="Search ClickHouse documentation">
  <input
    type="search"
    aria-label="Search documentation"
    autocomplete="off"
    spellcheck="false"
  >
  <button type="submit" aria-label="Search documentation">Search</button>
</form>

Suggested placeholder:

Search functions, engines, types, settings…

Submission behavior

  • Submit explicitly with Enter or the Search button.
  • Do not issue a request for empty, whitespace-only, or one-character normalized input.
  • Do not search on every keystroke.
  • Keep focus in the input after results, no-results, or unavailable settles.
  • Disable or mark the button busy while the identical query is in flight.
  • A different submitted query supersedes the earlier one.
  • The pane token must suppress any late result from an older search.

The UI delegates to:

app.catalog.docSearch(query)

No SQL or source-table knowledge belongs in doc-pane.ts.

Keyboard behavior

  • Enter in the search input submits.
  • ArrowDown in the input focuses the first result when one exists.
  • / while focus is inside the drawer but not in a text-editing control focuses the search input.
  • Escape with non-empty search text clears the input and current search state first.
  • Escape with an empty search input preserves the drawer’s existing close behavior.
  • Escape handled inside the drawer must continue to prevent the global shortcut handler from also cancelling a running query.
  • Browser-reserved shortcuts remain browser-owned.

Search result state

Add a new body state alongside loading, found entry, disambiguation, missing, and unavailable.

Example:

23 results for “array”

[aggregate function] groupArray
Creates an array of argument values…

[function] arrayJoin
Unfolds an array into rows…

[data type] Array
An array of values of type T…

Render with semantic list markup:

<div role="status" aria-live="polite">23 results for “array”</div>
<ul aria-label="Documentation search results">
  <li><button type="button">…</button></li>
</ul>

Each result button contains:

  • logical DocKind badge;
  • canonical title/name;
  • one or two lines of plain-text summary;
  • optional safe visual highlighting of matched name fragments.

Do not render server result text as HTML.

Physical source_table provenance remains in the model for diagnostics/testing but does not replace the logical kind badge in the primary UI.

Result selection

Selecting a result must:

  1. capture the current search snapshot;
  2. push that snapshot onto the existing bounded Back stack;
  3. call the existing target-aware entry lookup path with the result’s DocTarget;
  4. render the existing structured/Markdown documentation entry;
  5. preserve all existing alias, related-entry, and disambiguation behavior.

Search results are not full documentation entries. Do not add another entry renderer.

Back-stack search snapshots

Extend the pane’s existing BackEntry union:

type BackEntry =
  | { kind: 'target'; target: DocTarget }
  | { kind: 'disambiguation'; name: string }
  | {
      kind: 'search';
      query: string;
      response: DocSearchResponse;
      selectedIndex: number;
      scrollTop: number;
      connectionGeneration: number;
    };

When navigating from results to an entry, store:

  • normalized query;
  • bounded search response;
  • selected result index;
  • result-body scroll position;
  • active connection generation.

Back from the entry restores:

  • input text;
  • the same result list without another SQL request;
  • result count;
  • scroll position;
  • focus to the previously selected result when still connected.

If the connection generation changed, do not restore stale results; clear the invalid snapshot and require a new search.

The existing Back-stack cap remains authoritative.

Loading state

During a search:

  • retain the query in the input;
  • set aria-busy="true" on the result/body region;
  • show a button spinner or disabled busy state;
  • prevent duplicate manual submission of the identical in-flight query.

Using the existing full-body loading state is acceptable initially. Retaining the previous body until the replacement settles is preferred but not required.

No-results state

When docSearch() returns missing, render:

No documentation found for “xyz”.

Keep the query and input focus. This is distinct from a target-specific missing documentation entry.

Unavailable state

When docSearch() returns unavailable, reuse the drawer’s quiet unavailable/Retry pattern:

Reference search isn't available on this server or connection.

Retry reruns the current normalized query through docSearch().

Do not show a toast for capability or permission failures.

Pane state and lifecycle

Likely additions:

interface PaneState {
  // existing fields
  searchInput: HTMLInputElement;
  searchButton: HTMLButtonElement;
  currentSearch: {
    query: string;
    response: DocSearchResponse;
  } | null;
}

Required stale-response behavior:

  • submitting a new search invalidates the previous search paint;
  • selecting a result invalidates an in-flight search paint;
  • external openDocEntry() or openDocDisambiguation() invalidates in-flight search paint and begins its existing fresh browsing session;
  • closing the drawer invalidates pending search responses;
  • sign-out/reconnect invalidates pending search responses;
  • no late response may replace newer body content.

Focus behavior

  • Opening an external entry continues to record the initiating focus target.
  • Search submission does not unexpectedly move focus.
  • Result count is announced through aria-live.
  • ArrowDown explicitly moves to the first result.
  • Selecting a result moves focus according to the existing entry-rendering convention.
  • Back restores result focus when possible.
  • Closing the drawer restores focus through the existing initiator logic.
  • Search controls remain usable after entry, alias, related, disambiguation, missing, unavailable, and Back transitions.

Styling

Add styles for:

  • flexible/wrapping Reference header;
  • search input and button sizing;
  • busy/disabled search state;
  • result count/status;
  • semantic result list reset;
  • full-width result buttons;
  • kind badge/title/summary layout;
  • one/two-line summary truncation;
  • hover, keyboard focus, and restored-selection states;
  • no-results and unavailable states;
  • narrow drawer widths.

Do not alter the drawer’s persisted-width behavior or make the pane modal.

Suggested implementation boundary

src/ui/doc-pane.ts

Own:

  • persistent search form;
  • submission and keyboard handling;
  • pane-token stale checks;
  • result/loading/missing/unavailable rendering;
  • result selection through existing lookup;
  • search Back snapshots;
  • focus and scroll restoration;
  • live-region announcements.
src/styles.css

Own only layout and visual states.

src/ui/app.types.ts or narrow pane contract

Expose catalog.docSearch() without broadening dependencies unnecessarily.

Tests

Header
  • Reference title remains present.
  • Search form has role="search" and an accessible name.
  • Input and button are labelled.
  • Close remains rightmost.
  • Header safely wraps at constrained width.
  • Search form survives body replacement.
Submission
  • Enter submits.
  • Button submits.
  • empty/whitespace/one-character input does not call the service.
  • normalized query is passed to the service.
  • duplicate identical submission while in flight does not cause another request.
  • a different second query supersedes the first.
Stale responses
  • late first search cannot replace second search results.
  • late search cannot replace a selected entry.
  • late search cannot repaint a closed pane.
  • reconnect/sign-out prevents old search results from rendering.
  • external F1/hover/completion open suppresses an in-flight search.
Results
  • count and query render correctly.
  • count is announced with aria-live.
  • results use semantic list/buttons.
  • kind, title, and summary render.
  • summaries are text, not HTML.
  • physical source remains available in the model but logical kind is primary.
  • missing renders the search no-results state.
  • unavailable renders Retry.
  • Retry repeats the current query.
Selection and Back
  • selecting a result calls the existing target-aware lookup.
  • search snapshot is pushed before entry navigation.
  • Back restores query, result rows, selected index, focus, and scroll.
  • Back does not rerun SQL while the snapshot remains generation-valid.
  • changed generation rejects the snapshot.
  • existing Back-stack cap still applies.
Keyboard/focus
  • ArrowDown focuses first result.
  • / focuses search only from appropriate non-text drawer targets.
  • Escape clears non-empty search before closing.
  • Escape with empty search closes the pane.
  • Escape does not also cancel a running query.
  • drawer close restores the valid initiator.
Regressions
  • editor hover opening remains unchanged.
  • completion info opening remains unchanged.
  • F1 entry/disambiguation remains unchanged.
  • aliases and related entries remain unchanged.
  • existing loading, missing, unavailable, Retry, and Markdown rendering remain unchanged.
  • CodeViewer teardown remains correct.
  • drawer resizing and persisted width remain unchanged.

Acceptance criteria

  • The persistent Reference header contains a responsive, accessible search form.
  • Search is explicitly submitted and delegates only to catalog.docSearch().
  • Results render as a safe semantic list with kind, name, and summary.
  • Selecting a result uses the existing full-entry lookup/rendering path.
  • Search Back snapshots restore query, results, selection, focus, and scroll without rerunning SQL.
  • Pane tokens and connection generation prevent stale search repaint.
  • Empty, loading, no-results, and unavailable states behave distinctly.
  • Escape, ArrowDown, /, close, and focus restoration are accessible and do not conflict with global shortcuts.
  • Existing Reference entry/disambiguation/navigation behavior remains intact.

Non-goals

  • SQL construction, capability probing, ranking, merge, or caching logic.
  • Search-as-you-type.
  • Kind filter UI.
  • Position/proximity-aware ranking.
  • Remote documentation search.
  • New full-entry rendering.

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia in src/ui/doc-pane.ts e analizza il Reference drawer esistente, la ricerca delle voci sensibile al target, lo stack Back e la gestione del focus; poi esamina il contratto di catalog.docSearch() di #421. Aggiorna src/styles.css e il contratto circoscritto di app.types.ts secondo necessità. Il lavoro è completo quando funzionano gli stati di ricerca accessibili, l’elenco sicuro dei risultati, la selezione, gli snapshot di Back sensibili alla generazione, la soppressione delle risposte obsolete e i comportamenti di tastiera e di regressione elencati, senza modificare il rendering esistente delle voci.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
clickhouse, typescript
Ambito
frontend
Tipo di issue
Funzionalità
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Tranquilla
Chiarezza
Abbastanza chiara
Idoneità per principianti
52/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.