From 582a6fb4291788bc8250f69cf7da2e6261ffddb8 Mon Sep 17 00:00:00 2001 From: Amruth Pillai Date: Thu, 17 Sep 2026 12:19:06 +0200 Subject: [PATCH] fix(web): preserve dialogs opened during close animations Opening another dialog during the previous dialog's 300 ms close animation could clear the new dialog and its close handler. This caused the post-merge dashboard lifecycle test to lose the Duplicate Resume dialog after renaming a resume. - Scope delayed cleanup to the original dialog and require it to remain closed. - Add regression coverage for both open and closing replacement dialogs; both cases failed before the fix and pass afterward. - Include the fix in the v5.3.1 release notes. Validation: `pnpm check`, `pnpm typecheck`, `pnpm test`, and the focused dialog-store suite (12 passing tests). --- apps/web/src/dialogs/store.test.ts | 23 +++++++++++++++++++++++ apps/web/src/dialogs/store.ts | 3 +++ docs/changelog/index.mdx | 4 ++++ 3 files changed, 30 insertions(+) diff --git a/apps/web/src/dialogs/store.test.ts b/apps/web/src/dialogs/store.test.ts index 370a9d34d..bb63d6b83 100644 --- a/apps/web/src/dialogs/store.test.ts +++ b/apps/web/src/dialogs/store.test.ts @@ -63,6 +63,29 @@ describe("useDialogStore", () => { vi.advanceTimersByTime(300); expect(useDialogStore.getState().activeDialog).toBeNull(); }); + + it.each([false, true])("preserves a replacement dialog and its own closing delay (closing=%s)", (closing) => { + useDialogStore.getState().openDialog("api-key.create", undefined); + useDialogStore.getState().closeDialog(); + vi.advanceTimersByTime(100); + + useDialogStore.getState().openDialog("resume.create", undefined); + const onBeforeClose = () => false; + useDialogStore.getState().setOnBeforeClose(onBeforeClose); + if (closing) useDialogStore.getState().closeDialog(); + vi.advanceTimersByTime(200); + + expect(useDialogStore.getState()).toMatchObject({ + open: !closing, + activeDialog: { type: "resume.create" }, + onBeforeClose, + }); + + if (!closing) useDialogStore.getState().closeDialog(); + vi.advanceTimersByTime(300); + expect(useDialogStore.getState().activeDialog).toBeNull(); + expect(useDialogStore.getState().onBeforeClose).toBeNull(); + }); }); describe("onOpenChange", () => { diff --git a/apps/web/src/dialogs/store.ts b/apps/web/src/dialogs/store.ts index eafd0ca98..618bc9f42 100644 --- a/apps/web/src/dialogs/store.ts +++ b/apps/web/src/dialogs/store.ts @@ -40,8 +40,11 @@ export const useDialogStore = create((set) => ({ onBeforeClose: null, }), closeDialog: () => { + const closingDialog = useDialogStore.getState().activeDialog; set({ open: false }); setTimeout(() => { + const state = useDialogStore.getState(); + if (state.open || state.activeDialog !== closingDialog) return; set({ activeDialog: null, onBeforeClose: null }); }, 300); }, diff --git a/docs/changelog/index.mdx b/docs/changelog/index.mdx index d870dce65..8d165a7d2 100644 --- a/docs/changelog/index.mdx +++ b/docs/changelog/index.mdx @@ -11,6 +11,10 @@ rss: true - **Manage your cover-letter library through MCP.** Connected assistants can now create, read, update, duplicate, delete, import, and export independent cover letters, refresh their styling from a resume, or copy an embedded letter into the library. Revision checks protect newer edits from being overwritten. Thanks to [@emanuelet](https://github.com/emanuelet). [e6a6bf0e6](https://github.com/reactive-resume/reactive-resume/commit/e6a6bf0e6) - **Explore the redesigned homepage.** Try interactive resume, export, and ATS previews, browse templates, and discover supported languages before opening the builder. [6416da28a](https://github.com/reactive-resume/reactive-resume/commit/6416da28a) +## Resume Builder + +- Fixed newly opened dialogs disappearing when another dialog had just closed, including duplicating a resume immediately after renaming it. [0c2d5ac9f](https://github.com/reactive-resume/reactive-resume/commit/0c2d5ac9f) + ## PDF Export & Templates - Fixed list indentation when an item continues onto another page, including nested lists and numbered lists with wider markers. Thanks to [@santhiprakash](https://github.com/santhiprakash). [51ac77295](https://github.com/reactive-resume/reactive-resume/commit/51ac77295)