fix(vendors): preserve status during roster edits

This commit is contained in:
Codex Review Integration 2026-08-20 20:59:27 -03:00
parent 146491fafb
commit f0f3485bee
2 changed files with 45 additions and 19 deletions

View file

@ -97,6 +97,7 @@ export interface VendorRosterForm {
selectedCompanyId: string | number | null;
selectCompany: (company: VendorFacetCompany | null) => Promise<void>;
clearSelectedCompany: (nextName?: string) => void;
setTechnicianActive: (index: number, isActive: boolean) => void;
resetForm: () => void;
}
@ -133,7 +134,7 @@ export function useVendorRosterForm({
values: mode === "update" && routeRoster ? toFormValues(routeRoster) : undefined,
mode: "onChange",
});
const { control, handleSubmit, reset, formState } = form;
const { control, handleSubmit, reset, setValue, formState } = form;
// react-hook-form exposes formState through a Proxy that only tracks properties read during
// render. Reading dirtyFields inside the submit callback would not subscribe and would come
// back empty, so it is resolved here on every render.
@ -163,6 +164,16 @@ export function useVendorRosterForm({
clearConflict();
}, [clearConflict, createDefaults, reset, resetSelection]);
const setTechnicianActive = useCallback(
(index: number, isActive: boolean) => {
setValue(`technicians.${index}.isActive`, isActive, {
shouldDirty: true,
shouldValidate: true,
});
},
[setValue],
);
const submit = (formValues: VendorCompanyRosterFormValues) => {
setConflict(null);
const values = withoutBlankNewTechnicians(formValues);
@ -228,6 +239,7 @@ export function useVendorRosterForm({
selectedCompanyId: selection.selectedCompanyId,
selectCompany: selection.selectCompany,
clearSelectedCompany: selection.clearSelectedCompany,
setTechnicianActive,
resetForm,
};
}

View file

@ -1,5 +1,5 @@
import { useEffect, useState, type ReactNode } from "react";
import { Controller, useWatch } from "react-hook-form";
import { useWatch } from "react-hook-form";
import CloseIcon from "@mui/icons-material/Close";
import EditOutlinedIcon from "@mui/icons-material/EditOutlined";
import LaunchIcon from "@mui/icons-material/Launch";
@ -240,6 +240,32 @@ function DrawerActions({ onEdit }: { onEdit: () => void }) {
);
}
function TechnicianStatusControl({
isActive,
persistedIsActive,
onRequestDeactivation,
onChange,
}: {
isActive: boolean;
persistedIsActive: boolean;
onRequestDeactivation: () => void;
onChange: (checked: boolean) => void;
}) {
return (
<Stack direction="row" spacing={1} sx={{ alignItems: "center" }}>
<Text variant="description">{isActive ? "Active" : "Inactive"}</Text>
<Switch
checked={isActive}
slotProps={{ input: { "aria-label": "Active status" } }}
onChange={(_event, checked) => {
if (persistedIsActive && !checked) onRequestDeactivation();
else onChange(checked);
}}
/>
</Stack>
);
}
function DrawerEditor({
vendor,
onClose,
@ -312,23 +338,11 @@ function DrawerEditor({
Total Jobs
</Text>
</Box>
<Controller
control={form.control}
name={`technicians.${selectedIndex}.isActive`}
shouldUnregister
render={({ field }) => (
<Stack direction="row" spacing={1} sx={{ alignItems: "center" }}>
<Text variant="description">{field.value ? "Active" : "Inactive"}</Text>
<Switch
checked={Boolean(field.value)}
slotProps={{ input: { "aria-label": "Active status" } }}
onChange={(_event, checked) => {
if (persistedIsActive && !checked) onRequestDeactivation(vendor);
else field.onChange(checked);
}}
/>
</Stack>
)}
<TechnicianStatusControl
isActive={Boolean(technicians[selectedIndex]?.isActive)}
persistedIsActive={persistedIsActive}
onRequestDeactivation={() => onRequestDeactivation(vendor)}
onChange={(checked) => form.setTechnicianActive(selectedIndex, checked)}
/>
</Stack>
</>