/** * AdminUserAccessOverviewPage * * Admin page for viewing comprehensive user access permissions. * Shows what pages a user can see and what data they can access. */ import React, { useState, useEffect } from 'react'; import { FaSync, FaUserShield, FaEye, FaDatabase, FaCube, FaChevronDown, FaChevronRight, FaCheckCircle, FaTimesCircle, FaInfoCircle } from 'react-icons/fa'; import api from '../../api'; import styles from './Admin.module.css'; interface UserOption { id: string; username: string; email: string; fullName: string; isSysAdmin: boolean; enabled: boolean; } interface RoleInfo { id: string; roleLabel: string; description: { [key: string]: string }; scope: 'global' | 'mandate' | 'instance'; mandateId?: string; featureInstanceId?: string; source: string; sourceMandateId?: string; sourceMandateName?: string; sourceInstanceId?: string; sourceInstanceLabel?: string; } interface AccessEntry { item: string; view?: boolean; read?: string; create?: string; update?: string; delete?: string; grantedByRoleLabels: string[]; roleScope: string; } interface MandateInfo { id: string; name: string; label?: string; roleIds: string[]; featureInstances: { id: string; label: string; featureCode: string; featureLabel: { [key: string]: string }; roleIds: string[]; }[]; } interface UserAccessOverview { user: UserOption; isSysAdmin: boolean; sysAdminNote?: string; roles: RoleInfo[]; mandates: MandateInfo[]; uiAccess: AccessEntry[]; dataAccess: AccessEntry[]; resourceAccess: AccessEntry[]; } type TabId = 'overview' | 'ui' | 'data' | 'resources'; export const AdminUserAccessOverviewPage: React.FC = () => { const [users, setUsers] = useState([]); const [selectedUserId, setSelectedUserId] = useState(''); const [overview, setOverview] = useState(null); const [loading, setLoading] = useState(false); const [loadingUsers, setLoadingUsers] = useState(true); const [error, setError] = useState(null); const [activeTab, setActiveTab] = useState('overview'); const [expandedRoles, setExpandedRoles] = useState>(new Set()); const [expandedMandates, setExpandedMandates] = useState>(new Set()); // Fetch users list on mount useEffect(() => { const fetchUsers = async () => { try { setLoadingUsers(true); const response = await api.get('/api/admin/user-access-overview/users'); setUsers(response.data); } catch (err: any) { setError(err?.response?.data?.detail || err?.message || 'Failed to fetch users'); } finally { setLoadingUsers(false); } }; fetchUsers(); }, []); // Fetch access overview when user is selected useEffect(() => { if (!selectedUserId) { setOverview(null); return; } const fetchOverview = async () => { try { setLoading(true); setError(null); const response = await api.get(`/api/admin/user-access-overview/${selectedUserId}`); const data = response.data; setOverview(data); // Auto-expand all mandates setExpandedMandates(new Set(data.mandates?.map((m: MandateInfo) => m.id) || [])); } catch (err: any) { setError(err?.response?.data?.detail || err?.message || 'Failed to fetch overview'); setOverview(null); } finally { setLoading(false); } }; fetchOverview(); }, [selectedUserId]); const toggleRole = (roleId: string) => { setExpandedRoles(prev => { const newSet = new Set(prev); if (newSet.has(roleId)) { newSet.delete(roleId); } else { newSet.add(roleId); } return newSet; }); }; const toggleMandate = (mandateId: string) => { setExpandedMandates(prev => { const newSet = new Set(prev); if (newSet.has(mandateId)) { newSet.delete(mandateId); } else { newSet.add(mandateId); } return newSet; }); }; const getScopeColor = (scope: string): string => { switch (scope) { case 'instance': return '#10b981'; case 'mandate': return '#3b82f6'; case 'global': return '#8b5cf6'; default: return '#6b7280'; } }; const getAccessLevelColor = (level: string): string => { switch (level) { case 'ALL': return '#10b981'; case 'GROUP': return '#3b82f6'; case 'MY': return '#f59e0b'; case 'NONE': return '#ef4444'; default: return '#6b7280'; } }; const renderOverviewTab = () => { if (!overview) return null; return (
{/* SysAdmin Notice */} {overview.isSysAdmin && (
{overview.sysAdminNote || 'Dieser Benutzer ist SysAdmin und hat vollen Systemzugriff.'}
)} {/* Mandates & Feature Instances */}

Mandate & Feature-Instanzen

{overview.mandates.length === 0 ? (

Keine Mandate-Zuordnungen vorhanden.

) : (
{overview.mandates.map(mandate => (
toggleMandate(mandate.id)} >
{expandedMandates.has(mandate.id) ? : } {mandate.label || mandate.name} {mandate.featureInstances.length} Feature-Instanz(en)
{expandedMandates.has(mandate.id) && (
{mandate.featureInstances.length === 0 ? (

Keine Feature-Instanzen zugewiesen.

) : (
{mandate.featureInstances.map(instance => (
{instance.label}
Feature: {instance.featureLabel?.de || instance.featureCode}
Rollen: {instance.roleIds.length > 0 ? overview.roles .filter(r => instance.roleIds.includes(r.id)) .map(r => r.roleLabel) .join(', ') : 'Keine' }
))}
)}
)}
))}
)} {/* Roles */}

