new features

This commit is contained in:
Matthias Hochmeister
2026-03-23 16:58:46 +01:00
parent 948b211f70
commit 55ded22a6f
8 changed files with 452 additions and 43 deletions

View File

@@ -15,9 +15,7 @@ import {
DialogContent,
DialogContentText,
DialogTitle,
FormControlLabel,
IconButton,
Switch,
Table,
TableBody,
TableCell,
@@ -153,17 +151,6 @@ function PermissionMatrixTab() {
};
// ── Mutations ──
const maintenanceMutation = useMutation({
mutationFn: ({ featureGroup, active }: { featureGroup: string; active: boolean }) =>
permissionsApi.setMaintenanceFlag(featureGroup, active),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['admin-permission-matrix'] });
queryClient.invalidateQueries({ queryKey: ['my-permissions'] });
showSuccess('Wartungsmodus aktualisiert');
},
onError: () => showError('Fehler beim Aktualisieren des Wartungsmodus'),
});
const permissionMutation = useMutation({
mutationFn: (updates: { group: string; permissions: string[] }[]) =>
permissionsApi.setBulkPermissions(updates),
@@ -325,28 +312,7 @@ function PermissionMatrixTab() {
</Alert>
)}
{/* Section 1: Maintenance Toggles */}
<Card>
<CardContent>
<Typography variant="h6" gutterBottom>Wartungsmodus</Typography>
<Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
Wenn aktiviert, wird die Funktion für alle Benutzer ausser Administratoren ausgeblendet.
</Typography>
{featureGroups.map((fg: FeatureGroup) => (
<Box key={fg.id} sx={{ display: 'flex', alignItems: 'center', gap: 1, py: 0.5 }}>
<FormControlLabel
control={<Switch checked={maintenance[fg.id] ?? false}
onChange={() => maintenanceMutation.mutate({ featureGroup: fg.id, active: !(maintenance[fg.id] ?? false) })}
disabled={maintenanceMutation.isPending} />}
label={fg.label}
/>
{maintenance[fg.id] && <Chip label="Wartungsmodus" color="warning" size="small" />}
</Box>
))}
</CardContent>
</Card>
{/* Section 2: Dependency Configuration */}
{/* Section 1: Dependency Configuration */}
<Card>
<CardContent>
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 1 }}>

View File

@@ -1,12 +1,14 @@
import { useState, useEffect } from 'react';
import {
Box, Card, CardContent, Typography, Switch, FormControlLabel,
TextField, Button, Alert, CircularProgress,
TextField, Button, Alert, CircularProgress, Chip,
} from '@mui/material';
import BuildIcon from '@mui/icons-material/Build';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { settingsApi } from '../../services/settings';
import { permissionsApi } from '../../services/permissions';
import { useNotification } from '../../contexts/NotificationContext';
import type { PermissionMatrix, FeatureGroup } from '../../types/permissions.types';
export default function ServiceModeTab() {
const queryClient = useQueryClient();
@@ -17,6 +19,11 @@ export default function ServiceModeTab() {
queryFn: () => settingsApi.get('service_mode'),
});
const { data: matrix, isLoading: matrixLoading } = useQuery<PermissionMatrix>({
queryKey: ['admin-permission-matrix'],
queryFn: permissionsApi.getMatrix,
});
const currentValue = setting?.value ?? { active: false, message: '' };
const [active, setActive] = useState<boolean>(currentValue.active ?? false);
const [message, setMessage] = useState<string>(currentValue.message ?? '');
@@ -46,17 +53,28 @@ export default function ServiceModeTab() {
mutation.mutate({ active, message, ends_at: endsAt || null });
};
const maintenanceMutation = useMutation({
mutationFn: ({ featureGroup, active }: { featureGroup: string; active: boolean }) =>
permissionsApi.setMaintenanceFlag(featureGroup, active),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['admin-permission-matrix'] });
queryClient.invalidateQueries({ queryKey: ['my-permissions'] });
showSuccess('Feature-Wartungsmodus aktualisiert');
},
onError: () => showError('Fehler beim Aktualisieren des Feature-Wartungsmodus'),
});
if (isLoading) {
return <Box sx={{ display: 'flex', justifyContent: 'center', p: 4 }}><CircularProgress /></Box>;
}
return (
<Box sx={{ maxWidth: 600 }}>
<Box sx={{ maxWidth: 600, display: 'flex', flexDirection: 'column', gap: 3 }}>
<Card>
<CardContent>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 3 }}>
<BuildIcon color={active ? 'error' : 'action'} />
<Typography variant="h6">Wartungsmodus</Typography>
<Typography variant="h6">Globaler Wartungsmodus</Typography>
</Box>
{active && (
@@ -117,6 +135,39 @@ export default function ServiceModeTab() {
</Button>
</CardContent>
</Card>
<Card>
<CardContent>
<Typography variant="h6" gutterBottom>Feature Wartungsmodus</Typography>
<Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
Einzelne Funktionen in den Wartungsmodus versetzen. Betroffene Bereiche werden für alle Benutzer ausser Administratoren ausgeblendet.
</Typography>
{matrixLoading ? (
<Box sx={{ display: 'flex', justifyContent: 'center', py: 2 }}>
<CircularProgress size={24} />
</Box>
) : matrix ? (
matrix.featureGroups.map((fg: FeatureGroup) => (
<Box key={fg.id} sx={{ display: 'flex', alignItems: 'center', gap: 1, py: 0.5 }}>
<FormControlLabel
control={
<Switch
checked={matrix.maintenance[fg.id] ?? false}
onChange={() => maintenanceMutation.mutate({
featureGroup: fg.id,
active: !(matrix.maintenance[fg.id] ?? false),
})}
disabled={maintenanceMutation.isPending}
/>
}
label={fg.label}
/>
{matrix.maintenance[fg.id] && <Chip label="Wartungsmodus" color="warning" size="small" />}
</Box>
))
) : null}
</CardContent>
</Card>
</Box>
);
}
}