fix(spaces): не закрывать ConfirmDialog при удалении из меню
Docker / build (push) Failing after 20s
Docker / build (push) Failing after 20s
Диалог вынесен из DropdownMenu, иначе размонтировался вместе с меню. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -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}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user