new features

This commit is contained in:
Matthias Hochmeister
2026-03-23 15:07:17 +01:00
parent 34ee80b8c1
commit bfcf1556da
22 changed files with 397 additions and 75 deletions

View File

@@ -21,6 +21,12 @@ import {
Select,
Stack,
Tab,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Tabs,
TextField,
Tooltip,
@@ -34,6 +40,7 @@ import {
DeleteOutline,
Edit,
Error as ErrorIcon,
History,
MoreHoriz,
PauseCircle,
RemoveCircle,
@@ -97,6 +104,65 @@ function fmtDate(iso: string | null | undefined): string {
});
}
function fmtDatetime(iso: string | null | undefined): string {
if (!iso) return '---';
return new Date(iso).toLocaleString('de-DE', {
day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit',
});
}
// -- Status History Section ---------------------------------------------------
const StatusHistorySection: React.FC<{ equipmentId: string }> = ({ equipmentId }) => {
const [history, setHistory] = useState<{ alter_status: string; neuer_status: string; bemerkung?: string; geaendert_von_name?: string; erstellt_am: string }[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
equipmentApi.getStatusHistory(equipmentId)
.then(setHistory)
.catch(() => setHistory([]))
.finally(() => setLoading(false));
}, [equipmentId]);
if (loading || history.length === 0) return null;
return (
<>
<Typography variant="h6" sx={{ mt: 3, mb: 1.5, display: 'flex', alignItems: 'center', gap: 1 }}>
<History fontSize="small" /> Status-Verlauf
</Typography>
<TableContainer component={Paper} variant="outlined">
<Table size="small">
<TableHead>
<TableRow>
<TableCell>Datum</TableCell>
<TableCell>Von</TableCell>
<TableCell>Nach</TableCell>
<TableCell>Bemerkung</TableCell>
<TableCell>Geändert von</TableCell>
</TableRow>
</TableHead>
<TableBody>
{history.map((h, idx) => (
<TableRow key={idx}>
<TableCell>{fmtDatetime(h.erstellt_am)}</TableCell>
<TableCell>
<Chip size="small" label={AusruestungStatusLabel[h.alter_status as AusruestungStatus] || h.alter_status} color={STATUS_CHIP_COLOR[h.alter_status as AusruestungStatus] || 'default'} />
</TableCell>
<TableCell>
<Chip size="small" label={AusruestungStatusLabel[h.neuer_status as AusruestungStatus] || h.neuer_status} color={STATUS_CHIP_COLOR[h.neuer_status as AusruestungStatus] || 'default'} />
</TableCell>
<TableCell>{h.bemerkung || '—'}</TableCell>
<TableCell>{h.geaendert_von_name || '—'}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</>
);
};
// -- Wartungslog Art config ---------------------------------------------------
const WARTUNG_ART_CHIP_COLOR: Record<AusruestungWartungslogArt, 'info' | 'warning' | 'default'> = {
@@ -337,6 +403,8 @@ const UebersichtTab: React.FC<UebersichtTabProps> = ({ equipment, onStatusUpdate
</Button>
</DialogActions>
</Dialog>
<StatusHistorySection equipmentId={equipment.id} />
</Box>
);
};
@@ -430,7 +498,7 @@ const WartungTab: React.FC<WartungTabProps> = ({ equipmentId, wartungslog, onAdd
<Typography variant="body2">{entry.beschreibung}</Typography>
<Typography variant="body2" color="text.secondary" sx={{ mt: 0.25 }}>
{[
entry.kosten != null && `${entry.kosten.toFixed(2)} EUR`,
entry.kosten != null && `${Number(entry.kosten).toFixed(2)} EUR`,
entry.pruefende_stelle && entry.pruefende_stelle,
].filter(Boolean).join(' · ')}
</Typography>
@@ -563,7 +631,7 @@ const WartungTab: React.FC<WartungTabProps> = ({ equipmentId, wartungslog, onAdd
function AusruestungDetailPage() {
const { id } = useParams<{ id: string }>();
const navigate = useNavigate();
const { isAdmin, canManageCategory } = usePermissions();
const { isAdmin, canManageCategory, canManageEquipmentMaintenance } = usePermissions();
const notification = useNotification();
const [equipment, setEquipment] = useState<AusruestungDetail | null>(null);
@@ -706,6 +774,8 @@ function AusruestungDetailPage() {
value={activeTab}
onChange={(_, v) => setActiveTab(v)}
aria-label="Ausrüstung Detailansicht"
variant="scrollable"
scrollButtons="auto"
>
<Tab label="Übersicht" />
<Tab
@@ -733,7 +803,7 @@ function AusruestungDetailPage() {
equipmentId={equipment.id}
wartungslog={equipment.wartungslog ?? []}
onAdded={fetchEquipment}
canWrite={canWrite}
canWrite={canManageEquipmentMaintenance}
/>
</TabPanel>