fix: don't re-prompt DDL guard when creating a migration without running

This commit is contained in:
Diego Imbert
2026-06-20 16:40:02 +02:00
parent ee65da8d83
commit 40cc718feb
2 changed files with 29 additions and 19 deletions
@@ -11,8 +11,7 @@
let promptStatement = $state<string | undefined>(undefined)
let promptOpen = $state(false)
let resolvePrompt: ((choice: Choice) => void) | undefined = undefined
let resolveMigrationClosed: (() => void) | undefined = undefined
let migrationCreated = false
let resolveMigrationClosed: ((created: boolean) => void) | undefined = undefined
// Set when a migration is created *and run* during a guard() call, so the
// caller can refresh the schema afterwards.
let migrationRan = false
@@ -41,23 +40,18 @@
})
}
function handleMigrationCreated(ran: boolean) {
migrationCreated = true
if (ran) migrationRan = true
}
function handleMigrationClosed() {
function handleMigrationClosed(result: { created: boolean; ran: boolean }) {
if (result.ran) migrationRan = true
const r = resolveMigrationClosed
resolveMigrationClosed = undefined
r?.()
r?.(result.created)
}
// Open the prefilled new-migration modal. Resolves with whether a migration
// was actually created (false if the user cancelled / closed it).
function openMigrationModal(statement: string): Promise<boolean> {
return new Promise((resolve) => {
migrationCreated = false
resolveMigrationClosed = () => resolve(migrationCreated)
resolveMigrationClosed = (created: boolean) => resolve(created)
newMigrationModal?.open({ codeUp: statement })
})
}
@@ -135,6 +129,5 @@
bind:this={newMigrationModal}
{workspace}
{datatable}
onCreated={handleMigrationCreated}
onClose={handleMigrationClosed}
/>
@@ -20,15 +20,22 @@
datatable: string
/** Called after a successful create; `ran` is true when it was also run. */
onCreated?: (ran: boolean) => void
onClose?: () => void
/** Called whenever the modal closes. `result` reports whether the close
* was due to a create (and whether that create was also run) vs a cancel —
* computed synchronously so callers don't depend on onCreated/onClose order. */
onClose?: (result: { created: boolean; ran: boolean }) => void
} = $props()
let isOpen = $state(false)
// Notify the parent whenever the modal closes (after a create or a cancel),
// so callers that sequence modals (e.g. the DDL guard) can advance.
// The reason the modal is about to close, set synchronously before `isOpen`
// flips so the onClose effect reports it reliably regardless of effect timing.
let closeResult = { created: false, ran: false }
let prevOpen = false
$effect(() => {
if (prevOpen && !isOpen) onClose?.()
if (prevOpen && !isOpen) {
onClose?.(closeResult)
closeResult = { created: false, ran: false }
}
prevOpen = isOpen
})
let tab = $state('up')
@@ -106,9 +113,10 @@
return
}
}
isOpen = false
sendUserToast(run ? 'Migration created and run' : 'Migration created')
closeResult = { created: true, ran: run }
onCreated?.(run)
sendUserToast(run ? 'Migration created and run' : 'Migration created')
isOpen = false
} catch (e: any) {
sendUserToast(`Failed to create migration: ${e?.body ?? e?.message ?? e}`, true)
} finally {
@@ -117,7 +125,16 @@
}
</script>
<Modal2 bind:isOpen title="New migration — {datatable}" fixedWidth="md" fixedHeight="adaptive">
<!-- closeOnOutsideClick is off: the "Create and run" split-button menu renders in a
portal outside the modal, so an outside-click close would fire on its items and be
mistaken for a cancel. Close via the header X or Escape instead. -->
<Modal2
bind:isOpen
title="New migration — {datatable}"
fixedWidth="md"
fixedHeight="adaptive"
closeOnOutsideClick={false}
>
<div class="flex flex-col gap-3 w-full grow min-h-0">
<TextInput
bind:value={name}