"use client" import * as React from "react" import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog" import { Checkbox } from "@/components/ui/checkbox" import { Button } from "@/components/ui/button" import { Tooltip, TooltipTrigger, TooltipContent } from "@/components/ui/tooltip" import { RoleView } from "@/db/schema/users" import { getAllRoleView, getMenuPermissions, upsertPermissions } from "@/lib/roles/services" import { useToast } from "@/hooks/use-toast" import { Loader } from "lucide-react" import { permissionLabelMap } from "@/config/permissionsConfig" interface PermissionDialogProps { open: boolean onOpenChange: (val: boolean) => void itemKey?: string itemTitle?: string } export function PermissionDialog({ open, onOpenChange, itemKey, itemTitle, }: PermissionDialogProps) { // **(A)**: 체크박스에 의해 새로 추가할 권한(perms) const [permissions, setPermissions] = React.useState([]) // **(B)**: 체크된 Roles(새로 부여할 대상) const [selectedRoles, setSelectedRoles] = React.useState([]) // **(C)**: 전체 Role 목록 const [roles, setRoles] = React.useState([]) // **(D)**: Role별 이미 존재하는 권한들 → UI 표시용 const [rolePermsMap, setRolePermsMap] = React.useState>({}) const { toast } = useToast() const [isPending, startTransition] = React.useTransition() // 1) Role 목록 로드 React.useEffect(() => { getAllRoleView("evcp").then((res) => { setRoles(res) }) }, []) // 2) Dialog 열릴 때 → DB에서 “이미 부여된 권한” 로드 React.useEffect(() => { if (open && itemKey) { // 기존에 어떤 Role들이 itemKey 퍼미션을 가지고 있는지 getMenuPermissions(itemKey).then((rows) => { // rows: { roleId, permKey: "itemKey.xxx" } // rolePermsMap[r.roleId] = ["create","viewAll",...] const rMap: Record = {} for (const row of rows) { const splitted = row.permKey.split(".") const shortPerm = splitted[1] if (!rMap[row.roleId]) { rMap[row.roleId] = [] } rMap[row.roleId].push(shortPerm) } setRolePermsMap(rMap) // 권한 체크박스(permissions)와 selectedRoles는 // "항상 비어있는 상태"로 시작 (새로 추가할 용도) setPermissions([]) setSelectedRoles([]) }) } else if (!open) { // Dialog가 닫힐 때 리셋 setPermissions([]) setSelectedRoles([]) setRolePermsMap({}) } }, [open, itemKey]) // Checkbox toggle: 권한 function togglePermission(perm: string) { setPermissions((prev) => prev.includes(perm) ? prev.filter((p) => p !== perm) : [...prev, perm] ) } // Checkbox toggle: Role function toggleRole(roleId: number) { setSelectedRoles((prev) => prev.includes(roleId) ? prev.filter((p) => p !== roleId) : [...prev, roleId] ) } async function handleSave() { if (!itemKey) { toast({ variant: "destructive", title: "오류", description: "선택한 메뉴가 없어 권한을 생성할 수 없습니다.", }) onOpenChange(false) return } // permission_key = itemKey.perm const permissionKeys = permissions.map((perm) => `${itemKey}.${perm}`) startTransition(async () => { try { await upsertPermissions({ roleIds: selectedRoles, permissionKeys, itemTitle, }) toast({ variant: "default", title: "권한 설정 완료", description: "새 권한이 정상적으로 설정되었습니다.", }) setPermissions([]) setSelectedRoles([]) setRolePermsMap({}) onOpenChange(false) } catch (err) { toast({ variant: "destructive", title: "오류", description: "권한 설정에 실패했습니다. 다시 시도해주세요.", }) } }) } function handleCancel() { setPermissions([]) setSelectedRoles([]) setRolePermsMap({}) onOpenChange(false) } const isDisabled = isPending return ( 권한 설정 - {itemTitle}
{/* 1) Role 표시: 이미 가진 권한은 slash 구분 */}

Role & 이미 부여된 권한

{roles.map((r) => { const existPerms = rolePermsMap[r.id] || [] const permsText = existPerms .map((perm) => permissionLabelMap[perm] ?? perm) // ↑ 매핑에 없는 키일 경우 대비해 ?? perm 로 처리 .join(" / ") return (
toggleRole(r.id)} disabled={isDisabled} /> {r.name} {r.description ?? "No description"} {/* 이미 가진 권한 텍스트 */} {permsText && ( {permsText} )}
) })}
{/* 2) 새 권한 체크박스 */}

새로 부여할 권한

{/* 왼쪽 */}
{/* 생성 */}

생성

togglePermission("create")} disabled={isDisabled} /> {permissionLabelMap["create"]}
{/* 보기 */}

보기

togglePermission("viewAll")} disabled={isDisabled} /> {permissionLabelMap["viewAll"]}
togglePermission("viewOwn")} disabled={isDisabled} /> {permissionLabelMap["viewOwn"]}
{/* 오른쪽 */}
{/* 편집 */}

편집

togglePermission("editAll")} disabled={isDisabled} /> {permissionLabelMap["editAll"]}
togglePermission("editOwn")} disabled={isDisabled} /> {permissionLabelMap["editOwn"]}
{/* 삭제 */}

삭제

togglePermission("deleteAll")} disabled={isDisabled} /> {permissionLabelMap["deleteAll"]}
togglePermission("deleteOwn")} disabled={isDisabled} /> {permissionLabelMap["deleteOwn"]}
) }