From 9cfa05c17f424ab4d393339950d53b773999221e Mon Sep 17 00:00:00 2001 From: devinleighsmith Date: Mon, 20 Nov 2023 14:31:51 -0800 Subject: [PATCH] temp commit --- .../CompensationRequisitionTrayContainer.tsx | 7 +- .../list/CompensationListContainer.tsx | 12 +- .../mapSideBar/context/popoutContext.tsx | 57 +++++++++ .../router/CompensationRequisitionRouter.tsx | 8 +- .../features/mapSideBar/router/MapRouter.tsx | 31 +++++ .../mapSideBar/shared/MapContentContainer.tsx | 114 ++++++++++++++++++ .../mapSideBar/shared/MapContentView.tsx | 51 ++++++++ .../mapSideBar/shared/SidebarFooter.tsx | 2 +- .../features/properties/map/MapContainer.tsx | 38 +++--- 9 files changed, 294 insertions(+), 26 deletions(-) create mode 100644 source/frontend/src/features/mapSideBar/context/popoutContext.tsx create mode 100644 source/frontend/src/features/mapSideBar/shared/MapContentContainer.tsx create mode 100644 source/frontend/src/features/mapSideBar/shared/MapContentView.tsx diff --git a/source/frontend/src/features/mapSideBar/acquisition/tabs/compensation/CompensationRequisitionTrayContainer.tsx b/source/frontend/src/features/mapSideBar/acquisition/tabs/compensation/CompensationRequisitionTrayContainer.tsx index 6a56b1b9f7..72c7986462 100644 --- a/source/frontend/src/features/mapSideBar/acquisition/tabs/compensation/CompensationRequisitionTrayContainer.tsx +++ b/source/frontend/src/features/mapSideBar/acquisition/tabs/compensation/CompensationRequisitionTrayContainer.tsx @@ -13,13 +13,14 @@ export interface ICompensationRequisitionTrayContainerProps { compensationRequisitionId?: number; onClose: () => void; View: React.FunctionComponent>; + onUpdate: () => void; } export const CompensationRequisitionTrayContainer: React.FunctionComponent< React.PropsWithChildren -> = ({ compensationRequisitionId, onClose, View }) => { +> = ({ compensationRequisitionId, onClose, View, onUpdate }) => { const { getSystemConstant } = useSystemConstants(); - const { file, project, setProject, setProjectLoading, setStaleFile, setStaleLastUpdatedBy } = + const { file, project, setProject, setProjectLoading, setStaleLastUpdatedBy } = useContext(SideBarContext); const [editMode, setEditMode] = useState(false); @@ -87,7 +88,7 @@ export const CompensationRequisitionTrayContainer: React.FunctionComponent< onUpdate={() => { fetchCompensationReq(); setStaleLastUpdatedBy(true); - setStaleFile(true); + onUpdate(); }} > ) : null; diff --git a/source/frontend/src/features/mapSideBar/acquisition/tabs/compensation/list/CompensationListContainer.tsx b/source/frontend/src/features/mapSideBar/acquisition/tabs/compensation/list/CompensationListContainer.tsx index 027cc55b58..a22d91eba2 100644 --- a/source/frontend/src/features/mapSideBar/acquisition/tabs/compensation/list/CompensationListContainer.tsx +++ b/source/frontend/src/features/mapSideBar/acquisition/tabs/compensation/list/CompensationListContainer.tsx @@ -1,9 +1,11 @@ import axios, { AxiosError } from 'axios'; -import React, { useCallback, useContext } from 'react'; +import React, { useCallback, useContext, useEffect } from 'react'; import { toast } from 'react-toastify'; import { FileTypes } from '@/constants'; +import { PopoutContext } from '@/features/mapSideBar/context/popoutContext'; import { SideBarContext } from '@/features/mapSideBar/context/sidebarContext'; +import CompensationRequisitionRouter from '@/features/mapSideBar/router/CompensationRequisitionRouter'; import { useAcquisitionProvider } from '@/hooks/repositories/useAcquisitionProvider'; import { useCompensationRequisitionRepository } from '@/hooks/repositories/useRequisitionCompensationRepository'; import { getDeleteModalProps, useModalContext } from '@/hooks/useModalContext'; @@ -44,6 +46,10 @@ export const CompensationListContainer: React.FunctionComponent< await getAcquisitionCompensationRequisitions(fileId); }, [getAcquisitionCompensationRequisitions, fileId]); + const { setRouterComponent, popoutUpdated } = useContext(PopoutContext); + + setRouterComponent(CompensationRequisitionRouter); + const onUpdateTotalCompensation = async ( totalAllowableCompensation: number | null, ): Promise => { @@ -121,10 +127,10 @@ export const CompensationListContainer: React.FunctionComponent< }; React.useEffect(() => { - if (compensations === undefined || staleFile) { + if (compensations === undefined || popoutUpdated) { fetchData(); } - }, [fetchData, staleFile, compensations]); + }, [fetchData, popoutUpdated, compensations]); return ( void; + RouterComponent: React.FunctionComponent | null; + setRouterComponent: ( + routerComponent: React.FunctionComponent, + ) => void; + popoutUpdated: boolean; + setPopoutUpdated: (popoutUpdated: boolean) => void; +} + +export interface IMapSidebarPopoutRouterProps { + setShowActionBar: (showActionBar: boolean) => void; + onUpdate: () => void; +} + +export const PopoutContext = React.createContext({ + showActionBar: false, + setShowActionBar: (showActionBar: boolean) => { + throw Error('setShowActionBar function not defined'); + }, + RouterComponent: null, + setRouterComponent: (routerComponent: React.FunctionComponent) => { + throw Error('setRouterComponent function not defined'); + }, + popoutUpdated: false, + setPopoutUpdated: (popoutUpdated: boolean) => { + throw Error('setPopoutUpdated function not defined'); + }, +}); + +export const PopoutContextProvider = (props: { + children: React.ReactChild | React.ReactChild[] | React.ReactNode; +}) => { + const [showActionBar, setShowActionBar] = useState(false); + const [popoutUpdated, setPopoutUpdated] = useState(false); + const [RouterComponent, setRouterComponent] = + useState | null>(null); + + return ( + + {props.children} + + ); +}; diff --git a/source/frontend/src/features/mapSideBar/router/CompensationRequisitionRouter.tsx b/source/frontend/src/features/mapSideBar/router/CompensationRequisitionRouter.tsx index 9c4a30da3b..8696e7ffe6 100644 --- a/source/frontend/src/features/mapSideBar/router/CompensationRequisitionRouter.tsx +++ b/source/frontend/src/features/mapSideBar/router/CompensationRequisitionRouter.tsx @@ -6,13 +6,10 @@ import AppRoute from '@/utils/AppRoute'; import { CompensationRequisitionTrayContainer } from '../acquisition/tabs/compensation/CompensationRequisitionTrayContainer'; import { CompensationRequisitionTrayView } from '../acquisition/tabs/compensation/CompensationRequisitionTrayView'; - -interface ICompensationRequisitionRouterProps { - setShowActionBar: (show: boolean) => void; -} +import { IMapSidebarPopoutRouterProps } from '../context/popoutContext'; export const CompensationRequisitionRouter: React.FunctionComponent< - React.PropsWithChildren + React.PropsWithChildren > = React.memo(props => { const location = useLocation(); const history = useHistory(); @@ -45,6 +42,7 @@ export const CompensationRequisitionRouter: React.FunctionComponent< compensationRequisitionId={Number(match.params.id)} onClose={onClose} View={CompensationRequisitionTrayView} + onUpdate={props.onUpdate} /> )} claim={Claims.COMPENSATION_REQUISITION_VIEW} diff --git a/source/frontend/src/features/mapSideBar/router/MapRouter.tsx b/source/frontend/src/features/mapSideBar/router/MapRouter.tsx index 73a1ae1f42..c39f630773 100644 --- a/source/frontend/src/features/mapSideBar/router/MapRouter.tsx +++ b/source/frontend/src/features/mapSideBar/router/MapRouter.tsx @@ -2,6 +2,7 @@ import queryString from 'query-string'; import { memo, useEffect, useMemo } from 'react'; import { matchPath, Switch, useHistory, useLocation } from 'react-router-dom'; +import { ReactComponent as RealEstateAgent } from '@/assets/images/real-estate-agent.svg'; import { SideBarType } from '@/components/common/mapFSM/machineDefinition/types'; import { useMapStateMachine } from '@/components/common/mapFSM/MapStateMachineContext'; import Claims from '@/constants/claims'; @@ -13,12 +14,17 @@ import AppRoute from '@/utils/AppRoute'; import AcquisitionContainer from '../acquisition/AcquisitionContainer'; import AcquisitionView from '../acquisition/AcquisitionView'; import AddAcquisitionContainer from '../acquisition/add/AddAcquisitionContainer'; +import AcquisitionHeader from '../acquisition/common/AcquisitionHeader'; import LeaseContainer from '../lease/LeaseContainer'; import AddProjectContainer from '../project/add/AddProjectContainer'; import ProjectContainer from '../project/ProjectContainer'; import ProjectContainerView from '../project/ProjectContainerView'; import AddResearchContainer from '../research/add/AddResearchContainer'; import ResearchContainer from '../research/ResearchContainer'; +import MapContentContainer from '../shared/MapContentContainer'; +import MapContentView from '../shared/MapContentView'; +import SidebarFooter from '../shared/SidebarFooter'; +import CompensationRequisitionRouter from './CompensationRequisitionRouter'; interface IMapRouterProps {} @@ -162,6 +168,31 @@ export const MapRouter: React.FunctionComponent = memo(props => key={'Acquisition'} title={'Acquisition File'} /> + ( + + } + /> + )} + claim={Claims.ACQUISITION_VIEW} + key={'new_acq'} + title={'Acquisition File'} + /> ( diff --git a/source/frontend/src/features/mapSideBar/shared/MapContentContainer.tsx b/source/frontend/src/features/mapSideBar/shared/MapContentContainer.tsx new file mode 100644 index 0000000000..6b2ca13880 --- /dev/null +++ b/source/frontend/src/features/mapSideBar/shared/MapContentContainer.tsx @@ -0,0 +1,114 @@ +import { FormikProps } from 'formik'; +import * as React from 'react'; +import { useCallback, useRef, useState } from 'react'; +import { useHistory, useLocation, useRouteMatch } from 'react-router-dom'; + +import { useQuery } from '@/hooks/use-query'; +import { Api_LastUpdatedBy } from '@/models/api/File'; + +import { IMapSidebarPopoutRouterProps } from '../context/popoutContext'; +import { IMapContentViewProps } from './MapContentView'; +import { ISidebarFooterProps } from './SidebarFooter'; + +interface IMapContentContainerProps { + View: React.FunctionComponent>; + Header: React.FunctionComponent>; + Footer: React.FunctionComponent; + PopupRouter: React.FunctionComponent>; + onClose: (() => void) | undefined; + title: React.ReactNode; + icon: React.ReactNode | React.FunctionComponent>; +} + +export interface IHeaderContainerProps { + lastUpdatedBy: Api_LastUpdatedBy | null; + onClose: (() => void) | undefined; +} + +export interface IBodyContainerProps { + formikRef: React.RefObject>; +} + +export interface IFooterContainerProps { + formikRef: React.RefObject>; + onSave: () => Promise; + onCancel: () => void; +} + +export const MapContentContainer: React.FunctionComponent< + React.PropsWithChildren +> = ({ View, Header, Footer, PopupRouter, title, icon, onClose, ...props }) => { + const formikRef = useRef>(null); + const [isValid, setIsValid] = useState(true); + const [showConfirmModal, setShowConfirmModal] = useState(false); + + const location = useLocation(); + const history = useHistory(); + const match = useRouteMatch(); + const query = useQuery(); + const isEditing = query.get('edit') === 'true'; + + const setIsEditing = (value: boolean) => { + if (value) { + query.set('edit', value.toString()); + } else { + query.delete('edit'); + } + history.push({ search: query.toString() }); + }; + + const handleSaveClick = async () => { + await formikRef?.current?.validateForm(); + if (!formikRef?.current?.isValid) { + setIsValid(false); + } else { + setIsValid(true); + } + + if (formikRef !== undefined) { + formikRef.current?.setSubmitting(true); + formikRef.current?.submitForm(); + } + }; + + const handleCancelClick = () => { + if (formikRef !== undefined) { + if (formikRef.current?.dirty) { + setShowConfirmModal(true); + } else { + handleCancelConfirm(); + } + } else { + handleCancelConfirm(); + } + }; + + const handleCancelConfirm = () => { + if (formikRef !== undefined) { + formikRef.current?.resetForm(); + } + setShowConfirmModal(false); + setIsEditing(false); + }; + + const close = useCallback(() => onClose && onClose(), [onClose]); + + return ( + + {props.children} + + ); +}; + +export default MapContentContainer; diff --git a/source/frontend/src/features/mapSideBar/shared/MapContentView.tsx b/source/frontend/src/features/mapSideBar/shared/MapContentView.tsx new file mode 100644 index 0000000000..443f7777ba --- /dev/null +++ b/source/frontend/src/features/mapSideBar/shared/MapContentView.tsx @@ -0,0 +1,51 @@ +import { FormikProps } from 'formik'; +import * as React from 'react'; +import { useContext } from 'react'; + +import { SideBarContext } from '../context/sidebarContext'; +import MapSideBarLayout from '../layout/MapSideBarLayout'; +import { IHeaderContainerProps } from './MapContentContainer'; +import { ISidebarFooterProps } from './SidebarFooter'; + +export interface IMapContentViewProps { + title: React.ReactNode; + Header: React.FunctionComponent>; + Footer: React.FunctionComponent>; + icon: React.ReactNode | React.FunctionComponent>; + isEditing: boolean; + formikRef: React.RefObject>; + isFormValid: boolean; + onClose: (() => void) | undefined; + onSave: () => Promise; + onCancel: () => void; +} + +export const MapContentView: React.FunctionComponent = ({ + Header, + Footer, + title, + icon, + isEditing, + formikRef, + isFormValid, + onClose, + onCancel, + onSave, +}) => { + const { file, lastUpdatedBy } = useContext(SideBarContext); + + return ( + } + footer={ + isEditing && ( +