shoc-frontend-new/src/domain/work-orders/utils/slide-over-draft.ts

73 lines
2 KiB
TypeScript

import type {
WorkOrderTablePatch,
WorkOrderTableRow,
} from "@/domain/work-orders/types/work-order-table-row";
/**
* Fields compared for dirty state and included in Save patch.
* Only keys that map to board PATCH (or required companions like dispatcherName / vendor labels).
* POC, locationId, and tech phone are not board-editable — exclude so Save cannot no-op.
*/
export const SLIDE_OVER_EDIT_KEYS = [
"woNumber",
"site",
"type",
"dispatcherId",
"dispatcherName",
"scheduledOn",
"targetWeek",
"scheduleWeekOnly",
"dueDate",
"completedDate",
"apptTime",
"pm",
"serviceNotes",
"extraServices",
"vendorId",
// company/tech are display companions; board persists vendor via vendorId only
"status",
] as const satisfies ReadonlyArray<keyof WorkOrderTableRow>;
type EditKey = (typeof SLIDE_OVER_EDIT_KEYS)[number];
function sameExtraServices(a: string[] | undefined, b: string[] | undefined): boolean {
const left = a ?? [];
const right = b ?? [];
if (left.length !== right.length) return false;
return left.every((value, index) => value === right[index]);
}
export function isSlideOverDraftDirty(
draft: WorkOrderTableRow,
baseline: WorkOrderTableRow,
): boolean {
for (const key of SLIDE_OVER_EDIT_KEYS) {
if (key === "extraServices") {
if (!sameExtraServices(draft.extraServices, baseline.extraServices)) return true;
continue;
}
if (draft[key] !== baseline[key]) return true;
}
return false;
}
export function buildSlideOverPatch(
draft: WorkOrderTableRow,
baseline: WorkOrderTableRow,
): WorkOrderTablePatch {
const patch: WorkOrderTablePatch = {};
for (const key of SLIDE_OVER_EDIT_KEYS) {
if (key === "extraServices") {
if (!sameExtraServices(draft.extraServices, baseline.extraServices)) {
patch.extraServices = draft.extraServices;
}
continue;
}
if (draft[key] !== baseline[key]) {
(patch as Record<EditKey, WorkOrderTableRow[EditKey]>)[key] = draft[key];
}
}
return patch;
}