mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-04 04:23:13 +00:00
fix(work-orders): enforce single-service wizard create per SH-118
Use single service selection in the wizard and omit extraServices from board create.
This commit is contained in:
parent
8bfa600301
commit
64c485025b
4 changed files with 52 additions and 63 deletions
|
|
@ -28,18 +28,14 @@ export function WizardStepLocationServiceSelect({
|
|||
onUpdate,
|
||||
onPatch,
|
||||
}: WizardStepLocationServiceSelectProps) {
|
||||
const svcSel = [draft.pm, ...draft.extraServices].filter((p, i, a) => !!p && a.indexOf(p) === i);
|
||||
|
||||
const clearVendorIfPrimaryChanged = (nextPm: string): Partial<WorkOrderWizardDraft> =>
|
||||
nextPm !== draft.pm ? { vendorId: "", vendorName: "", techPhone: "" } : {};
|
||||
|
||||
const toggleSvc = (p: string) => {
|
||||
const next = svcSel.includes(p) ? svcSel.filter((x) => x !== p) : [...svcSel, p];
|
||||
const nextPm = next[0] ?? "";
|
||||
const selectSvc = (p: string) => {
|
||||
onPatch({
|
||||
pm: nextPm,
|
||||
extraServices: next.slice(1),
|
||||
...clearVendorIfPrimaryChanged(nextPm),
|
||||
pm: p,
|
||||
extraServices: [],
|
||||
...clearVendorIfPrimaryChanged(p),
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -63,13 +59,7 @@ export function WizardStepLocationServiceSelect({
|
|||
),
|
||||
};
|
||||
})}
|
||||
onPick={(p) =>
|
||||
onPatch({
|
||||
pm: p,
|
||||
extraServices: draft.extraServices.filter((x) => x !== p),
|
||||
...clearVendorIfPrimaryChanged(p),
|
||||
})
|
||||
}
|
||||
onPick={selectSvc}
|
||||
/>
|
||||
{!svcOpen ? (
|
||||
<button
|
||||
|
|
@ -95,8 +85,8 @@ export function WizardStepLocationServiceSelect({
|
|||
>
|
||||
<WizardServiceNotesFields
|
||||
services={services}
|
||||
sel={svcSel}
|
||||
onToggle={toggleSvc}
|
||||
sel={draft.pm ? [draft.pm] : []}
|
||||
onToggle={selectSvc}
|
||||
note={draft.pmNote}
|
||||
setNote={(v) => onUpdate("pmNote", v)}
|
||||
search={svcSearch}
|
||||
|
|
|
|||
|
|
@ -7,42 +7,7 @@ function trimOrUndefined(value: string | undefined): string | undefined {
|
|||
return trimmed ? trimmed : undefined;
|
||||
}
|
||||
|
||||
function normalizeExtraServices(
|
||||
primary: string | undefined,
|
||||
extras: string[],
|
||||
): string[] | undefined {
|
||||
if (extras.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const seen = new Set<string>();
|
||||
|
||||
const primaryKey = primary?.toLowerCase() ?? "";
|
||||
|
||||
const out: string[] = [];
|
||||
|
||||
for (const raw of extras) {
|
||||
const trimmed = raw.trim();
|
||||
|
||||
if (!trimmed) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const key = trimmed.toLowerCase();
|
||||
|
||||
if (key === primaryKey || seen.has(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
seen.add(key);
|
||||
|
||||
out.push(trimmed);
|
||||
}
|
||||
|
||||
return out.length > 0 ? out : undefined;
|
||||
}
|
||||
|
||||
/** Mutates `payload` with primary/extra services, service notes, POC, tech phone, and vendor notes. */
|
||||
/** Mutates `payload` with primary service, service notes, POC, tech phone, and vendor notes. */
|
||||
export function assignWizardServicePocFields(
|
||||
payload: WorkOrderBoardCreatePayload,
|
||||
draft: WorkOrderWizardDraft,
|
||||
|
|
@ -53,12 +18,6 @@ export function assignWizardServicePocFields(
|
|||
payload.primaryService = primaryService;
|
||||
}
|
||||
|
||||
const extraServices = normalizeExtraServices(primaryService, draft.extraServices);
|
||||
|
||||
if (extraServices) {
|
||||
payload.extraServices = extraServices;
|
||||
}
|
||||
|
||||
const serviceNotes = trimOrUndefined(draft.pmNote);
|
||||
|
||||
if (serviceNotes) {
|
||||
|
|
|
|||
|
|
@ -39,10 +39,50 @@ describe("WizardStepLocationServiceSelect — vendor clear on service change", (
|
|||
expect(onPatch).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
pm: "Plumbing",
|
||||
extraServices: [],
|
||||
vendorId: "",
|
||||
vendorName: "",
|
||||
techPhone: "",
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("replaces the selected service in Service & Notes without persisting extraServices", () => {
|
||||
const onPatch = vi.fn();
|
||||
const draft: WorkOrderWizardDraft = {
|
||||
...EMPTY_WIZARD_DRAFT,
|
||||
pm: "HVAC",
|
||||
extraServices: ["Plumbing"],
|
||||
vendorId: "9",
|
||||
vendorName: "Old Vendor",
|
||||
techPhone: "555-0100",
|
||||
};
|
||||
|
||||
render(
|
||||
<WizardStepLocationServiceSelect
|
||||
draft={draft}
|
||||
services={[
|
||||
{ id: "1", value: "HVAC" },
|
||||
{ id: "2", value: "Plumbing" },
|
||||
{ id: "3", value: "Electrical" },
|
||||
]}
|
||||
svcOpen={true}
|
||||
onSvcOpenChange={vi.fn()}
|
||||
svcSearch=""
|
||||
onSvcSearchChange={vi.fn()}
|
||||
onUpdate={vi.fn()}
|
||||
onPatch={onPatch}
|
||||
/>,
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: "Electrical" }));
|
||||
|
||||
expect(onPatch).toHaveBeenCalledWith({
|
||||
pm: "Electrical",
|
||||
extraServices: [],
|
||||
vendorId: "",
|
||||
vendorName: "",
|
||||
techPhone: "",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -122,8 +122,6 @@ describe("mapWizardDraftToBoardCreatePayload", () => {
|
|||
|
||||
primaryService: "HVAC PM",
|
||||
|
||||
extraServices: ["Filter change", "Coil clean"],
|
||||
|
||||
serviceNotes: "Check unit on roof",
|
||||
|
||||
pocName: "Jane Site Lead",
|
||||
|
|
@ -141,6 +139,8 @@ describe("mapWizardDraftToBoardCreatePayload", () => {
|
|||
|
||||
expect(payload.trade).toBeUndefined();
|
||||
|
||||
expect(payload.extraServices).toBeUndefined();
|
||||
|
||||
expect(payload.description).toBeUndefined();
|
||||
|
||||
expect(payload.scheduleWeekOnly).toBeUndefined();
|
||||
|
|
@ -294,7 +294,7 @@ describe("mapWizardDraftToBoardCreatePayload", () => {
|
|||
expect(payload.vendorNotes).toBe("Also not in description");
|
||||
});
|
||||
|
||||
it("maps service notes and extras as structured fields instead of description", () => {
|
||||
it("maps service notes as structured fields and omits extraServices from wizard create", () => {
|
||||
const payload = mapWizardDraftToBoardCreatePayload({
|
||||
...EMPTY_WIZARD_DRAFT,
|
||||
|
||||
|
|
@ -311,7 +311,7 @@ describe("mapWizardDraftToBoardCreatePayload", () => {
|
|||
|
||||
expect(payload.primaryService).toBe("HVAC PM");
|
||||
|
||||
expect(payload.extraServices).toEqual(["Filter change", "Coil clean"]);
|
||||
expect(payload.extraServices).toBeUndefined();
|
||||
|
||||
expect(payload.serviceNotes).toBe("Check unit on roof");
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue