From 3290b80817842161cbfc3dedd18db3c6c4be30a6 Mon Sep 17 00:00:00 2001 From: Diego Imbert Date: Mon, 8 Jun 2026 01:03:48 +0200 Subject: [PATCH] fix(drafts): preserve the user-typed draft_path on reload of draft-only items MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The flow / app / raw-app editors all dropped the saved `draft_path` back to the URL's `u/{user}/draft_{uuid}` slot the moment the user reloaded a draft-only edit page: the route sourced the Path widget's initial path from `page.params.path` instead of the previously-saved `draft_path`, and the first user edit then mirrored that URL path back into the autosaved draft — silently overwriting the friendly name in both the row and the editor. - Flow route: after computing `effectiveFlow`, override `flowInitialPath` with `effectiveFlow.draft_path` when set. - App route: pass `newPath={(app.value as any)?.draft_path ?? app.path}` through to `AppEditor`; AppEditorHeader's `newEditedPath` default now prefers a non-empty `newPath` over the random `_app` seed (the `newApp && !newPath` branch keeps the `/apps/add` friendly auto-name). - Raw-app route: surface `savedRawAppDraft.draft_path` onto `backendApp` so the `extractRawApp` path seeds `newPath` with the friendly name. Reload + a subsequent edit now leaves `draft_path` intact for all three kinds; verified end-to-end via the `/drafts/get_draft/...` endpoint. --- .../components/apps/editor/AppEditorHeader.svelte | 4 +++- .../(logged)/apps/edit/[...path]/+page.svelte | 2 +- .../(logged)/apps_raw/edit/[...path]/+page.svelte | 13 ++++++++++++- .../(logged)/flows/edit/[...path]/+page.svelte | 9 +++++++++ 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte b/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte index bd3b1dce67..6322083976 100644 --- a/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte +++ b/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte @@ -141,7 +141,9 @@ * rename detection still works. */ let newEditedPath = $state( untrack(() => - newApp ? userPathPrefix($userStore?.username) + random_adj() + '_app' : (newPath ?? '') + newApp && !newPath + ? userPathPrefix($userStore?.username) + random_adj() + '_app' + : (newPath ?? '') ) ) let deployedValue: Value | undefined = $state(undefined) // Value to diff against diff --git a/frontend/src/routes/(root)/(logged)/apps/edit/[...path]/+page.svelte b/frontend/src/routes/(root)/(logged)/apps/edit/[...path]/+page.svelte index e1acb84259..bbff2a42de 100644 --- a/frontend/src/routes/(root)/(logged)/apps/edit/[...path]/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/apps/edit/[...path]/+page.svelte @@ -345,7 +345,7 @@ on:restore={onRestore} summary={app.summary} app={app.value} - newPath={app.path} + newPath={(app.value as any)?.draft_path ?? app.path} path={page.params.path ?? ''} policy={app.policy} bind:savedApp diff --git a/frontend/src/routes/(root)/(logged)/apps_raw/edit/[...path]/+page.svelte b/frontend/src/routes/(root)/(logged)/apps_raw/edit/[...path]/+page.svelte index 9c2609c9a7..4f7562e564 100644 --- a/frontend/src/routes/(root)/(logged)/apps_raw/edit/[...path]/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/apps_raw/edit/[...path]/+page.svelte @@ -210,7 +210,11 @@ summary = app.summary // lastVersion = app.version policy = app.policy - newPath = app.path + // Reload of a draft-only (or rename-in-progress) raw app: prefer + // the previously-typed `draft_path` so the topbar shows the + // pending friendly name instead of the autogenerated + // `u/{user}/draft_{uuid}` URL slot. + newPath = (app as any).draft_path ?? app.path } /** Increments per `loadApp` call. Stale loads (e.g. when picker @@ -321,8 +325,15 @@ summary?: string policy?: any custom_path?: string + draft_path?: string } | undefined + // Surface the saved `draft_path` on `backendApp` so the + // extract-from-backend path below seeds `newPath` with the + // friendly name instead of the URL `draft_{uuid}` slot. + if (savedRawAppDraft?.draft_path) { + ;(backendApp as any).draft_path = savedRawAppDraft.draft_path + } if (backendApp.no_deployed) { backendApp.value = { files: savedRawAppDraft?.files ?? {}, diff --git a/frontend/src/routes/(root)/(logged)/flows/edit/[...path]/+page.svelte b/frontend/src/routes/(root)/(logged)/flows/edit/[...path]/+page.svelte index 61ff0766e6..a0c1a9de56 100644 --- a/frontend/src/routes/(root)/(logged)/flows/edit/[...path]/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/flows/edit/[...path]/+page.svelte @@ -294,6 +294,15 @@ ? ({ ...deployedFlow, ...draftFromBackend } as Flow) : (deployedFlow as Flow) savedFlow = structuredClone($state.snapshot(effectiveFlow)) as Flow + // Reload of a draft-only (or rename-in-progress) flow: surface + // the previously-typed `draft_path` to the Path widget so the + // topbar shows the user's pending name instead of the + // autogenerated `u/{user}/draft_{uuid}` URL slot. Without this + // the widget seeds from `page.params.path`, the user's first + // edit clobbers `draft.draft_path` back to the URL path, and + // the home list silently loses the friendly name. + const renderedDraftPath = (effectiveFlow as any).draft_path as string | undefined + if (renderedDraftPath) flowInitialPath = renderedDraftPath const localDraft = flowHandle.draft const previousMeta = flowHandle.meta