diff --git a/src/app/(protected)/workorders/_components/list/table/cells/service-notes-dialog.tsx b/src/app/(protected)/workorders/_components/list/table/cells/service-notes-dialog.tsx index edd1cf79..c5e9d20c 100644 --- a/src/app/(protected)/workorders/_components/list/table/cells/service-notes-dialog.tsx +++ b/src/app/(protected)/workorders/_components/list/table/cells/service-notes-dialog.tsx @@ -212,6 +212,41 @@ function getServiceOptionState( }; } +function resolveRenamedPrimaryName({ + selectedName, + selectedServiceId, + serviceIdsByName, + services, + previous, + pm, + serviceId, +}: { + selectedName: string | undefined; + selectedServiceId?: string | number | null; + serviceIdsByName: Record; + services?: Service[]; + previous: DialogTarget; + pm: string; + serviceId?: string | number | null; +}) { + const chosenService = services?.find( + (service) => String(service.id) === String(selectedServiceId), + ); + const selectionTracksChosenId = + selectedName != null && + selectedServiceId != null && + String(serviceIdsByName[selectedName]) === String(selectedServiceId); + if (selectionTracksChosenId && chosenService != null) return chosenService.name; + + const savedServiceUnchanged = + previous.serviceId != null && String(previous.serviceId) === String(serviceId); + const selectedSavedId = String(selectedServiceId ?? "") === String(serviceId ?? ""); + const selectedSavedLabel = selectedName === previous.pm; + return savedServiceUnchanged && selectedSavedId && selectedSavedLabel && previous.pm !== pm + ? pm + : undefined; +} + function useServiceNotesDraft({ open, target, @@ -261,13 +296,25 @@ function useServiceNotesDraft({ setNote(serviceNotes ?? ""); setAveta(Boolean(avetaRequired)); setSearch(""); - } else if ( - previous.serviceId != null && - String(previous.serviceId) === String(serviceId) && - previous.pm !== pm - ) { - setSel((current) => (current[0] === previous.pm ? [pm, ...current.slice(1)] : current)); - setServiceIdsByName((current) => ({ ...current, [pm]: serviceId! })); + } else { + const renamedPrimary = resolveRenamedPrimaryName({ + selectedName: sel[0], + selectedServiceId: primaryServiceId, + serviceIdsByName, + services, + previous, + pm, + serviceId, + }); + if (renamedPrimary != null && renamedPrimary !== sel[0]) { + setSel((current) => + current[0] === sel[0] ? [renamedPrimary, ...current.slice(1)] : current, + ); + setServiceIdsByName((current) => ({ + ...current, + [renamedPrimary]: primaryServiceId ?? serviceId!, + })); + } } lastTarget.current = { key: targetKey, pm: targetPm, serviceId: targetServiceId }; }, [ @@ -277,6 +324,9 @@ function useServiceNotesDraft({ targetServiceId, pm, serviceId, + sel, + primaryServiceId, + serviceIdsByName, extraServices, services, serviceNotes, diff --git a/src/test/app/(protected)/workorders/aveta-service-notes.test.tsx b/src/test/app/(protected)/workorders/aveta-service-notes.test.tsx index d2aa4c4f..6c7da328 100644 --- a/src/test/app/(protected)/workorders/aveta-service-notes.test.tsx +++ b/src/test/app/(protected)/workorders/aveta-service-notes.test.tsx @@ -729,4 +729,74 @@ describe("Aveta Service & Notes", () => { expect.objectContaining({ pm: "Other service", serviceId: 702 }), ); }); + + it("keeps the chosen identity when the saved same-label service is renamed", () => { + const onSave = vi.fn(); + const common = { + open: true, + onOpenChange: vi.fn(), + extraServices: [], + serviceNotes: "Saved notes", + avetaRequired: false, + pmTypes: [], + serviceQuery: { + isLoading: false, + isError: false, + isFetching: false, + hasData: true, + retry: vi.fn(), + }, + onSave, + }; + const view = renderWithProviders( + , + { withAuth: false }, + ); + + fireEvent.click(screen.getByRole("button", { name: /Retired ServicePrimary/i })); + fireEvent.change(screen.getByPlaceholderText(/describe the specific issue/i), { + target: { value: "Draft note" }, + }); + fireEvent.click(screen.getByRole("checkbox", { name: /Requires Aveta documentation/i })); + fireEvent.click(screen.getByRole("button", { name: "Extra Service" })); + view.rerender( + , + ); + expect(screen.getByRole("button", { name: /Retired ServicePrimary/i })).toBeInTheDocument(); + view.rerender( + , + ); + expect( + screen.getByRole("button", { name: /Renamed chosen servicePrimary/i }), + ).toBeInTheDocument(); + fireEvent.click(screen.getByRole("button", { name: "Save" })); + + expect(onSave).toHaveBeenCalledWith( + expect.objectContaining({ + pm: "Renamed chosen service", + serviceId: 2, + extraServices: ["Extra Service"], + serviceNotes: "Draft note", + avetaRequired: true, + }), + ); + }); });