Improve navigation handling in new map app
This commit is contained in:
parent
305f2f1671
commit
2afc7f8c8f
@ -129,7 +129,7 @@ export const categoryMapsConfig: {[key in Category]: CategoryMapDefinition} = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
[Category.Sustainability]: {
|
[Category.Sustainability]: {
|
||||||
mapStyle: 'sust_Dec',
|
mapStyle: 'sust_dec',
|
||||||
legend: {
|
legend: {
|
||||||
title: 'Sustainability',
|
title: 'Sustainability',
|
||||||
description: 'DEC Rating',
|
description: 'DEC Rating',
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { Building } from '../models/building';
|
import { Building, BuildingAttributeVerificationCounts } from '../models/building';
|
||||||
import { apiGet } from '../apiHelpers';
|
import { apiGet } from '../apiHelpers';
|
||||||
|
|
||||||
export function useBuildingData(buildingId: number, preloadedData: Building): [Building, (updatedBuilding: Building) => void, () => void] {
|
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);
|
setIsOld(false);
|
||||||
}, [buildingId]);
|
}, [buildingId]);
|
||||||
|
|
||||||
|
const updateData = useCallback((building: Building) => {
|
||||||
|
if(building.verified == undefined) {
|
||||||
|
building.verified = {} as BuildingAttributeVerificationCounts;
|
||||||
|
}
|
||||||
|
setBuildingData(building);
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
setIsOld(true);
|
setIsOld(true);
|
||||||
@ -43,5 +50,5 @@ export function useBuildingData(buildingId: number, preloadedData: Building): [B
|
|||||||
|
|
||||||
const reloadData = useCallback(() => setIsOld(true), []);
|
const reloadData = useCallback(() => setIsOld(true), []);
|
||||||
|
|
||||||
return [buildingData, setBuildingData, reloadData];
|
return [buildingData, updateData, reloadData];
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
import { usePrevious } from './use-previous';
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
export function useLastNotEmpty<T>(value: T): T {
|
export function useLastNotEmpty<T>(value: T): T {
|
||||||
const previousValue = usePrevious(value);
|
const [notEmpty, setNotEmpty] = useState(value);
|
||||||
|
useEffect(() => {
|
||||||
|
if(value != undefined) {
|
||||||
|
setNotEmpty(value);
|
||||||
|
}
|
||||||
|
}, [value]);
|
||||||
|
|
||||||
return value ?? previousValue;
|
return notEmpty;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
import { useEffect, useRef } from 'react';
|
|
||||||
|
|
||||||
export function usePrevious<T>(value: T) {
|
|
||||||
const ref = useRef<T>();
|
|
||||||
useEffect(() => {
|
|
||||||
ref.current = value;
|
|
||||||
});
|
|
||||||
|
|
||||||
return ref.current;
|
|
||||||
}
|
|
@ -46,30 +46,32 @@ function setOrToggle<T>(currentValue: T, newValue: T): T {
|
|||||||
|
|
||||||
export const MapApp: React.FC<MapAppProps> = props => {
|
export const MapApp: React.FC<MapAppProps> = props => {
|
||||||
const [categoryUrlParam] = useUrlCategoryParam();
|
const [categoryUrlParam] = useUrlCategoryParam();
|
||||||
const [selectedBuildingId, setSelectedBuildingId] = useUrlBuildingParam();
|
|
||||||
const [mode] = useUrlModeParam();
|
|
||||||
|
|
||||||
const [currentCategory, setCategory] = useState<Category>();
|
const [currentCategory, setCategory] = useState<Category>();
|
||||||
useEffect(() => setCategory(unless(categoryUrlParam, 'categories')), [categoryUrlParam]);
|
useEffect(() => setCategory(unless(categoryUrlParam, 'categories')), [categoryUrlParam]);
|
||||||
|
|
||||||
const displayCategory = useLastNotEmpty(currentCategory) ?? defaultMapCategory;
|
const displayCategory = useLastNotEmpty(currentCategory) ?? defaultMapCategory;
|
||||||
|
|
||||||
|
const [selectedBuildingId, setSelectedBuildingId] = useUrlBuildingParam('view', displayCategory);
|
||||||
|
|
||||||
const [building, updateBuilding, reloadBuilding] = useBuildingData(selectedBuildingId, props.building);
|
const [building, updateBuilding, reloadBuilding] = useBuildingData(selectedBuildingId, props.building);
|
||||||
const [buildingLike, updateBuildingLike] = useBuildingLikeData(selectedBuildingId, props.building_like);
|
const [buildingLike, updateBuildingLike] = useBuildingLikeData(selectedBuildingId, props.building_like);
|
||||||
const [userVerified, updateUserVerified, reloadUserVerified] = useUserVerifiedData(selectedBuildingId, props.user_verified);
|
const [userVerified, updateUserVerified, reloadUserVerified] = useUserVerifiedData(selectedBuildingId, props.user_verified);
|
||||||
|
|
||||||
const [revisionId, updateRevisionId] = useRevisionId(props.revisionId);
|
const [revisionId, updateRevisionId] = useRevisionId(props.revisionId);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
updateRevisionId(building?.revision_id)
|
updateRevisionId(building?.revision_id)
|
||||||
}, [building]);
|
}, [building]);
|
||||||
|
|
||||||
|
const [mode] = useUrlModeParam();
|
||||||
const viewEditMode = unless(mode, 'multi-edit');
|
const viewEditMode = unless(mode, 'multi-edit');
|
||||||
|
|
||||||
const [multiEditData, multiEditError] = useMultiEditData();
|
const [multiEditData, multiEditError] = useMultiEditData();
|
||||||
|
|
||||||
const selectBuilding = useCallback((selectedBuilding: Building) => {
|
const selectBuilding = useCallback((selectedBuilding: Building) => {
|
||||||
updateBuilding(Object.assign({}, building, selectedBuilding));
|
const currentId = selectedBuildingId;
|
||||||
setSelectedBuildingId(setOrToggle(selectedBuildingId, selectedBuilding?.building_id));
|
updateBuilding(selectedBuilding);
|
||||||
|
setSelectedBuildingId(setOrToggle(currentId, selectedBuilding?.building_id));
|
||||||
}, [selectedBuildingId, setSelectedBuildingId, updateBuilding, building]);
|
}, [selectedBuildingId, setSelectedBuildingId, updateBuilding, building]);
|
||||||
|
|
||||||
const colourBuilding = useCallback(async (building: Building) => {
|
const colourBuilding = useCallback(async (building: Building) => {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
import { Category } from '../config/categories-config';
|
||||||
import { intParamTransform } from './url-param-transform';
|
import { intParamTransform } from './url-param-transform';
|
||||||
import { useUrlParam } from './use-url-param';
|
import { useUrlParam } from './use-url-param';
|
||||||
|
|
||||||
export function useUrlBuildingParam() {
|
export function useUrlBuildingParam(defaultMode: 'view' | 'edit' | 'multi-edit', defaultCategory: Category | 'categories' = 'categories') {
|
||||||
return useUrlParam('building', intParamTransform);
|
return useUrlParam('building', intParamTransform, '/:mode/:category/:building?', {mode: defaultMode, category: defaultCategory});
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,9 @@ import { UrlParamTransform } from './url-param-transform';
|
|||||||
|
|
||||||
export function useUrlParam<T>(
|
export function useUrlParam<T>(
|
||||||
param: string,
|
param: string,
|
||||||
paramTransform: UrlParamTransform<T>
|
paramTransform: UrlParamTransform<T>,
|
||||||
|
pathPattern?: string,
|
||||||
|
defaultParams: { [key: string]: string} = {}
|
||||||
): [T, (newParam: T) => void] {
|
): [T, (newParam: T) => void] {
|
||||||
const match = useRouteMatch();
|
const match = useRouteMatch();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
@ -19,15 +21,12 @@ export function useUrlParam<T>(
|
|||||||
}, [param, paramTransform, match.url]);
|
}, [param, paramTransform, match.url]);
|
||||||
|
|
||||||
const setUrlParam = useCallback((value: T) => {
|
const setUrlParam = useCallback((value: T) => {
|
||||||
const stringValue = value == undefined ? '' : paramTransform.toParam(value);
|
const newParams = Object.assign({}, defaultParams, match.params);
|
||||||
const newPath = generatePath(match.path, {
|
newParams[param] = value == undefined ? undefined : paramTransform.toParam(value);
|
||||||
...match.params,
|
|
||||||
...{
|
const newPath = generatePath(pathPattern ?? match.path, newParams);
|
||||||
[param]: stringValue
|
|
||||||
}
|
|
||||||
});
|
|
||||||
history.push(newPath);
|
history.push(newPath);
|
||||||
}, [param, paramTransform, match.url]);
|
}, [param, paramTransform, pathPattern, defaultParams, match.url]);
|
||||||
|
|
||||||
return [paramValue, setUrlParam];
|
return [paramValue, setUrlParam];
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user