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)