feat(transcription): drive @mention fetch through the dropdown search input
For issue #380 (AC-2, AC-3, AC-4 + NFR debounce). The search input is now the single fetch trigger. The dropdown's searchQuery reactivity calls onSearch on every change — whether sourced from the editor mirror or the user's own input. PersonMentionEditor debounces these calls at 150 ms, short-circuits on empty queries (no fetch, items cleared), and tears down pending timers on destroy. The Tiptap suggestion plugin's items() now returns [] — per-keystroke fetches in the editor are gone. The same /api/persons?q= endpoint is used; the difference is in when and how often the request fires. Adds a cancel() method to the debounce utility so destroyed editors don't leave trailing fetches alive (which previously polluted the test ledger and would have wasted bandwidth in production tab-close races). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -40,6 +40,14 @@ $effect(() => {
|
||||
}
|
||||
});
|
||||
|
||||
// Fire onSearch whenever the effective query changes — covers both the
|
||||
// editor mirror and direct input edits. This is the only place onSearch
|
||||
// fires; when the dropdown is unmounted, the effect is disposed and no
|
||||
// further fetches occur.
|
||||
$effect(() => {
|
||||
onSearch(searchQuery);
|
||||
});
|
||||
|
||||
// highlightedIndex must be both writable (keyboard handler mutates it) and
|
||||
// reset when `items` changes (so it never points past the end of a new list).
|
||||
// A pure $derived is read-only and cannot serve both needs, so $state + $effect
|
||||
@@ -161,9 +169,8 @@ function selectItem(item: Person) {
|
||||
class="min-h-[44px] w-full bg-transparent font-sans text-sm text-ink placeholder:text-ink-3 focus:outline-none focus-visible:ring-2 focus-visible:ring-brand-navy focus-visible:ring-inset"
|
||||
placeholder={m.person_mention_search_prompt()}
|
||||
bind:value={searchQuery}
|
||||
oninput={(e) => {
|
||||
oninput={() => {
|
||||
userHasEdited = true;
|
||||
onSearch(e.currentTarget.value);
|
||||
}}
|
||||
onmousedown={(e) => e.stopPropagation()}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user