fix: route draft-only deletes through UserDraftDbSyncer on home page

This commit is contained in:
Diego Imbert
2026-06-02 14:16:48 +02:00
parent d6e8ffc988
commit 69d5aa6db9
4 changed files with 54 additions and 7 deletions
@@ -6,6 +6,7 @@
import type ShareModal from '$lib/components/ShareModal.svelte'
import { AppService, type ListableApp } from '$lib/gen'
import { userStore, workspaceStore } from '$lib/stores'
import { UserDraftDbSyncer } from '$lib/userDraftDbSyncer.svelte'
import { createEventDispatcher } from 'svelte'
import Button from '../button/Button.svelte'
import Row from './Row.svelte'
@@ -69,6 +70,22 @@
async function loadAppJson() {
appExport?.open(app.path)
}
async function deleteApp(path: string): Promise<void> {
// Draft-only items have no deployed row — the regular route would
// 404. Route the delete through the syncer instead; the `app` vs
// `raw_app` choice mirrors the row's own `raw_app` flag.
if (app.draft_only) {
await UserDraftDbSyncer.save({
workspace: $workspaceStore ?? '',
itemKind: app.raw_app ? 'raw_app' : 'app',
path,
value: null
})
} else {
await AppService.deleteApp({ workspace: $workspaceStore ?? '', path })
}
}
</script>
{#if menuOpen}
@@ -165,11 +182,11 @@
// TODO
// @ts-ignore
if (event?.shiftKey) {
await AppService.deleteApp({ workspace: $workspaceStore ?? '', path })
await deleteApp(path)
dispatch('change')
} else {
deleteConfirmedCallback = async () => {
await AppService.deleteApp({ workspace: $workspaceStore ?? '', path })
await deleteApp(path)
dispatch('change')
}
}
@@ -276,11 +293,11 @@
// TODO
// @ts-ignore
if (event?.shiftKey) {
await AppService.deleteApp({ workspace: $workspaceStore ?? '', path })
await deleteApp(path)
dispatch('change')
} else {
deleteConfirmedCallback = async () => {
await AppService.deleteApp({ workspace: $workspaceStore ?? '', path })
await deleteApp(path)
dispatch('change')
}
}
@@ -8,6 +8,7 @@
import type ShareModal from '$lib/components/ShareModal.svelte'
import { FlowService, type Flow } from '$lib/gen'
import { userStore, workspaceStore } from '$lib/stores'
import { UserDraftDbSyncer } from '$lib/userDraftDbSyncer.svelte'
import { createEventDispatcher } from 'svelte'
import Badge from '../badge/Badge.svelte'
import Button from '../button/Button.svelte'
@@ -83,7 +84,19 @@
async function deleteFlow(path: string): Promise<void> {
try {
await FlowService.deleteFlowByPath({ workspace: $workspaceStore!, path })
// Draft-only items have no deployed row to delete — the regular
// route would 404. Route the delete through the syncer so the
// per-user draft row is removed instead.
if (flow.draft_only) {
await UserDraftDbSyncer.save({
workspace: $workspaceStore!,
itemKind: 'flow',
path,
value: null
})
} else {
await FlowService.deleteFlowByPath({ workspace: $workspaceStore!, path })
}
dispatch('change')
sendUserToast(`Deleted flow ${path}`)
} catch (err) {
@@ -9,6 +9,7 @@
import { ScriptService, type Script } from '$lib/gen'
import { hubBaseUrlStore, userStore, workspaceStore } from '$lib/stores'
import { UserDraftDbSyncer } from '$lib/userDraftDbSyncer.svelte'
import { createEventDispatcher } from 'svelte'
import Badge from '../badge/Badge.svelte'
@@ -102,7 +103,19 @@
}
async function deleteScript(path: string): Promise<void> {
await ScriptService.deleteScriptByPath({ workspace: $workspaceStore!, path })
// Draft-only items have no deployed row to delete — the regular
// route would 404. Route the delete through the syncer so the
// per-user draft row is removed instead.
if (script.draft_only) {
await UserDraftDbSyncer.save({
workspace: $workspaceStore!,
itemKind: 'script',
path,
value: null
})
} else {
await ScriptService.deleteScriptByPath({ workspace: $workspaceStore!, path })
}
dispatch('change')
sendUserToast(`Deleted script ${path}`)
}
@@ -240,9 +240,13 @@
async function showCode(path: string, summary: string) {
viewCodeTitle = summary || path
await viewCodeDrawer?.openDrawer()
// `getDraft: true` so draft-only scripts (no deployed row at this
// path) still return their content via the per-user draft overlay
// instead of 404'ing.
script = await ScriptService.getScriptByPath({
workspace: $workspaceStore!,
path
path,
getDraft: true
})
}