feat: add inline editing for checklist vorlage items

This commit is contained in:
Matthias Hochmeister
2026-03-28 18:17:32 +01:00
parent 4c1f188371
commit 15337f768d

View File

@@ -623,6 +623,8 @@ function VorlageItemsSection({ vorlageId, queryClient, showSuccess, showError }:
}); });
const [newItem, setNewItem] = useState<CreateVorlageItemPayload>({ bezeichnung: '', pflicht: false, sort_order: 0 }); const [newItem, setNewItem] = useState<CreateVorlageItemPayload>({ bezeichnung: '', pflicht: false, sort_order: 0 });
const [editingId, setEditingId] = useState<number | null>(null);
const [editForm, setEditForm] = useState<{ bezeichnung: string; pflicht: boolean }>({ bezeichnung: '', pflicht: false });
const addMutation = useMutation({ const addMutation = useMutation({
mutationFn: (data: CreateVorlageItemPayload) => checklistenApi.addVorlageItem(vorlageId, data), mutationFn: (data: CreateVorlageItemPayload) => checklistenApi.addVorlageItem(vorlageId, data),
@@ -630,23 +632,62 @@ function VorlageItemsSection({ vorlageId, queryClient, showSuccess, showError }:
onError: () => showError('Fehler beim Hinzufügen'), onError: () => showError('Fehler beim Hinzufügen'),
}); });
const updateMutation = useMutation({
mutationFn: ({ id, data }: { id: number; data: { bezeichnung: string; pflicht: boolean } }) => checklistenApi.updateVorlageItem(id, data),
onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['checklisten-vorlage-items', vorlageId] }); setEditingId(null); showSuccess('Item aktualisiert'); },
onError: () => showError('Fehler beim Aktualisieren'),
});
const deleteMutation = useMutation({ const deleteMutation = useMutation({
mutationFn: (id: number) => checklistenApi.deleteVorlageItem(id), mutationFn: (id: number) => checklistenApi.deleteVorlageItem(id),
onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['checklisten-vorlage-items', vorlageId] }); showSuccess('Item entfernt'); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['checklisten-vorlage-items', vorlageId] }); showSuccess('Item entfernt'); },
onError: () => showError('Fehler beim Entfernen'), onError: () => showError('Fehler beim Entfernen'),
}); });
const startEdit = (item: ChecklistVorlageItem) => {
setEditingId(item.id);
setEditForm({ bezeichnung: item.bezeichnung, pflicht: item.pflicht });
};
if (isLoading) return <CircularProgress size={20} />; if (isLoading) return <CircularProgress size={20} />;
return ( return (
<Box> <Box>
<Typography variant="subtitle2" sx={{ mb: 1 }}>Checklisten-Items</Typography> <Typography variant="subtitle2" sx={{ mb: 1 }}>Checklisten-Items</Typography>
{items.map((item) => ( {items.map((item) => (
<Box key={item.id} sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 0.5 }}> <Box key={item.id} sx={{ mb: 0.5 }}>
<Typography variant="body2" sx={{ flexGrow: 1 }}> {editingId === item.id ? (
{item.bezeichnung} {item.pflicht && <Chip label="Pflicht" size="small" color="warning" sx={{ ml: 0.5 }} />} <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
</Typography> <TextField
<IconButton size="small" color="error" onClick={() => deleteMutation.mutate(item.id)}><DeleteIcon fontSize="small" /></IconButton> size="small"
value={editForm.bezeichnung}
onChange={(e) => setEditForm((f) => ({ ...f, bezeichnung: e.target.value }))}
sx={{ flexGrow: 1 }}
autoFocus
/>
<FormControlLabel
control={<Switch size="small" checked={editForm.pflicht} onChange={(e) => setEditForm((f) => ({ ...f, pflicht: e.target.checked }))} />}
label="Pflicht"
/>
<Button
size="small"
variant="contained"
disabled={!editForm.bezeichnung.trim() || updateMutation.isPending}
onClick={() => updateMutation.mutate({ id: item.id, data: editForm })}
>
Speichern
</Button>
<Button size="small" onClick={() => setEditingId(null)}>Abbrechen</Button>
</Box>
) : (
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
<Typography variant="body2" sx={{ flexGrow: 1 }}>
{item.bezeichnung} {item.pflicht && <Chip label="Pflicht" size="small" color="warning" sx={{ ml: 0.5 }} />}
</Typography>
<IconButton size="small" onClick={() => startEdit(item)}><EditIcon fontSize="small" /></IconButton>
<IconButton size="small" color="error" onClick={() => deleteMutation.mutate(item.id)}><DeleteIcon fontSize="small" /></IconButton>
</Box>
)}
</Box> </Box>
))} ))}
<Box sx={{ display: 'flex', gap: 1, mt: 1, alignItems: 'center' }}> <Box sx={{ display: 'flex', gap: 1, mt: 1, alignItems: 'center' }}>