import { useMemo } from 'react'; import { ChevronDown, ChevronRight, Check, Minus } from 'lucide-react'; import { useState } from 'react'; import type { Permission } from '@/services/api'; import { getPermissionCategoryLabel, getPermissionActionLabel } from '@/hooks/useRbac'; interface PermissionsMatrixProps { permissions: Permission[]; selectedPermissions: string[]; onTogglePermission: (permissionSlug: string) => void; onToggleCategory: (category: string, permissionSlugs: string[]) => void; readOnly?: boolean; } export function PermissionsMatrix({ permissions, selectedPermissions, onTogglePermission, onToggleCategory, readOnly = false, }: PermissionsMatrixProps) { const [expandedCategories, setExpandedCategories] = useState>(new Set()); const permissionsByCategory = useMemo(() => { const grouped: Record = {}; permissions.forEach((perm) => { if (!grouped[perm.category]) { grouped[perm.category] = []; } grouped[perm.category].push(perm); }); return grouped; }, [permissions]); const categories = useMemo(() => Object.keys(permissionsByCategory).sort(), [permissionsByCategory]); const toggleCategory = (category: string) => { setExpandedCategories((prev) => { const newSet = new Set(prev); if (newSet.has(category)) { newSet.delete(category); } else { newSet.add(category); } return newSet; }); }; const getCategoryStatus = (category: string): 'all' | 'some' | 'none' => { const categoryPerms = permissionsByCategory[category]; const selectedCount = categoryPerms.filter((p) => selectedPermissions.includes(p.slug)).length; if (selectedCount === 0) return 'none'; if (selectedCount === categoryPerms.length) return 'all'; return 'some'; }; const handleCategoryCheckboxClick = (category: string) => { if (readOnly) return; const categoryPerms = permissionsByCategory[category]; const slugs = categoryPerms.map((p) => p.slug); onToggleCategory(category, slugs); }; return (
{categories.map((category) => { const isExpanded = expandedCategories.has(category); const categoryPerms = permissionsByCategory[category]; const status = getCategoryStatus(category); const selectedCount = categoryPerms.filter((p) => selectedPermissions.includes(p.slug) ).length; return (
{/* Category Header */} {/* Permissions List */} {isExpanded && (
{categoryPerms.map((perm) => { const isSelected = selectedPermissions.includes(perm.slug); const [, action] = perm.slug.split(':'); return ( ); })}
)}
); })} {categories.length === 0 && (
No permissions available
)}
); }