From 90a5256deedcde41e6ba35710a9d937027377a29 Mon Sep 17 00:00:00 2001 From: Codex Review Integration Date: Wed, 19 Aug 2026 13:18:17 -0300 Subject: [PATCH] fix(vendors): gate deactivation prompt on saved status (SH-255) The drawer's Active toggle asked to deactivate whenever the switch moved from on to off, reading the unsaved form value. An inactive vendor toggled on and back off without saving therefore raised "Deactivate this vendor" for a vendor that was already inactive. Gate on the persisted technician status from the loaded roster instead, falling back to the clicked row. Deactivation is a property of the saved vendor, not of the toggle. --- .../_components/vendor-detail-drawer.tsx | 13 +++-- .../vendors/vendor-detail-drawer.test.tsx | 58 +++++++++++++++++++ 2 files changed, 66 insertions(+), 5 deletions(-) diff --git a/src/app/(protected)/vendors/_components/vendor-detail-drawer.tsx b/src/app/(protected)/vendors/_components/vendor-detail-drawer.tsx index 74d6ef02..fdb627be 100644 --- a/src/app/(protected)/vendors/_components/vendor-detail-drawer.tsx +++ b/src/app/(protected)/vendors/_components/vendor-detail-drawer.tsx @@ -254,10 +254,13 @@ function DrawerEditor({ const selectedIndex = technicians.findIndex( (technician) => technician.id != null && String(technician.id) === String(vendor.id), ); - const selectedTotalJobs = - roster?.technicians.find( - (technician) => technician.id != null && String(technician.id) === String(vendor.id), - )?.totalJobs ?? vendor.totalJobs; + const persistedTechnician = roster?.technicians.find( + (technician) => technician.id != null && String(technician.id) === String(vendor.id), + ); + const selectedTotalJobs = persistedTechnician?.totalJobs ?? vendor.totalJobs; + // Deactivation is a property of the saved vendor, not of the toggle: flipping an + // inactive vendor on and back off without saving must not ask to deactivate it. + const persistedIsActive = persistedTechnician?.isActive ?? vendor.isActive; if (form.isLoading) { return ; @@ -310,7 +313,7 @@ function DrawerEditor({ checked={Boolean(field.value)} slotProps={{ input: { "aria-label": "Active status" } }} onChange={(_event, checked) => { - if (field.value && !checked) onRequestDeactivation(vendor); + if (persistedIsActive && !checked) onRequestDeactivation(vendor); else field.onChange(checked); }} /> diff --git a/src/test/app/(protected)/vendors/vendor-detail-drawer.test.tsx b/src/test/app/(protected)/vendors/vendor-detail-drawer.test.tsx index df329a4a..3029e06c 100644 --- a/src/test/app/(protected)/vendors/vendor-detail-drawer.test.tsx +++ b/src/test/app/(protected)/vendors/vendor-detail-drawer.test.tsx @@ -1,4 +1,5 @@ import { screen } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; import { describe, expect, it, vi } from "vitest"; import { VendorDetailDrawer } from "@/app/(protected)/vendors/_components/vendor-detail-drawer"; import { renderWithProviders } from "@/test/test-utils"; @@ -134,3 +135,60 @@ describe("VendorDetailDrawer selected-technician display", () => { expect(screen.queryByRole("switch", { name: "Active status" })).not.toBeInTheDocument(); }); }); + +describe("VendorDetailDrawer deactivation prompt", () => { + const inactiveVendor: VendorListItem = { ...vendor, isActive: false }; + + it("does not prompt to deactivate a saved-inactive vendor toggled on and back off", async () => { + useVendorCompanyRoster.mockReturnValue( + rosterWith([ + { id: 1, contactName: "Adam", phone: "314-555-0198", isActive: false, totalJobs: 5 }, + ]), + ); + const onRequestDeactivation = vi.fn(); + + renderWithProviders( + , + { route: "/vendors", withAuth: false }, + ); + + const toggle = screen.getByRole("switch", { name: "Active status" }); + await userEvent.click(toggle); + expect(toggle).toBeChecked(); + + await userEvent.click(toggle); + + expect(toggle).not.toBeChecked(); + expect(onRequestDeactivation).not.toHaveBeenCalled(); + }); + + it("prompts to deactivate a saved-active vendor when the toggle is switched off", async () => { + useVendorCompanyRoster.mockReturnValue( + rosterWith([ + { id: 1, contactName: "Adam", phone: "314-555-0198", isActive: true, totalJobs: 5 }, + ]), + ); + const onRequestDeactivation = vi.fn(); + + renderWithProviders( + , + { route: "/vendors", withAuth: false }, + ); + + await userEvent.click(screen.getByRole("switch", { name: "Active status" })); + + expect(onRequestDeactivation).toHaveBeenCalledWith(vendor); + }); +});