-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5ca8e92
commit 9cfa05c
Showing
9 changed files
with
294 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
source/frontend/src/features/mapSideBar/context/popoutContext.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import * as React from 'react'; | ||
import { useState } from 'react'; | ||
|
||
export interface IPopoutContext { | ||
showActionBar: boolean; | ||
setShowActionBar: (showActionBar: boolean) => void; | ||
RouterComponent: React.FunctionComponent<IMapSidebarPopoutRouterProps> | null; | ||
setRouterComponent: ( | ||
routerComponent: React.FunctionComponent<IMapSidebarPopoutRouterProps>, | ||
) => void; | ||
popoutUpdated: boolean; | ||
setPopoutUpdated: (popoutUpdated: boolean) => void; | ||
} | ||
|
||
export interface IMapSidebarPopoutRouterProps { | ||
setShowActionBar: (showActionBar: boolean) => void; | ||
onUpdate: () => void; | ||
} | ||
|
||
export const PopoutContext = React.createContext<IPopoutContext>({ | ||
showActionBar: false, | ||
setShowActionBar: (showActionBar: boolean) => { | ||
throw Error('setShowActionBar function not defined'); | ||
}, | ||
RouterComponent: null, | ||
setRouterComponent: (routerComponent: React.FunctionComponent<IMapSidebarPopoutRouterProps>) => { | ||
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<React.FunctionComponent<IMapSidebarPopoutRouterProps> | null>(null); | ||
|
||
return ( | ||
<PopoutContext.Provider | ||
value={{ | ||
showActionBar: showActionBar, | ||
setShowActionBar: setShowActionBar, | ||
RouterComponent: RouterComponent, | ||
setRouterComponent: setRouterComponent, | ||
popoutUpdated: popoutUpdated, | ||
setPopoutUpdated: setPopoutUpdated, | ||
}} | ||
> | ||
{props.children} | ||
</PopoutContext.Provider> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
114 changes: 114 additions & 0 deletions
114
source/frontend/src/features/mapSideBar/shared/MapContentContainer.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<React.PropsWithChildren<IMapContentViewProps>>; | ||
Header: React.FunctionComponent<React.PropsWithChildren<IHeaderContainerProps>>; | ||
Footer: React.FunctionComponent<ISidebarFooterProps>; | ||
PopupRouter: React.FunctionComponent<React.PropsWithChildren<IMapSidebarPopoutRouterProps>>; | ||
onClose: (() => void) | undefined; | ||
title: React.ReactNode; | ||
icon: React.ReactNode | React.FunctionComponent<React.PropsWithChildren<unknown>>; | ||
} | ||
|
||
export interface IHeaderContainerProps { | ||
lastUpdatedBy: Api_LastUpdatedBy | null; | ||
onClose: (() => void) | undefined; | ||
} | ||
|
||
export interface IBodyContainerProps { | ||
formikRef: React.RefObject<FormikProps<any>>; | ||
} | ||
|
||
export interface IFooterContainerProps { | ||
formikRef: React.RefObject<FormikProps<any>>; | ||
onSave: () => Promise<void>; | ||
onCancel: () => void; | ||
} | ||
|
||
export const MapContentContainer: React.FunctionComponent< | ||
React.PropsWithChildren<IMapContentContainerProps> | ||
> = ({ View, Header, Footer, PopupRouter, title, icon, onClose, ...props }) => { | ||
const formikRef = useRef<FormikProps<any>>(null); | ||
const [isValid, setIsValid] = useState<boolean>(true); | ||
const [showConfirmModal, setShowConfirmModal] = useState<boolean>(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 ( | ||
<View | ||
title={title} | ||
icon={icon} | ||
Header={Header} | ||
Footer={Footer} | ||
formikRef={formikRef} | ||
isEditing={isEditing} | ||
onCancel={handleCancelClick} | ||
onClose={close} | ||
onSave={handleSaveClick} | ||
isFormValid={isValid} | ||
> | ||
{props.children} | ||
</View> | ||
); | ||
}; | ||
|
||
export default MapContentContainer; |
51 changes: 51 additions & 0 deletions
51
source/frontend/src/features/mapSideBar/shared/MapContentView.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<React.PropsWithChildren<IHeaderContainerProps>>; | ||
Footer: React.FunctionComponent<React.PropsWithChildren<ISidebarFooterProps>>; | ||
icon: React.ReactNode | React.FunctionComponent<React.PropsWithChildren<unknown>>; | ||
isEditing: boolean; | ||
formikRef: React.RefObject<FormikProps<any>>; | ||
isFormValid: boolean; | ||
onClose: (() => void) | undefined; | ||
onSave: () => Promise<void>; | ||
onCancel: () => void; | ||
} | ||
|
||
export const MapContentView: React.FunctionComponent<IMapContentViewProps> = ({ | ||
Header, | ||
Footer, | ||
title, | ||
icon, | ||
isEditing, | ||
formikRef, | ||
isFormValid, | ||
onClose, | ||
onCancel, | ||
onSave, | ||
}) => { | ||
const { file, lastUpdatedBy } = useContext(SideBarContext); | ||
|
||
return ( | ||
<MapSideBarLayout | ||
title={title} | ||
icon={icon} | ||
header={Header && <Header lastUpdatedBy={lastUpdatedBy} onClose={onClose} />} | ||
footer={ | ||
isEditing && ( | ||
<Footer onCancel={onCancel} onSave={onSave} displayRequiredFieldError={isFormValid} /> | ||
) | ||
} | ||
></MapSideBarLayout> | ||
); | ||
}; | ||
|
||
export default MapContentView; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.