From 42c567e5b58fdf63bfc64dcb7a1a2a83b5cd7d23 Mon Sep 17 00:00:00 2001 From: Denozordec Date: Sun, 19 Jul 2026 18:14:44 +0700 Subject: [PATCH] =?UTF-8?q?fix(spaces):=20=D0=BD=D0=B5=20=D0=B7=D0=B0?= =?UTF-8?q?=D0=BA=D1=80=D1=8B=D0=B2=D0=B0=D1=82=D1=8C=20ConfirmDialog=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B8=20=D1=83=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B8=20=D0=B8=D0=B7=20=D0=BC=D0=B5=D0=BD=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Диалог вынесен из DropdownMenu, иначе размонтировался вместе с меню. Co-authored-by: Cursor --- apps/web/src/components/confirm-dialog.tsx | 5 ++- .../src/components/layout/space-switcher.tsx | 42 ++++++++++++------- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/apps/web/src/components/confirm-dialog.tsx b/apps/web/src/components/confirm-dialog.tsx index 7e36cde..71df019 100644 --- a/apps/web/src/components/confirm-dialog.tsx +++ b/apps/web/src/components/confirm-dialog.tsx @@ -13,7 +13,8 @@ import { } from '@cfdm/ui/components/alert-dialog' interface ConfirmDialogProps { - trigger: ReactElement + /** Optional when using controlled `open` (e.g. open from DropdownMenu) */ + trigger?: ReactElement title: string description?: ReactNode confirmLabel?: string @@ -55,7 +56,7 @@ export function ConfirmDialog({ return ( - + {trigger ? : null} {title} diff --git a/apps/web/src/components/layout/space-switcher.tsx b/apps/web/src/components/layout/space-switcher.tsx index 48bc9a7..1c5c8e2 100644 --- a/apps/web/src/components/layout/space-switcher.tsx +++ b/apps/web/src/components/layout/space-switcher.tsx @@ -50,6 +50,7 @@ export function SpaceSwitcher() { const currentId = spaceId ?? spaces[0]?.id const current = spaces.find((s) => s.id === currentId) ?? spaces[0] const [createOpen, setCreateOpen] = useState(false) + const [deleteOpen, setDeleteOpen] = useState(false) const [name, setName] = useState('') useEffect(() => { @@ -75,9 +76,14 @@ export function SpaceSwitcher() { } function openCreateDialog() { + // After DropdownMenu unmounts — same tick would lose focus/state queueMicrotask(() => setCreateOpen(true)) } + function openDeleteDialog() { + queueMicrotask(() => setDeleteOpen(true)) + } + async function handleCreate() { const n = name.trim() if (!n) return @@ -173,22 +179,13 @@ export function SpaceSwitcher() { Создать пространство {current && current.kind !== MAIN_KIND ? ( - void handleSoftDelete(current)} - trigger={ - e.preventDefault()} - className="text-destructive" - > - - Удалить «{current.name}» - - } - /> + + + Удалить «{current.name}» + ) : null} @@ -218,6 +215,19 @@ export function SpaceSwitcher() { + + {/* Outside DropdownMenu — иначе AlertDialog размонтируется вместе с меню */} + {current && current.kind !== MAIN_KIND ? ( + void handleSoftDelete(current)} + /> + ) : null} ) }