From 582a4ebfce456efe64ce78f082ed5d2551505978 Mon Sep 17 00:00:00 2001 From: Nathan Curtis Date: Mon, 16 Dec 2024 12:39:31 -0800 Subject: [PATCH 1/8] [TM-1402] Prepopulate the tree list with all species that have been previous planted on this entity. --- .../TreeSpeciesInput/TreeSpeciesInput.tsx | 22 ++++++++++++++++--- .../v3/entityService/entityServiceSchemas.ts | 15 +++++++++++-- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/components/elements/Inputs/TreeSpeciesInput/TreeSpeciesInput.tsx b/src/components/elements/Inputs/TreeSpeciesInput/TreeSpeciesInput.tsx index 01ef9095..f5b8ebe9 100644 --- a/src/components/elements/Inputs/TreeSpeciesInput/TreeSpeciesInput.tsx +++ b/src/components/elements/Inputs/TreeSpeciesInput/TreeSpeciesInput.tsx @@ -14,6 +14,7 @@ import { EstablishmentEntityType, useEstablishmentTrees } from "@/connections/Es import { useEntityContext } from "@/context/entity.provider"; import { useModalContext } from "@/context/modal.provider"; import { useDebounce } from "@/hooks/useDebounce"; +import { useValueChanged } from "@/hooks/useValueChanged"; import { isReportModelName } from "@/types/common"; import { updateArrayState } from "@/utils/array"; @@ -105,12 +106,25 @@ const TreeSpeciesInput = (props: TreeSpeciesInputProps) => { const entity = (handleBaseEntityTrees ? entityName : undefined) as EstablishmentEntityType; const uuid = handleBaseEntityTrees ? entityUuid : undefined; - const [, { establishmentTrees, previousPlantingCounts }] = useEstablishmentTrees({ entity, uuid }); + const [establishmentLoaded, { establishmentTrees, previousPlantingCounts }] = useEstablishmentTrees({ entity, uuid }); + const shouldPrepopulate = value.length == 0 && Object.values(previousPlantingCounts ?? {}).length > 0; + useValueChanged(shouldPrepopulate, function () { + if (shouldPrepopulate) { + onChange( + Object.entries(previousPlantingCounts!).map(([name, previousCount]) => ({ + uuid: uuidv4(), + name, + taxon_id: previousCount.taxonId, + amount: 0 + })) + ); + } + }); const totalWithPrevious = useMemo( () => props.value.reduce( - (total, { name, amount }) => total + (amount ?? 0) + (previousPlantingCounts?.[name ?? ""] ?? 0), + (total, { name, amount }) => total + (amount ?? 0) + (previousPlantingCounts?.[name ?? ""]?.amount ?? 0), 0 ), [previousPlantingCounts, props.value] @@ -202,6 +216,8 @@ const TreeSpeciesInput = (props: TreeSpeciesInputProps) => { addValue(e); }; + if (!establishmentLoaded || shouldPrepopulate) return null; + return ( { - {(previousPlantingCounts?.[value.name ?? ""] ?? 0).toLocaleString()} + {(previousPlantingCounts?.[value.name ?? ""]?.amount ?? 0).toLocaleString()}
diff --git a/src/generated/v3/entityService/entityServiceSchemas.ts b/src/generated/v3/entityService/entityServiceSchemas.ts index bb11f5e3..9734a4f8 100644 --- a/src/generated/v3/entityService/entityServiceSchemas.ts +++ b/src/generated/v3/entityService/entityServiceSchemas.ts @@ -3,6 +3,17 @@ * * @version 1.0 */ +export type PreviousPlantingCountDto = { + /** + * Taxonomic ID for this tree species row + */ + taxonId: string | null; + /** + * Number of trees of this type that have been planted in all previous reports on this entity. + */ + amount: number; +}; + export type ScientificNameDto = { /** * The scientific name for this tree species @@ -20,9 +31,9 @@ export type EstablishmentsTreesDto = { /** * If the entity in this request is a report, the sum totals of previous planting by species. * - * @example {"Aster persaliens":256,"Cirsium carniolicum":1024} + * @example {"Aster persaliens":{"amount":256},"Cirsium carniolicum":{"taxonId":"wfo-0000130112","amount":1024}} */ previousPlantingCounts: { - [key: string]: number; + [key: string]: PreviousPlantingCountDto; } | null; }; From 8022bc429bb80d2f4985bac3cf30a135f74bd069 Mon Sep 17 00:00:00 2001 From: Nathan Curtis Date: Mon, 16 Dec 2024 13:36:06 -0800 Subject: [PATCH 2/8] [TM-1402] Avoid displaying the previous counts column on seeding inputs. --- .../TreeSpeciesInput/RHFSeedingTableInput.tsx | 1 + .../TreeSpeciesInput/RHFTreeSpeciesInput.tsx | 1 + .../Inputs/TreeSpeciesInput/TreeSpeciesInput.tsx | 16 +++++++++++----- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/components/elements/Inputs/TreeSpeciesInput/RHFSeedingTableInput.tsx b/src/components/elements/Inputs/TreeSpeciesInput/RHFSeedingTableInput.tsx index 62b487e3..7c4a8b9a 100644 --- a/src/components/elements/Inputs/TreeSpeciesInput/RHFSeedingTableInput.tsx +++ b/src/components/elements/Inputs/TreeSpeciesInput/RHFSeedingTableInput.tsx @@ -32,6 +32,7 @@ const RHFSeedingTableInput = (props: PropsWithChildren) {...props} title={t("Tree Species")} buttonCaptionSuffix={t("Species")} + withPreviousCounts={true} value={value ?? []} onChange={onChange} collection={collection} diff --git a/src/components/elements/Inputs/TreeSpeciesInput/TreeSpeciesInput.tsx b/src/components/elements/Inputs/TreeSpeciesInput/TreeSpeciesInput.tsx index f5b8ebe9..0b440284 100644 --- a/src/components/elements/Inputs/TreeSpeciesInput/TreeSpeciesInput.tsx +++ b/src/components/elements/Inputs/TreeSpeciesInput/TreeSpeciesInput.tsx @@ -30,6 +30,7 @@ export interface TreeSpeciesInputProps extends Omit title: string; buttonCaptionSuffix: string; withNumbers?: boolean; + withPreviousCounts?: boolean; value: TreeSpeciesValue[]; onChange: (value: any[]) => void; clearErrors: () => void; @@ -102,7 +103,9 @@ const TreeSpeciesInput = (props: TreeSpeciesInputProps) => { const { entityUuid, entityName } = useEntityContext(); const isEntity = entityName != null && entityUuid != null; const isReport = isEntity && isReportModelName(entityName); - const handleBaseEntityTrees = isReport || (isEntity && ["sites", "nurseries"].includes(entityName)); + const handleBaseEntityTrees = + props.withPreviousCounts && (isReport || (isEntity && ["sites", "nurseries"].includes(entityName))); + const displayPreviousCounts = props.withPreviousCounts && isReport; const entity = (handleBaseEntityTrees ? entityName : undefined) as EstablishmentEntityType; const uuid = handleBaseEntityTrees ? entityUuid : undefined; @@ -305,7 +308,10 @@ const TreeSpeciesInput = (props: TreeSpeciesInputProps) => {
-
+
{props.title} @@ -313,7 +319,7 @@ const TreeSpeciesInput = (props: TreeSpeciesInputProps) => { {props.value.length}
-
+
{isReport ? t("SPECIES PLANTED:") : t("TREES TO BE PLANTED:")} @@ -321,7 +327,7 @@ const TreeSpeciesInput = (props: TreeSpeciesInputProps) => { {props.withNumbers ? props.value.reduce((total, v) => total + (v.amount || 0), 0).toLocaleString() : "0"}
- +
{t("TOTAL PLANTED TO DATE:")} @@ -426,7 +432,7 @@ const TreeSpeciesInput = (props: TreeSpeciesInputProps) => { containerClassName="" />
- + {(previousPlantingCounts?.[value.name ?? ""]?.amount ?? 0).toLocaleString()} From f9b86f620f36e417717abbde941ff3224c3c13fa Mon Sep 17 00:00:00 2001 From: Nathan Curtis Date: Mon, 16 Dec 2024 13:42:18 -0800 Subject: [PATCH 3/8] [TM-1402] don't use taxonomic auto complete search for seedings. --- .../Inputs/TreeSpeciesInput/RHFSeedingTableInput.tsx | 1 + .../Inputs/TreeSpeciesInput/RHFTreeSpeciesInput.tsx | 1 + .../Inputs/TreeSpeciesInput/TreeSpeciesInput.tsx | 11 +++++++---- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/components/elements/Inputs/TreeSpeciesInput/RHFSeedingTableInput.tsx b/src/components/elements/Inputs/TreeSpeciesInput/RHFSeedingTableInput.tsx index 7c4a8b9a..447eadfb 100644 --- a/src/components/elements/Inputs/TreeSpeciesInput/RHFSeedingTableInput.tsx +++ b/src/components/elements/Inputs/TreeSpeciesInput/RHFSeedingTableInput.tsx @@ -33,6 +33,7 @@ const RHFSeedingTableInput = (props: PropsWithChildren) title={t("Tree Species")} buttonCaptionSuffix={t("Species")} withPreviousCounts={true} + useTaxonomicBackbone={true} value={value ?? []} onChange={onChange} collection={collection} diff --git a/src/components/elements/Inputs/TreeSpeciesInput/TreeSpeciesInput.tsx b/src/components/elements/Inputs/TreeSpeciesInput/TreeSpeciesInput.tsx index 0b440284..3a9a8cda 100644 --- a/src/components/elements/Inputs/TreeSpeciesInput/TreeSpeciesInput.tsx +++ b/src/components/elements/Inputs/TreeSpeciesInput/TreeSpeciesInput.tsx @@ -30,7 +30,8 @@ export interface TreeSpeciesInputProps extends Omit title: string; buttonCaptionSuffix: string; withNumbers?: boolean; - withPreviousCounts?: boolean; + withPreviousCounts: boolean; + useTaxonomicBackbone: boolean; value: TreeSpeciesValue[]; onChange: (value: any[]) => void; clearErrors: () => void; @@ -174,7 +175,7 @@ const TreeSpeciesInput = (props: TreeSpeciesInputProps) => { handleCreate?.({ uuid: uuidv4(), name: valueAutoComplete, - taxon_id: taxonId, + taxon_id: props.useTaxonomicBackbone ? taxonId : undefined, amount: props.withNumbers ? 0 : undefined }); @@ -200,7 +201,7 @@ const TreeSpeciesInput = (props: TreeSpeciesInputProps) => { handleUpdate({ ...editValue, name: valueAutoComplete, - taxon_id: findTaxonId(valueAutoComplete) + taxon_id: props.useTaxonomicBackbone ? taxonId : undefined }); setValueAutoComplete(""); @@ -254,6 +255,8 @@ const TreeSpeciesInput = (props: TreeSpeciesInputProps) => { value={valueAutoComplete} onChange={e => setValueAutoComplete(e.target.value)} onSearch={async search => { + if (!props.useTaxonomicBackbone) return []; + const result = await autocompleteSearch(search); setSearchResult(result); return result; @@ -390,7 +393,7 @@ const TreeSpeciesInput = (props: TreeSpeciesInputProps) => { } >
- +
From f4cc037f5d539f9469b0cff82e5897388b2cf658 Mon Sep 17 00:00:00 2001 From: Nathan Curtis Date: Mon, 16 Dec 2024 13:47:37 -0800 Subject: [PATCH 4/8] [TM-1402] If previous counts are being displayed, don't allow deleting a row that was previously reported on. --- .../TreeSpeciesInput/TreeSpeciesInput.tsx | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/components/elements/Inputs/TreeSpeciesInput/TreeSpeciesInput.tsx b/src/components/elements/Inputs/TreeSpeciesInput/TreeSpeciesInput.tsx index 3a9a8cda..8677e0eb 100644 --- a/src/components/elements/Inputs/TreeSpeciesInput/TreeSpeciesInput.tsx +++ b/src/components/elements/Inputs/TreeSpeciesInput/TreeSpeciesInput.tsx @@ -451,11 +451,21 @@ const TreeSpeciesInput = (props: TreeSpeciesInputProps) => { autoCompleteRef.current?.focus(); }} /> - setDeleteIndex(value.uuid ?? null)} - /> + name === value.name) == null + } + > + setDeleteIndex(value.uuid ?? null)} + /> +
)} From 06231317195c57e8269a561ad0b8a085f751b2ed Mon Sep 17 00:00:00 2001 From: Nathan Curtis Date: Mon, 16 Dec 2024 15:01:43 -0800 Subject: [PATCH 5/8] [TM-1402] Make the min for tree species 0. --- src/helpers/customForms.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/customForms.ts b/src/helpers/customForms.ts index 229a11bf..edc94756 100644 --- a/src/helpers/customForms.ts +++ b/src/helpers/customForms.ts @@ -732,7 +732,7 @@ const getFieldValidation = (question: FormQuestionRead, t: typeof useT, framewor const arrayItemShape = question.with_numbers ? yup.object({ name: yup.string().required(), - amount: yup.number().min(1).required() + amount: yup.number().min(0).required() }) : yup.object({ name: yup.string().required() From 26b670225efab43e1b69b20479b3fe03f2f17193 Mon Sep 17 00:00:00 2001 From: Nathan Curtis Date: Mon, 16 Dec 2024 15:20:59 -0800 Subject: [PATCH 6/8] [TM-1402] Update storyshot. --- .../TreeSpeciesInput.stories.storyshot | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/src/components/elements/Inputs/TreeSpeciesInput/__snapshots__/TreeSpeciesInput.stories.storyshot b/src/components/elements/Inputs/TreeSpeciesInput/__snapshots__/TreeSpeciesInput.stories.storyshot index 9810e81f..609851ed 100644 --- a/src/components/elements/Inputs/TreeSpeciesInput/__snapshots__/TreeSpeciesInput.stories.storyshot +++ b/src/components/elements/Inputs/TreeSpeciesInput/__snapshots__/TreeSpeciesInput.stories.storyshot @@ -133,18 +133,6 @@ exports[`Storyshots Components/Elements/Inputs/TreeSpeciesInput Default 1`] = `
-
-
-

-

-
-

Date: Mon, 16 Dec 2024 15:34:19 -0800 Subject: [PATCH 7/8] [TM-1402] Update storyshot. --- .../TreeSpeciesInput.stories.tsx | 2 ++ .../TreeSpeciesInput.stories.storyshot | 24 +++++++++++++++++++ .../WizardForm/WizardForm.stories.tsx | 4 ++++ 3 files changed, 30 insertions(+) diff --git a/src/components/elements/Inputs/TreeSpeciesInput/TreeSpeciesInput.stories.tsx b/src/components/elements/Inputs/TreeSpeciesInput/TreeSpeciesInput.stories.tsx index 6e0df776..f3fbe760 100644 --- a/src/components/elements/Inputs/TreeSpeciesInput/TreeSpeciesInput.stories.tsx +++ b/src/components/elements/Inputs/TreeSpeciesInput/TreeSpeciesInput.stories.tsx @@ -27,6 +27,8 @@ export const Default: Story = { label: "Tree Species Grown", description: "List the tree species that you expect to restore on this project, across all sites. Please enter the scientific name for each tree species.", + withPreviousCounts: false, + useTaxonomicBackbone: true, required: true, value: [ { diff --git a/src/components/elements/Inputs/TreeSpeciesInput/__snapshots__/TreeSpeciesInput.stories.storyshot b/src/components/elements/Inputs/TreeSpeciesInput/__snapshots__/TreeSpeciesInput.stories.storyshot index 609851ed..9810e81f 100644 --- a/src/components/elements/Inputs/TreeSpeciesInput/__snapshots__/TreeSpeciesInput.stories.storyshot +++ b/src/components/elements/Inputs/TreeSpeciesInput/__snapshots__/TreeSpeciesInput.stories.storyshot @@ -133,6 +133,18 @@ exports[`Storyshots Components/Elements/Inputs/TreeSpeciesInput Default 1`] = `

+
+
+

+

+
+

{ description: "TRee species input description", fieldProps: { title: "Tree Species", + withPreviousCounts: false, + useTaxonomicBackbone: false, buttonCaptionSuffix: "Species", required: true }, @@ -204,6 +206,8 @@ const getSteps = (edit?: boolean): FormStepSchema[] => { fieldProps: { title: "Tree Species", + withPreviousCounts: false, + useTaxonomicBackbone: false, buttonCaptionSuffix: "Species", required: true, withNumbers: true From 322b6a4e24ebea949fcf7cd7134a1b42b5d09478 Mon Sep 17 00:00:00 2001 From: Nathan Curtis Date: Mon, 16 Dec 2024 15:44:01 -0800 Subject: [PATCH 8/8] [TM-1402] Fix production build. --- .../[id]/components/edit/getEditOrganisationSteps.ts | 2 ++ .../project-pitch/create/[pitchUUID]/getCreatePitchSteps.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/pages/organization/[id]/components/edit/getEditOrganisationSteps.ts b/src/pages/organization/[id]/components/edit/getEditOrganisationSteps.ts index d58972eb..b14bd480 100644 --- a/src/pages/organization/[id]/components/edit/getEditOrganisationSteps.ts +++ b/src/pages/organization/[id]/components/edit/getEditOrganisationSteps.ts @@ -599,6 +599,8 @@ export const getSteps = (t: typeof useT, uuid: string): FormStepSchema[] => { ), fieldProps: { title: t("Tree Species"), + withPreviousCounts: false, + useTaxonomicBackbone: true, buttonCaptionSuffix: t("Species"), withNumbers: false } diff --git a/src/pages/organization/[id]/project-pitch/create/[pitchUUID]/getCreatePitchSteps.ts b/src/pages/organization/[id]/project-pitch/create/[pitchUUID]/getCreatePitchSteps.ts index f98dcbe1..39c190d1 100644 --- a/src/pages/organization/[id]/project-pitch/create/[pitchUUID]/getCreatePitchSteps.ts +++ b/src/pages/organization/[id]/project-pitch/create/[pitchUUID]/getCreatePitchSteps.ts @@ -332,6 +332,8 @@ export const getSteps = (t: typeof useT, uuid: string): FormStepSchema[] => [ ), fieldProps: { title: t("Tree Species"), + withPreviousCounts: false, + useTaxonomicBackbone: true, buttonCaptionSuffix: t("Species"), withNumbers: true }