Fix: Freigaberollen korrekt filtern und speichern
- Korrigiere normalizeApprovalPermissions: verwende Set für korrekte Deduplizierung - Füge getAvailableApprovalRoles hinzu, um basierend auf der Benutzerrolle die verfügbaren Freigaberollen zu bestimmen: - ADMIN (Vorstand): Vorstand A, Vorstand B - FINANCE (Finanz-AG): Finanz-AG - MEMBER (AG-Mitglied): Keine - Aktualisiere renderApprovalPermissionSelector mit rollenbasierter Filterung - Verhindere Auswahl inkompatibler Kombinationen (z.B. Vorstand A + B zusammen)
This commit is contained in:
@@ -45,6 +45,7 @@ import {
|
||||
approvalLabel,
|
||||
canManageBudgets,
|
||||
canManageUsers,
|
||||
getAvailableApprovalRoles,
|
||||
roleLabel
|
||||
} from "@/lib/domain";
|
||||
|
||||
@@ -1091,7 +1092,8 @@ export function DashboardShell({
|
||||
function renderApprovalPermissionSelector(
|
||||
value: ApprovalPermissionValue[],
|
||||
onToggle: (approvalType: ApprovalPermissionValue) => void,
|
||||
helperText: string
|
||||
helperText: string,
|
||||
availableApprovalTypes: ApprovalPermissionValue[]
|
||||
) {
|
||||
return (
|
||||
<Stack spacing={1}>
|
||||
@@ -1099,21 +1101,27 @@ export function DashboardShell({
|
||||
Freigaberollen
|
||||
</Typography>
|
||||
<Stack direction="row" gap={1} useFlexGap flexWrap="wrap">
|
||||
{APPROVAL_FLOW.map((approvalType) => {
|
||||
const selected = value.includes(approvalType);
|
||||
{availableApprovalTypes.length > 0 ? (
|
||||
availableApprovalTypes.map((approvalType) => {
|
||||
const selected = value.includes(approvalType);
|
||||
|
||||
return (
|
||||
<Button
|
||||
key={approvalType}
|
||||
type="button"
|
||||
size="small"
|
||||
variant={selected ? "contained" : "outlined"}
|
||||
onClick={() => onToggle(approvalType)}
|
||||
>
|
||||
{approvalLabel(approvalType)}
|
||||
</Button>
|
||||
);
|
||||
})}
|
||||
return (
|
||||
<Button
|
||||
key={approvalType}
|
||||
type="button"
|
||||
size="small"
|
||||
variant={selected ? "contained" : "outlined"}
|
||||
onClick={() => onToggle(approvalType)}
|
||||
>
|
||||
{approvalLabel(approvalType)}
|
||||
</Button>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
Keine Freigaberollen verfuegbar
|
||||
</Typography>
|
||||
)}
|
||||
</Stack>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
{helperText}
|
||||
@@ -1778,7 +1786,8 @@ export function DashboardShell({
|
||||
...current,
|
||||
approvalPermissions: toggleApprovalPermission(current.approvalPermissions, approvalType)
|
||||
})),
|
||||
"Lege fest, für welche Freigabeschritte dieses Konto zeichnen darf."
|
||||
"Lege fest, für welche Freigabeschritte dieses Konto zeichnen darf.",
|
||||
getAvailableApprovalRoles(userForm.role)
|
||||
)}
|
||||
<Button type="submit" variant="outlined" disabled={busy}>
|
||||
Nutzer speichern
|
||||
@@ -1970,7 +1979,8 @@ export function DashboardShell({
|
||||
updateManagedUserDraft(user, {
|
||||
approvalPermissions: toggleApprovalPermission(draft.approvalPermissions, approvalType)
|
||||
}),
|
||||
"Lege fest, welche Freigabeschritte dieses Konto autorisieren darf."
|
||||
"Lege fest, welche Freigabeschritte dieses Konto autorisieren darf.",
|
||||
getAvailableApprovalRoles(draft.role)
|
||||
)}
|
||||
<Stack direction="row" gap={1} useFlexGap flexWrap="wrap">
|
||||
<Button type="button" variant="contained" disabled={busy} onClick={() => handleUpdateUser(user)}>
|
||||
|
||||
@@ -97,6 +97,17 @@ export function canDeleteExpense(
|
||||
return viewerId === creatorId && approvalStatus === "PENDING" && !paidAt && !documentedAt;
|
||||
}
|
||||
|
||||
export function getAvailableApprovalRoles(role: AppRole): ApprovalTypeValue[] {
|
||||
switch (role) {
|
||||
case "ADMIN":
|
||||
return ["CHAIR_A", "CHAIR_B"];
|
||||
case "FINANCE":
|
||||
return ["FINANCE"];
|
||||
case "MEMBER":
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
export function normalizeApprovalPermissions(
|
||||
_role: AppRole,
|
||||
approvalPermissions: ApprovalTypeValue[] | null | undefined,
|
||||
@@ -104,9 +115,18 @@ export function normalizeApprovalPermissions(
|
||||
) {
|
||||
const rawPermissions = approvalPermissions ?? (approvalPreference ? [approvalPreference] : []);
|
||||
|
||||
return APPROVAL_FLOW.filter(
|
||||
(approvalType, index) => rawPermissions.includes(approvalType) && rawPermissions.indexOf(approvalType) === index
|
||||
) as ApprovalTypeValue[];
|
||||
// Deduplizierung: behalte jeden Eintrag nur beim ersten Vorkommen
|
||||
const seen = new Set<ApprovalTypeValue>();
|
||||
const unique: ApprovalTypeValue[] = [];
|
||||
for (const perm of rawPermissions) {
|
||||
if (!seen.has(perm)) {
|
||||
seen.add(perm);
|
||||
unique.push(perm);
|
||||
}
|
||||
}
|
||||
|
||||
// Sortiere nach der Reihenfolge in APPROVAL_FLOW
|
||||
return APPROVAL_FLOW.filter((type) => unique.includes(type)) as ApprovalTypeValue[];
|
||||
}
|
||||
|
||||
export function getLegacyApprovalPreference(approvalPermissions: ApprovalTypeValue[]) {
|
||||
|
||||
Reference in New Issue
Block a user