From 2afc7f8c8f297600bc016c431c0a9f6ebd677a99 Mon Sep 17 00:00:00 2001 From: Maciej Ziarkowski Date: Wed, 24 Feb 2021 07:48:09 +0000 Subject: [PATCH] Improve navigation handling in new map app --- .../frontend/config/category-maps-config.ts | 2 +- app/src/frontend/hooks/use-building-data.ts | 11 +++++++++-- app/src/frontend/hooks/use-last-not-empty.ts | 12 ++++++++---- app/src/frontend/hooks/use-previous.ts | 10 ---------- app/src/frontend/map-app.tsx | 18 ++++++++++-------- app/src/frontend/nav/use-url-building-param.ts | 5 +++-- app/src/frontend/nav/use-url-param.ts | 17 ++++++++--------- 7 files changed, 39 insertions(+), 36 deletions(-) delete mode 100644 app/src/frontend/hooks/use-previous.ts diff --git a/app/src/frontend/config/category-maps-config.ts b/app/src/frontend/config/category-maps-config.ts index 637346b3..4261a685 100644 --- a/app/src/frontend/config/category-maps-config.ts +++ b/app/src/frontend/config/category-maps-config.ts @@ -129,7 +129,7 @@ export const categoryMapsConfig: {[key in Category]: CategoryMapDefinition} = { }, }, [Category.Sustainability]: { - mapStyle: 'sust_Dec', + mapStyle: 'sust_dec', legend: { title: 'Sustainability', description: 'DEC Rating', diff --git a/app/src/frontend/hooks/use-building-data.ts b/app/src/frontend/hooks/use-building-data.ts index 3c8ff7a9..8b2fc295 100644 --- a/app/src/frontend/hooks/use-building-data.ts +++ b/app/src/frontend/hooks/use-building-data.ts @@ -1,6 +1,6 @@ import { useCallback, useEffect, useState } from 'react'; -import { Building } from '../models/building'; +import { Building, BuildingAttributeVerificationCounts } from '../models/building'; import { apiGet } from '../apiHelpers'; export function useBuildingData(buildingId: number, preloadedData: Building): [Building, (updatedBuilding: Building) => void, () => void] { @@ -29,6 +29,13 @@ export function useBuildingData(buildingId: number, preloadedData: Building): [B setIsOld(false); }, [buildingId]); + const updateData = useCallback((building: Building) => { + if(building.verified == undefined) { + building.verified = {} as BuildingAttributeVerificationCounts; + } + setBuildingData(building); + }, []); + useEffect(() => { return () => { setIsOld(true); @@ -43,5 +50,5 @@ export function useBuildingData(buildingId: number, preloadedData: Building): [B const reloadData = useCallback(() => setIsOld(true), []); - return [buildingData, setBuildingData, reloadData]; + return [buildingData, updateData, reloadData]; } diff --git a/app/src/frontend/hooks/use-last-not-empty.ts b/app/src/frontend/hooks/use-last-not-empty.ts index de577f88..228acfe0 100644 --- a/app/src/frontend/hooks/use-last-not-empty.ts +++ b/app/src/frontend/hooks/use-last-not-empty.ts @@ -1,7 +1,11 @@ -import { usePrevious } from './use-previous'; - +import { useEffect, useState } from 'react'; export function useLastNotEmpty(value: T): T { - const previousValue = usePrevious(value); + const [notEmpty, setNotEmpty] = useState(value); + useEffect(() => { + if(value != undefined) { + setNotEmpty(value); + } + }, [value]); - return value ?? previousValue; + return notEmpty; } diff --git a/app/src/frontend/hooks/use-previous.ts b/app/src/frontend/hooks/use-previous.ts deleted file mode 100644 index 4f32cd66..00000000 --- a/app/src/frontend/hooks/use-previous.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { useEffect, useRef } from 'react'; - -export function usePrevious(value: T) { - const ref = useRef(); - useEffect(() => { - ref.current = value; - }); - - return ref.current; -} \ No newline at end of file diff --git a/app/src/frontend/map-app.tsx b/app/src/frontend/map-app.tsx index 24d704f4..f4fd3b20 100644 --- a/app/src/frontend/map-app.tsx +++ b/app/src/frontend/map-app.tsx @@ -46,30 +46,32 @@ function setOrToggle(currentValue: T, newValue: T): T { export const MapApp: React.FC = props => { const [categoryUrlParam] = useUrlCategoryParam(); - const [selectedBuildingId, setSelectedBuildingId] = useUrlBuildingParam(); - const [mode] = useUrlModeParam(); const [currentCategory, setCategory] = useState(); useEffect(() => setCategory(unless(categoryUrlParam, 'categories')), [categoryUrlParam]); - + const displayCategory = useLastNotEmpty(currentCategory) ?? defaultMapCategory; - + + const [selectedBuildingId, setSelectedBuildingId] = useUrlBuildingParam('view', displayCategory); + const [building, updateBuilding, reloadBuilding] = useBuildingData(selectedBuildingId, props.building); const [buildingLike, updateBuildingLike] = useBuildingLikeData(selectedBuildingId, props.building_like); const [userVerified, updateUserVerified, reloadUserVerified] = useUserVerifiedData(selectedBuildingId, props.user_verified); - + const [revisionId, updateRevisionId] = useRevisionId(props.revisionId); useEffect(() => { updateRevisionId(building?.revision_id) }, [building]); - + + const [mode] = useUrlModeParam(); const viewEditMode = unless(mode, 'multi-edit'); const [multiEditData, multiEditError] = useMultiEditData(); const selectBuilding = useCallback((selectedBuilding: Building) => { - updateBuilding(Object.assign({}, building, selectedBuilding)); - setSelectedBuildingId(setOrToggle(selectedBuildingId, selectedBuilding?.building_id)); + const currentId = selectedBuildingId; + updateBuilding(selectedBuilding); + setSelectedBuildingId(setOrToggle(currentId, selectedBuilding?.building_id)); }, [selectedBuildingId, setSelectedBuildingId, updateBuilding, building]); const colourBuilding = useCallback(async (building: Building) => { diff --git a/app/src/frontend/nav/use-url-building-param.ts b/app/src/frontend/nav/use-url-building-param.ts index 9a8e221c..1fe194f8 100644 --- a/app/src/frontend/nav/use-url-building-param.ts +++ b/app/src/frontend/nav/use-url-building-param.ts @@ -1,6 +1,7 @@ +import { Category } from '../config/categories-config'; import { intParamTransform } from './url-param-transform'; import { useUrlParam } from './use-url-param'; -export function useUrlBuildingParam() { - return useUrlParam('building', intParamTransform); +export function useUrlBuildingParam(defaultMode: 'view' | 'edit' | 'multi-edit', defaultCategory: Category | 'categories' = 'categories') { + return useUrlParam('building', intParamTransform, '/:mode/:category/:building?', {mode: defaultMode, category: defaultCategory}); } diff --git a/app/src/frontend/nav/use-url-param.ts b/app/src/frontend/nav/use-url-param.ts index b44dbb5d..c032ba2c 100644 --- a/app/src/frontend/nav/use-url-param.ts +++ b/app/src/frontend/nav/use-url-param.ts @@ -5,7 +5,9 @@ import { UrlParamTransform } from './url-param-transform'; export function useUrlParam( param: string, - paramTransform: UrlParamTransform + paramTransform: UrlParamTransform, + pathPattern?: string, + defaultParams: { [key: string]: string} = {} ): [T, (newParam: T) => void] { const match = useRouteMatch(); const history = useHistory(); @@ -19,15 +21,12 @@ export function useUrlParam( }, [param, paramTransform, match.url]); const setUrlParam = useCallback((value: T) => { - const stringValue = value == undefined ? '' : paramTransform.toParam(value); - const newPath = generatePath(match.path, { - ...match.params, - ...{ - [param]: stringValue - } - }); + const newParams = Object.assign({}, defaultParams, match.params); + newParams[param] = value == undefined ? undefined : paramTransform.toParam(value); + + const newPath = generatePath(pathPattern ?? match.path, newParams); history.push(newPath); - }, [param, paramTransform, match.url]); + }, [param, paramTransform, pathPattern, defaultParams, match.url]); return [paramValue, setUrlParam]; }