mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-07 16:19:01 +00:00
fix(vendors): keep company input in sync
This commit is contained in:
parent
ff10bbd8ec
commit
db3ae2ca3f
2 changed files with 152 additions and 6 deletions
|
|
@ -46,7 +46,6 @@ export function VendorFormFields({
|
|||
onCompanySelected,
|
||||
showTotalJobs = false,
|
||||
}: VendorFormFieldsProps) {
|
||||
const [companyInput, setCompanyInput] = useState("");
|
||||
const [tradeInput, setTradeInput] = useState("");
|
||||
|
||||
return (
|
||||
|
|
@ -99,28 +98,24 @@ export function VendorFormFields({
|
|||
: option.name === value.name
|
||||
}
|
||||
value={field.value ?? ""}
|
||||
inputValue={companyInput || (typeof field.value === "string" ? field.value : "")}
|
||||
inputValue={field.value ?? ""}
|
||||
onInputChange={(_event, value, reason) => {
|
||||
if (reason === "input") {
|
||||
setCompanyInput(value);
|
||||
field.onChange(value);
|
||||
}
|
||||
}}
|
||||
onChange={(_event, value, reason) => {
|
||||
if (typeof value === "string") {
|
||||
field.onChange(value);
|
||||
setCompanyInput(value);
|
||||
return;
|
||||
}
|
||||
if (value) {
|
||||
field.onChange(value.name);
|
||||
setCompanyInput(value.name);
|
||||
if (reason === "selectOption") {
|
||||
onCompanySelected(value);
|
||||
}
|
||||
} else {
|
||||
field.onChange("");
|
||||
setCompanyInput("");
|
||||
}
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
|
|
|
|||
151
src/test/app/(protected)/vendors/vendor-form-fields.test.tsx
vendored
Normal file
151
src/test/app/(protected)/vendors/vendor-form-fields.test.tsx
vendored
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
import { screen } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useForm, type FieldErrors } from "react-hook-form";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { VendorFormFields } from "@/app/(protected)/vendors/_components/vendor-form-fields";
|
||||
import { vendorSchema, type VendorFormValues } from "@/domain/vendors/schemas/vendor-schema";
|
||||
import type { VendorFacetCompany } from "@/domain/vendors/types/vendor";
|
||||
import { renderWithProviders } from "@/test/test-utils";
|
||||
|
||||
const companies: VendorFacetCompany[] = [
|
||||
{
|
||||
name: "Gateway Plumbing",
|
||||
companyPhone: "(314) 555-0198",
|
||||
email: "dispatch@gatewayplumbing.com",
|
||||
address: "1 Main St",
|
||||
city: "St. Louis",
|
||||
state: "MO",
|
||||
zip: "63101",
|
||||
googleMapsUrl: "https://maps.google.com/gateway",
|
||||
},
|
||||
];
|
||||
|
||||
const emptyForm: VendorFormValues = {
|
||||
companyName: "",
|
||||
contactName: "Tech Person",
|
||||
email: "",
|
||||
phone: "",
|
||||
companyPhone: "",
|
||||
googleMapsUrl: "",
|
||||
notes: "",
|
||||
totalJobs: 0,
|
||||
address: "",
|
||||
city: "",
|
||||
state: "",
|
||||
zip: "",
|
||||
tradeSpecialties: "",
|
||||
isActive: true,
|
||||
};
|
||||
|
||||
function Harness({
|
||||
defaultValues,
|
||||
resetTarget,
|
||||
}: {
|
||||
defaultValues: VendorFormValues;
|
||||
resetTarget: VendorFormValues;
|
||||
}) {
|
||||
const { control, reset, setValue } = useForm<VendorFormValues>({
|
||||
resolver: zodResolver(vendorSchema),
|
||||
defaultValues,
|
||||
});
|
||||
|
||||
const onCompanySelected = (company: VendorFacetCompany | null) => {
|
||||
if (!company) return;
|
||||
setValue("companyPhone", company.companyPhone);
|
||||
setValue("email", company.email);
|
||||
setValue("address", company.address);
|
||||
setValue("city", company.city);
|
||||
setValue("state", company.state);
|
||||
setValue("zip", company.zip);
|
||||
setValue("googleMapsUrl", company.googleMapsUrl);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<VendorFormFields
|
||||
control={control}
|
||||
errors={{} as FieldErrors<VendorFormValues>}
|
||||
companies={companies}
|
||||
tradeOptions={[]}
|
||||
onCompanySelected={onCompanySelected}
|
||||
/>
|
||||
<button type="button" onClick={() => reset(resetTarget)}>
|
||||
reset-form
|
||||
</button>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const companyField = () => screen.getByRole("combobox", { name: "Company" }) as HTMLInputElement;
|
||||
|
||||
describe("VendorFormFields company autocomplete state", () => {
|
||||
it("clears a previously typed company when the form is reset (create-form reopen)", async () => {
|
||||
renderWithProviders(<Harness defaultValues={emptyForm} resetTarget={emptyForm} />, {
|
||||
withAuth: false,
|
||||
});
|
||||
|
||||
await userEvent.type(companyField(), "Leftover Co");
|
||||
expect(companyField()).toHaveValue("Leftover Co");
|
||||
|
||||
await userEvent.click(screen.getByRole("button", { name: "reset-form" }));
|
||||
|
||||
expect(companyField()).toHaveValue("");
|
||||
});
|
||||
|
||||
it("shows the switched company value instead of previously typed text when the form is reset", async () => {
|
||||
renderWithProviders(
|
||||
<Harness
|
||||
defaultValues={emptyForm}
|
||||
resetTarget={{ ...emptyForm, companyName: "Beta LLC", contactName: "Other Tech" }}
|
||||
/>,
|
||||
{ withAuth: false },
|
||||
);
|
||||
|
||||
await userEvent.type(companyField(), "Acme");
|
||||
expect(companyField()).toHaveValue("Acme");
|
||||
|
||||
await userEvent.click(screen.getByRole("button", { name: "reset-form" }));
|
||||
|
||||
expect(companyField()).toHaveValue("Beta LLC");
|
||||
});
|
||||
|
||||
it("reflects the company provided by an external reset even when nothing was typed", async () => {
|
||||
renderWithProviders(
|
||||
<Harness
|
||||
defaultValues={{ ...emptyForm, companyName: "Acme Corp" }}
|
||||
resetTarget={{ ...emptyForm, companyName: "Beta LLC" }}
|
||||
/>,
|
||||
{ withAuth: false },
|
||||
);
|
||||
|
||||
expect(companyField()).toHaveValue("Acme Corp");
|
||||
|
||||
await userEvent.click(screen.getByRole("button", { name: "reset-form" }));
|
||||
|
||||
expect(companyField()).toHaveValue("Beta LLC");
|
||||
});
|
||||
|
||||
it("updates the displayed company as the user types (freeSolo)", async () => {
|
||||
renderWithProviders(<Harness defaultValues={emptyForm} resetTarget={emptyForm} />, {
|
||||
withAuth: false,
|
||||
});
|
||||
|
||||
await userEvent.type(companyField(), "Acme");
|
||||
|
||||
expect(companyField()).toHaveValue("Acme");
|
||||
});
|
||||
|
||||
it("selects a company option, autofills company details, and shows the company name", async () => {
|
||||
renderWithProviders(<Harness defaultValues={emptyForm} resetTarget={emptyForm} />, {
|
||||
withAuth: false,
|
||||
});
|
||||
|
||||
await userEvent.type(companyField(), "Gate");
|
||||
const option = await screen.findByRole("option", { name: "Gateway Plumbing" });
|
||||
await userEvent.click(option);
|
||||
|
||||
expect(companyField()).toHaveValue("Gateway Plumbing");
|
||||
expect(screen.getByRole("textbox", { name: "Company Phone" })).toHaveValue("(314) 555-0198");
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Reference in a new issue