Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LF-4388 animal details sub components handle edit and readonly modes #3485

Open
wants to merge 15 commits into
base: integration
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/webapp/public/locales/de/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,11 @@
"WHAT_PLANTING_METHOD": "Was ist die Umpflanzmethode?",
"WILD_CROP": "Wildfrüchte"
},
"ANIMAL": {
"ATTRIBUTE": {
"LITEFARM_ID": "MISSING"
}
},
"BED_PLAN": {
"LENGTH_OF_BED": "Länge der Betten",
"NUMBER_0F_BEDS": "# Anzahl der Betten",
Expand Down
1 change: 1 addition & 0 deletions packages/webapp/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@
"BATCH_NAME": "Batch name",
"DAM": "Dam",
"DATE_OF_BIRTH": "Date of birth",
"LITEFARM_ID": "LiteFarm ID",
"ORGANIC_STATUS": "Organic status",
"OTHER_DETAILS_ANIMAL": "Other animal details",
"OTHER_DETAILS_BATCH": "Batch details",
Expand Down
1 change: 1 addition & 0 deletions packages/webapp/public/locales/es/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@
"BATCH_NAME": "MISSING",
"DAM": "MISSING",
"DATE_OF_BIRTH": "MISSING",
"LITEFARM_ID": "MISSING",
"ORGANIC_STATUS": "MISSING",
"OTHER_DETAILS_ANIMAL": "MISSING",
"OTHER_DETAILS_BATCH": "MISSING",
Expand Down
1 change: 1 addition & 0 deletions packages/webapp/public/locales/fr/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@
"BATCH_NAME": "MISSING",
"DAM": "MISSING",
"DATE_OF_BIRTH": "MISSING",
"LITEFARM_ID": "MISSING",
"ORGANIC_STATUS": "MISSING",
"OTHER_DETAILS_ANIMAL": "MISSING",
"OTHER_DETAILS_BATCH": "MISSING",
Expand Down
5 changes: 5 additions & 0 deletions packages/webapp/public/locales/ml/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,11 @@
"WHAT_PLANTING_METHOD": "",
"WILD_CROP": ""
},
"ANIMAL": {
"ATTRIBUTE": {
"LITEFARM_ID": "MISSING"
}
},
"BED_PLAN": {
"LENGTH_OF_BED": "",
"NUMBER_0F_BEDS": "",
Expand Down
5 changes: 5 additions & 0 deletions packages/webapp/public/locales/pa/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,11 @@
"WHAT_PLANTING_METHOD": "ਟ੍ਰਾਂਸਪਲਾਂਟ ਕਰਨ ਦਾ ਤਰੀਕਾ ਕੀ ਹੈ?",
"WILD_CROP": "ਜੰਗਲੀ ਫਸਲ"
},
"ANIMAL": {
"ATTRIBUTE": {
"LITEFARM_ID": "MISSING"
}
},
"BED_PLAN": {
"LENGTH_OF_BED": "ਬੇਡ ਦੀ ਲੰਬਾਈ",
"NUMBER_0F_BEDS": "# ਬੇਡ",
Expand Down
1 change: 1 addition & 0 deletions packages/webapp/public/locales/pt/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@
"BATCH_NAME": "MISSING",
"DAM": "MISSING",
"DATE_OF_BIRTH": "MISSING",
"LITEFARM_ID": "MISSING",
"ORGANIC_STATUS": "MISSING",
"OTHER_DETAILS_ANIMAL": "MISSING",
"OTHER_DETAILS_BATCH": "MISSING",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,6 @@ export default function AddAnimalsFormCard({

const breedSelectRef = useRef<SelectInstance>(null);

// Ref used to prevent breed being cleared when navigating back to basics step
const prevAnimalTypeRef = useRef(watchAnimalType?.value);

useEffect(() => {
if (prevAnimalTypeRef.current !== watchAnimalType?.value) {
breedSelectRef?.current?.clearValue();
prevAnimalTypeRef.current = watchAnimalType?.value;
}
}, [watchAnimalType?.value]);

return (
<Card className={styles.form} isActive={isActive}>
<div className={styles.formHeader}>
Expand All @@ -111,6 +101,7 @@ export default function AddAnimalsFormCard({
onTypeChange={(option) => {
trigger(`${namePrefix}${BasicsFields.TYPE}`);
onTypeChange?.(option);
breedSelectRef?.current?.clearValue();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We possibly don't need a ref here at all,

resetField(`${namePrefix}${BasicsFields.BREED}`, { defaultValue: null });

seems to do the trick.
Also, not related to this PR, but do we need a ref for the UUID value? Couldn't we set it in the useEffect hook without storing it in a ref?

}}
error={get(errors, `${namePrefix}${BasicsFields.TYPE}`)}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export type AnimalTypeSelectProps = {
typeOptions: OptionsOrGroups<Option, GroupBase<Option>>;
onTypeChange?: (Option: Option | null) => void;
error?: FieldError;
isDisabled?: boolean;
};

export function AnimalTypeSelect<T extends FieldValues>({
Expand All @@ -38,6 +39,7 @@ export function AnimalTypeSelect<T extends FieldValues>({
typeOptions,
onTypeChange,
error,
isDisabled = false,
}: AnimalTypeSelectProps & UseControllerProps<T>) {
const { t } = useTranslation();
return (
Expand All @@ -56,6 +58,7 @@ export function AnimalTypeSelect<T extends FieldValues>({
onTypeChange?.(option);
}}
value={value}
isDisabled={isDisabled}
/>
)}
/>
Expand All @@ -68,6 +71,7 @@ export type AnimalBreedSelectProps = {
breedOptions: Option[];
isTypeSelected?: boolean;
breedSelectRef?: RefObject<SelectInstance>;
isDisabled?: boolean;
};

export function AnimalBreedSelect<T extends FieldValues>({
Expand All @@ -76,6 +80,7 @@ export function AnimalBreedSelect<T extends FieldValues>({
breedOptions,
isTypeSelected,
breedSelectRef,
isDisabled = false,
}: AnimalBreedSelectProps & UseControllerProps<T>) {
const { t } = useTranslation();
return (
Expand All @@ -94,7 +99,7 @@ export function AnimalBreedSelect<T extends FieldValues>({
? t('ADD_ANIMAL.BREED_PLACEHOLDER')
: t('ADD_ANIMAL.BREED_PLACEHOLDER_DISABLED')
}
isDisabled={!isTypeSelected}
isDisabled={!isTypeSelected || isDisabled}
onChange={(option) => onChange(option)}
value={value}
/>
Expand Down
78 changes: 54 additions & 24 deletions packages/webapp/src/components/Animals/DetailCards/General.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
* GNU General Public License for more details, see <https://www.gnu.org/licenses/>.
*/

import { useMemo } from 'react';
import { Controller, useFormContext } from 'react-hook-form';
import { useMemo, useRef } from 'react';
import { Controller, get, useFormContext } from 'react-hook-form';
import { SelectInstance } from 'react-select';
import clsx from 'clsx';
import Input, { getInputErrors } from '../../Form/Input';
import RadioGroup from '../../Form/RadioGroup';
import ReactSelect from '../../Form/ReactSelect';
Expand All @@ -33,12 +35,21 @@ import {
hookFormMinValidation,
hookFormMaxCharsValidation,
} from '../../Form/hookformValidationUtils';
import LockedInput from '../../Form/LockedInput';
import {
AnimalTypeSelect,
Option as AnimalSelectOption,
AnimalBreedSelect,
} from '../AddAnimalsFormCard/AnimalSelect';

export type GeneralDetailsProps = CommonDetailsProps & {
sexOptions: Option[DetailsFields.SEX][];
useOptions: Option[DetailsFields.USE][];
animalOrBatch: AnimalOrBatchKeys;
sexDetailsOptions?: SexDetailsType;
typeOptions?: AnimalSelectOption[];
breedOptions?: AnimalSelectOption[];
onTypeChange?: (Option: AnimalSelectOption | null) => void;
};

const GeneralDetails = ({
Expand All @@ -48,6 +59,10 @@ const GeneralDetails = ({
animalOrBatch,
sexDetailsOptions,
namePrefix = '',
mode = 'add',
typeOptions = [],
onTypeChange,
breedOptions = [],
}: GeneralDetailsProps) => {
const {
control,
Expand All @@ -61,6 +76,11 @@ const GeneralDetails = ({
const watchBatchCount = watch(`${namePrefix}${DetailsFields.COUNT}`) || 0;
const watchedUse = watch(`${namePrefix}${DetailsFields.USE}`) as Option[DetailsFields.USE][];

const watchAnimalType = watch(`${namePrefix}${DetailsFields.TYPE}`);
const filteredBreeds = breedOptions.filter(({ type }) => type === watchAnimalType?.value);

const breedSelectRef = useRef<SelectInstance>(null);

const isOtherUseSelected = !watchedUse ? false : watchedUse.some((use) => use.key === 'OTHER');

const sexInputs = useMemo(() => {
Expand All @@ -75,6 +95,7 @@ const GeneralDetails = ({
radios={sexOptions}
hookFormControl={control}
row
disabled={mode === 'readonly'}
/>
</div>
</>
Expand All @@ -99,6 +120,7 @@ const GeneralDetails = ({
min: hookFormMinValidation(1),
}}
onChange={() => trigger(`${namePrefix}${DetailsFields.COUNT}`)}
disabled={mode === 'readonly'}
/>
<Controller
name={`${namePrefix}${DetailsFields.SEX_DETAILS}`}
Expand All @@ -116,6 +138,7 @@ const GeneralDetails = ({
initialDetails={value || sexDetailsOptions}
maxCount={watchBatchCount}
onConfirm={(details) => onChange(details)}
isDisabled={mode === 'readonly'}
/>
);
}}
Expand All @@ -125,7 +148,16 @@ const GeneralDetails = ({
}, [animalOrBatch, t, sexOptions, control, watchBatchCount]);

return (
<div className={styles.sectionWrapper}>
<div className={clsx(styles.sectionWrapper, mode === 'edit' && styles.edit)}>
{(mode === 'readonly' || mode === 'edit') && (
<>
{/* @ts-ignore */}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not getting any errors when removing this, do we need it?

<LockedInput
label={t('ANIMAL.ATTRIBUTE.LITEFARM_ID')}
placeholder={getValues(`${namePrefix}${DetailsFields.ID}`)}
/>
</>
)}
{animalOrBatch === AnimalOrBatchKeys.BATCH && (
<>
{/* @ts-ignore */}
Expand All @@ -139,33 +171,29 @@ const GeneralDetails = ({
optional
placeholder={t('ADD_ANIMAL.PLACEHOLDER.BATCH_NAME')}
errors={getInputErrors(errors, `${namePrefix}${DetailsFields.BATCH_NAME}`)}
disabled={mode === 'readonly'}
/>
</>
)}
<Controller
control={control}
<AnimalTypeSelect
name={`${namePrefix}${DetailsFields.TYPE}`}
render={({ field: { onChange, value } }) => (
<ReactSelect
label={t('ANIMAL.ANIMAL_TYPE')}
value={value}
onChange={onChange}
isDisabled
/>
)}
/>
<Controller
control={control}
typeOptions={typeOptions}
onTypeChange={(option) => {
trigger(`${namePrefix}${DetailsFields.TYPE}`);
onTypeChange?.(option);
breedSelectRef?.current?.clearValue();
}}
error={get(errors, `${namePrefix}${DetailsFields.TYPE}`)}
isDisabled={mode !== 'edit'}
/>
<AnimalBreedSelect
breedSelectRef={breedSelectRef}
name={`${namePrefix}${DetailsFields.BREED}`}
render={({ field: { onChange, value } }) => (
<ReactSelect
label={t('ANIMAL.ANIMAL_BREED')}
optional
value={value}
onChange={onChange}
isDisabled
/>
)}
control={control}
breedOptions={filteredBreeds}
isTypeSelected={!!watchAnimalType}
isDisabled={mode !== 'edit'}
/>
{sexInputs}
<Controller
Expand All @@ -180,6 +208,7 @@ const GeneralDetails = ({
onChange={onChange}
options={useOptions}
style={{ paddingBottom: '12px' }} // accomodate "Clear all" button space
isDisabled={mode === 'readonly'}
/>
)}
/>
Expand All @@ -195,6 +224,7 @@ const GeneralDetails = ({
optional
placeholder={t('ADD_ANIMAL.PLACEHOLDER.OTHER_USE')}
errors={getInputErrors(errors, `${namePrefix}${DetailsFields.OTHER_USE}`)}
disabled={mode === 'readonly'}
/>
</>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export type OriginProps = CommonDetailsProps & {
originOptions: Option[DetailsFields.ORIGIN][];
};

const Origin = ({ t, currency, originOptions, namePrefix = '' }: OriginProps) => {
const Origin = ({ t, currency, originOptions, namePrefix = '', mode = 'add' }: OriginProps) => {
const {
control,
register,
Expand Down Expand Up @@ -58,6 +58,7 @@ const Origin = ({ t, currency, originOptions, namePrefix = '' }: OriginProps) =>
label={t('common:DATE')}
hookFormRegister={register(`${namePrefix}${DetailsFields.BROUGHT_IN_DATE}`)}
optional
disabled={mode === 'readonly'}
/>
{/* @ts-ignore */}
<Input
Expand All @@ -71,6 +72,7 @@ const Origin = ({ t, currency, originOptions, namePrefix = '' }: OriginProps) =>
optional
placeholder={t('ADD_ANIMAL.PLACEHOLDER.SUPPLIER')}
errors={getInputErrors(errors, `${namePrefix}${DetailsFields.SUPPLIER}`)}
disabled={mode === 'readonly'}
/>
{/* @ts-ignore */}
<Input
Expand All @@ -83,6 +85,7 @@ const Origin = ({ t, currency, originOptions, namePrefix = '' }: OriginProps) =>
optional
placeholder={t('ADD_ANIMAL.PLACEHOLDER.PRICE')}
errors={getInputErrors(errors, `${namePrefix}${DetailsFields.PRICE}`)}
disabled={mode === 'readonly'}
/>
</>
) : (
Expand All @@ -99,6 +102,7 @@ const Origin = ({ t, currency, originOptions, namePrefix = '' }: OriginProps) =>
optional
placeholder={t('ADD_ANIMAL.PLACEHOLDER.DAM')}
errors={getInputErrors(errors, `${namePrefix}${DetailsFields.DAM}`)}
disabled={mode === 'readonly'}
/>
{/* @ts-ignore */}
<Input
Expand All @@ -112,6 +116,7 @@ const Origin = ({ t, currency, originOptions, namePrefix = '' }: OriginProps) =>
optional
placeholder={t('ADD_ANIMAL.PLACEHOLDER.SIRE')}
errors={getInputErrors(errors, `${namePrefix}${DetailsFields.SIRE}`)}
disabled={mode === 'readonly'}
/>
</>
);
Expand All @@ -125,6 +130,7 @@ const Origin = ({ t, currency, originOptions, namePrefix = '' }: OriginProps) =>
label={t('ANIMAL.ATTRIBUTE.DATE_OF_BIRTH')}
hookFormRegister={register(`${namePrefix}${DetailsFields.DATE_OF_BIRTH}`)}
optional
disabled={mode === 'readonly'}
/>
<div>
{/* @ts-ignore */}
Expand All @@ -133,6 +139,7 @@ const Origin = ({ t, currency, originOptions, namePrefix = '' }: OriginProps) =>
radios={originOptions}
hookFormControl={control}
row
disabled={mode === 'readonly'}
/>
</div>
{origin && fields}
Expand Down
Loading
Loading