feat(badges): Remote First confirmation warning + title tooltips

Enabling Remote First now shows an inline warning explaining that it
bypasses the local cache and queries the server on every keystroke.
User must confirm before it activates; Cancel leaves the checkbox off.
Disabling still takes effect immediately. Label and checkbox also get
title tooltips. Active state gets a warning tonal highlight.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-06-09 12:12:28 -04:00
parent 7b45b548e4
commit b6481a3507

View File

@@ -15,7 +15,8 @@ import {
QrCode,
RemoveFormatting,
Search,
StepForward
StepForward,
TriangleAlert
} from '@lucide/svelte';
import { fade, slide } from 'svelte/transition';
import { ae_loc, ae_api } from '$lib/stores/ae_stores';
@@ -77,6 +78,28 @@ function handle_search_trigger() {
badges_loc.current.search_version++;
}
let show_remote_first_confirm = $state(false);
function handle_remote_first_click(e: MouseEvent) {
// Always manage state manually so the checkbox never flickers mid-handler.
e.preventDefault();
const checkbox = e.currentTarget as HTMLInputElement;
if (checkbox.checked) {
// User wants to enable — show confirmation first.
show_remote_first_confirm = true;
} else {
badges_loc.current.qry__remote_first = false;
show_remote_first_confirm = false;
handle_search_trigger();
}
}
function confirm_remote_first() {
badges_loc.current.qry__remote_first = true;
show_remote_first_confirm = false;
handle_search_trigger();
}
function prevent_default<T extends Event>(fn: (event: T) => void) {
return function (event: T) {
event.preventDefault();
@@ -346,17 +369,49 @@ function handle_qr_scan_result(event: {
{#if $ae_loc.trusted_access}
<label
transition:fade={{ duration: 150 }}
class="bg-surface-200-800 rounded-token flex cursor-pointer items-center gap-1 px-2 py-1 text-xs font-semibold">
title="Remote First: skip the local cache and query the server directly on every search"
class="bg-surface-200-800 rounded-token flex cursor-pointer items-center gap-1 px-2 py-1 text-xs font-semibold"
class:preset-tonal-warning={badges_loc.current.qry__remote_first}>
<span>Remote First</span>
<input
type="checkbox"
bind:checked={badges_loc.current.qry__remote_first}
onchange={handle_search_trigger}
checked={badges_loc.current.qry__remote_first}
onclick={handle_remote_first_click}
title="When enabled, every search queries the server directly instead of using the local cache"
class="checkbox checkbox-sm" />
</label>
{/if}
{/if}
</div>
{#if show_remote_first_confirm}
<div
transition:slide={{ duration: 150 }}
class="flex w-full flex-col gap-2 rounded-md border border-warning-400 dark:border-warning-600 bg-warning-50 dark:bg-warning-900/20 px-3 py-2 text-sm">
<div class="flex items-start gap-2">
<TriangleAlert size="1em" class="mt-0.5 shrink-0 text-warning-600 dark:text-warning-400" />
<p class="text-warning-900 dark:text-warning-100">
<strong>Remote First</strong> skips the local cache and queries the server on every keystroke.
Results will always reflect the latest data but searches may be slower.
Use this only if recent changes aren't showing up in search results.
</p>
</div>
<div class="flex justify-end gap-2">
<button
type="button"
onclick={() => (show_remote_first_confirm = false)}
class="btn btn-sm preset-tonal-surface border border-surface-300-700">
Cancel
</button>
<button
type="button"
onclick={confirm_remote_first}
class="btn btn-sm preset-filled-warning border border-warning-600">
Enable Remote First
</button>
</div>
</div>
{/if}
</form>
{:else if $events_sess.badges.show_form__scan}
<div