From a9ca756de8cd023c0f2cb9954f344fff11146bc2 Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Sat, 27 Jun 2026 19:46:24 +0900 Subject: feat(concurrency): 'Saved.' confirmation on the limit row + handoff update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backend now persists concurrency limits across reboots (no API contract change — same endpoints/shapes, so no re-pin/re-mirror needed). Taking the suggested optional UX hint: after a successful Save the limit row shows a brief green 'Saved.' that clears on the next edit (mirrors the ChatLimitField pattern). backend-handoff.md §2j: notes the persistence change + the two earlier backend-only changes (200ms release cooldown; 'queued' status — already shipped as CR-13). typecheck 0/0, 926 tests green, biome clean, build OK. --- src/features/concurrency/ui/ConcurrencyLimitRow.svelte | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src') diff --git a/src/features/concurrency/ui/ConcurrencyLimitRow.svelte b/src/features/concurrency/ui/ConcurrencyLimitRow.svelte index 411a3cd..5aacb88 100644 --- a/src/features/concurrency/ui/ConcurrencyLimitRow.svelte +++ b/src/features/concurrency/ui/ConcurrencyLimitRow.svelte @@ -23,6 +23,9 @@ let saving = $state(false); let removing = $state(false); let error = $state(null); + /** Brief "Saved" confirmation after a successful save (mirrors ChatLimitField). + * Cleared when the field is edited again. */ + let justSaved = $state(false); $effect(() => { const incoming = String(limit.limit); @@ -35,6 +38,12 @@ const parsed = $derived(parseLimitInput(draft)); const dirty = $derived(parsed !== null && parsed !== limit.limit); + // Clear the "Saved" hint + any error as soon as the user edits the field. + function onInput(): void { + justSaved = false; + error = null; + } + async function handleSave(): Promise { if (parsed === null || parsed === limit.limit) return; saving = true; @@ -46,6 +55,7 @@ // also re-assert it via the seed effect above once the parent reloads). draft = String(result.limit); lastSeed = draft; + justSaved = true; } else { error = result.error; } @@ -72,6 +82,7 @@ class="input input-bordered input-xs w-20 font-mono" aria-label={`Concurrency limit for ${limit.providerId}`} bind:value={draft} + oninput={onInput} disabled={saving || removing} />