mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-09 16:05:42 +00:00
fix(drafts): low-code apps — drop spurious autosave on /edit + remount on Load from server
Two bugs in low-code app editor (raw apps use a separate code path):
1. Every /edit visit looked like an autosave because loadApp() called
UserDraft.discard('app', path, undefined). The comment claimed
"this load doesn't POST" but discard always POSTs value: null
server-side — that surfaced as a DELETE-my-draft on every page
load AND a flash in the AutosaveIndicator.
The discard was originally intended to wipe the in-memory cell so
AppEditor remounts "fresh". But the path-change $effect upstream
already sets app = undefined before each loadApp, which unmounts
AppEditor and releases the handle's entry — so a remount via
app = backendApp naturally starts with an empty handle. Drop the
discard.
2. The conflict modal's "Load from server" called loadApp() but
didn't remount AppEditor. Since AppEditor's stateApp is captured
once at mount and doesn't react to prop changes, the editor kept
showing the conflicting local edits even after a successful reload.
Wrap the onLoadFromServer to await loadApp() then bump redraw to
force a fresh mount.
This commit is contained in:
@@ -166,11 +166,14 @@
|
||||
policy: backendApp_.policy,
|
||||
custom_path: backendApp_.custom_path
|
||||
}
|
||||
// Backend canonical: wipe the in-memory cell so AppEditor remounts
|
||||
// fresh from `backendApp.value`. The cell will be re-seeded by
|
||||
// AppEditor's mirror $effect; the first such write is swallowed
|
||||
// by `acquireEntry`'s seed guard so this load doesn't POST.
|
||||
UserDraft.discard('app', path, undefined)
|
||||
// Backend canonical: assign the fresh response onto `app`. The
|
||||
// path-change $effect upstream sets `app = undefined` before
|
||||
// calling loadApp, which unmounts AppEditor and releases the
|
||||
// UserDraft entry — so when `app = backendApp` triggers a
|
||||
// remount, the new handle starts fresh with no stale draft to
|
||||
// dedup against. (`UserDraft.discard` was here previously but
|
||||
// it POSTs `value: null` server-side, which surfaced as a
|
||||
// spurious autosave on every /edit visit.)
|
||||
app = backendApp
|
||||
}
|
||||
|
||||
@@ -225,7 +228,14 @@
|
||||
{path}
|
||||
{otherDraftsUsers}
|
||||
editPathFor={(forkedPath) => `/apps/edit/${forkedPath}`}
|
||||
onLoadFromServer={() => loadApp()}
|
||||
onLoadFromServer={async () => {
|
||||
// AppEditor's `stateApp` is captured once at mount and doesn't
|
||||
// react to prop changes, so a plain loadApp() reload would update
|
||||
// `app` but leave the editor displaying the conflicting local
|
||||
// state. `redraw++` remounts AppEditor against the fresh `app`.
|
||||
await loadApp()
|
||||
redraw++
|
||||
}}
|
||||
getLocalDraft={() => app?.value}
|
||||
/>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user