diff --git a/packages/webapp/public/locales/de/translation.json b/packages/webapp/public/locales/de/translation.json index a50d16b9dd..72bddad162 100644 --- a/packages/webapp/public/locales/de/translation.json +++ b/packages/webapp/public/locales/de/translation.json @@ -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", diff --git a/packages/webapp/public/locales/en/translation.json b/packages/webapp/public/locales/en/translation.json index 825341764d..2ad0a9245e 100644 --- a/packages/webapp/public/locales/en/translation.json +++ b/packages/webapp/public/locales/en/translation.json @@ -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", diff --git a/packages/webapp/public/locales/es/translation.json b/packages/webapp/public/locales/es/translation.json index 770950d0ce..98da6afb9c 100644 --- a/packages/webapp/public/locales/es/translation.json +++ b/packages/webapp/public/locales/es/translation.json @@ -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", diff --git a/packages/webapp/public/locales/fr/translation.json b/packages/webapp/public/locales/fr/translation.json index 28ab8c458c..7c5b87a96e 100644 --- a/packages/webapp/public/locales/fr/translation.json +++ b/packages/webapp/public/locales/fr/translation.json @@ -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", diff --git a/packages/webapp/public/locales/ml/translation.json b/packages/webapp/public/locales/ml/translation.json index 26e5a5f42c..d684c9d157 100644 --- a/packages/webapp/public/locales/ml/translation.json +++ b/packages/webapp/public/locales/ml/translation.json @@ -201,6 +201,11 @@ "WHAT_PLANTING_METHOD": "", "WILD_CROP": "" }, + "ANIMAL": { + "ATTRIBUTE": { + "LITEFARM_ID": "MISSING" + } + }, "BED_PLAN": { "LENGTH_OF_BED": "", "NUMBER_0F_BEDS": "", diff --git a/packages/webapp/public/locales/pa/translation.json b/packages/webapp/public/locales/pa/translation.json index df35f65388..db1d0972e8 100644 --- a/packages/webapp/public/locales/pa/translation.json +++ b/packages/webapp/public/locales/pa/translation.json @@ -201,6 +201,11 @@ "WHAT_PLANTING_METHOD": "ਟ੍ਰਾਂਸਪਲਾਂਟ ਕਰਨ ਦਾ ਤਰੀਕਾ ਕੀ ਹੈ?", "WILD_CROP": "ਜੰਗਲੀ ਫਸਲ" }, + "ANIMAL": { + "ATTRIBUTE": { + "LITEFARM_ID": "MISSING" + } + }, "BED_PLAN": { "LENGTH_OF_BED": "ਬੇਡ ਦੀ ਲੰਬਾਈ", "NUMBER_0F_BEDS": "# ਬੇਡ", diff --git a/packages/webapp/public/locales/pt/translation.json b/packages/webapp/public/locales/pt/translation.json index aec3373292..6288cbba2a 100644 --- a/packages/webapp/public/locales/pt/translation.json +++ b/packages/webapp/public/locales/pt/translation.json @@ -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", diff --git a/packages/webapp/src/components/Animals/AddAnimalsFormCard/AddAnimalsFormCard.tsx b/packages/webapp/src/components/Animals/AddAnimalsFormCard/AddAnimalsFormCard.tsx index 66041e2dfc..3fa50904de 100644 --- a/packages/webapp/src/components/Animals/AddAnimalsFormCard/AddAnimalsFormCard.tsx +++ b/packages/webapp/src/components/Animals/AddAnimalsFormCard/AddAnimalsFormCard.tsx @@ -88,16 +88,6 @@ export default function AddAnimalsFormCard({ const breedSelectRef = useRef(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 (
@@ -111,6 +101,7 @@ export default function AddAnimalsFormCard({ onTypeChange={(option) => { trigger(`${namePrefix}${BasicsFields.TYPE}`); onTypeChange?.(option); + breedSelectRef?.current?.clearValue(); }} error={get(errors, `${namePrefix}${BasicsFields.TYPE}`)} /> diff --git a/packages/webapp/src/components/Animals/AddAnimalsFormCard/AnimalSelect.tsx b/packages/webapp/src/components/Animals/AddAnimalsFormCard/AnimalSelect.tsx index 6476eb8156..f054b34719 100644 --- a/packages/webapp/src/components/Animals/AddAnimalsFormCard/AnimalSelect.tsx +++ b/packages/webapp/src/components/Animals/AddAnimalsFormCard/AnimalSelect.tsx @@ -30,6 +30,7 @@ export type AnimalTypeSelectProps = { typeOptions: OptionsOrGroups>; onTypeChange?: (Option: Option | null) => void; error?: FieldError; + isDisabled?: boolean; }; export function AnimalTypeSelect({ @@ -38,6 +39,7 @@ export function AnimalTypeSelect({ typeOptions, onTypeChange, error, + isDisabled = false, }: AnimalTypeSelectProps & UseControllerProps) { const { t } = useTranslation(); return ( @@ -56,6 +58,7 @@ export function AnimalTypeSelect({ onTypeChange?.(option); }} value={value} + isDisabled={isDisabled} /> )} /> @@ -68,6 +71,7 @@ export type AnimalBreedSelectProps = { breedOptions: Option[]; isTypeSelected?: boolean; breedSelectRef?: RefObject; + isDisabled?: boolean; }; export function AnimalBreedSelect({ @@ -76,6 +80,7 @@ export function AnimalBreedSelect({ breedOptions, isTypeSelected, breedSelectRef, + isDisabled = false, }: AnimalBreedSelectProps & UseControllerProps) { const { t } = useTranslation(); return ( @@ -94,7 +99,7 @@ export function AnimalBreedSelect({ ? t('ADD_ANIMAL.BREED_PLACEHOLDER') : t('ADD_ANIMAL.BREED_PLACEHOLDER_DISABLED') } - isDisabled={!isTypeSelected} + isDisabled={!isTypeSelected || isDisabled} onChange={(option) => onChange(option)} value={value} /> diff --git a/packages/webapp/src/components/Animals/DetailCards/General.tsx b/packages/webapp/src/components/Animals/DetailCards/General.tsx index 72c1ce3eb4..840ab3da7d 100644 --- a/packages/webapp/src/components/Animals/DetailCards/General.tsx +++ b/packages/webapp/src/components/Animals/DetailCards/General.tsx @@ -13,8 +13,10 @@ * GNU General Public License for more details, see . */ -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'; @@ -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 = ({ @@ -48,6 +59,10 @@ const GeneralDetails = ({ animalOrBatch, sexDetailsOptions, namePrefix = '', + mode = 'add', + typeOptions = [], + onTypeChange, + breedOptions = [], }: GeneralDetailsProps) => { const { control, @@ -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(null); + const isOtherUseSelected = !watchedUse ? false : watchedUse.some((use) => use.key === 'OTHER'); const sexInputs = useMemo(() => { @@ -75,6 +95,7 @@ const GeneralDetails = ({ radios={sexOptions} hookFormControl={control} row + disabled={mode === 'readonly'} />
@@ -99,6 +120,7 @@ const GeneralDetails = ({ min: hookFormMinValidation(1), }} onChange={() => trigger(`${namePrefix}${DetailsFields.COUNT}`)} + disabled={mode === 'readonly'} /> onChange(details)} + isDisabled={mode === 'readonly'} /> ); }} @@ -125,7 +148,16 @@ const GeneralDetails = ({ }, [animalOrBatch, t, sexOptions, control, watchBatchCount]); return ( -
+
+ {(mode === 'readonly' || mode === 'edit') && ( + <> + {/* @ts-ignore */} + + + )} {animalOrBatch === AnimalOrBatchKeys.BATCH && ( <> {/* @ts-ignore */} @@ -139,33 +171,29 @@ const GeneralDetails = ({ optional placeholder={t('ADD_ANIMAL.PLACEHOLDER.BATCH_NAME')} errors={getInputErrors(errors, `${namePrefix}${DetailsFields.BATCH_NAME}`)} + disabled={mode === 'readonly'} /> )} - ( - - )} - /> - { + trigger(`${namePrefix}${DetailsFields.TYPE}`); + onTypeChange?.(option); + breedSelectRef?.current?.clearValue(); + }} + error={get(errors, `${namePrefix}${DetailsFields.TYPE}`)} + isDisabled={mode !== 'edit'} + /> + ( - - )} + control={control} + breedOptions={filteredBreeds} + isTypeSelected={!!watchAnimalType} + isDisabled={mode !== 'edit'} /> {sexInputs} )} /> @@ -195,6 +224,7 @@ const GeneralDetails = ({ optional placeholder={t('ADD_ANIMAL.PLACEHOLDER.OTHER_USE')} errors={getInputErrors(errors, `${namePrefix}${DetailsFields.OTHER_USE}`)} + disabled={mode === 'readonly'} /> )} diff --git a/packages/webapp/src/components/Animals/DetailCards/Origin.tsx b/packages/webapp/src/components/Animals/DetailCards/Origin.tsx index 6c54a5237c..9a39d0944e 100644 --- a/packages/webapp/src/components/Animals/DetailCards/Origin.tsx +++ b/packages/webapp/src/components/Animals/DetailCards/Origin.tsx @@ -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, @@ -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 */} optional placeholder={t('ADD_ANIMAL.PLACEHOLDER.SUPPLIER')} errors={getInputErrors(errors, `${namePrefix}${DetailsFields.SUPPLIER}`)} + disabled={mode === 'readonly'} /> {/* @ts-ignore */} optional placeholder={t('ADD_ANIMAL.PLACEHOLDER.PRICE')} errors={getInputErrors(errors, `${namePrefix}${DetailsFields.PRICE}`)} + disabled={mode === 'readonly'} /> ) : ( @@ -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 */} optional placeholder={t('ADD_ANIMAL.PLACEHOLDER.SIRE')} errors={getInputErrors(errors, `${namePrefix}${DetailsFields.SIRE}`)} + disabled={mode === 'readonly'} /> ); @@ -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'} />
{/* @ts-ignore */} @@ -133,6 +139,7 @@ const Origin = ({ t, currency, originOptions, namePrefix = '' }: OriginProps) => radios={originOptions} hookFormControl={control} row + disabled={mode === 'readonly'} />
{origin && fields} diff --git a/packages/webapp/src/components/Animals/DetailCards/Other.tsx b/packages/webapp/src/components/Animals/DetailCards/Other.tsx index 1ecfbe23f7..ff82034347 100644 --- a/packages/webapp/src/components/Animals/DetailCards/Other.tsx +++ b/packages/webapp/src/components/Animals/DetailCards/Other.tsx @@ -42,6 +42,7 @@ const OtherDetails = ({ namePrefix = '', imageUploadTargetRoute, getOnFileUpload, + mode = 'add', }: OtherDetailsProps) => { const { control, @@ -84,6 +85,7 @@ const OtherDetails = ({ label={t('ANIMAL.ATTRIBUTE.WEANING_DATE')} hookFormRegister={register(`${namePrefix}${DetailsFields.WEANING_DATE}`)} optional + disabled={mode === 'readonly'} /> )} @@ -96,6 +98,7 @@ const OtherDetails = ({ value={value} onChange={onChange} options={organicStatusOptions} + isDisabled={mode === 'readonly'} /> )} /> @@ -108,12 +111,14 @@ const OtherDetails = ({ optional placeholder={t('ADD_ANIMAL.PLACEHOLDER.OTHER_DETAILS')} errors={errors?.[`${namePrefix}${DetailsFields.OTHER_DETAILS}`]?.message} + disabled={mode === 'readonly'} />
); diff --git a/packages/webapp/src/components/Animals/DetailCards/Unique.tsx b/packages/webapp/src/components/Animals/DetailCards/Unique.tsx index d00d5785b9..c97c9a0774 100644 --- a/packages/webapp/src/components/Animals/DetailCards/Unique.tsx +++ b/packages/webapp/src/components/Animals/DetailCards/Unique.tsx @@ -33,6 +33,7 @@ const UniqueDetails = ({ tagTypeOptions, tagColorOptions, namePrefix = '', + mode = 'add', }: UniqueDetailsProps) => { const { control, @@ -58,6 +59,7 @@ const UniqueDetails = ({ optional placeholder={t('ADD_ANIMAL.PLACEHOLDER.NAME')} errors={getInputErrors(errors, `${namePrefix}${DetailsFields.NAME}`)} + disabled={mode === 'readonly'} /> {/* @ts-ignore */} )} /> @@ -96,6 +100,7 @@ const UniqueDetails = ({ onChange={onChange} options={tagTypeOptions} placeholder={t('ADD_ANIMAL.PLACEHOLDER.TAG_TYPE')} + isDisabled={mode === 'readonly'} /> )} /> @@ -111,6 +116,7 @@ const UniqueDetails = ({ optional placeholder={t('ADD_ANIMAL.PLACEHOLDER.TAG_TYPE_INFO')} errors={getInputErrors(errors, `${namePrefix}${DetailsFields.TAG_TYPE_INFO}`)} + disabled={mode === 'readonly'} /> )} diff --git a/packages/webapp/src/components/Animals/DetailCards/styles.module.scss b/packages/webapp/src/components/Animals/DetailCards/styles.module.scss index a6adc0a6e6..ffa1edc3ee 100644 --- a/packages/webapp/src/components/Animals/DetailCards/styles.module.scss +++ b/packages/webapp/src/components/Animals/DetailCards/styles.module.scss @@ -21,6 +21,10 @@ background: var(--White); } +.sectionWrapper.edit { + gap: 16px; // increase gap in edit mode to accomodate Clear on selects +} + .countAndSexDetailsWrapper { display: flex; align-items: start; diff --git a/packages/webapp/src/components/Form/SexDetails/index.tsx b/packages/webapp/src/components/Form/SexDetails/index.tsx index 814643735b..e9e9012b9f 100644 --- a/packages/webapp/src/components/Form/SexDetails/index.tsx +++ b/packages/webapp/src/components/Form/SexDetails/index.tsx @@ -26,6 +26,7 @@ type SexDetailsProps = { maxCount: number; onConfirm: (d: Details) => void; onCancel?: () => void; + isDisabled?: boolean; }; const initialize = (details: Details) => () => structuredClone(details) as Details; @@ -35,6 +36,7 @@ export default function SexDetails({ initialDetails, onCancel, onConfirm, + isDisabled = false, }: SexDetailsProps) { const [anchor, setAnchor] = useState(null); const [details, setDetails] = useState(initialize(initialDetails)); @@ -71,8 +73,12 @@ export default function SexDetails({ error={total > maxCount ? t('ADD_ANIMAL.SEX_DETAIL_ERROR', { count: maxCount }) : undefined} showResetIcon={false} rightSection={} + disabled={isDisabled} mainSection={ - setAnchor(e.currentTarget)} className={styles.button}> + {} : (e) => setAnchor(e.currentTarget)} + className={styles.button} + > {!total ? ( {t('ADD_ANIMAL.SPECIFY_SEX')} diff --git a/packages/webapp/src/components/ImagePicker/index.tsx b/packages/webapp/src/components/ImagePicker/index.tsx index 6bb6b6310c..d38edaa7f4 100644 --- a/packages/webapp/src/components/ImagePicker/index.tsx +++ b/packages/webapp/src/components/ImagePicker/index.tsx @@ -15,6 +15,7 @@ import { ChangeEvent, DragEvent, useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; +import clsx from 'clsx'; import { AddLink } from '../Typography'; import PureFilePickerWrapper from '../Form/FilePickerWrapper'; import TextButton from '../Form/Button/TextButton'; @@ -42,6 +43,7 @@ type CommonProps = { label?: string; optional?: boolean; defaultUrl?: string; + disabled?: boolean; }; type CustomFileUpload = CommonProps & { @@ -63,6 +65,7 @@ export default function ImagePicker({ label, optional = true, // false is not yet supported onFileUpload, + disabled = false, }: ImagePickerProps) { const [previewUrl, setPreviewUrl] = useState(defaultUrl); const [showFileSizeExceedsModal, setShowFileSizeExceedsModal] = useState(false); @@ -125,10 +128,14 @@ export default function ImagePicker({
{label && } {previewUrl ? ( -
+
image preview
- + {t('UPLOADER.CHANGE_IMAGE')} @@ -144,8 +151,9 @@ export default function ImagePicker({ <> {t('UPLOADER.UPLOAD_IMAGE')} @@ -153,7 +161,7 @@ export default function ImagePicker({
. */ +@import '../../assets/mixin.scss'; + .imageContainer { display: flex; align-items: start; @@ -24,6 +26,21 @@ } } +.imageContainer.disabled, +.dropContainer.disabled, +.filePickerWrapper.disabled { + pointer-events: none; + cursor: default; +} + +.imageContainer.disabled { + @include svgColorFill(var(--Colors-Neutral-Neutral-200)); + + button { + color: var(--Colors-Neutral-Neutral-200); + } +} + .imageActions { margin-left: 8px; gap: 4px; diff --git a/packages/webapp/src/containers/Animals/AddAnimals/types.ts b/packages/webapp/src/containers/Animals/AddAnimals/types.ts index d074444223..fe728d7a7f 100644 --- a/packages/webapp/src/containers/Animals/AddAnimals/types.ts +++ b/packages/webapp/src/containers/Animals/AddAnimals/types.ts @@ -46,6 +46,7 @@ export enum DetailsFields { BASICS_FIELD_ARRAY_ID = 'field_array_id', // remove before submitting // GENERAL + ID = 'id', BATCH_NAME = 'batch_name', TYPE = 'type', BREED = 'breed', @@ -98,6 +99,7 @@ export type Option = { export type AnimalDetailsFormFields = { [DetailsFields.ANIMAL_OR_BATCH]?: string; [DetailsFields.BASICS_FIELD_ARRAY_ID]?: string; + [DetailsFields.ID]?: string; [DetailsFields.BATCH_NAME]?: string; [DetailsFields.COUNT]?: number; [DetailsFields.NAME]?: string; @@ -130,6 +132,7 @@ export interface FormMethods extends UseFormReturn; export const Default: Story = { render: () => { const formMethods: FormMethods = useForm({ - defaultValues, + defaultValues: addDefaults, }); return ( diff --git a/packages/webapp/src/stories/Animals/Details/BatchDetails.stories.tsx b/packages/webapp/src/stories/Animals/Details/BatchDetails.stories.tsx index 922b79eab4..cbf50472bd 100644 --- a/packages/webapp/src/stories/Animals/Details/BatchDetails.stories.tsx +++ b/packages/webapp/src/stories/Animals/Details/BatchDetails.stories.tsx @@ -27,7 +27,7 @@ import { useOptions, organicStatusOptions, originOptions, - defaultValues, + addDefaults, getOnFileUpload, } from './mockData'; @@ -43,7 +43,7 @@ type Story = StoryObj; export const Default: Story = { render: () => { const formMethods: FormMethods = useForm({ - defaultValues, + defaultValues: addDefaults, }); return ( diff --git a/packages/webapp/src/stories/Animals/Details/General.stories.tsx b/packages/webapp/src/stories/Animals/Details/General.stories.tsx index 91ca1d5749..bac6e9e133 100644 --- a/packages/webapp/src/stories/Animals/Details/General.stories.tsx +++ b/packages/webapp/src/stories/Animals/Details/General.stories.tsx @@ -23,7 +23,15 @@ import GeneralDetails, { import { AnimalOrBatchKeys } from '../../../containers/Animals/types'; import { FormMethods } from '../../../containers/Animals/AddAnimals/types'; -import { sexOptions, sexDetailsOptions, useOptions, defaultValues } from './mockData'; +import { + typeOptions, + breedOptions, + sexOptions, + sexDetailsOptions, + useOptions, + addDefaults, + defaultValues, +} from './mockData'; // https://storybook.js.org/docs/writing-stories/typescript const meta: Meta = { @@ -31,11 +39,12 @@ const meta: Meta = { component: GeneralDetails, decorators: [ ...componentDecorators, - (Story) => { + (Story, { args }) => { const { t } = useTranslation(); const formMethods: FormMethods = useForm({ mode: 'onBlur', - defaultValues, + defaultValues: + args.mode === 'readonly' || args.mode === 'edit' ? defaultValues : addDefaults, }); return ( @@ -70,3 +79,45 @@ export const Batch: Story = { }, render: (args, context) => , }; + +export const AnimalReadOnly: Story = { + args: { + ...commonProps, + animalOrBatch: AnimalOrBatchKeys.ANIMAL, + mode: 'readonly', + }, + render: (args, context) => , +}; + +export const BatchReadOnly: Story = { + args: { + ...commonProps, + animalOrBatch: AnimalOrBatchKeys.BATCH, + sexDetailsOptions, + mode: 'readonly', + }, + render: (args, context) => , +}; + +export const AnimalEdit: Story = { + args: { + ...commonProps, + animalOrBatch: AnimalOrBatchKeys.ANIMAL, + mode: 'edit', + typeOptions, + breedOptions, + }, + render: (args, context) => , +}; + +export const BatchEdit: Story = { + args: { + ...commonProps, + animalOrBatch: AnimalOrBatchKeys.BATCH, + sexDetailsOptions, + mode: 'edit', + typeOptions, + breedOptions, + }, + render: (args, context) => , +}; diff --git a/packages/webapp/src/stories/Animals/Details/Origin.stories.tsx b/packages/webapp/src/stories/Animals/Details/Origin.stories.tsx index a7dacf4b8a..bcb3cda6ae 100644 --- a/packages/webapp/src/stories/Animals/Details/Origin.stories.tsx +++ b/packages/webapp/src/stories/Animals/Details/Origin.stories.tsx @@ -19,7 +19,7 @@ import { Meta, StoryObj } from '@storybook/react'; import { componentDecorators } from '../../Pages/config/Decorators'; import Origin, { OriginProps } from '../../../components/Animals/DetailCards/Origin'; import { FormMethods } from '../../../containers/Animals/AddAnimals/types'; -import { originOptions } from './mockData'; +import { originOptions, addDefaults, defaultValues } from './mockData'; // https://storybook.js.org/docs/writing-stories/typescript const meta: Meta = { @@ -27,9 +27,13 @@ const meta: Meta = { component: Origin, decorators: [ ...componentDecorators, - (Story) => { + (Story, { args }) => { const { t } = useTranslation(); - const formMethods: FormMethods = useForm({ mode: 'onBlur' }); + const formMethods: FormMethods = useForm({ + mode: 'onBlur', + defaultValues: + args.mode === 'readonly' || args.mode === 'edit' ? defaultValues : addDefaults, + }); return ( @@ -49,3 +53,21 @@ export const OriginDetails: Story = { args: { currency: '$', originOptions }, render: (args, context) => , }; + +export const OriginReadonly: Story = { + args: { + currency: '$', + originOptions, + mode: 'readonly', + }, + render: (args, context) => , +}; + +export const OriginEdit: Story = { + args: { + currency: '$', + originOptions, + mode: 'edit', + }, + render: (args, context) => , +}; diff --git a/packages/webapp/src/stories/Animals/Details/Other.stories.tsx b/packages/webapp/src/stories/Animals/Details/Other.stories.tsx index 65129d512a..5f53583cd5 100644 --- a/packages/webapp/src/stories/Animals/Details/Other.stories.tsx +++ b/packages/webapp/src/stories/Animals/Details/Other.stories.tsx @@ -20,7 +20,7 @@ import { componentDecorators } from '../../Pages/config/Decorators'; import Other, { OtherDetailsProps } from '../../../components/Animals/DetailCards/Other'; import { AnimalOrBatchKeys } from '../../../containers/Animals/types'; import { FormMethods } from '../../../containers/Animals/AddAnimals/types'; -import { organicStatusOptions, getOnFileUpload } from './mockData'; +import { organicStatusOptions, getOnFileUpload, addDefaults, defaultValues } from './mockData'; // https://storybook.js.org/docs/writing-stories/typescript const meta: Meta = { @@ -28,9 +28,13 @@ const meta: Meta = { component: Other, decorators: [ ...componentDecorators, - (Story) => { + (Story, { args }) => { const { t } = useTranslation(); - const formMethods: FormMethods = useForm({ mode: 'onBlur' }); + const formMethods: FormMethods = useForm({ + mode: 'onBlur', + defaultValues: + args.mode === 'readonly' || args.mode === 'edit' ? defaultValues : addDefaults, + }); return ( @@ -63,3 +67,43 @@ export const Batch: Story = { }, render: (args, context) => , }; + +export const AnimalReadonly: Story = { + args: { + organicStatusOptions, + animalOrBatch: AnimalOrBatchKeys.ANIMAL, + getOnFileUpload, + mode: 'readonly', + }, + render: (args, context) => , +}; + +export const BatchReadonly: Story = { + args: { + organicStatusOptions, + animalOrBatch: AnimalOrBatchKeys.BATCH, + getOnFileUpload, + mode: 'readonly', + }, + render: (args, context) => , +}; + +export const AnimalEdit: Story = { + args: { + organicStatusOptions, + animalOrBatch: AnimalOrBatchKeys.ANIMAL, + getOnFileUpload, + mode: 'edit', + }, + render: (args, context) => , +}; + +export const BatchEdit: Story = { + args: { + organicStatusOptions, + animalOrBatch: AnimalOrBatchKeys.BATCH, + getOnFileUpload, + mode: 'edit', + }, + render: (args, context) => , +}; diff --git a/packages/webapp/src/stories/Animals/Details/Unique.stories.tsx b/packages/webapp/src/stories/Animals/Details/Unique.stories.tsx index fcbca50ee0..588ee1b9bb 100644 --- a/packages/webapp/src/stories/Animals/Details/Unique.stories.tsx +++ b/packages/webapp/src/stories/Animals/Details/Unique.stories.tsx @@ -19,7 +19,7 @@ import { Meta, StoryObj } from '@storybook/react'; import { componentDecorators } from '../../Pages/config/Decorators'; import UniqueDetails, { UniqueDetailsProps } from '../../../components/Animals/DetailCards/Unique'; import { FormMethods } from '../../../containers/Animals/AddAnimals/types'; -import { tagTypeOptions, tagColorOptions } from './mockData'; +import { tagTypeOptions, tagColorOptions, addDefaults, defaultValues } from './mockData'; // https://storybook.js.org/docs/writing-stories/typescript const meta: Meta = { @@ -27,9 +27,13 @@ const meta: Meta = { component: UniqueDetails, decorators: [ ...componentDecorators, - (Story) => { + (Story, { args }) => { const { t } = useTranslation(); - const formMethods: FormMethods = useForm({ mode: 'onBlur' }); + const formMethods: FormMethods = useForm({ + mode: 'onBlur', + defaultValues: + args.mode === 'readonly' || args.mode === 'edit' ? defaultValues : addDefaults, + }); return ( @@ -49,3 +53,21 @@ export const Unique: Story = { args: { tagTypeOptions, tagColorOptions }, render: (args, context) => , }; + +export const UniqueReadonly: Story = { + args: { + tagTypeOptions, + tagColorOptions, + mode: 'readonly', + }, + render: (args, context) => , +}; + +export const UniqueEdit: Story = { + args: { + tagTypeOptions, + tagColorOptions, + mode: 'edit', + }, + render: (args, context) => , +}; diff --git a/packages/webapp/src/stories/Animals/Details/mockData.ts b/packages/webapp/src/stories/Animals/Details/mockData.ts index a47bfd2dfb..fb6d3ade94 100644 --- a/packages/webapp/src/stories/Animals/Details/mockData.ts +++ b/packages/webapp/src/stories/Animals/Details/mockData.ts @@ -22,6 +22,50 @@ import { import { FileEvent } from '../../../components/ImagePicker'; import { GetOnFileUpload } from '../../../components/ImagePicker/useImagePickerUpload'; import { OrganicStatus } from '../../../types'; +import { Details } from '@mui/icons-material'; + +export const typeOptions = [ + { + label: 'Cattle', + value: 'default_1', + }, + { + label: 'Pigs', + value: 'default_2', + }, + { + label: 'Chicken', + value: 'default_3', + }, +]; + +export const breedOptions = [ + { + label: 'Angus', + value: 'default_1', + type: 'default_1', + }, + { + label: 'Yorkshire Large White', + value: 'default_4', + type: 'default_2', + }, + { + label: 'Landrace', + value: 'default_5', + type: 'default_2', + }, + { + label: 'Cornish Cross', + value: 'default_7', + type: 'default_3', + }, + { + label: 'Ross 308', + value: 'default_8', + type: 'default_3', + }, +]; export const sexOptions = [ { value: 0, label: `I don't know` }, @@ -30,8 +74,8 @@ export const sexOptions = [ ]; export const sexDetailsOptions = [ - { id: 0, label: 'Male', count: 0 }, - { id: 1, label: 'Female', count: 0 }, + { id: 0, label: 'Male', count: 1 }, + { id: 1, label: 'Female', count: 2 }, ]; export const useOptions = [ @@ -66,9 +110,26 @@ export const originOptions = [ { value: 2, label: 'Born at the farm', key: 'BORN_AT_FARM' }, ]; -export const defaultValues: Partial = { +export const addDefaults: Partial = { [DetailsFields.TYPE]: { value: 'default_1', label: 'Cattle' }, - [DetailsFields.BREED]: { value: 'default_2', label: 'Angus' }, + [DetailsFields.BREED]: { + label: 'Angus', + value: 'default_1', + type: 'default_1', + }, + [DetailsFields.SEX]: 2, + [DetailsFields.COUNT]: 3, +}; + +export const defaultValues: Partial = { + ...addDefaults, + [DetailsFields.USE]: [{ value: 2, label: 'Other', key: 'OTHER' }], + [DetailsFields.ID]: 'ID12', + [DetailsFields.ORIGIN]: 1, + [DetailsFields.BROUGHT_IN_DATE]: '2024-10-01', + [DetailsFields.TAG_TYPE]: { value: 3, label: 'Other', key: 'OTHER' }, + [DetailsFields.TAG_TYPE_INFO]: 'Microchip', + [DetailsFields.ANIMAL_IMAGE]: '/src/assets/images/certification/Farmland.svg', }; export const getOnFileUpload: GetOnFileUpload = diff --git a/packages/webapp/src/stories/Form/SexDetails/SexDetails.stories.tsx b/packages/webapp/src/stories/Form/SexDetails/SexDetails.stories.tsx index 0f81a9a4a0..4fff6cdc0c 100644 --- a/packages/webapp/src/stories/Form/SexDetails/SexDetails.stories.tsx +++ b/packages/webapp/src/stories/Form/SexDetails/SexDetails.stories.tsx @@ -26,7 +26,27 @@ const meta: Meta = { maxCount: 100, }, render: (args) => { - const { control } = useForm(); + const { control } = useForm( + args.isDisabled + ? { + defaultValues: { + name: [ + { + count: 1, + id: 0, + label: 'Male', + }, + { + count: 2, + id: 2, + label: 'Female', + }, + ], + }, + } + : {}, + ); + return (