fix(frontend): drop in-memory handle in DiffDrawer restoreDraft/restoreDeployed

Same UserDraft.remove-without-clearing-in-memory bug as the previous
two commits, this time in the DiffDrawer's "Restore to draft" /
"Restore to deployed" buttons on all four /edit routes. The handler
deletes the DB draft (in the deployed case), wipes the localStorage
entry, navigates, and reloads — but the route's UserDraft handle
still holds the old draft + meta in memory, so the reload's
staleness check compares the stale meta against the freshly fetched
backend and surfaces a spurious "newer version was deployed" modal.

- scripts/edit, flows/edit, apps_raw/edit: route-level handle —
  `handle.setDraftAndMeta(undefined, {})` before the reload.
- apps/edit: the handle lives in the AppEditor child, so force a
  remount by setting `app = undefined; redraw++` before goto/loadApp
  (matches the existing pattern from the toast's onResetToDeployed).
This commit is contained in:
Diego Imbert
2026-05-15 15:41:26 +02:00
parent fec207cc99
commit 202b3f69d8
4 changed files with 26 additions and 0 deletions
@@ -239,6 +239,12 @@
}
diffDrawer?.closeDrawer()
UserDraft.remove('app', path)
// Force AppEditor to unmount so its UserDraft handle releases —
// otherwise loadApp's `UserDraft.get` would read the stale autosave
// from the still-alive in-memory entry and the staleness check
// would fire a spurious "newer version was deployed" modal.
app = undefined
redraw++
goto(`/apps/edit/${savedApp.draft.path}`)
await loadApp()
redraw++
@@ -258,6 +264,8 @@
})
}
UserDraft.remove('app', path)
app = undefined
redraw++
goto(`/apps/edit/${savedApp.path}`)
await loadApp()
redraw++
@@ -278,6 +278,11 @@
}
diffDrawer?.closeDrawer()
UserDraft.remove('raw_app', path)
// Drop the in-memory handle state so loadApp sees no local draft
// on the next pass — otherwise the staleness check would compare
// the stale in-memory meta against the freshly fetched backend and
// fire a spurious modal.
draftHandle.setDraftAndMeta(undefined, {})
goto(`/apps/edit/${savedApp.draft.path}`)
await loadApp()
redraw++
@@ -297,6 +302,7 @@
})
}
UserDraft.remove('raw_app', path)
draftHandle.setDraftAndMeta(undefined, {})
goto(`/apps/edit/${savedApp.path}`)
await loadApp()
redraw++
@@ -304,6 +304,11 @@
}
diffDrawer?.closeDrawer()
UserDraft.remove('flow', flowDraftPath)
// Drop the in-memory handle state so loadFlow sees no local draft
// on the next pass — otherwise the staleness check would compare
// the stale in-memory meta against the freshly fetched backend and
// fire a spurious modal.
flowHandle.setDraftAndMeta(undefined, {})
goto(`/flows/edit/${savedFlow.draft.path}`)
loadFlow()
}
@@ -322,6 +327,7 @@
})
}
UserDraft.remove('flow', flowDraftPath)
flowHandle.setDraftAndMeta(undefined, {})
goto(`/flows/edit/${savedFlow.path}`)
loadFlow()
}
@@ -299,6 +299,11 @@
}
diffDrawer?.closeDrawer()
UserDraft.remove('script', draftPath)
// Drop the in-memory handle state so loadScript sees no local draft
// on the next pass — otherwise the staleness check would compare the
// stale in-memory meta against the freshly fetched backend and fire
// a spurious modal.
scriptHandle.setDraftAndMeta(undefined, {})
goto(`/scripts/edit/${savedScript.draft.path}`)
loadScript()
}
@@ -317,6 +322,7 @@
})
}
UserDraft.remove('script', draftPath)
scriptHandle.setDraftAndMeta(undefined, {})
goto(`/scripts/edit/${savedScript.path}`)
loadScript()
}