feat: add issue kanban/attachments/deadlines, dashboard widget DnD, and checklisten system
This commit is contained in:
131
frontend/src/services/checklisten.ts
Normal file
131
frontend/src/services/checklisten.ts
Normal file
@@ -0,0 +1,131 @@
|
||||
import { api } from './api';
|
||||
import type {
|
||||
ChecklistVorlage,
|
||||
ChecklistVorlageItem,
|
||||
FahrzeugChecklistItem,
|
||||
ChecklistAusfuehrung,
|
||||
ChecklistFaelligkeit,
|
||||
ChecklistVorlageFilter,
|
||||
ChecklistAusfuehrungFilter,
|
||||
CreateVorlagePayload,
|
||||
UpdateVorlagePayload,
|
||||
CreateVorlageItemPayload,
|
||||
UpdateVorlageItemPayload,
|
||||
CreateFahrzeugItemPayload,
|
||||
UpdateFahrzeugItemPayload,
|
||||
SubmitAusfuehrungPayload,
|
||||
} from '../types/checklist.types';
|
||||
|
||||
export const checklistenApi = {
|
||||
// ── Vorlagen (Templates) ──
|
||||
getVorlagen: async (filter?: ChecklistVorlageFilter): Promise<ChecklistVorlage[]> => {
|
||||
const params = new URLSearchParams();
|
||||
if (filter?.fahrzeug_typ_id != null) params.set('fahrzeug_typ_id', String(filter.fahrzeug_typ_id));
|
||||
if (filter?.aktiv != null) params.set('aktiv', String(filter.aktiv));
|
||||
const qs = params.toString();
|
||||
const r = await api.get(`/api/checklisten/vorlagen${qs ? `?${qs}` : ''}`);
|
||||
return r.data.data;
|
||||
},
|
||||
|
||||
getVorlage: async (id: number): Promise<ChecklistVorlage> => {
|
||||
const r = await api.get(`/api/checklisten/vorlagen/${id}`);
|
||||
return r.data.data;
|
||||
},
|
||||
|
||||
createVorlage: async (data: CreateVorlagePayload): Promise<ChecklistVorlage> => {
|
||||
const r = await api.post('/api/checklisten/vorlagen', data);
|
||||
return r.data.data;
|
||||
},
|
||||
|
||||
updateVorlage: async (id: number, data: UpdateVorlagePayload): Promise<ChecklistVorlage> => {
|
||||
const r = await api.put(`/api/checklisten/vorlagen/${id}`, data);
|
||||
return r.data.data;
|
||||
},
|
||||
|
||||
deleteVorlage: async (id: number): Promise<void> => {
|
||||
await api.delete(`/api/checklisten/vorlagen/${id}`);
|
||||
},
|
||||
|
||||
// ── Vorlage Items ──
|
||||
getVorlageItems: async (vorlageId: number): Promise<ChecklistVorlageItem[]> => {
|
||||
const r = await api.get(`/api/checklisten/vorlagen/${vorlageId}/items`);
|
||||
return r.data.data;
|
||||
},
|
||||
|
||||
addVorlageItem: async (vorlageId: number, data: CreateVorlageItemPayload): Promise<ChecklistVorlageItem> => {
|
||||
const r = await api.post(`/api/checklisten/vorlagen/${vorlageId}/items`, data);
|
||||
return r.data.data;
|
||||
},
|
||||
|
||||
updateVorlageItem: async (id: number, data: UpdateVorlageItemPayload): Promise<ChecklistVorlageItem> => {
|
||||
const r = await api.put(`/api/checklisten/items/${id}`, data);
|
||||
return r.data.data;
|
||||
},
|
||||
|
||||
deleteVorlageItem: async (id: number): Promise<void> => {
|
||||
await api.delete(`/api/checklisten/items/${id}`);
|
||||
},
|
||||
|
||||
// ── Vehicle-specific Items ──
|
||||
getVehicleItems: async (fahrzeugId: string): Promise<FahrzeugChecklistItem[]> => {
|
||||
const r = await api.get(`/api/checklisten/fahrzeug/${fahrzeugId}/items`);
|
||||
return r.data.data;
|
||||
},
|
||||
|
||||
addVehicleItem: async (fahrzeugId: string, data: CreateFahrzeugItemPayload): Promise<FahrzeugChecklistItem> => {
|
||||
const r = await api.post(`/api/checklisten/fahrzeug/${fahrzeugId}/items`, data);
|
||||
return r.data.data;
|
||||
},
|
||||
|
||||
updateVehicleItem: async (id: number, data: UpdateFahrzeugItemPayload): Promise<FahrzeugChecklistItem> => {
|
||||
const r = await api.put(`/api/checklisten/fahrzeug-items/${id}`, data);
|
||||
return r.data.data;
|
||||
},
|
||||
|
||||
deleteVehicleItem: async (id: number): Promise<void> => {
|
||||
await api.delete(`/api/checklisten/fahrzeug-items/${id}`);
|
||||
},
|
||||
|
||||
// ── Checklists for a Vehicle ──
|
||||
getChecklistenForVehicle: async (fahrzeugId: string): Promise<ChecklistVorlage[]> => {
|
||||
const r = await api.get(`/api/checklisten/fahrzeug/${fahrzeugId}/checklisten`);
|
||||
return r.data.data;
|
||||
},
|
||||
|
||||
// ── Executions ──
|
||||
startExecution: async (fahrzeugId: string, vorlageId: number): Promise<ChecklistAusfuehrung> => {
|
||||
const r = await api.post('/api/checklisten/ausfuehrungen', { fahrzeug_id: fahrzeugId, vorlage_id: vorlageId });
|
||||
return r.data.data;
|
||||
},
|
||||
|
||||
submitExecution: async (id: string, data: SubmitAusfuehrungPayload): Promise<ChecklistAusfuehrung> => {
|
||||
const r = await api.put(`/api/checklisten/ausfuehrungen/${id}`, data);
|
||||
return r.data.data;
|
||||
},
|
||||
|
||||
approveExecution: async (id: string): Promise<ChecklistAusfuehrung> => {
|
||||
const r = await api.post(`/api/checklisten/ausfuehrungen/${id}/freigabe`);
|
||||
return r.data.data;
|
||||
},
|
||||
|
||||
getExecution: async (id: string): Promise<ChecklistAusfuehrung> => {
|
||||
const r = await api.get(`/api/checklisten/ausfuehrungen/${id}`);
|
||||
return r.data.data;
|
||||
},
|
||||
|
||||
getExecutions: async (filter?: ChecklistAusfuehrungFilter): Promise<ChecklistAusfuehrung[]> => {
|
||||
const params = new URLSearchParams();
|
||||
if (filter?.fahrzeug_id) params.set('fahrzeug_id', filter.fahrzeug_id);
|
||||
if (filter?.vorlage_id != null) params.set('vorlage_id', String(filter.vorlage_id));
|
||||
if (filter?.status?.length) params.set('status', filter.status.join(','));
|
||||
const qs = params.toString();
|
||||
const r = await api.get(`/api/checklisten/ausfuehrungen${qs ? `?${qs}` : ''}`);
|
||||
return r.data.data;
|
||||
},
|
||||
|
||||
// ── Overdue / Due ──
|
||||
getOverdue: async (): Promise<ChecklistFaelligkeit[]> => {
|
||||
const r = await api.get('/api/checklisten/faellig');
|
||||
return r.data.data;
|
||||
},
|
||||
};
|
||||
28
frontend/src/services/fahrzeugTypen.ts
Normal file
28
frontend/src/services/fahrzeugTypen.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { api } from './api';
|
||||
import type { FahrzeugTyp } from '../types/checklist.types';
|
||||
|
||||
export const fahrzeugTypenApi = {
|
||||
getAll: async (): Promise<FahrzeugTyp[]> => {
|
||||
const r = await api.get('/api/fahrzeug-typen');
|
||||
return r.data.data;
|
||||
},
|
||||
|
||||
getById: async (id: number): Promise<FahrzeugTyp> => {
|
||||
const r = await api.get(`/api/fahrzeug-typen/${id}`);
|
||||
return r.data.data;
|
||||
},
|
||||
|
||||
create: async (data: Partial<FahrzeugTyp>): Promise<FahrzeugTyp> => {
|
||||
const r = await api.post('/api/fahrzeug-typen', data);
|
||||
return r.data.data;
|
||||
},
|
||||
|
||||
update: async (id: number, data: Partial<FahrzeugTyp>): Promise<FahrzeugTyp> => {
|
||||
const r = await api.put(`/api/fahrzeug-typen/${id}`, data);
|
||||
return r.data.data;
|
||||
},
|
||||
|
||||
delete: async (id: number): Promise<void> => {
|
||||
await api.delete(`/api/fahrzeug-typen/${id}`);
|
||||
},
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
import { api } from './api';
|
||||
import type { Issue, IssueComment, CreateIssuePayload, UpdateIssuePayload, IssueTyp, IssueFilters, AssignableMember, IssueStatusDef, IssuePriorityDef, IssueWidgetSummary, IssueHistorie } from '../types/issue.types';
|
||||
import type { Issue, IssueComment, CreateIssuePayload, UpdateIssuePayload, IssueTyp, IssueFilters, AssignableMember, IssueStatusDef, IssuePriorityDef, IssueWidgetSummary, IssueHistorie, IssueDatei } from '../types/issue.types';
|
||||
|
||||
export const issuesApi = {
|
||||
getIssues: async (filters?: IssueFilters): Promise<Issue[]> => {
|
||||
@@ -98,4 +98,20 @@ export const issuesApi = {
|
||||
deletePriority: async (id: number): Promise<void> => {
|
||||
await api.delete(`/api/issues/priorities/${id}`);
|
||||
},
|
||||
// Files
|
||||
uploadFile: async (issueId: number, file: File): Promise<IssueDatei> => {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
const r = await api.post(`/api/issues/${issueId}/files`, formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
});
|
||||
return r.data.data;
|
||||
},
|
||||
getFiles: async (issueId: number): Promise<IssueDatei[]> => {
|
||||
const r = await api.get(`/api/issues/${issueId}/files`);
|
||||
return r.data.data;
|
||||
},
|
||||
deleteFile: async (fileId: string): Promise<void> => {
|
||||
await api.delete(`/api/issues/files/${fileId}`);
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user