/** * PermissionMatrix * * User × Role matrix with inline toggles and edit/remove actions. */ import React, { useState, useCallback } from 'react'; import { FaEdit, FaTrash } from 'react-icons/fa'; import { useConfirm } from '../../hooks/useConfirm'; import type { FeatureAccessUser } from '../../hooks/useFeatureAccess'; import type { FeatureInstanceRole } from '../../hooks/useFeatureAccess'; import styles from './Admin.module.css'; import matrixStyles from './PermissionMatrix.module.css'; import { useLanguage } from '../../providers/language/LanguageContext'; export interface PermissionMatrixProps { users: FeatureAccessUser[]; roles: FeatureInstanceRole[]; onEditUser: (user: FeatureAccessUser) => void; onRemoveUser: (user: FeatureAccessUser) => void; onAddUser: () => void; disabled?: boolean; } export const PermissionMatrix: React.FC = ({ users, roles, onEditUser, onRemoveUser, onAddUser, disabled = false, }) => { const { t } = useLanguage(); const [removingId, setRemovingId] = useState(null); const { confirm, ConfirmDialog } = useConfirm(); const handleRemove = useCallback(async (user: FeatureAccessUser) => { if (removingId) return; const ok = await confirm(t('"{name}" aus dieser Instanz entfernen?', { name: user.username }), { title: t('Benutzer entfernen'), confirmLabel: t('Entfernen'), variant: 'danger', }); if (!ok) return; setRemovingId(user.userId); onRemoveUser(user); setRemovingId(null); }, [removingId, confirm, onRemoveUser, t]); if (roles.length === 0) { return (

{t('Keine Rollen in dieser Instanz')}

); } return (
{roles.map((r) => ( ))} {users.length === 0 ? ( ) : ( users.map((user) => ( {roles.map((role) => { const hasRole = user.roleIds?.includes(role.id) ?? false; return ( ); })} )) )}
{t('Benutzer')} {r.roleLabel} {t('Aktiv')} {t('Aktionen')}
{t('Keine Benutzer zugewiesen.')}
{user.username} {user.email && ( {user.email} )} {hasRole ? '✓' : '—'} {user.enabled ? '✓' : '—'}
); }; export default PermissionMatrix;