diff --git a/frontend/src/lib/components/DdlMigrationGuard.svelte b/frontend/src/lib/components/DdlMigrationGuard.svelte index 4d8cbbb718..51868c9990 100644 --- a/frontend/src/lib/components/DdlMigrationGuard.svelte +++ b/frontend/src/lib/components/DdlMigrationGuard.svelte @@ -11,8 +11,7 @@ let promptStatement = $state(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 { 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} /> diff --git a/frontend/src/lib/components/workspaceSettings/NewDataTableMigrationModal.svelte b/frontend/src/lib/components/workspaceSettings/NewDataTableMigrationModal.svelte index c737684bd9..6fd0c4998b 100644 --- a/frontend/src/lib/components/workspaceSettings/NewDataTableMigrationModal.svelte +++ b/frontend/src/lib/components/workspaceSettings/NewDataTableMigrationModal.svelte @@ -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 @@ } - + +