From 1dedc43d5e5bbfd5f63612875404fa0794531a11 Mon Sep 17 00:00:00 2001 From: Wayne Date: Sat, 24 Aug 2024 21:09:34 +0900 Subject: [PATCH] Default client type due master --- .../ControlledAutoComplete.tsx | 251 +++++++++++------- .../CreateProject/ProjectClientDetails.tsx | 31 +-- 2 files changed, 165 insertions(+), 117 deletions(-) diff --git a/src/components/ControlledAutoComplete/ControlledAutoComplete.tsx b/src/components/ControlledAutoComplete/ControlledAutoComplete.tsx index ed7e81b..c2a2044 100644 --- a/src/components/ControlledAutoComplete/ControlledAutoComplete.tsx +++ b/src/components/ControlledAutoComplete/ControlledAutoComplete.tsx @@ -1,117 +1,164 @@ -"use client" +"use client"; -import { Autocomplete, MenuItem, TextField, Checkbox, Chip } from "@mui/material"; -import { Controller, FieldValues, Path, Control, RegisterOptions } from "react-hook-form"; +import { + Autocomplete, + MenuItem, + TextField, + Checkbox, + Chip, +} from "@mui/material"; +import { + Controller, + FieldValues, + Path, + Control, + RegisterOptions, +} from "react-hook-form"; import { useTranslation } from "react-i18next"; -import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; -import CheckBoxIcon from '@mui/icons-material/CheckBox'; +import CheckBoxOutlineBlankIcon from "@mui/icons-material/CheckBoxOutlineBlank"; +import CheckBoxIcon from "@mui/icons-material/CheckBox"; const icon = ; const checkedIcon = ; // label -> e.g. code - name -> 001 - WL // name -> WL -interface Props { - control: Control, - options: T[], - name: Path, // register name - label?: string, // display label - noOptionsText?: string, - isMultiple?: boolean, - rules?: RegisterOptions - disabled?: boolean, +interface Props< + T extends { id?: number | string | null; label?: string; name?: string }, + TField extends FieldValues, +> { + control: Control; + options: T[]; + name: Path; // register name + label?: string; // display label + noOptionsText?: string; + isMultiple?: boolean; + rules?: RegisterOptions; + disabled?: boolean; } function ControlledAutoComplete< - T extends { id?: number | string; label?: string; name?: string }, - TField extends FieldValues ->( - props: Props -) { - const { t } = useTranslation() - const { control, options, name, label, noOptionsText, isMultiple, rules, disabled } = props; + T extends { id?: number | string; label?: string; name?: string }, + TField extends FieldValues, +>(props: Props) { + const { t } = useTranslation(); + const { + control, + options, + name, + label, + noOptionsText, + isMultiple, + rules, + disabled, + } = props; - // set default value if value is null - if (!Boolean(isMultiple) && !Boolean(control._formValues[name])) { - control._formValues[name] = options[0]?.id ?? undefined - } else if (Boolean(isMultiple) && !Boolean(control._formValues[name])) { - control._formValues[name] = [] - } + // set default value if value is null + if (!Boolean(isMultiple) && !Boolean(control._formValues[name])) { + control._formValues[name] = options[0]?.id ?? undefined; + } else if (Boolean(isMultiple) && !Boolean(control._formValues[name])) { + control._formValues[name] = []; + } - return ( - { - - return ( - isMultiple ? - { - return field.value?.includes(option.id) - })} - options={options} - getOptionLabel={(option) => option.label ?? option.name!!} - isOptionEqualToValue={(option, value) => option.id === value.id} - renderOption={(params, option, { selected }) => { - return ( -
  • - - {option.label ?? option.name} -
  • - ); - }} - renderTags={(tagValue, getTagProps) => { - return tagValue.map((option, index) => ( - - )) - }} - onChange={(event, value) => { - field.onChange(value?.map(v => v.id)) - }} - renderInput={(params) => } - /> - : - option.id === field.value) ?? options[0]} - options={options} - getOptionLabel={(option) => option.label ?? option.name!!} - isOptionEqualToValue={(option, value) => option?.id === value?.id} - renderOption={(params, option) => { - return ( - - {option.label ?? option.name} - - ); - }} - renderTags={(tagValue, getTagProps) => { - return tagValue.map((option, index) => ( - - )) - }} - onChange={(event, value) => { - field.onChange(value?.id ?? null) - }} - renderInput={(params) => } - />) + return ( + { + return isMultiple ? ( + { + return field.value?.includes(option.id); + })} + options={options} + getOptionLabel={(option) => option.label ?? option.name!} + isOptionEqualToValue={(option, value) => option.id === value.id} + renderOption={(params, option, { selected }) => { + return ( +
  • + + {option.label ?? option.name} +
  • + ); + }} + renderTags={(tagValue, getTagProps) => { + return tagValue.map((option, index) => ( + + )); + }} + onChange={(event, value) => { + field.onChange(value?.map((v) => v.id)); + }} + onBlur={field.onBlur} + renderInput={(params) => ( + + )} + /> + ) : ( + option.id === field.value) ?? options[0] + } + options={options} + getOptionLabel={(option) => option.label ?? option.name!} + isOptionEqualToValue={(option, value) => option?.id === value?.id} + renderOption={(params, option) => { + return ( + + {option.label ?? option.name} + + ); + }} + renderTags={(tagValue, getTagProps) => { + return tagValue.map((option, index) => ( + + )); + }} + onChange={(event, value) => { + field.onChange(value?.id ?? null); }} - /> - ) + onBlur={field.onBlur} + renderInput={(params) => ( + + )} + /> + ); + }} + /> + ); } -export default ControlledAutoComplete; \ No newline at end of file +export default ControlledAutoComplete; diff --git a/src/components/CreateProject/ProjectClientDetails.tsx b/src/components/CreateProject/ProjectClientDetails.tsx index 110f722..a506569 100644 --- a/src/components/CreateProject/ProjectClientDetails.tsx +++ b/src/components/CreateProject/ProjectClientDetails.tsx @@ -72,7 +72,7 @@ const ProjectClientDetails: React.FC = ({ const { t } = useTranslation(); const { register, - formState: { errors, defaultValues }, + formState: { errors, defaultValues, touchedFields }, watch, control, setValue, @@ -111,21 +111,22 @@ const ProjectClientDetails: React.FC = ({ // get customer (client) contact combo const clientSubsidiaryId = watch("clientSubsidiaryId"); - const [firstCustomerLoaded, setFirstCustomerLoaded] = useState(false); useEffect(() => { if (selectedCustomerId !== undefined) { fetchCustomer(selectedCustomerId).then( ({ contacts, subsidiaryIds, customer }) => { setCustomerContacts(contacts); setCustomerSubsidiaryIds(subsidiaryIds); - - if (isEditMode && firstCustomerLoaded) { - setValue("clientTypeId", customer.customerType.id); - } - - if (isEditMode && !firstCustomerLoaded) { - setFirstCustomerLoaded(true); - } else if (subsidiaryIds.length > 0) + setValue( + "clientTypeId", + touchedFields["clientTypeId"] + ? customer.customerType.id + : defaultValues?.clientTypeId || customer.customerType.id, + { + shouldTouch: isEditMode, + }, + ); + if (subsidiaryIds.length > 0) setValue( "clientSubsidiaryId", clientSubsidiaryId !== undefined && clientSubsidiaryId !== null @@ -161,13 +162,13 @@ const ProjectClientDetails: React.FC = ({ } else if (customerContacts?.length > 0) { setSubsidiaryContacts(() => []); setValue( - "clientContactId", - selectedCustomerId === defaultValues?.clientId && - !Boolean(defaultValues?.clientSubsidiaryId) + "clientContactId", + selectedCustomerId === defaultValues?.clientId && + !Boolean(defaultValues?.clientSubsidiaryId) ? customerContacts.find( (contact) => contact.id === defaultValues.clientContactId, - )?.id ?? customerContacts[0].id - : customerContacts[0].id + )?.id ?? customerContacts[0].id + : customerContacts[0].id, ); setValue("isSubsidiaryContact", false); }