Zugewiesene Rollen

{overview.roles.length === 0 ? (

Keine Rollen zugewiesen.

) : (
{overview.roles.map(role => (
toggleRole(role.id)} >
{expandedRoles.has(role.id) ? : } {role.roleLabel} {role.scope}
{expandedRoles.has(role.id) && (

Beschreibung: {role.description?.de || role.description?.en || '-'}

Quelle: {role.source === 'mandate' ? `Mandate: ${role.sourceMandateName}` : `Feature-Instanz: ${role.sourceInstanceLabel}` }

)}
))}
)}
); }; const renderUiAccessTab = () => { if (!overview) return null; return (
UI-Zugriffsrechte bestimmen, welche Seiten und Views der Benutzer sehen kann.
{overview.uiAccess.length === 0 ? (

Keine UI-Berechtigungen

Diesem Benutzer wurden keine expliziten UI-Berechtigungen zugewiesen.

) : ( {overview.uiAccess.map((entry, idx) => ( ))}
UI-Element Sichtbar Gewährt durch
{entry.item} {entry.view ? ( ) : ( )} {entry.grantedByRoleLabels?.join(', ') || '-'}
)}
); }; const renderDataAccessTab = () => { if (!overview) return null; return (
Daten-Zugriffsrechte: ALL = Alle Datensätze, GROUP = Gruppen-Datensätze, MY = Eigene Datensätze, NONE = Kein Zugriff
{overview.dataAccess.length === 0 ? (

Keine Daten-Berechtigungen

Diesem Benutzer wurden keine expliziten Daten-Berechtigungen zugewiesen.

) : ( {overview.dataAccess.map((entry, idx) => ( ))}
Tabelle/Feld Lesen Erstellen Update Löschen Gewährt durch
{entry.item} {entry.read || '-'} {entry.create || '-'} {entry.update || '-'} {entry.delete || '-'} {entry.grantedByRoleLabels?.join(', ') || '-'}
)}
); }; const renderResourceAccessTab = () => { if (!overview) return null; return (
Ressourcen-Zugriffsrechte bestimmen, welche System-Ressourcen (z.B. AI-Modelle) der Benutzer verwenden kann.
{overview.resourceAccess.length === 0 ? (

Keine Ressourcen-Berechtigungen

Diesem Benutzer wurden keine expliziten Ressourcen-Berechtigungen zugewiesen.

) : ( {overview.resourceAccess.map((entry, idx) => ( ))}
Ressource Zugriff Gewährt durch
{entry.item} {entry.view ? ( ) : ( )} {entry.grantedByRoleLabels?.join(', ') || '-'}
)}
); }; if (error && !overview) { return (
⚠️

Fehler: {error}

); } return (

Benutzer-Zugriffsübersicht

Zeigt alle Berechtigungen eines Benutzers an

{/* User Selection */}
{selectedUserId && ( )}
{/* Content */} {!selectedUserId ? (

Benutzer auswählen

Wählen Sie einen Benutzer aus, um dessen Zugriffsberechtigungen anzuzeigen.

) : loading ? (
Lade Zugriffsübersicht...
) : overview ? ( <> {/* User Info */}
{overview.user.fullName || overview.user.username} | {overview.user.email} {overview.isSysAdmin && ( <> | SysAdmin )}
{/* Tabs */}
{/* Tab Content */}
{activeTab === 'overview' && renderOverviewTab()} {activeTab === 'ui' && renderUiAccessTab()} {activeTab === 'data' && renderDataAccessTab()} {activeTab === 'resources' && renderResourceAccessTab()}
) : null}
); }; export default AdminUserAccessOverviewPage;