fix(drafts): skip public-secret-URL fetch in the Deploy drawer for draft-only apps

Opening the Deploy drawer on a `/edit/u/{user}/draft_{uuid}` app fired
`AppService.getPublicSecretOfApp` immediately because the gating effect
only checked `appPath != ''` + `savedApp`. The `/secret_of/{path}` route
plain-SELECTs `app.id`, so a draft-only path 404'd with
"App not found at name …" and the public-URL ClipboardPanel spun
forever waiting on `secretUrl`.

Thread the existing `newApp` signal (already on `AppEditorHeader` /
`RawAppEditorHeader`) into `AppEditorHeaderDeploy`, gate the fetch
behind `!newApp`, and render the existing "Deploy this app once to get
the public secret URL" placeholder instead of the spinner for
draft-only items.
This commit is contained in:
Diego Imbert
2026-06-07 23:49:50 +02:00
parent 131eb8078d
commit 5f94207c02
3 changed files with 20 additions and 4 deletions
@@ -757,6 +757,7 @@
{/snippet}
<AppEditorHeaderDeploy
{newPath}
{newApp}
{policy}
{setPublishState}
appPath={$appPath}
@@ -36,7 +36,8 @@
newPath,
hideSecretUrl = false,
preserveOnBehalfOf = $bindable(false),
rawApp = false
rawApp = false,
newApp = false
}: {
policy: any
setPublishState: () => void
@@ -57,6 +58,11 @@
// document and break no-CORP cross-origin subresources (external images,
// {@html} embeds, CDN imports).
rawApp?: boolean
/** True while the editor is on a draft-only URL (`/edit/u/{user}/draft_{uuid}`
* with no deployed row yet). Suppresses the public-secret-URL fetch
* (`/secret_of/...` 404s with no `app` row) and renders a placeholder
* instead of the eternally-spinning link. */
newApp?: boolean
} = $props()
let isDeployer = $derived($userStore?.groups?.includes(WM_DEPLOYERS_GROUP) ?? false)
@@ -139,7 +145,15 @@
})
$effect(() => {
appPath && appPath != '' && savedApp && secretUrl == undefined && untrack(() => getSecretUrl())
// Skip the secret URL fetch on draft-only items — `/secret_of/...`
// has no `app` row to look up and would 404, leaving the UI
// component spinning indefinitely.
!newApp &&
appPath &&
appPath != '' &&
savedApp &&
secretUrl == undefined &&
untrack(() => getSecretUrl())
})
</script>
@@ -267,8 +281,8 @@
disabled={!savedApp}
/>
</div>
{#if !savedApp}
<ClipboardPanel content={`Save this app once to get the public secret URL`} size="md" />
{#if !savedApp || newApp}
<ClipboardPanel content={`Deploy this app once to get the public secret URL`} size="md" />
{:else if secretUrlHref}
<div class="flex justify-end mb-1">
<Toggle
@@ -609,6 +609,7 @@
<AppEditorHeaderDeploy
{newPath}
{newApp}
{policy}
{setPublishState}
{appPath}