@@ -1,7 +1,7 @@ |
/* eslint-disable flowtype/no-types-missing-file-annotation */ |
- |
import * as React from 'react' |
-import { connect, useSelector } from 'react-redux' |
+import {useEffect, useState, Fragment, ChangeEvent } from 'react' |
+import { connect, useSelector, useDispatch } from 'react-redux' |
import { useKeycloak } from '@react-keycloak/web' |
import area from '@turf/area' |
import shp from 'shpjs' |
@@ -65,6 +65,7 @@ |
import type { SettingsType } from '../reducers/settings' |
import { getProjectByEQIPNum } from '../reducers/manageProjects' |
import * as routes from '../constants/routes' |
+import * as types from '../constants/action_types' |
|
import { |
onDeleteProject, |
@@ -90,6 +91,7 @@ |
import Project from './Project' |
import { |
getEditingStation, |
+ isEQIPNumAlreadyUsed, |
onEditProjectGetProjectMembers, |
} from '../actions/manageProjects' |
import UserSelect from './UserSelect' |
@@ -219,43 +221,71 @@ |
}))(Dialog) |
|
function ManageProjects(props: Props) { |
- const [undoProject, setUndoProject] = React.useState<ProjectType | undefined>() |
- const [undoMember, setUndoMember] = React.useState<MemberType | undefined>() |
- const [isCreatingNewProject, setIsCreatingNewProject] = React.useState(false) |
- const [isEditingProject, setIsEditingProject] = React.useState(false) |
- const [activeStep, setActiveStep] = React.useState(0) |
- const [createProjectMemberName, setCreateProjectMemberName] = React.useState('') |
- const [createProjectMemberNameInputValue, setCreateProjectMemberNameInputValue] = React.useState('') |
- const [createProjectMemberRoleInputValue, setCreateProjectMemberRoleInputValue] = React.useState('') |
- const [createProjectMembers, setCreateProjectMembers] = React.useState([]) |
- const [createProjectSelectedPractice, setCreateProjectSelectedPractice] = React.useState('') |
- const [createProjectPractices, setCreateProjectPractices] = React.useState([]) |
- const [createProjectDetailsTitle, setCreateProjectDetailsTitle] = React.useState('') |
- const [createProjectDetailsId, setCreateProjectDetailsId] = React.useState('') |
- const [createProjectDetailsEQIPNum, setCreateProjectDetailsEQIPNum] = React.useState(-1) |
- const [createProjectDetailsTreatmentType, setCreateProjectDetailsTreatmentType] = React.useState('') |
- const [createProjectDetailsStatus, setCreateProjectDetailsStatus] = React.useState('New') |
- const [createProjectDetailsTreatmentDescription, setCreateProjectDetailsTreatmentDescription] = React.useState('') |
- const [createStationDetailsID, setCreateStationDetailsID] = React.useState('') |
- const [createStationDetailsProjectID, setCreateStationDetailsProjectID] = React.useState('') |
- const [createStationDetailsTreatmentIndicator, setCreateStationDetailsTreatmentIndicator] = React.useState('') |
- const [createStationLatitude, setCreateStationLatitude] = React.useState('') |
- const [createStationLongitude, setCreateStationLongitude] = React.useState('') |
- const [createStationDrainageAcres, setCreateStationDrainageAcres] = React.useState('') |
- const [createStationDraingeGeometry, setCreateStationDrainageGeometry] = React.useState() |
- const [documentUploadCategories, setDocumentUploadCategories] = React.useState([]) |
- const [errorInputs, setErrorInputs] = React.useState([]) |
- const [projectFilterText, setProjectFilterText] = React.useState('') |
- const [userRoleConservationist, setUserRoleConservationist] = React.useState(false) |
+ const [undoProject, setUndoProject] = useState<ProjectType | undefined>() |
+ const [undoMember, setUndoMember] = useState<MemberType | undefined>() |
+ const [isCreatingNewProject, setIsCreatingNewProject] = useState(false) |
+ const [isEditingProject, setIsEditingProject] = useState(false) |
+ const [activeStep, setActiveStep] = useState(0) |
+ const [createProjectMemberName, setCreateProjectMemberName] = useState('') |
+ const [createProjectMemberNameInputValue, setCreateProjectMemberNameInputValue] = useState('') |
+ const [createProjectMemberRoleInputValue, setCreateProjectMemberRoleInputValue] = useState('') |
+ const [createProjectMembers, setCreateProjectMembers] = useState([]) |
+ const [createProjectSelectedPractice, setCreateProjectSelectedPractice] = useState('') |
+ const [createProjectPractices, setCreateProjectPractices] = useState([]) |
+ const [createProjectDetailsTitle, setCreateProjectDetailsTitle] = useState('') |
+ const [createProjectDetailsId, setCreateProjectDetailsId] = useState('') |
+ const [createProjectDetailsEQIPNum, setCreateProjectDetailsEQIPNum] = useState(-1) |
+ const [createProjectDetailsTreatmentType, setCreateProjectDetailsTreatmentType] = useState('') |
+ const [createProjectDetailsStatus, setCreateProjectDetailsStatus] = useState('New') |
+ const [createProjectDetailsTreatmentDescription, setCreateProjectDetailsTreatmentDescription] = useState('') |
+ const [createStationDetailsID, setCreateStationDetailsID] = useState('') |
+ const [createStationDetailsProjectID, setCreateStationDetailsProjectID] = useState('') |
+ const [createStationDetailsTreatmentIndicator, setCreateStationDetailsTreatmentIndicator] = useState('') |
+ const [createStationLatitude, setCreateStationLatitude] = useState('') |
+ const [createStationLongitude, setCreateStationLongitude] = useState('') |
+ const [createStationDrainageAcres, setCreateStationDrainageAcres] = useState('') |
+ const [createStationDraingeGeometry, setCreateStationDrainageGeometry] = useState() |
+ const [documentUploadCategories, setDocumentUploadCategories] = useState([]) |
+ const [errorInputs, setErrorInputs] = useState([]) |
+ const [projectFilterText, setProjectFilterText] = useState('') |
+ const [userRoleConservationist, setUserRoleConservationist] = useState(false) |
|
const users = useSelector((state) => state.users) |
const { keycloak, initialized } = useKeycloak() |
+ const dispatch = useDispatch() |
+ const eqipIdAlreadyUsed = useSelector((state) => state.manageProjects.isEQIPIDAlreadyUsed) |
+ console.log({eqipIdAlreadyUsed, createProjectDetailsEQIPNum}) |
|
const selectedProjects = props.manageProjects.projects.filter( |
(p) => p.selected === true |
) |
|
- React.useEffect(() => { |
+ useEffect(() => { |
+ dispatch({ type: types.SET_EQIP_NUM_ALREADY_USED, payload: null }) |
+ const timeoutHandle = setTimeout(() => { |
+ console.log('user stopped typing 2 seconds ago') |
+ if(createProjectDetailsEQIPNum !== -1){ |
+ dispatch(isEQIPNumAlreadyUsed(createProjectDetailsEQIPNum)) |
+ } |
+ }, 2000) |
+ |
+ return () => { |
+ clearTimeout(timeoutHandle) |
+ } |
+ },[createProjectDetailsEQIPNum]) |
+ |
+ useEffect(() => { |
+ if(eqipIdAlreadyUsed){ |
+ const oldErrorInputs = errorInputs |
+ oldErrorInputs.push('detailsEQIPNum') |
+ setErrorInputs(oldErrorInputs) |
+ } else{ |
+ const newErrorInputs = errorInputs.filter(e => e!== 'detailsEQIPNum') |
+ setErrorInputs(newErrorInputs) |
+ } |
+ }, [eqipIdAlreadyUsed]) |
+ |
+ useEffect(() => { |
//TODO: on fetch from the backend, set isEditingStation to false. |
if (props.manageProjects.isEditingStation && !createStationDetailsID) { |
loadMonitoringStation(getEditingStation(props.manageProjects)) |
@@ -266,20 +296,20 @@ |
} |
}, [props.manageProjects.isEditingStation]) |
|
- React.useEffect(() => { |
+ useEffect(() => { |
if (users.user.id) { |
setUserRoleConservationist('Conservationist' === users.user['role']) |
} |
}, [users]) |
|
- React.useEffect(() => { |
+ useEffect(() => { |
// hide the south panel, the user won't be using it in this context. |
if (props.tabbedPanel.windowState === windowStates.minimized) { |
props.setTabbedPanelWindowState(windowStates.opened) |
} |
}) |
|
- React.useEffect(() => { |
+ useEffect(() => { |
if ( |
props.manageProjects.isEditingDocument && |
selectedProjects.length >= 0 |
@@ -296,7 +326,7 @@ |
]) |
|
// when users.users is updated, update members for each project --> to address the case of if a user's role is updated, then this will be reflected in project stepper |
- React.useEffect(() => { |
+ useEffect(() => { |
props.manageProjects.projects.map((project) => |
props.onEditProjectGetProjectMembers(project.id) |
) |
@@ -662,7 +692,7 @@ |
/> |
)} |
renderOption={(option, { selected }) => ( |
- <React.Fragment> |
+ <Fragment> |
<Checkbox |
icon={icon} |
checkedIcon={checkedIcon} |
@@ -673,7 +703,7 @@ |
<span style={{ fontSize: 12 }}> |
{option.text} |
</span> |
- </React.Fragment> |
+ </Fragment> |
)} |
/> |
</FormControl> |
@@ -847,7 +877,7 @@ |
<Select |
value={createStationDetailsTreatmentIndicator} |
onChange={( |
- event: React.ChangeEvent<HTMLInputElement> |
+ event: ChangeEvent<HTMLInputElement> |
) => |
setCreateStationDetailsTreatmentIndicator( |
event.target.value |
@@ -1227,7 +1257,7 @@ |
const errors = [] |
if (createProjectDetailsTitle === '') errors.push('detailsTitle') |
if (createProjectDetailsId === '') errors.push('detailsId') |
- if (createProjectDetailsEQIPNum === -1) errors.push('detailsEQIPNum') |
+ if (createProjectDetailsEQIPNum === -1 || eqipIdAlreadyUsed) errors.push('detailsEQIPNum') |
if (createProjectDetailsTreatmentType === '') |
errors.push('detailsTreatmentType') |
if (createProjectDetailsStatus === '') errors.push('detailsStatus') |
@@ -1394,12 +1424,12 @@ |
<HtmlTooltip |
key={member.id} |
title={ |
- <React.Fragment> |
+ <Fragment> |
<Typography color="inherit"> |
Name: {member.name} |
</Typography> |
Role: {member.role} <br /> |
- </React.Fragment> |
+ </Fragment> |
} |
> |
<Chip |
@@ -1446,14 +1476,14 @@ |
options={projectUsers} |
getOptionLabel={(option) => option.name} |
renderOption={(option) => ( |
- <React.Fragment> |
+ <Fragment> |
<ListItemText style={{fontWeight: 'bold'}}> |
{option.name} |
</ListItemText> |
<Typography variant="body2" style={{color: '#969696'}}> |
{option.role} |
</Typography> |
- </React.Fragment> |
+ </Fragment> |
)} |
renderInput={(params) => ( |
<TextField |
@@ -1525,7 +1555,7 @@ |
<Select |
value={createProjectSelectedPractice} |
onChange={( |
- event: React.ChangeEvent<HTMLInputElement> |
+ event: ChangeEvent<HTMLInputElement> |
) => { |
setCreateProjectSelectedPractice( |
event.target.value |
@@ -1612,6 +1642,7 @@ |
<Grid item xs={6}> |
<TextField |
error={errorInputs.indexOf('detailsEQIPNum') >= 0} |
+ helperText={errorInputs.indexOf('detailsEQIPNum') >= 0 ? 'That EQIP Contract Number is already associated with a project.' : null} |
label="EQIP Contract Number" |
fullWidth |
onChange={(event) => { |
@@ -1653,7 +1684,7 @@ |
<Select |
value={createProjectDetailsTreatmentType} |
onChange={( |
- event: React.ChangeEvent<HTMLInputElement> |
+ event: ChangeEvent<HTMLInputElement> |
) => |
setCreateProjectDetailsTreatmentType( |
event.target.value |
@@ -1684,7 +1715,7 @@ |
<Select |
value={createProjectDetailsStatus} |
onChange={( |
- event: React.ChangeEvent<HTMLInputElement> |
+ event: ChangeEvent<HTMLInputElement> |
) => |
setCreateProjectDetailsStatus( |
event.target.value |
@@ -1943,7 +1974,7 @@ |
onClose={() => props.closeDismissSnackbar()} |
message={dismissSnackbarMessage} |
action={ |
- <React.Fragment> |
+ <Fragment> |
<Button |
color="secondary" |
size="small" |
@@ -1961,7 +1992,7 @@ |
> |
<CloseIcon fontSize="small" /> |
</IconButton> |
- </React.Fragment> |
+ </Fragment> |
} |
/> |
</Portal> |
@@ -1983,7 +2014,7 @@ |
onExit={(e) => handleSnackBarExit()} |
message={snackbarMessage} |
action={ |
- <React.Fragment> |
+ <Fragment> |
<Button |
color="secondary" |
size="small" |
@@ -2001,7 +2032,7 @@ |
> |
<CloseIcon fontSize="small" /> |
</IconButton> |
- </React.Fragment> |
+ </Fragment> |
} |
/> |
</Portal> |