fix(spaces): не закрывать ConfirmDialog при удалении из меню
Docker / build (push) Failing after 20s

Диалог вынесен из DropdownMenu, иначе размонтировался вместе с меню.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Denozordec
2026-07-19 18:14:44 +07:00
co-authored by Cursor
parent 670b5a4468
commit 42c567e5b5
2 changed files with 29 additions and 18 deletions
+3 -2
View File
@@ -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 (
<AlertDialog open={open} onOpenChange={setOpen}>
<AlertDialogTrigger render={trigger} />
{trigger ? <AlertDialogTrigger render={trigger} /> : null}
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>{title}</AlertDialogTitle>
@@ -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() {
Создать пространство
</DropdownMenuItem>
{current && current.kind !== MAIN_KIND ? (
<ConfirmDialog
title="В корзину?"
description="Пространство скроется из списка. Данные сохранятся — можно восстановить на странице «Пространство»."
confirmLabel="В корзину"
destructive
onConfirm={() => void handleSoftDelete(current)}
trigger={
<DropdownMenuItem
onClick={(e) => e.preventDefault()}
className="text-destructive"
>
<Trash2Icon className="size-4" />
Удалить «{current.name}»
</DropdownMenuItem>
}
/>
<DropdownMenuItem
onClick={openDeleteDialog}
className="text-destructive"
>
<Trash2Icon className="size-4" />
Удалить «{current.name}»
</DropdownMenuItem>
) : null}
</DropdownMenuGroup>
</DropdownMenuContent>
@@ -218,6 +215,19 @@ export function SpaceSwitcher() {
</DialogFooter>
</DialogContent>
</Dialog>
{/* Outside DropdownMenu — иначе AlertDialog размонтируется вместе с меню */}
{current && current.kind !== MAIN_KIND ? (
<ConfirmDialog
open={deleteOpen}
onOpenChange={setDeleteOpen}
title="В корзину?"
description="Пространство скроется из списка. Данные сохранятся — можно восстановить на странице «Пространство»."
confirmLabel="В корзину"
destructive
onConfirm={() => void handleSoftDelete(current)}
/>
) : null}
</>
)
}