mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-05 17:42:06 +00:00
Add the Completion Docs page under Data Management: a searchable template table, a read-only detail panel, add and edit with a live document preview, and delete behind a confirmation that counts the open work orders still using the template and links to them. Add, edit and delete are hidden for users whose role lacks the matching template permission. The preview shares the work-order completion document's page frame, header, safety bullets and procedure heading so the two stay identical.
64 lines
2.5 KiB
TypeScript
64 lines
2.5 KiB
TypeScript
import type { z } from "zod";
|
|
import { apiDeleteNoContent, apiGet, apiPost, apiPut } from "@/api/api";
|
|
import { API_PATHS } from "@/api/api-paths";
|
|
import { handleApiResponse } from "@/api/handle-api-response";
|
|
import { mapCompletionTemplate } from "@/domain/completion-templates/mappers/completion-template-mapper";
|
|
import {
|
|
completionTemplateDtoSchema,
|
|
completionTemplateListDtoSchema,
|
|
linkedWorkOrdersDtoSchema,
|
|
} from "@/domain/completion-templates/schemas/completion-template-schema";
|
|
import type {
|
|
CompletionTemplate,
|
|
CompletionTemplateInput,
|
|
CompletionTemplateLegacyFields,
|
|
LinkedWorkOrders,
|
|
} from "@/domain/completion-templates/types/completion-template";
|
|
|
|
export const UNEXPECTED_TEMPLATE_RESPONSE = "The server sent an unexpected response.";
|
|
|
|
function parse<T>(schema: z.ZodType<T>, data: unknown): T {
|
|
const result = schema.safeParse(handleApiResponse<unknown>(data));
|
|
if (!result.success) throw new Error(UNEXPECTED_TEMPLATE_RESPONSE);
|
|
return result.data;
|
|
}
|
|
|
|
function toBody(input: CompletionTemplateInput, legacy?: CompletionTemplateLegacyFields) {
|
|
return { ...legacy, ...input };
|
|
}
|
|
|
|
export const completionTemplatesApi = {
|
|
list: async (search: string): Promise<CompletionTemplate[]> => {
|
|
const term = search.trim();
|
|
const data = await apiGet<unknown>(API_PATHS.workOrder.completionTemplates, {
|
|
searchParams: term === "" ? undefined : { search: term },
|
|
});
|
|
return parse(completionTemplateListDtoSchema, data).map(mapCompletionTemplate);
|
|
},
|
|
|
|
create: async (input: CompletionTemplateInput): Promise<CompletionTemplate> => {
|
|
const data = await apiPost<unknown>(API_PATHS.workOrder.completionTemplates, toBody(input));
|
|
return mapCompletionTemplate(parse(completionTemplateDtoSchema, data));
|
|
},
|
|
|
|
/** Replaces the whole procedure list and keeps the legacy fields the template already had. */
|
|
update: async (
|
|
template: CompletionTemplate,
|
|
input: CompletionTemplateInput,
|
|
): Promise<CompletionTemplate> => {
|
|
const data = await apiPut<unknown>(
|
|
API_PATHS.workOrder.completionTemplateById(template.id),
|
|
toBody(input, template.legacy),
|
|
);
|
|
return mapCompletionTemplate(parse(completionTemplateDtoSchema, data));
|
|
},
|
|
|
|
delete: async (id: number): Promise<void> => {
|
|
await apiDeleteNoContent(API_PATHS.workOrder.completionTemplateById(id));
|
|
},
|
|
|
|
linkedWorkOrders: async (id: number): Promise<LinkedWorkOrders> => {
|
|
const data = await apiGet<unknown>(API_PATHS.workOrder.completionTemplateLinkedWorkOrders(id));
|
|
return parse(linkedWorkOrdersDtoSchema, data);
|
|
},
|
|
};
|