Lift map colour scale context up into MapApp

This commit is contained in:
Maciej Ziarkowski 2022-12-08 13:24:22 +00:00 committed by Mateusz Konieczny
parent ed0f0c7d69
commit f6c0d3fd4b
2 changed files with 28 additions and 16 deletions

View File

@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useState } from 'react';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { Redirect, Route, Switch } from 'react-router-dom';
import loadable from '@loadable/component';
@ -18,7 +18,8 @@ import Welcome from './pages/welcome';
import { PrivateRoute } from './route';
import { useLastNotEmpty } from './hooks/use-last-not-empty';
import { Category } from './config/categories-config';
import { defaultMapCategory } from './config/category-maps-config';
import { BuildingMapTileset } from './config/tileserver-config';
import { defaultMapCategory, categoryMapsConfig } from './config/category-maps-config';
import { useMultiEditData } from './hooks/use-multi-edit-data';
import { useAuth } from './auth-context';
import { sendBuildingUpdate } from './api-data/building-update';
@ -59,6 +60,15 @@ function setOrToggle<T>(currentValue: T, newValue: T): T {
}
}
function useStateWithOptions<T>(defaultValue: T, options: T[]): [T, (x: T) => void] {
const [value, setValue] = useState(defaultValue);
const effectiveValue = options.includes(value) ? value : options[0];
const handleChange = useCallback((x) => setValue(x), []);
return [effectiveValue, handleChange];
}
export const MapApp: React.FC<MapAppProps> = props => {
const { user } = useAuth();
const [categoryUrlParam] = useUrlCategoryParam();
@ -121,6 +131,11 @@ export const MapApp: React.FC<MapAppProps> = props => {
}
}, [selectedBuildingId, updateUserVerified, reloadBuilding, userVerified]);
const categoryMapDefinitions = useMemo(() => categoryMapsConfig[displayCategory], [displayCategory]);
const availableMapStyles = useMemo(() => categoryMapDefinitions.map(x => x.mapStyle), [categoryMapDefinitions]);
const [mapColourScale, setMapColourScale] = useStateWithOptions<BuildingMapTileset>(undefined, availableMapStyles);
return (
<>
<PrivateRoute path="/:mode(edit|multi-edit)" /> {/* empty private route to ensure auth for editing */}
@ -158,9 +173,11 @@ export const MapApp: React.FC<MapAppProps> = props => {
<ColouringMap
selectedBuildingId={selectedBuildingId}
mode={mode || 'basic'}
category={displayCategory}
revisionId={revisionId}
onBuildingAction={mode === 'multi-edit' ? colourBuilding : selectBuilding}
mapColourScale={mapColourScale}
onMapColourScale={setMapColourScale}
categoryMapDefinitions={categoryMapDefinitions}
/>
</>
);

View File

@ -6,7 +6,6 @@ import './map.css';
import { apiGet } from '../apiHelpers';
import { HelpIcon } from '../components/icons';
import { categoryMapsConfig } from '../config/category-maps-config';
import { Category } from '../config/categories-config';
import { initialMapViewport, mapBackgroundColor, MapTheme, LayerEnablementState } from '../config/map-config';
@ -41,21 +40,26 @@ import { CreativeSwitcher } from './creative-switcher';
import { HousingSwitcher } from './housing-switcher';
import { BuildingMapTileset } from '../config/tileserver-config';
import { useDisplayPreferences } from '../displayPreferences-context';
import { CategoryMapDefinition } from '../config/category-maps-config';
interface ColouringMapProps {
selectedBuildingId: number;
mode: 'basic' | 'view' | 'edit' | 'multi-edit';
category: Category;
revisionId: string;
onBuildingAction: (building: Building) => void;
mapColourScale: BuildingMapTileset;
onMapColourScale: (x: BuildingMapTileset) => void;
categoryMapDefinitions: CategoryMapDefinition[]
}
export const ColouringMap : FC<ColouringMapProps> = ({
category,
mode,
revisionId,
onBuildingAction,
selectedBuildingId,
mapColourScale,
onMapColourScale,
categoryMapDefinitions,
children
}) => {
const { darkLightTheme, darkLightThemeSwitch } = useDisplayPreferences();
@ -63,7 +67,6 @@ export const ColouringMap : FC<ColouringMapProps> = ({
const [position, setPosition] = useState(initialMapViewport.position);
const [zoom, setZoom] = useState(initialMapViewport.zoom);
const [mapColourScale, setMapColourScale] = useState<BuildingMapTileset>();
const handleLocate = useCallback(
(lat: number, lng: number, zoom: number) => {
@ -92,14 +95,6 @@ export const ColouringMap : FC<ColouringMapProps> = ({
[dataLayers],
)
const categoryMapDefinitions = useMemo(() => categoryMapsConfig[category], [category]);
useEffect(() => {
if(!categoryMapDefinitions.some(def => def.mapStyle === mapColourScale)) {
setMapColourScale(categoryMapDefinitions[0].mapStyle);
}
}, [categoryMapDefinitions, mapColourScale]);
const hasSelection = selectedBuildingId != undefined;
const isEdit = ['edit', 'multi-edit'].includes(mode);
@ -170,7 +165,7 @@ export const ColouringMap : FC<ColouringMapProps> = ({
<HelpIcon /> {isEdit ? 'Click a building to edit' : 'Click a building for details'}
</div>
}
<Legend mapColourScaleDefinitions={categoryMapDefinitions} mapColourScale={mapColourScale} onMapColourScale={setMapColourScale}/>
<Legend mapColourScaleDefinitions={categoryMapDefinitions} mapColourScale={mapColourScale} onMapColourScale={onMapColourScale}/>
<ThemeSwitcher onSubmit={darkLightThemeSwitch} currentTheme={darkLightTheme} />
<DataLayerSwitcher onSubmit={layerSwitch} currentDisplay={dataLayers} />
{