fix:user invitations
This commit is contained in:
parent
7366da06ac
commit
1fe4f4cad9
1 changed files with 22 additions and 32 deletions
|
|
@ -8,7 +8,6 @@
|
|||
import React, { useState, useEffect, useMemo } from 'react';
|
||||
import { useInvitations, type Invitation, type InvitationCreate } from '../../hooks/useInvitations';
|
||||
import { useUserMandates, type Mandate, type Role } from '../../hooks/useUserMandates';
|
||||
import { useFeatureAccess, type FeatureInstance } from '../../hooks/useFeatureAccess';
|
||||
import { FormGeneratorTable } from '../../components/FormGenerator/FormGeneratorTable';
|
||||
import { FormGeneratorForm, type AttributeDefinition } from '../../components/FormGenerator/FormGeneratorForm';
|
||||
import { FaPlus, FaSync, FaEnvelopeOpenText, FaBuilding, FaCopy, FaLink } from 'react-icons/fa';
|
||||
|
|
@ -29,12 +28,10 @@ export const AdminInvitationsPage: React.FC = () => {
|
|||
} = useInvitations();
|
||||
|
||||
const { fetchMandates, fetchRoles } = useUserMandates();
|
||||
const { fetchInstances } = useFeatureAccess();
|
||||
|
||||
// State
|
||||
const [mandates, setMandates] = useState<Mandate[]>([]);
|
||||
const [selectedMandateId, setSelectedMandateId] = useState<string>('');
|
||||
const [featureInstances, setFeatureInstances] = useState<FeatureInstance[]>([]);
|
||||
const [roles, setRoles] = useState<Role[]>([]);
|
||||
const [showCreateModal, setShowCreateModal] = useState(false);
|
||||
const [showUrlModal, setShowUrlModal] = useState<Invitation | null>(null);
|
||||
|
|
@ -61,18 +58,13 @@ export const AdminInvitationsPage: React.FC = () => {
|
|||
}).catch(() => setBackendAttributes([]));
|
||||
}, [fetchMandates]);
|
||||
|
||||
// Load invitations, feature instances, and roles when mandate changes
|
||||
// Load invitations and roles when mandate changes (same roles as AdminUserMandatesPage: user, viewer, admin)
|
||||
useEffect(() => {
|
||||
if (selectedMandateId) {
|
||||
fetchInvitations(selectedMandateId, { includeExpired: showExpired, includeUsed: showUsed });
|
||||
fetchInstances(selectedMandateId).then(instances => {
|
||||
setFeatureInstances(instances);
|
||||
});
|
||||
fetchRoles(selectedMandateId).then(fetchedRoles => {
|
||||
setRoles(fetchedRoles);
|
||||
});
|
||||
fetchRoles(selectedMandateId).then(setRoles);
|
||||
}
|
||||
}, [selectedMandateId, showExpired, showUsed, fetchInvitations, fetchInstances, fetchRoles]);
|
||||
}, [selectedMandateId, showExpired, showUsed, fetchInvitations, fetchRoles]);
|
||||
|
||||
// Format timestamp
|
||||
const formatDate = (timestamp: number) => {
|
||||
|
|
@ -164,29 +156,20 @@ export const AdminInvitationsPage: React.FC = () => {
|
|||
},
|
||||
], [roles]);
|
||||
|
||||
// Form attributes from backend - merge with dynamic instance and role options
|
||||
// Form attributes - same role options as AdminUserMandatesPage (user, viewer, admin)
|
||||
const createFields: AttributeDefinition[] = useMemo(() => {
|
||||
const excludedFields = ['id', 'mandateId', 'token', 'createdBy', 'createdAt', 'expiresAt', 'currentUses', 'inviteUrl'];
|
||||
const excludedFields = ['id', 'mandateId', 'token', 'createdBy', 'createdAt', 'expiresAt', 'currentUses', 'inviteUrl', 'featureInstanceId'];
|
||||
|
||||
// Feature instance options
|
||||
const instanceOptions = featureInstances.map(i => ({
|
||||
value: i.id,
|
||||
label: i.label || `${i.featureCode} (${i.id.slice(0, 8)}...)`
|
||||
}));
|
||||
|
||||
// Instance-level roles (with featureInstanceId)
|
||||
// Mandate-level roles (user, viewer, admin) - same as when adding mandate members
|
||||
const roleOptions = roles
|
||||
.filter(r => !!r.featureInstanceId) // Only instance-level roles
|
||||
.map(r => ({ value: r.id, label: `${r.roleLabel} (${featureInstances.find(i => i.id === r.featureInstanceId)?.label || r.featureCode || ''})` }));
|
||||
.filter(r => !r.featureInstanceId)
|
||||
.map(r => ({ value: r.id, label: r.roleLabel }));
|
||||
|
||||
const fields = backendAttributes
|
||||
.filter(attr => !excludedFields.includes(attr.name))
|
||||
.map(attr => ({
|
||||
...attr,
|
||||
// Override options with dynamic data
|
||||
options: attr.name === 'roleIds' ? roleOptions
|
||||
: attr.name === 'featureInstanceId' ? instanceOptions
|
||||
: attr.options,
|
||||
options: attr.name === 'roleIds' ? roleOptions : attr.options,
|
||||
})) as AttributeDefinition[];
|
||||
|
||||
// Add helper field expiresInHours if not in model but fields exist
|
||||
|
|
@ -194,8 +177,14 @@ export const AdminInvitationsPage: React.FC = () => {
|
|||
fields.push({ name: 'expiresInHours', label: 'Gültigkeitsdauer (Stunden)', type: 'number',
|
||||
required: true, default: 72 } as any);
|
||||
}
|
||||
return fields;
|
||||
}, [roles, featureInstances, backendAttributes]);
|
||||
// Override required for targetUsername and email (both required for invitations)
|
||||
return fields.map(f => {
|
||||
if (f.name === 'targetUsername' || f.name === 'email') {
|
||||
return { ...f, required: true };
|
||||
}
|
||||
return f;
|
||||
});
|
||||
}, [roles, backendAttributes]);
|
||||
|
||||
// Handle create invitation
|
||||
const handleCreateInvitation = async (data: InvitationCreate) => {
|
||||
|
|
@ -326,7 +315,6 @@ export const AdminInvitationsPage: React.FC = () => {
|
|||
<button
|
||||
className={styles.primaryButton}
|
||||
onClick={() => setShowCreateModal(true)}
|
||||
disabled={roles.length === 0}
|
||||
>
|
||||
<FaPlus /> Neue Einladung
|
||||
</button>
|
||||
|
|
@ -358,7 +346,6 @@ export const AdminInvitationsPage: React.FC = () => {
|
|||
<button
|
||||
className={styles.primaryButton}
|
||||
onClick={() => setShowCreateModal(true)}
|
||||
disabled={roles.length === 0}
|
||||
>
|
||||
<FaPlus /> Erste Einladung erstellen
|
||||
</button>
|
||||
|
|
@ -414,8 +401,11 @@ export const AdminInvitationsPage: React.FC = () => {
|
|||
</button>
|
||||
</div>
|
||||
<div className={styles.modalContent}>
|
||||
{roles.length === 0 ? (
|
||||
<p>Keine Rollen verfügbar. Erstellen Sie zuerst Rollen für diesen Mandanten.</p>
|
||||
{roles.filter(r => !r.featureInstanceId).length === 0 ? (
|
||||
<div className={styles.loadingContainer}>
|
||||
<div className={styles.spinner} />
|
||||
<span>Lade Rollen...</span>
|
||||
</div>
|
||||
) : createFields.length === 0 ? (
|
||||
<div className={styles.loadingContainer}>
|
||||
<div className={styles.spinner} />
|
||||
|
|
|
|||
Loading…
Reference in a new issue