From 1102d2a96d51f08ea4ec33e3ef4bda60ddaec2ed Mon Sep 17 00:00:00 2001 From: Shreyas Devalapurkar Date: Wed, 10 Mar 2021 16:50:14 -0800 Subject: [PATCH] 868 Frontend: IUCN Classifications (#110) BHBC-868: IUCN Classifications (frontend) --- .../projects/CreateProjectPage.test.tsx | 2 + .../features/projects/CreateProjectPage.tsx | 32 +- .../CreateProjectPage.test.tsx.snap | 68 +- .../components/ProjectDetailsForm.tsx | 14 +- .../components/ProjectFundingItemForm.tsx | 7 +- .../components/ProjectIUCNForm.test.tsx | 73 +++ .../projects/components/ProjectIUCNForm.tsx | 175 ++++++ .../ProjectDetailsForm.test.tsx.snap | 2 +- .../ProjectFundingItemForm.test.tsx.snap | 2 +- .../ProjectIUCNForm.test.tsx.snap | 581 ++++++++++++++++++ 10 files changed, 935 insertions(+), 21 deletions(-) create mode 100644 app/src/features/projects/components/ProjectIUCNForm.test.tsx create mode 100644 app/src/features/projects/components/ProjectIUCNForm.tsx create mode 100644 app/src/features/projects/components/__snapshots__/ProjectIUCNForm.test.tsx.snap diff --git a/app/src/features/projects/CreateProjectPage.test.tsx b/app/src/features/projects/CreateProjectPage.test.tsx index 2afaa3d3df..5d8da7bd4c 100644 --- a/app/src/features/projects/CreateProjectPage.test.tsx +++ b/app/src/features/projects/CreateProjectPage.test.tsx @@ -87,6 +87,8 @@ describe('CreateProjectPage', () => { expect(getByText('Species')).toBeVisible(); + expect(getByText('IUCN Classification')).toBeVisible(); + expect(getByText('Funding and Partnerships')).toBeVisible(); expect(asFragment()).toMatchSnapshot(); diff --git a/app/src/features/projects/CreateProjectPage.tsx b/app/src/features/projects/CreateProjectPage.tsx index 05e340237f..ce18c2ed50 100644 --- a/app/src/features/projects/CreateProjectPage.tsx +++ b/app/src/features/projects/CreateProjectPage.tsx @@ -42,6 +42,10 @@ import ProjectObjectivesForm, { ProjectObjectivesFormInitialValues, ProjectObjectivesFormYupSchema } from 'features/projects/components/ProjectObjectivesForm'; +import ProjectIUCNForm, { + ProjectIUCNFormInitialValues, + ProjectIUCNFormYupSchema +} from 'features/projects/components/ProjectIUCNForm'; import ProjectPermitForm, { IProjectPermitForm, ProjectPermitFormInitialValues, @@ -104,7 +108,7 @@ const useStyles = makeStyles((theme) => ({ })); const NUM_PARTIAL_PROJECT_STEPS = 2; -const NUM_ALL_PROJECT_STEPS = 7; +const NUM_ALL_PROJECT_STEPS = 8; /** * Page for creating a new project. @@ -274,6 +278,32 @@ const CreateProjectPage: React.FC = () => { stepValues: ProjectSpeciesFormInitialValues, stepValidation: ProjectSpeciesFormYupSchema }, + { + stepTitle: 'IUCN Classification', + stepSubTitle: 'Lorem ipsum dolor sit amet, consectur whatever whatever', + stepContent: ( + { + return { value: item.id, label: item.name }; + }) || [] + } + subClassifications={ + [ + { id: 1, name: 'Sub-class 1' }, + { id: 2, name: 'Sub-class 2' } + ].map((item) => { + return { value: item.id, label: item.name }; + }) || [] + } + /> + ), + stepValues: ProjectIUCNFormInitialValues, + stepValidation: ProjectIUCNFormYupSchema + }, { stepTitle: 'Funding and Partnerships', stepSubTitle: 'Specify funding and partnerships for the project', diff --git a/app/src/features/projects/__snapshots__/CreateProjectPage.test.tsx.snap b/app/src/features/projects/__snapshots__/CreateProjectPage.test.tsx.snap index b28b0b4feb..6e2ed7e3c9 100644 --- a/app/src/features/projects/__snapshots__/CreateProjectPage.test.tsx.snap +++ b/app/src/features/projects/__snapshots__/CreateProjectPage.test.tsx.snap @@ -756,6 +756,72 @@ exports[`CreateProjectPage adds the extra create project steps if at least 1 per >
+

+ IUCN Classification +

+
+ Lorem ipsum dolor sit amet, consectur whatever whatever +
+
+ + + +
+
+
+ +
+
+ + + + + + +

diff --git a/app/src/features/projects/components/ProjectDetailsForm.tsx b/app/src/features/projects/components/ProjectDetailsForm.tsx index cdfe4e8ffe..98616f63f7 100644 --- a/app/src/features/projects/components/ProjectDetailsForm.tsx +++ b/app/src/features/projects/components/ProjectDetailsForm.tsx @@ -1,13 +1,4 @@ -import { - FormControl, - FormHelperText, - Grid, - InputLabel, - MenuItem, - OutlinedInput, - Select, - TextField -} from '@material-ui/core'; +import { FormControl, FormHelperText, Grid, InputLabel, MenuItem, Select, TextField } from '@material-ui/core'; import MultiAutocompleteFieldVariableSize, { IMultiAutocompleteFieldOption } from 'components/fields/MultiAutocompleteFieldVariableSize'; @@ -88,8 +79,7 @@ const ProjectDetailsForm: React.FC = (props) => { onChange={handleChange} error={touched.project_type && Boolean(errors.project_type)} displayEmpty - inputProps={{ 'aria-label': 'Project Type' }} - input={}> + inputProps={{ 'aria-label': 'Project Type' }}> {props.project_type.map((item) => ( {item.label} diff --git a/app/src/features/projects/components/ProjectFundingItemForm.tsx b/app/src/features/projects/components/ProjectFundingItemForm.tsx index 191d32101f..41c6ccdcd1 100644 --- a/app/src/features/projects/components/ProjectFundingItemForm.tsx +++ b/app/src/features/projects/components/ProjectFundingItemForm.tsx @@ -12,7 +12,6 @@ import { InputAdornment, InputLabel, MenuItem, - OutlinedInput, Select, TextField, Typography @@ -143,8 +142,7 @@ const ProjectFundingItemForm: React.FC = (props) = }} error={touched.agency_id && Boolean(errors.agency_id)} displayEmpty - inputProps={{ 'aria-label': 'Agency Name' }} - input={}> + inputProps={{ 'aria-label': 'Agency Name' }}> {props.funding_sources.map((item) => ( {item.label} @@ -169,8 +167,7 @@ const ProjectFundingItemForm: React.FC = (props) = onChange={handleChange} error={touched.investment_action_category && Boolean(errors.investment_action_category)} displayEmpty - inputProps={{ 'aria-label': `${investment_action_category_label}` }} - input={}> + inputProps={{ 'aria-label': `${investment_action_category_label}` }}> {props.investment_action_category // Only show the investment action categories whose fs_id matches the agency_id id .filter((item) => item.fs_id === values.agency_id) diff --git a/app/src/features/projects/components/ProjectIUCNForm.test.tsx b/app/src/features/projects/components/ProjectIUCNForm.test.tsx new file mode 100644 index 0000000000..ff83c8e783 --- /dev/null +++ b/app/src/features/projects/components/ProjectIUCNForm.test.tsx @@ -0,0 +1,73 @@ +import { render } from '@testing-library/react'; +import { Formik } from 'formik'; +import React from 'react'; +import { IMultiAutocompleteFieldOption } from 'components/fields/MultiAutocompleteFieldVariableSize'; +import ProjectIUCNForm, { + IProjectIUCNForm, + ProjectIUCNFormInitialValues, + ProjectIUCNFormYupSchema +} from './ProjectIUCNForm'; + +const classifications: IMultiAutocompleteFieldOption[] = [ + { + value: 'class_1', + label: 'Class 1' + }, + { + value: 'class_2', + label: 'Class 2' + } +]; + +const subClassifications: IMultiAutocompleteFieldOption[] = [ + { + value: 'subclass_1', + label: 'Sub-class 1' + }, + { + value: 'subclass_2', + label: 'Sub-class 2' + } +]; + +describe('ProjectIUCNForm', () => { + it('renders correctly with default empty values', () => { + const { asFragment } = render( + {}}> + {() => } + + ); + + expect(asFragment()).toMatchSnapshot(); + }); + + it('renders correctly with existing details values', () => { + const existingFormValues: IProjectIUCNForm = { + classificationDetails: [ + { + classification: 'class_1', + subClassification1: 'subclass_1', + subClassification2: 'subclass_2' + } + ] + }; + + const { asFragment } = render( + {}}> + {() => } + + ); + + expect(asFragment()).toMatchSnapshot(); + }); +}); diff --git a/app/src/features/projects/components/ProjectIUCNForm.tsx b/app/src/features/projects/components/ProjectIUCNForm.tsx new file mode 100644 index 0000000000..f3e80d68cd --- /dev/null +++ b/app/src/features/projects/components/ProjectIUCNForm.tsx @@ -0,0 +1,175 @@ +import { + FormControl, + FormHelperText, + Grid, + InputLabel, + MenuItem, + Select, + Box, + IconButton, + Button +} from '@material-ui/core'; +import Icon from '@mdi/react'; +import { mdiTrashCanOutline, mdiArrowRight } from '@mdi/js'; +import { FieldArray, useFormikContext } from 'formik'; +import { IMultiAutocompleteFieldOption } from 'components/fields/MultiAutocompleteFieldVariableSize'; +import React from 'react'; +import * as yup from 'yup'; + +export interface IProjectIUCNFormArrayItem { + classification: string; + subClassification1: string; + subClassification2: string; +} + +export interface IProjectIUCNForm { + classificationDetails: IProjectIUCNFormArrayItem[]; +} + +export const ProjectIUCNFormArrayItemInitialValues: IProjectIUCNFormArrayItem = { + classification: '', + subClassification1: '', + subClassification2: '' +}; + +export const ProjectIUCNFormInitialValues: IProjectIUCNForm = { + classificationDetails: [ProjectIUCNFormArrayItemInitialValues] +}; + +export const ProjectIUCNFormYupSchema = yup.object().shape({ + classificationDetails: yup.array().of( + yup.object().shape({ + classification: yup.string().required('You must specify a classification'), + subClassification1: yup.string().required('You must specify a sub-classification'), + subClassification2: yup.string().required('You must specify a sub-classification') + }) + ) +}); + +export interface IProjectIUCNFormProps { + classifications: IMultiAutocompleteFieldOption[]; + subClassifications: IMultiAutocompleteFieldOption[]; +} + +/** + * Create project - IUCN classification section + * + * @return {*} + */ +const ProjectIUCNForm: React.FC = (props: any) => { + const { values, handleChange, handleSubmit, getFieldMeta } = useFormikContext(); + + return ( +
+ ( + + + {values.classificationDetails.map((classificationDetail, index) => { + const classificationMeta = getFieldMeta(`classificationDetails.[${index}].classification`); + const subClassification1Meta = getFieldMeta(`classificationDetails.[${index}].subClassification1`); + const subClassification2Meta = getFieldMeta(`classificationDetails.[${index}].subClassification2`); + + return ( + + + + + Classification + + {classificationMeta.error} + + + + + + + + Sub-classification + + {subClassification1Meta.error} + + + + + + + + Sub-classification + + {subClassification2Meta.error} + + + + arrayHelpers.remove(index)}> + + + + + + ); + })} + + + + + + )} + /> + + ); +}; + +export default ProjectIUCNForm; diff --git a/app/src/features/projects/components/__snapshots__/ProjectDetailsForm.test.tsx.snap b/app/src/features/projects/components/__snapshots__/ProjectDetailsForm.test.tsx.snap index 11beb53a18..a4463c6c4a 100644 --- a/app/src/features/projects/components/__snapshots__/ProjectDetailsForm.test.tsx.snap +++ b/app/src/features/projects/components/__snapshots__/ProjectDetailsForm.test.tsx.snap @@ -112,7 +112,7 @@ exports[`ProjectDetailsForm renders correctly with default empty values 1`] = ` class="PrivateNotchedOutline-root-1 MuiOutlinedInput-notchedOutline" > Project Type diff --git a/app/src/features/projects/components/__snapshots__/ProjectFundingItemForm.test.tsx.snap b/app/src/features/projects/components/__snapshots__/ProjectFundingItemForm.test.tsx.snap index 95b0d904ef..e8fe543ed3 100644 --- a/app/src/features/projects/components/__snapshots__/ProjectFundingItemForm.test.tsx.snap +++ b/app/src/features/projects/components/__snapshots__/ProjectFundingItemForm.test.tsx.snap @@ -131,7 +131,7 @@ exports[`ProjectFundingItemForm renders correctly with default empty values 1`] class="PrivateNotchedOutline-root-2 MuiOutlinedInput-notchedOutline" > Agency Name diff --git a/app/src/features/projects/components/__snapshots__/ProjectIUCNForm.test.tsx.snap b/app/src/features/projects/components/__snapshots__/ProjectIUCNForm.test.tsx.snap new file mode 100644 index 0000000000..718b506005 --- /dev/null +++ b/app/src/features/projects/components/__snapshots__/ProjectIUCNForm.test.tsx.snap @@ -0,0 +1,581 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ProjectIUCNForm renders correctly with default empty values 1`] = ` + +
+
+
+
+
+
+
+ +
+
+ + ​ + +
+ + + +
+

+

+
+
+ + + +
+
+
+ +
+
+ + ​ + +
+ + + +
+

+

+
+
+ + + +
+
+
+ +
+
+ + ​ + +
+ + + +
+

+

+
+
+ +
+
+
+
+
+ +
+
+
+
+`; + +exports[`ProjectIUCNForm renders correctly with existing details values 1`] = ` + +
+
+
+
+
+
+
+ +
+
+ Class 1 +
+ + + +
+

+

+
+
+ + + +
+
+
+ +
+
+ Sub-class 1 +
+ + + +
+

+

+
+
+ + + +
+
+
+ +
+
+ Sub-class 2 +
+ + + +
+

+

+
+
+ +
+
+
+
+
+ +
+
+
+
+`;