import { useEffect, useState } from 'react' import { toast } from 'sonner' import { assignSysRoleMenus, getAllSysMenus, getSysRoleMenus } from '@/api' import { CheckboxTree, useCheckboxTree, type CheckboxTreeNode } from '@/components/checkbox-tree' import { DialogSkeleton } from '@/components/dialog-skeleton' import { Button } from '@/components/ui/button.tsx' import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog.tsx' import { Spinner } from '@/components/ui/spinner.tsx' import type { SysMenu, SysRole } from '@/schemas' interface Props { currentRow?: SysRole | null onClose: () => void onConfirm: () => void open: boolean } const buildTreeData = (data: SysMenu[], parentId: string | null = null): CheckboxTreeNode[] => { return data .filter((item) => (item.parent_id?.toString() ?? null) === parentId) .map((item) => { const children = buildTreeData(data, item.id.toString()) return { id: item.id.toString(), label: item.name, data: item, children: children.length > 0 ? children : [], } }) } export function AssignMenusDialog({ open, onClose, onConfirm, currentRow }: Props) { const [treeData, setTreeData] = useState([]) const { getNodeState, toggleNode, setCheckedIds, getCheckedIdsWithParents } = useCheckboxTree( treeData, [], ) const [loading, setLoading] = useState(false) const [skeletonLoading, setSkeletonLoading] = useState(true) useEffect(() => { const fetchMenus = async () => { setSkeletonLoading(true) const { data: menus } = await getAllSysMenus() const { data: checkedMenus } = await getSysRoleMenus(currentRow?.id as number) setTreeData(buildTreeData(menus)) setCheckedIds(checkedMenus.map((item) => item.id.toString())) setSkeletonLoading(false) } if (open && currentRow?.id) fetchMenus() }, [open, currentRow, setCheckedIds]) const handleConfirm = async () => { try { setLoading(true) await assignSysRoleMenus( currentRow?.id as number, getCheckedIdsWithParents().map((item) => parseInt(item)), ) toast('操作成功!') onConfirm() } finally { setLoading(false) } } return ( 分配菜单权限
(
{node.data?.name}
)} />
) }