From 0862d43ba3f24a9e2998ce9a2082ea03cdcf8752 Mon Sep 17 00:00:00 2001 From: Marcel Date: Sun, 14 Jun 2026 00:44:45 +0200 Subject: [PATCH] fix(timeline): mark the event form dirty on date/precision/picker changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The beforeNavigate unsaved-changes guard only fired for title/type/description (their oninput/onchange hooks set `dirty`). Editing only the date, precision, end-date, or the linked persons/documents left `dirty` false, so a curator could navigate away and silently lose those edits — defeating the guard for the senior author audience. Add an $effect that watches those values and marks dirty on any change after the initial prop snapshot (first run only arms the watcher). Addresses PR #832 review (round-2 clean-agent concern). Co-Authored-By: Claude Opus 4.8 --- frontend/src/lib/timeline/EventForm.svelte | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/frontend/src/lib/timeline/EventForm.svelte b/frontend/src/lib/timeline/EventForm.svelte index 46e51e98..38d752ea 100644 --- a/frontend/src/lib/timeline/EventForm.svelte +++ b/frontend/src/lib/timeline/EventForm.svelte @@ -105,6 +105,22 @@ function markDirty() { dirty = true; } +// title/type/description set `dirty` through their own oninput/onchange hooks, +// but the date/precision/end-date (inside DatePrecisionField) and the two pickers +// have no such hook — so changing only a date or a linked person would otherwise +// slip past the beforeNavigate guard. Watch those values and mark dirty on any +// change after the initial prop snapshot (the first run only arms the watcher). +let dirtyArmed = $state(false); +$effect(() => { + void dateIso; + void precision; + void endDateIso; + void selectedPersons.length; + void selectedDocuments.length; + if (dirtyArmed) dirty = true; + else dirtyArmed = true; +}); + // Guards a submit with a blank title client-side. The server re-validates and // owns the authoritative fail(400) with per-field flags. function handleSubmit(e: SubmitEvent) {