fix: add checklisten sidebar sub-items and replace unicode escapes with proper umlauts
This commit is contained in:
@@ -30,7 +30,7 @@ import type { CreateFahrzeugItemPayload } from '../../types/checklist.types';
|
||||
// ── Helpers ──
|
||||
|
||||
const formatDate = (iso?: string) =>
|
||||
iso ? new Date(iso).toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' }) : '\u2013';
|
||||
iso ? new Date(iso).toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' }) : '–';
|
||||
|
||||
// ══════════════════════════════════════════════════════════════════════════════
|
||||
// Component
|
||||
@@ -76,8 +76,8 @@ const FahrzeugChecklistTab: React.FC<FahrzeugChecklistTabProps> = ({ fahrzeugId
|
||||
|
||||
const addItemMutation = useMutation({
|
||||
mutationFn: (data: CreateFahrzeugItemPayload) => checklistenApi.addVehicleItem(fahrzeugId, data),
|
||||
onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['checklisten-fahrzeug-items', fahrzeugId] }); setNewItem({ bezeichnung: '', pflicht: false, sort_order: 0 }); showSuccess('Item hinzugef\u00fcgt'); },
|
||||
onError: () => showError('Fehler beim Hinzuf\u00fcgen'),
|
||||
onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['checklisten-fahrzeug-items', fahrzeugId] }); setNewItem({ bezeichnung: '', pflicht: false, sort_order: 0 }); showSuccess('Item hinzugefügt'); },
|
||||
onError: () => showError('Fehler beim Hinzufügen'),
|
||||
});
|
||||
|
||||
const deleteItemMutation = useMutation({
|
||||
@@ -120,7 +120,7 @@ const FahrzeugChecklistTab: React.FC<FahrzeugChecklistTabProps> = ({ fahrzeugId
|
||||
vehicleItems.map((item) => (
|
||||
<TableRow key={item.id}>
|
||||
<TableCell>{item.bezeichnung}</TableCell>
|
||||
<TableCell align="center">{item.pflicht ? <Chip label="Pflicht" size="small" color="warning" /> : '\u2013'}</TableCell>
|
||||
<TableCell align="center">{item.pflicht ? <Chip label="Pflicht" size="small" color="warning" /> : '–'}</TableCell>
|
||||
<TableCell align="center">
|
||||
<Switch
|
||||
size="small"
|
||||
@@ -144,7 +144,7 @@ const FahrzeugChecklistTab: React.FC<FahrzeugChecklistTabProps> = ({ fahrzeugId
|
||||
<TextField size="small" placeholder="Neues Item..." value={newItem.bezeichnung} onChange={(e) => setNewItem((n) => ({ ...n, bezeichnung: e.target.value }))} sx={{ flexGrow: 1 }} />
|
||||
<FormControlLabel control={<Switch size="small" checked={newItem.pflicht} onChange={(e) => setNewItem((n) => ({ ...n, pflicht: e.target.checked }))} />} label="Pflicht" />
|
||||
<Button size="small" variant="outlined" startIcon={<Add />} disabled={!newItem.bezeichnung.trim() || addItemMutation.isPending} onClick={() => addItemMutation.mutate(newItem)}>
|
||||
Hinzuf\u00fcgen
|
||||
Hinzufügen
|
||||
</Button>
|
||||
</Box>
|
||||
</>
|
||||
@@ -159,7 +159,7 @@ const FahrzeugChecklistTab: React.FC<FahrzeugChecklistTabProps> = ({ fahrzeugId
|
||||
{templatesLoading ? (
|
||||
<CircularProgress size={24} />
|
||||
) : templates.length === 0 ? (
|
||||
<Typography color="text.secondary">Keine Vorlagen f\u00fcr dieses Fahrzeug.</Typography>
|
||||
<Typography color="text.secondary">Keine Vorlagen für dieses Fahrzeug.</Typography>
|
||||
) : (
|
||||
<TableContainer component={Paper} variant="outlined">
|
||||
<Table size="small">
|
||||
@@ -167,7 +167,7 @@ const FahrzeugChecklistTab: React.FC<FahrzeugChecklistTabProps> = ({ fahrzeugId
|
||||
<TableRow>
|
||||
<TableCell>Vorlage</TableCell>
|
||||
<TableCell>Intervall</TableCell>
|
||||
<TableCell>N\u00e4chste F\u00e4lligkeit</TableCell>
|
||||
<TableCell>Nächste Fälligkeit</TableCell>
|
||||
<TableCell align="right">Aktion</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
@@ -178,11 +178,11 @@ const FahrzeugChecklistTab: React.FC<FahrzeugChecklistTabProps> = ({ fahrzeugId
|
||||
<TableRow key={t.id}>
|
||||
<TableCell>{t.name}</TableCell>
|
||||
<TableCell>
|
||||
{t.intervall === 'weekly' ? 'W\u00f6chentlich' : t.intervall === 'monthly' ? 'Monatlich' : t.intervall === 'yearly' ? 'J\u00e4hrlich' : t.intervall === 'custom' ? `${t.intervall_tage ?? '?'} Tage` : '\u2013'}
|
||||
{t.intervall === 'weekly' ? 'Wöchentlich' : t.intervall === 'monthly' ? 'Monatlich' : t.intervall === 'yearly' ? 'Jährlich' : t.intervall === 'custom' ? `${t.intervall_tage ?? '?'} Tage` : '–'}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{due ? (
|
||||
<Chip icon={<Warning />} label={`F\u00e4llig: ${formatDate(due.naechste_faellig_am)}`} color="error" size="small" />
|
||||
<Chip icon={<Warning />} label={`Fällig: ${formatDate(due.naechste_faellig_am)}`} color="error" size="small" />
|
||||
) : (
|
||||
<Typography variant="body2" color="text.secondary">Aktuell</Typography>
|
||||
)}
|
||||
@@ -195,7 +195,7 @@ const FahrzeugChecklistTab: React.FC<FahrzeugChecklistTabProps> = ({ fahrzeugId
|
||||
startIcon={<PlayArrow />}
|
||||
onClick={() => navigate(`/checklisten/ausfuehrung/new?fahrzeug=${fahrzeugId}&vorlage=${t.id}`)}
|
||||
>
|
||||
Ausf\u00fchren
|
||||
Ausführen
|
||||
</Button>
|
||||
)}
|
||||
</TableCell>
|
||||
@@ -210,12 +210,12 @@ const FahrzeugChecklistTab: React.FC<FahrzeugChecklistTabProps> = ({ fahrzeugId
|
||||
|
||||
{/* Section 3: Recent executions */}
|
||||
<Box>
|
||||
<Typography variant="h6" sx={{ mb: 1.5 }}>Letzte Ausf\u00fchrungen</Typography>
|
||||
<Typography variant="h6" sx={{ mb: 1.5 }}>Letzte Ausführungen</Typography>
|
||||
|
||||
{executionsLoading ? (
|
||||
<CircularProgress size={24} />
|
||||
) : executions.length === 0 ? (
|
||||
<Typography color="text.secondary">Noch keine Ausf\u00fchrungen f\u00fcr dieses Fahrzeug.</Typography>
|
||||
<Typography color="text.secondary">Noch keine Ausführungen für dieses Fahrzeug.</Typography>
|
||||
) : (
|
||||
<TableContainer component={Paper} variant="outlined">
|
||||
<Table size="small">
|
||||
@@ -224,7 +224,7 @@ const FahrzeugChecklistTab: React.FC<FahrzeugChecklistTabProps> = ({ fahrzeugId
|
||||
<TableCell>Datum</TableCell>
|
||||
<TableCell>Vorlage</TableCell>
|
||||
<TableCell>Status</TableCell>
|
||||
<TableCell>Ausgef\u00fchrt von</TableCell>
|
||||
<TableCell>Ausgeführt von</TableCell>
|
||||
<TableCell>Freigegeben von</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
@@ -232,12 +232,12 @@ const FahrzeugChecklistTab: React.FC<FahrzeugChecklistTabProps> = ({ fahrzeugId
|
||||
{executions.slice(0, 20).map((e) => (
|
||||
<TableRow key={e.id} hover sx={{ cursor: 'pointer' }} onClick={() => navigate(`/checklisten/ausfuehrung/${e.id}`)}>
|
||||
<TableCell>{formatDate(e.ausgefuehrt_am ?? e.created_at)}</TableCell>
|
||||
<TableCell>{e.vorlage_name ?? '\u2013'}</TableCell>
|
||||
<TableCell>{e.vorlage_name ?? '–'}</TableCell>
|
||||
<TableCell>
|
||||
<Chip label={CHECKLIST_STATUS_LABELS[e.status]} color={CHECKLIST_STATUS_COLORS[e.status]} size="small" />
|
||||
</TableCell>
|
||||
<TableCell>{e.ausgefuehrt_von_name ?? '\u2013'}</TableCell>
|
||||
<TableCell>{e.freigegeben_von_name ?? '\u2013'}</TableCell>
|
||||
<TableCell>{e.ausgefuehrt_von_name ?? '–'}</TableCell>
|
||||
<TableCell>{e.freigegeben_von_name ?? '–'}</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
|
||||
@@ -228,6 +228,16 @@ function Sidebar({ mobileOpen, onMobileClose }: SidebarProps) {
|
||||
issuesSubItems.push({ text: 'Einstellungen', path: `/issues?tab=${issuesSubItems.length}` });
|
||||
}
|
||||
|
||||
// Build Checklisten sub-items dynamically (tab order must match Checklisten.tsx)
|
||||
const checklistenSubItems: SubItem[] = [
|
||||
{ text: 'Übersicht', path: '/checklisten?tab=0' },
|
||||
];
|
||||
if (hasPermission('checklisten:manage_templates')) {
|
||||
checklistenSubItems.push({ text: 'Vorlagen', path: '/checklisten?tab=1' });
|
||||
checklistenSubItems.push({ text: 'Fahrzeugtypen', path: '/checklisten?tab=2' });
|
||||
}
|
||||
checklistenSubItems.push({ text: 'Historie', path: `/checklisten?tab=${checklistenSubItems.length}` });
|
||||
|
||||
const items = baseNavigationItems
|
||||
.map((item) => {
|
||||
if (item.path === '/fahrzeuge') return fahrzeugeItem;
|
||||
@@ -239,6 +249,7 @@ function Sidebar({ mobileOpen, onMobileClose }: SidebarProps) {
|
||||
return { ...item, subItems: ausruestungSubItems, permission: canSeeAusruestung ? undefined : 'ausruestungsanfrage:view' };
|
||||
}
|
||||
if (item.path === '/issues') return { ...item, subItems: issuesSubItems };
|
||||
if (item.path === '/checklisten') return { ...item, subItems: checklistenSubItems };
|
||||
return item;
|
||||
})
|
||||
.filter((item) => !item.permission || hasPermission(item.permission));
|
||||
|
||||
Reference in New Issue
Block a user