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

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

Co-authored-by: Cursor <[email protected]>
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' } from '@cfdm/ui/components/alert-dialog'
interface ConfirmDialogProps { interface ConfirmDialogProps {
trigger: ReactElement /** Optional when using controlled `open` (e.g. open from DropdownMenu) */
trigger?: ReactElement
title: string title: string
description?: ReactNode description?: ReactNode
confirmLabel?: string confirmLabel?: string
@@ -55,7 +56,7 @@ export function ConfirmDialog({
return ( return (
<AlertDialog open={open} onOpenChange={setOpen}> <AlertDialog open={open} onOpenChange={setOpen}>
<AlertDialogTrigger render={trigger} /> {trigger ? <AlertDialogTrigger render={trigger} /> : null}
<AlertDialogContent> <AlertDialogContent>
<AlertDialogHeader> <AlertDialogHeader>
<AlertDialogTitle>{title}</AlertDialogTitle> <AlertDialogTitle>{title}</AlertDialogTitle>
@@ -50,6 +50,7 @@ export function SpaceSwitcher() {
const currentId = spaceId ?? spaces[0]?.id const currentId = spaceId ?? spaces[0]?.id
const current = spaces.find((s) => s.id === currentId) ?? spaces[0] const current = spaces.find((s) => s.id === currentId) ?? spaces[0]
const [createOpen, setCreateOpen] = useState(false) const [createOpen, setCreateOpen] = useState(false)
const [deleteOpen, setDeleteOpen] = useState(false)
const [name, setName] = useState('') const [name, setName] = useState('')
useEffect(() => { useEffect(() => {
@@ -75,9 +76,14 @@ export function SpaceSwitcher() {
} }
function openCreateDialog() { function openCreateDialog() {
// After DropdownMenu unmounts — same tick would lose focus/state
queueMicrotask(() => setCreateOpen(true)) queueMicrotask(() => setCreateOpen(true))
} }
function openDeleteDialog() {
queueMicrotask(() => setDeleteOpen(true))
}
async function handleCreate() { async function handleCreate() {
const n = name.trim() const n = name.trim()
if (!n) return if (!n) return
@@ -173,22 +179,13 @@ export function SpaceSwitcher() {
Создать пространство Создать пространство
</DropdownMenuItem> </DropdownMenuItem>
{current && current.kind !== MAIN_KIND ? ( {current && current.kind !== MAIN_KIND ? (
<ConfirmDialog <DropdownMenuItem
title="В корзину?" onClick={openDeleteDialog}
description="Пространство скроется из списка. Данные сохранятся — можно восстановить на странице «Пространство»." className="text-destructive"
confirmLabel="В корзину" >
destructive <Trash2Icon className="size-4" />
onConfirm={() => void handleSoftDelete(current)} Удалить «{current.name}»
trigger={ </DropdownMenuItem>
<DropdownMenuItem
onClick={(e) => e.preventDefault()}
className="text-destructive"
>
<Trash2Icon className="size-4" />
Удалить «{current.name}»
</DropdownMenuItem>
}
/>
) : null} ) : null}
</DropdownMenuGroup> </DropdownMenuGroup>
</DropdownMenuContent> </DropdownMenuContent>
@@ -218,6 +215,19 @@ export function SpaceSwitcher() {
</DialogFooter> </DialogFooter>
</DialogContent> </DialogContent>
</Dialog> </Dialog>
{/* Outside DropdownMenu — иначе AlertDialog размонтируется вместе с меню */}
{current && current.kind !== MAIN_KIND ? (
<ConfirmDialog
open={deleteOpen}
onOpenChange={setDeleteOpen}
title="В корзину?"
description="Пространство скроется из списка. Данные сохранятся — можно восстановить на странице «Пространство»."
confirmLabel="В корзину"
destructive
onConfirm={() => void handleSoftDelete(current)}
/>
) : null}
</> </>
) )
} }