From 066149c6fbe6b4bbf4f2d8f8cd5e57fad9ca3bb6 Mon Sep 17 00:00:00 2001 From: Diego Imbert Date: Fri, 15 May 2026 17:58:49 +0200 Subject: [PATCH] feat(frontend): restored-from-local toast in resource/variable editors Resource and variable editors silently loaded LS autosaves over the backend value, leaving users with no signal that the form wasn't reflecting deployed state. Both now fire the standard `notifyRestoredFromLocal` toast (with a "Reset to deployed" action that re-seeds the handle from the just-fetched backend) the first time a lazy-fetch finds the local draft diverging from the remote. --- .../src/lib/components/ResourceEditor.svelte | 16 ++++++++++++++++ .../src/lib/components/VariableEditor.svelte | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/frontend/src/lib/components/ResourceEditor.svelte b/frontend/src/lib/components/ResourceEditor.svelte index 6827eb74f5..6460d8fbcc 100644 --- a/frontend/src/lib/components/ResourceEditor.svelte +++ b/frontend/src/lib/components/ResourceEditor.svelte @@ -13,6 +13,7 @@ import { getUserExt } from '$lib/user' import type { UserExt } from '$lib/stores' import { UserDraft, type UserDraftHandle } from '$lib/userDraft.svelte' + import { notifyRestoredFromLocal } from '$lib/userDraftToast' interface Props { canSave?: boolean @@ -204,6 +205,21 @@ labels: r.labels ?? undefined, wsSpecific: r.ws_specific ?? false } + // Surface the local autosave-vs-backend divergence before the + // handle is registered, so the user knows the form is showing + // their unsaved work. The "Reset to deployed" action drops the + // LS entry and re-seeds the handle from the just-fetched + // backend state. + const persisted = UserDraft.get('resource', initialPath ?? '', { + workspace: ws + }) + if (persisted !== undefined && !deepEqual(persisted, s)) { + notifyRestoredFromLocal(false, true, { + onResetToDeployed: () => { + UserDraft.save('resource', initialPath ?? '', s, { workspace: ws }) + } + }) + } ensureHandle(ws, s) initialStates[ws] = structuredClone(s) existedInitially[ws] = true diff --git a/frontend/src/lib/components/VariableEditor.svelte b/frontend/src/lib/components/VariableEditor.svelte index 3ab1d71fc9..8eaea0295d 100644 --- a/frontend/src/lib/components/VariableEditor.svelte +++ b/frontend/src/lib/components/VariableEditor.svelte @@ -16,6 +16,7 @@ import { getUserExt } from '$lib/user' import type { UserExt } from '$lib/stores' import { UserDraft, type UserDraftHandle } from '$lib/userDraft.svelte' + import { notifyRestoredFromLocal } from '$lib/userDraftToast' const dispatch = createEventDispatcher() @@ -129,6 +130,17 @@ labels: v.labels ?? undefined, wsSpecific: v.ws_specific ?? false } + // See ResourceEditor for the same pattern: tell the user the + // form is showing their local autosave (not the backend), + // with a one-click "Reset to deployed" escape. + const persisted = UserDraft.get('variable', p, { workspace: ws }) + if (persisted !== undefined && !deepEqual(persisted, s)) { + notifyRestoredFromLocal(false, true, { + onResetToDeployed: () => { + UserDraft.save('variable', p, s, { workspace: ws }) + } + }) + } ensureHandle(ws, s) initialStates[ws] = structuredClone(s) existedInitially[ws] = true