From 5674f693d7dc0de78911d592d1096d9c593dd569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Malfait?= Date: Fri, 19 Jun 2026 12:57:06 +0200 Subject: [PATCH] fix: prevent Create Workspace redirect from being cancelled (#21835) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Clicking **Create Workspace** in the multi-workspace dropdown did nothing. The handler closed the dropdown right before redirecting: ```ts const createWorkspace = () => { closeDropdown(MULTI_WORKSPACE_DROPDOWN_ID); // unmounts this component redirectToDefaultDomain({ ... }); // schedules window.open ~1ms later }; ``` `redirectToDefaultDomain` → `useRedirect` wraps the navigation in `useDebouncedCallback(..., 1)`. `closeDropdown` flips the dropdown content to `{isDropdownOpen && ...}` → `false`, unmounting `MultiWorkspaceDropdownDefaultComponents` — the component that owns that debounced callback. `use-debounce` drops the pending call on unmount, so the queued `window.open` never fires. React commits the unmount before the 1ms timer, so it loses every time. Regression from #21723, which added the `closeDropdown` call. ## Fix Remove the `closeDropdown` call. The redirect navigates the whole page away, so closing the dropdown first is unnecessary — and it mirrors the sibling "switch workspace" handler, which already redirects without closing. ## Why not reorder, or drop the debounce? The 1ms debounce in `useRedirect` is intentional (#9079, "sleep before redirect"). Callers set cookie-backed state immediately before redirecting — e.g. `redirectToDefaultDomain` clears the `lastAuthenticateWorkspaceDomain` cookie via `useCookieStorage`. Deferring the hard navigation by one macrotask lets that cookie write flush before the page tears down; removing it risks dropping the write. Reordering wouldn't help either, since the unmount still beats the timer. So the debounce is left untouched. ## Logout is not affected `signOut` → `clearSession` navigates with `window.location.assign(...)` directly (synchronous, not debounced) and never calls `closeDropdown`, so it can't hit this race. ## Testing - Before: clicking Create Workspace → `window.open` called 0 times, page unchanged. - After: navigates to `/welcome?action=create-new-workspace` and renders the "Create your workspace" form. - Switch-workspace and Log out both still work. Review in cubic --- .../internal/MultiWorkspaceDropdownDefaultComponents.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownDefaultComponents.tsx b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownDefaultComponents.tsx index f7f27d9b89..588e6e4b37 100644 --- a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownDefaultComponents.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownDefaultComponents.tsx @@ -85,11 +85,7 @@ export const MultiWorkspaceDropdownDefaultComponents = () => { ); }; - // The workspace name (and logo + subdomain) are collected by the shared - // creation form on the root domain, so we send the user there on the - // WorkspaceCreation step instead of creating a nameless workspace on the fly. const createWorkspace = () => { - closeDropdown(MULTI_WORKSPACE_DROPDOWN_ID); redirectToDefaultDomain({ pathname: AppPath.SignInUp, searchParams: { action: 'create-new-workspace' },