add useContext to allow changing display state from two places
- buttons on the map - sidebar buttons
This commit is contained in:
parent
38c75ac1a3
commit
e885d758dc
@ -6,6 +6,7 @@ import './app.css';
|
||||
|
||||
import { AuthRoute, PrivateRoute } from './route';
|
||||
import { AuthProvider } from './auth-context';
|
||||
import { DisplayPreferencesProvider } from './displayPreferences-context';
|
||||
import { Header } from './header';
|
||||
import { MapApp } from './map-app';
|
||||
import { Building, UserVerified } from './models/building';
|
||||
@ -53,41 +54,43 @@ export const App: React.FC<AppProps> = props => {
|
||||
const mapAppPaths = ['/', '/:mode(view|edit|multi-edit)/:category/:building(\\d+)?/(history)?'];
|
||||
|
||||
return (
|
||||
<AuthProvider preloadedUser={props.user}>
|
||||
<Switch>
|
||||
<Route exact path={mapAppPaths}>
|
||||
<Header animateLogo={false} />
|
||||
</Route>
|
||||
<Route>
|
||||
<Header animateLogo={true} />
|
||||
</Route>
|
||||
</Switch>
|
||||
<Switch>
|
||||
<Route exact path="/about.html" component={AboutPage} />
|
||||
<AuthRoute exact path="/login.html" component={Login} />
|
||||
<AuthRoute exact path="/forgotten-password.html" component={ForgottenPassword} />
|
||||
<AuthRoute exact path="/password-reset.html" component={PasswordReset} />
|
||||
<AuthRoute exact path="/sign-up.html" component={SignUp} />
|
||||
<PrivateRoute exact path="/my-account.html" component={MyAccountPage} />
|
||||
<Route exact path="/privacy-policy.html" component={PrivacyPolicyPage} />
|
||||
<Route exact path="/contributor-agreement.html" component={ContributorAgreementPage} />
|
||||
<Route exact path="/ordnance-survey-licence.html" component={OrdnanceSurveyLicencePage} />
|
||||
<Route exact path="/ordnance-survey-uprn.html" component={OrdnanceSurveyUprnPage} />
|
||||
<Route exact path="/data-accuracy.html" component={DataAccuracyPage} />
|
||||
<Route exact path="/data-extracts.html" component={DataExtracts} />
|
||||
<Route exact path="/contact.html" component={ContactPage} />
|
||||
<Route exact path="/code-of-conduct.html" component={CodeOfConductPage} />
|
||||
<Route exact path="/leaderboard.html" component={LeaderboardPage} />
|
||||
<Route exact path="/history.html" component={ChangesPage} />
|
||||
<Route exact path={mapAppPaths} >
|
||||
<MapApp
|
||||
building={props.building}
|
||||
user_verified={props.user_verified}
|
||||
revisionId={props.revisionId}
|
||||
/>
|
||||
</Route>
|
||||
<Route component={NotFound} />
|
||||
</Switch>
|
||||
</AuthProvider>
|
||||
<DisplayPreferencesProvider>
|
||||
<AuthProvider preloadedUser={props.user}>
|
||||
<Switch>
|
||||
<Route exact path={mapAppPaths}>
|
||||
<Header animateLogo={false} />
|
||||
</Route>
|
||||
<Route>
|
||||
<Header animateLogo={true} />
|
||||
</Route>
|
||||
</Switch>
|
||||
<Switch>
|
||||
<Route exact path="/about.html" component={AboutPage} />
|
||||
<AuthRoute exact path="/login.html" component={Login} />
|
||||
<AuthRoute exact path="/forgotten-password.html" component={ForgottenPassword} />
|
||||
<AuthRoute exact path="/password-reset.html" component={PasswordReset} />
|
||||
<AuthRoute exact path="/sign-up.html" component={SignUp} />
|
||||
<PrivateRoute exact path="/my-account.html" component={MyAccountPage} />
|
||||
<Route exact path="/privacy-policy.html" component={PrivacyPolicyPage} />
|
||||
<Route exact path="/contributor-agreement.html" component={ContributorAgreementPage} />
|
||||
<Route exact path="/ordnance-survey-licence.html" component={OrdnanceSurveyLicencePage} />
|
||||
<Route exact path="/ordnance-survey-uprn.html" component={OrdnanceSurveyUprnPage} />
|
||||
<Route exact path="/data-accuracy.html" component={DataAccuracyPage} />
|
||||
<Route exact path="/data-extracts.html" component={DataExtracts} />
|
||||
<Route exact path="/contact.html" component={ContactPage} />
|
||||
<Route exact path="/code-of-conduct.html" component={CodeOfConductPage} />
|
||||
<Route exact path="/leaderboard.html" component={LeaderboardPage} />
|
||||
<Route exact path="/history.html" component={ChangesPage} />
|
||||
<Route exact path={mapAppPaths} >
|
||||
<MapApp
|
||||
building={props.building}
|
||||
user_verified={props.user_verified}
|
||||
revisionId={props.revisionId}
|
||||
/>
|
||||
</Route>
|
||||
<Route component={NotFound} />
|
||||
</Switch>
|
||||
</AuthProvider>
|
||||
</DisplayPreferencesProvider>
|
||||
);
|
||||
};
|
||||
|
@ -58,6 +58,7 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({
|
||||
const [userError, setUserError] = useState<string>(undefined);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
|
||||
const login = useCallback(async (data: UserLoginData, cb: (err) => void = noop) => {
|
||||
if(isAuthenticated) {
|
||||
return;
|
||||
@ -199,7 +200,7 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({
|
||||
logout,
|
||||
signup,
|
||||
generateApiKey,
|
||||
deleteAccount
|
||||
deleteAccount,
|
||||
}}>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
|
@ -9,12 +9,12 @@
|
||||
.map-switcher-inline {
|
||||
border-radius: 4px;
|
||||
}
|
||||
.map-switcher-inline .btn {
|
||||
.map-switcher-inline {
|
||||
background: #FFC0CB;
|
||||
margin: 0;
|
||||
min-width: 280px;
|
||||
}
|
||||
.map-switcher-inline.night .btn {
|
||||
.map-switcher-inline.night {
|
||||
background: #FFC0CB;
|
||||
color: #fff;
|
||||
background-color: #343a40;
|
||||
|
@ -15,9 +15,9 @@ import SelectDataEntry from '../data-components/select-data-entry';
|
||||
import Verification from '../data-components/verification';
|
||||
import withCopyEdit from '../data-container';
|
||||
import PlanningDataOfficialDataEntry from '../data-components/planning-data-entry';
|
||||
|
||||
import { CategoryViewProps } from './category-view-props';
|
||||
import { Category } from '../../config/categories-config';
|
||||
import { useDisplayPreferences } from '../../displayPreferences-context';
|
||||
|
||||
const currentTimestamp = new Date().valueOf();
|
||||
const milisecondsInYear = 1000 * 60 * 60 * 24 * 365;
|
||||
@ -48,6 +48,7 @@ function isArchived(item) {
|
||||
}
|
||||
|
||||
const PlanningView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
||||
const { flood, floodSwitchOnClick, housing, housingSwitchOnClick, creative, creativeSwitchOnClick, vista, vistaSwitchOnClick } = useDisplayPreferences();
|
||||
const communityLinkUrl = `/${props.mode}/${Category.Community}/${props.building.building_id}`;
|
||||
return (
|
||||
<Fragment>
|
||||
@ -121,12 +122,6 @@ const PlanningView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
||||
/>
|
||||
</DataEntryGroup>
|
||||
<DataEntryGroup name="Possible future applications (crowdsourced data)" collapsed={true} >
|
||||
<form className={`map-switcher-inline`}>
|
||||
<button className="btn btn-outline btn-outline-dark"
|
||||
type="submit">
|
||||
Click to see the data mapped
|
||||
</button>
|
||||
</form>
|
||||
<UserOpinionEntry
|
||||
slug='community_expected_planning_application'
|
||||
title={buildingUserFields.community_expected_planning_application.title}
|
||||
@ -149,56 +144,37 @@ const PlanningView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
||||
value={null}
|
||||
disabled={true}
|
||||
/>
|
||||
{
|
||||
<form className={`map-switcher-inline`}>
|
||||
<button className="btn btn-outline btn-outline-dark"
|
||||
type="submit">
|
||||
Click to see the data mapped
|
||||
</button>
|
||||
</form>
|
||||
}
|
||||
<button className="map-switcher-inline btn btn-outline btn-outline-dark" onClick={floodSwitchOnClick}>
|
||||
{(flood === 'enabled')? 'Click to hide overlay' : 'Click to see the data mapped'}
|
||||
</button>
|
||||
<LogicalDataEntry
|
||||
title="Is the building in a Housing Zone?"
|
||||
slug="planning_live_application"
|
||||
value={null}
|
||||
disabled={true}
|
||||
/>
|
||||
{
|
||||
<form className={`map-switcher-inline`}>
|
||||
<button className="btn btn-outline btn-outline-dark"
|
||||
type="submit">
|
||||
Click to see the data mapped
|
||||
</button>
|
||||
</form>
|
||||
}
|
||||
<button className="map-switcher-inline btn btn-outline btn-outline-dark" onClick={housingSwitchOnClick}>
|
||||
{(housing === 'enabled')? 'Click to hide overlay' : 'Click to see the data mapped'}
|
||||
</button>
|
||||
<LogicalDataEntry
|
||||
title="Is the building in a Creative Enterprise Zone?"
|
||||
slug="planning_live_application"
|
||||
value={null}
|
||||
disabled={true}
|
||||
/>
|
||||
{
|
||||
<form className={`map-switcher-inline`}>
|
||||
<button className="btn btn-outline btn-outline-dark"
|
||||
type="submit">
|
||||
Click to see the data mapped
|
||||
</button>
|
||||
</form>
|
||||
}
|
||||
<button className="map-switcher-inline btn btn-outline btn-outline-dark" onClick={creativeSwitchOnClick}>
|
||||
{(creative === 'enabled')? 'Click to hide overlay' : 'Click to see the data mapped'}
|
||||
</button>
|
||||
<LogicalDataEntry
|
||||
title="Is the building within a Protected Vista?"
|
||||
slug="planning_live_application"
|
||||
value={null}
|
||||
disabled={true}
|
||||
/>
|
||||
{
|
||||
<form className={`map-switcher-inline`}>
|
||||
<button className="btn btn-outline btn-outline-dark"
|
||||
type="submit">
|
||||
Click to see the data mapped
|
||||
</button>
|
||||
</form>
|
||||
}
|
||||
<br/>
|
||||
<button className="map-switcher-inline btn btn-outline btn-outline-dark" onClick={vistaSwitchOnClick}>
|
||||
{(vista === 'enabled')? 'Click to hide overlay' : 'Click to see the data mapped'}
|
||||
</button>
|
||||
{/*
|
||||
<DataEntry
|
||||
title={dataFields.planning_glher_url.title}
|
||||
|
@ -10,21 +10,7 @@ export const initialMapViewport: MapViewport = {
|
||||
|
||||
export type MapTheme = 'light' | 'night' | 'night_outlines';
|
||||
|
||||
export type BoroughEnablementState = 'enabled' | 'disabled';
|
||||
|
||||
export type ParcelEnablementState = 'enabled' | 'disabled';
|
||||
|
||||
export type FloodEnablementState = 'enabled' | 'disabled';
|
||||
|
||||
export type ConservationAreasEnablementState = 'enabled' | 'disabled';
|
||||
|
||||
export type HistoricDataEnablementState = 'enabled' | 'disabled';
|
||||
|
||||
export type VistaEnablementState = 'enabled' | 'disabled';
|
||||
|
||||
export type HousingEnablementState = 'enabled' | 'disabled';
|
||||
|
||||
export type CreativeEnablementState = 'enabled' | 'disabled';
|
||||
export type LayerEnablementState = 'enabled' | 'disabled';
|
||||
|
||||
export const mapBackgroundColor: Record<MapTheme, string> = {
|
||||
light: '#F0EEEB',
|
||||
|
160
app/src/frontend/displayPreferences-context.tsx
Normal file
160
app/src/frontend/displayPreferences-context.tsx
Normal file
@ -0,0 +1,160 @@
|
||||
import React, { createContext, useCallback, useContext, useEffect, useState } from 'react';
|
||||
|
||||
import { LayerEnablementState } from './config/map-config';
|
||||
|
||||
interface DisplayPreferencesContextState {
|
||||
vista: LayerEnablementState;
|
||||
vistaSwitch: (e: React.FormEvent<HTMLFormElement>) => void;
|
||||
vistaSwitchOnClick: React.MouseEventHandler<HTMLButtonElement>;
|
||||
|
||||
flood: LayerEnablementState;
|
||||
floodSwitch: (e: React.FormEvent<HTMLFormElement>) => void;
|
||||
floodSwitchOnClick: React.MouseEventHandler<HTMLButtonElement>;
|
||||
|
||||
creative: LayerEnablementState;
|
||||
creativeSwitch: (e: React.FormEvent<HTMLFormElement>) => void;
|
||||
creativeSwitchOnClick: React.MouseEventHandler<HTMLButtonElement>;
|
||||
|
||||
housing: LayerEnablementState;
|
||||
housingSwitch: (e: React.FormEvent<HTMLFormElement>) => void;
|
||||
housingSwitchOnClick: React.MouseEventHandler<HTMLButtonElement>;
|
||||
}
|
||||
|
||||
const stub = (): never => {
|
||||
throw new Error('DisplayPreferencesProvider not set up');
|
||||
};
|
||||
|
||||
export const DisplayPreferencesContext = createContext<DisplayPreferencesContextState>({
|
||||
vista: undefined,
|
||||
vistaSwitch: stub,
|
||||
vistaSwitchOnClick: undefined,
|
||||
|
||||
flood: undefined,
|
||||
floodSwitch: stub,
|
||||
floodSwitchOnClick: undefined,
|
||||
|
||||
creative: undefined,
|
||||
creativeSwitch: stub,
|
||||
creativeSwitchOnClick: undefined,
|
||||
|
||||
housing: undefined,
|
||||
housingSwitch: stub,
|
||||
housingSwitchOnClick: undefined,
|
||||
|
||||
/*
|
||||
conservation: undefined,
|
||||
conservationSwitch: stub,
|
||||
conservationSwitchOnClick: undefined,
|
||||
|
||||
parcel: undefined,
|
||||
parcelSwitch: stub,
|
||||
parcelSwitchOnClick: undefined,
|
||||
|
||||
borough: undefined,
|
||||
boroughSwitch: stub,
|
||||
boroughSwitchOnClick: undefined,
|
||||
not needed right now
|
||||
|
||||
historicData
|
||||
*/
|
||||
});
|
||||
|
||||
const noop = () => {};
|
||||
|
||||
export const DisplayPreferencesProvider: React.FC<{}> = ({children}) => {
|
||||
const [vista, setVista] = useState<LayerEnablementState>('disabled');
|
||||
const [flood, setFlood] = useState<LayerEnablementState>('disabled');
|
||||
const [creative, setCreative] = useState<LayerEnablementState>('disabled');
|
||||
const [housing, setHousing] = useState<LayerEnablementState>('disabled');
|
||||
|
||||
/*
|
||||
const [borough, setBorough] = useState<LayerEnablementState>('enabled');
|
||||
const [parcel, setParcel] = useState<LayerEnablementState>('disabled');
|
||||
const [conservation, setConservation] = useState<LayerEnablementState>('disabled');
|
||||
const [historicData, setHistoricData] = useState<LayerEnablementState>('disabled');
|
||||
*/
|
||||
|
||||
|
||||
const vistaSwitch = useCallback(
|
||||
(e) => {
|
||||
e.preventDefault();
|
||||
const newVista = (vista === 'enabled')? 'disabled' : 'enabled';
|
||||
setVista(newVista);
|
||||
},
|
||||
[vista],
|
||||
)
|
||||
|
||||
const vistaSwitchOnClick = (e) => {
|
||||
e.preventDefault();
|
||||
const newVista = (vista === 'enabled')? 'disabled' : 'enabled';
|
||||
setVista(newVista);
|
||||
}
|
||||
|
||||
const floodSwitch = useCallback(
|
||||
(e) => {
|
||||
e.preventDefault();
|
||||
const newFlood = (flood === 'enabled')? 'disabled' : 'enabled';
|
||||
setFlood(newFlood);
|
||||
},
|
||||
[flood],
|
||||
)
|
||||
|
||||
const floodSwitchOnClick = (e) => {
|
||||
e.preventDefault();
|
||||
const newFlood = (flood === 'enabled')? 'disabled' : 'enabled';
|
||||
setFlood(newFlood);
|
||||
}
|
||||
|
||||
const housingSwitch = useCallback(
|
||||
(e) => {
|
||||
e.preventDefault();
|
||||
const newHousing = (housing === 'enabled')? 'disabled' : 'enabled';
|
||||
setHousing(newHousing);
|
||||
},
|
||||
[housing],
|
||||
)
|
||||
|
||||
const housingSwitchOnClick = (e) => {
|
||||
e.preventDefault();
|
||||
const newHousing = (housing === 'enabled')? 'disabled' : 'enabled';
|
||||
setHousing(newHousing);
|
||||
}
|
||||
|
||||
const creativeSwitch = useCallback(
|
||||
(e) => {
|
||||
e.preventDefault();
|
||||
const newCreative = (creative === 'enabled')? 'disabled' : 'enabled';
|
||||
setCreative(newCreative);
|
||||
},
|
||||
[creative],
|
||||
)
|
||||
|
||||
const creativeSwitchOnClick = (e) => {
|
||||
e.preventDefault();
|
||||
const newCreative = (creative === 'enabled')? 'disabled' : 'enabled';
|
||||
setCreative(newCreative);
|
||||
}
|
||||
|
||||
return (
|
||||
<DisplayPreferencesContext.Provider value={{
|
||||
vista,
|
||||
vistaSwitch,
|
||||
vistaSwitchOnClick,
|
||||
flood,
|
||||
floodSwitch,
|
||||
floodSwitchOnClick,
|
||||
creative,
|
||||
creativeSwitch,
|
||||
creativeSwitchOnClick,
|
||||
housing,
|
||||
housingSwitch,
|
||||
housingSwitchOnClick
|
||||
}}>
|
||||
{children}
|
||||
</DisplayPreferencesContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useDisplayPreferences = (): DisplayPreferencesContextState => {
|
||||
return useContext(DisplayPreferencesContext);
|
||||
};
|
@ -1,19 +1,20 @@
|
||||
import React from 'react';
|
||||
|
||||
import './creative-switcher.css';
|
||||
import { useDisplayPreferences } from '../displayPreferences-context';
|
||||
|
||||
interface CreativeSwitcherProps {
|
||||
currentDisplay: string;
|
||||
onSubmit: (e: React.FormEvent<HTMLFormElement>) => void;
|
||||
}
|
||||
|
||||
const CreativeSwitcherProps: React.FC<CreativeSwitcherProps> = (props) => (
|
||||
<form className={`creative-switcher ${props.currentDisplay}`} onSubmit={props.onSubmit}>
|
||||
<button className="btn btn-outline btn-outline-dark"
|
||||
type="submit">
|
||||
Creative Enterprise Zones display ({(props.currentDisplay === 'enabled')? 'Enabled' : 'Disabled'})
|
||||
</button>
|
||||
</form>
|
||||
);
|
||||
|
||||
const CreativeSwitcherProps: React.FC<CreativeSwitcherProps> = (props) => {
|
||||
const { creative, creativeSwitch } = useDisplayPreferences();
|
||||
return (
|
||||
<form className={`creative-switcher ${creative}`} onSubmit={creativeSwitch}>
|
||||
<button className="btn btn-outline btn-outline-dark"
|
||||
type="submit">
|
||||
Creative Enterprise Zones display ({(creative === 'enabled')? 'Enabled' : 'Disabled'})
|
||||
</button>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
export default CreativeSwitcherProps;
|
||||
|
@ -1,19 +1,20 @@
|
||||
import React from 'react';
|
||||
|
||||
import './flood-switcher.css';
|
||||
import { useDisplayPreferences } from '../displayPreferences-context';
|
||||
|
||||
interface FloodSwitcherProps {
|
||||
currentDisplay: string;
|
||||
onSubmit: (e: React.FormEvent<HTMLFormElement>) => void;
|
||||
}
|
||||
|
||||
const FloodSwitcherProps: React.FC<FloodSwitcherProps> = (props) => (
|
||||
<form className={`flood-switcher ${props.currentDisplay}`} onSubmit={props.onSubmit}>
|
||||
<button className="btn btn-outline btn-outline-dark"
|
||||
type="submit">
|
||||
Switch flood zone overlay ({(props.currentDisplay === 'enabled')? 'Enabled' : 'Disabled'})
|
||||
</button>
|
||||
</form>
|
||||
);
|
||||
|
||||
const FloodSwitcherProps: React.FC<FloodSwitcherProps> = (props) => {
|
||||
const { flood, floodSwitch } = useDisplayPreferences();
|
||||
return (
|
||||
<form className={`flood-switcher ${flood}`} onSubmit={floodSwitch}>
|
||||
<button className="btn btn-outline btn-outline-dark"
|
||||
type="submit">
|
||||
Switch flood zone overlay ({(flood === 'enabled')? 'Enabled' : 'Disabled'})
|
||||
</button>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
export default FloodSwitcherProps;
|
||||
|
@ -1,19 +1,21 @@
|
||||
import React from 'react';
|
||||
|
||||
import './housing-switcher.css';
|
||||
import { useDisplayPreferences } from '../displayPreferences-context';
|
||||
|
||||
interface HousingSwitcherProps {
|
||||
currentDisplay: string;
|
||||
onSubmit: (e: React.FormEvent<HTMLFormElement>) => void;
|
||||
}
|
||||
|
||||
const HousingSwitcherProps: React.FC<HousingSwitcherProps> = (props) => (
|
||||
<form className={`housing-switcher ${props.currentDisplay}`} onSubmit={props.onSubmit}>
|
||||
const HousingSwitcherProps: React.FC<HousingSwitcherProps> = (props) => {
|
||||
const { housing, housingSwitch } = useDisplayPreferences();
|
||||
return (
|
||||
<form className={`housing-switcher ${housing}`} onSubmit={housingSwitch}>
|
||||
<button className="btn btn-outline btn-outline-dark"
|
||||
type="submit">
|
||||
Housing Zone display ({(props.currentDisplay === 'enabled')? 'Enabled' : 'Disabled'})
|
||||
Housing Zone display ({(housing === 'enabled')? 'Enabled' : 'Disabled'})
|
||||
</button>
|
||||
</form>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
export default HousingSwitcherProps;
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { GeoJsonObject } from 'geojson';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { GeoJSON } from 'react-leaflet';
|
||||
import { BoroughEnablementState } from '../../config/map-config';
|
||||
import { LayerEnablementState } from '../../config/map-config';
|
||||
import { apiGet } from '../../apiHelpers';
|
||||
|
||||
export function BoroughBoundaryLayer({enablement}: {enablement: BoroughEnablementState}) {
|
||||
export function BoroughBoundaryLayer({enablement}: {enablement: LayerEnablementState}) {
|
||||
const [boundaryGeojson, setBoundaryGeojson] = useState<GeoJsonObject>(null);
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { GeoJsonObject } from 'geojson';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { GeoJSON } from 'react-leaflet';
|
||||
import { ConservationAreasEnablementState } from '../../config/map-config';
|
||||
import { LayerEnablementState } from '../../config/map-config';
|
||||
import { apiGet } from '../../apiHelpers';
|
||||
|
||||
export function ConservationAreaBoundaryLayer({enablement}: {enablement: ConservationAreasEnablementState}) {
|
||||
export function ConservationAreaBoundaryLayer({enablement}: {enablement: LayerEnablementState}) {
|
||||
const [boundaryGeojson, setBoundaryGeojson] = useState<GeoJsonObject>(null);
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -1,25 +1,26 @@
|
||||
import { GeoJsonObject } from 'geojson';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { GeoJSON } from 'react-leaflet';
|
||||
import { CreativeEnablementState } from '../../config/map-config';
|
||||
import { apiGet } from '../../apiHelpers';
|
||||
import { useDisplayPreferences } from '../../displayPreferences-context';
|
||||
|
||||
export function CreativeBoundaryLayer({enablement}: {enablement: CreativeEnablementState}) {
|
||||
export function CreativeBoundaryLayer() {
|
||||
const [boundaryGeojson, setBoundaryGeojson] = useState<GeoJsonObject>(null);
|
||||
const { creative } = useDisplayPreferences();
|
||||
|
||||
useEffect(() => {
|
||||
apiGet('/geometries/creative_enterprise_zones.geojson')
|
||||
.then(data => setBoundaryGeojson(data as GeoJsonObject));
|
||||
}, []);
|
||||
|
||||
if(enablement == "enabled") {
|
||||
if(creative == "enabled") {
|
||||
return boundaryGeojson &&
|
||||
<GeoJSON
|
||||
attribution="Creative Enterprise Zones data from <a href=https://apps.london.gov.uk/planning/?_gl=1*avicz4*_ga*MTg1MjY3MzMuMTY2NzcxMjIwMg..*_ga_PY4SWZN1RJ*MTY2NzcxMjI1NS4xLjAuMTY2NzcxMjI1NS42MC4wLjA>PLanning Datamap</a> licence: <a href=https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/>Open Government Licence v3.0</a> The boundaries are based on Ordnance Survey mapping and the data is published under Ordnance Survey's 'presumption to publish'. Contains OS data © Crown copyright and database rights 2019."
|
||||
data={boundaryGeojson}
|
||||
style={{color: '#f0f', fill: true, weight: 1, opacity: 0.6}}
|
||||
/>;
|
||||
} else if (enablement == "disabled") {
|
||||
} else if (creative == "disabled") {
|
||||
return <div></div>
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +1,26 @@
|
||||
import { GeoJsonObject } from 'geojson';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { GeoJSON } from 'react-leaflet';
|
||||
import { FloodEnablementState } from '../../config/map-config';
|
||||
import { apiGet } from '../../apiHelpers';
|
||||
import { useDisplayPreferences } from '../../displayPreferences-context';
|
||||
|
||||
export function FloodBoundaryLayer({enablement}: {enablement: FloodEnablementState}) {
|
||||
export function FloodBoundaryLayer() {
|
||||
const [boundaryGeojson, setBoundaryGeojson] = useState<GeoJsonObject>(null);
|
||||
const { flood } = useDisplayPreferences();
|
||||
|
||||
useEffect(() => {
|
||||
apiGet('/geometries/flood_zones_simplified.geojson')
|
||||
.then(data => setBoundaryGeojson(data as GeoJsonObject));
|
||||
}, []);
|
||||
|
||||
if(enablement == "enabled") {
|
||||
if(flood == "enabled") {
|
||||
return boundaryGeojson &&
|
||||
<GeoJSON
|
||||
attribution='Flood zone from <a href=https://data.london.gov.uk/dataset/flood-risk-zones>London Datastore</a>: © Environment Agency copyright and/or database right 2017. All rights reserved. Some features of this map are based on digital spatial data from the Centre for Ecology & Hydrology, © NERC (CEH) © Crown copyright and database rights 2017 Ordnance Survey 100024198'
|
||||
data={boundaryGeojson}
|
||||
style={{color: '#00f', fill: true, weight: 1, opacity: 0.6}}
|
||||
/>;
|
||||
} else if (enablement == "disabled") {
|
||||
} else if (flood == "disabled") {
|
||||
return <div></div>
|
||||
// do not display anything
|
||||
return boundaryGeojson &&
|
||||
|
@ -1,9 +1,9 @@
|
||||
import * as React from 'react';
|
||||
import { TileLayer } from 'react-leaflet';
|
||||
import { HistoricDataEnablementState } from '../../config/map-config';
|
||||
import { LayerEnablementState } from '../../config/map-config';
|
||||
import { BuildingBaseLayer } from './building-base-layer';
|
||||
|
||||
export function HistoricDataLayer({enablement}: {enablement: HistoricDataEnablementState}) {
|
||||
export function HistoricDataLayer({enablement}: {enablement: LayerEnablementState}) {
|
||||
if(enablement == "enabled") {
|
||||
return <><TileLayer
|
||||
url="https://mapseries-tilesets.s3.amazonaws.com/london_1890s/{z}/{x}/{y}.png"
|
||||
|
@ -1,25 +1,26 @@
|
||||
import { GeoJsonObject } from 'geojson';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { GeoJSON } from 'react-leaflet';
|
||||
import { HousingEnablementState } from '../../config/map-config';
|
||||
import { apiGet } from '../../apiHelpers';
|
||||
import { useDisplayPreferences } from '../../displayPreferences-context';
|
||||
|
||||
export function HousingBoundaryLayer({enablement}: {enablement: HousingEnablementState}) {
|
||||
export function HousingBoundaryLayer() {
|
||||
const [boundaryGeojson, setBoundaryGeojson] = useState<GeoJsonObject>(null);
|
||||
const { housing } = useDisplayPreferences();
|
||||
|
||||
useEffect(() => {
|
||||
apiGet('/geometries/housing_zones.geojson')
|
||||
.then(data => setBoundaryGeojson(data as GeoJsonObject));
|
||||
}, []);
|
||||
|
||||
if(enablement == "enabled") {
|
||||
if(housing == "enabled") {
|
||||
return boundaryGeojson &&
|
||||
<GeoJSON
|
||||
attribution="Housing Zones from <a href=https://data.london.gov.uk/dataset/housing_zones>London Datastore</a>. The boundaries are based on Ordnance Survey mapping and the data is published under Ordnance Survey's 'presumption to publish'. Contains OS data © Crown copyright and database rights 2019. Greater London Authority - Contains public sector information licensed under the <a href=https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/>Open Government Licence v3.0</a>'"
|
||||
data={boundaryGeojson}
|
||||
style={{color: '#FF8000', fill: true, weight: 1, opacity: 0.6}}
|
||||
/>;
|
||||
} else if (enablement == "disabled") {
|
||||
} else if (housing == "disabled") {
|
||||
return <div></div>
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { GeoJsonObject } from 'geojson';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { GeoJSON } from 'react-leaflet';
|
||||
import { ParcelEnablementState } from '../../config/map-config';
|
||||
import { LayerEnablementState } from '../../config/map-config';
|
||||
import { apiGet } from '../../apiHelpers';
|
||||
|
||||
export function ParcelBoundaryLayer({enablement}: {enablement: ParcelEnablementState}) {
|
||||
export function ParcelBoundaryLayer({enablement}: {enablement: LayerEnablementState}) {
|
||||
const [boundaryGeojson, setBoundaryGeojson] = useState<GeoJsonObject>(null);
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -1,25 +1,26 @@
|
||||
import { GeoJsonObject } from 'geojson';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { GeoJSON } from 'react-leaflet';
|
||||
import { FloodEnablementState } from '../../config/map-config';
|
||||
import { apiGet } from '../../apiHelpers';
|
||||
import { useDisplayPreferences } from '../../displayPreferences-context';
|
||||
|
||||
export function VistaBoundaryLayer({enablement}: {enablement: FloodEnablementState}) {
|
||||
export function VistaBoundaryLayer() {
|
||||
const [boundaryGeojson, setBoundaryGeojson] = useState<GeoJsonObject>(null);
|
||||
const { vista } = useDisplayPreferences();
|
||||
|
||||
useEffect(() => {
|
||||
apiGet('/geometries/protected_vistas.geojson')
|
||||
.then(data => setBoundaryGeojson(data as GeoJsonObject));
|
||||
}, []);
|
||||
|
||||
if(enablement == "enabled") {
|
||||
if(vista == "enabled") {
|
||||
return boundaryGeojson &&
|
||||
<GeoJSON
|
||||
attribution=' London Views Management Framework (LVMF) – Extended background vistas from <a href=https://data.london.gov.uk/dataset/london-views-management-framework-lvmf-extended-background-vistas>London Datastore</a>: <a href=https://creativecommons.org/licenses/by/4.0/legalcode>CC-BY-SA 4.0</a> by Greater London Authority (GLA)'
|
||||
data={boundaryGeojson}
|
||||
style={{color: '#0f0', fill: true, weight: 1, opacity: 0.6}}
|
||||
/>;
|
||||
} else if (enablement == "disabled") {
|
||||
return <div></div>
|
||||
} else {
|
||||
return <></>
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,8 @@ 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, BoroughEnablementState, ParcelEnablementState, FloodEnablementState, ConservationAreasEnablementState, HistoricDataEnablementState, CreativeEnablementState, HousingEnablementState, VistaEnablementState } from '../config/map-config';
|
||||
import { initialMapViewport, mapBackgroundColor, MapTheme, LayerEnablementState } from '../config/map-config';
|
||||
|
||||
import { Building } from '../models/building';
|
||||
|
||||
import { CityBaseMapLayer } from './layers/city-base-map-layer';
|
||||
@ -55,16 +56,16 @@ export const ColouringMap : FC<ColouringMapProps> = ({
|
||||
selectedBuildingId,
|
||||
children
|
||||
}) => {
|
||||
|
||||
const [theme, setTheme] = useState<MapTheme>('night');
|
||||
const [borough, setBorough] = useState<BoroughEnablementState>('enabled');
|
||||
const [parcel, setParcel] = useState<ParcelEnablementState>('disabled');
|
||||
const [flood, setFlood] = useState<FloodEnablementState>('disabled');
|
||||
const [conservation, setConservation] = useState<ConservationAreasEnablementState>('disabled');
|
||||
const [historicData, setHistoricData] = useState<HistoricDataEnablementState>('disabled');
|
||||
const [creative, setCreative] = useState<CreativeEnablementState>('disabled');
|
||||
const [housing, setHousing] = useState<HousingEnablementState>('disabled');
|
||||
const [vista, setVista] = useState<VistaEnablementState>('disabled');
|
||||
{/* TODO start change remaining ones */}
|
||||
const [borough, setBorough] = useState<LayerEnablementState>('enabled');
|
||||
const [parcel, setParcel] = useState<LayerEnablementState>('disabled');
|
||||
const [flood, setFlood] = useState<LayerEnablementState>('disabled');
|
||||
const [conservation, setConservation] = useState<LayerEnablementState>('disabled');
|
||||
const [historicData, setHistoricData] = useState<LayerEnablementState>('disabled');
|
||||
const [creative, setCreative] = useState<LayerEnablementState>('disabled');
|
||||
const [housing, setHousing] = useState<LayerEnablementState>('disabled');
|
||||
{/* TODO end */}
|
||||
const [position, setPosition] = useState(initialMapViewport.position);
|
||||
const [zoom, setZoom] = useState(initialMapViewport.zoom);
|
||||
|
||||
@ -97,6 +98,7 @@ export const ColouringMap : FC<ColouringMapProps> = ({
|
||||
[theme],
|
||||
)
|
||||
|
||||
{/* change remaining ones */}
|
||||
const boroughSwitch = useCallback(
|
||||
(e) => {
|
||||
e.preventDefault();
|
||||
@ -142,15 +144,6 @@ export const ColouringMap : FC<ColouringMapProps> = ({
|
||||
[historicData],
|
||||
)
|
||||
|
||||
const vistaSwitch = useCallback(
|
||||
(e) => {
|
||||
e.preventDefault();
|
||||
const newVista = (vista === 'enabled')? 'disabled' : 'enabled';
|
||||
setVista(newVista);
|
||||
},
|
||||
[vista],
|
||||
)
|
||||
|
||||
const housingSwitch = useCallback(
|
||||
(e) => {
|
||||
e.preventDefault();
|
||||
@ -168,6 +161,7 @@ export const ColouringMap : FC<ColouringMapProps> = ({
|
||||
},
|
||||
[creative],
|
||||
)
|
||||
{/* TODO end */}
|
||||
|
||||
const categoryMapDefinitions = useMemo(() => categoryMapsConfig[category], [category]);
|
||||
|
||||
@ -220,11 +214,11 @@ export const ColouringMap : FC<ColouringMapProps> = ({
|
||||
<HistoricDataLayer enablement={historicData}/>
|
||||
<BoroughBoundaryLayer enablement={borough}/>
|
||||
<ParcelBoundaryLayer enablement={parcel}/>
|
||||
<FloodBoundaryLayer enablement={flood}/>
|
||||
<FloodBoundaryLayer />
|
||||
<ConservationAreaBoundaryLayer enablement={conservation}/>
|
||||
<VistaBoundaryLayer enablement={vista}/>
|
||||
<HousingBoundaryLayer enablement={housing}/>
|
||||
<CreativeBoundaryLayer enablement={creative}/>
|
||||
<VistaBoundaryLayer />
|
||||
<HousingBoundaryLayer />
|
||||
<CreativeBoundaryLayer />
|
||||
<BuildingNumbersLayer revisionId={revisionId} />
|
||||
{
|
||||
selectedBuildingId &&
|
||||
@ -249,14 +243,16 @@ export const ColouringMap : FC<ColouringMapProps> = ({
|
||||
}
|
||||
<Legend mapColourScaleDefinitions={categoryMapDefinitions} mapColourScale={mapColourScale} onMapColourScale={setMapColourScale}/>
|
||||
<ThemeSwitcher onSubmit={themeSwitch} currentTheme={theme} />
|
||||
|
||||
{/* TODO change remaining ones*/}
|
||||
<BoroughSwitcher onSubmit={boroughSwitch} currentDisplay={borough} />
|
||||
<ParcelSwitcher onSubmit={parcelSwitch} currentDisplay={parcel} />
|
||||
<FloodSwitcher onSubmit={floodSwitch} currentDisplay={flood} />
|
||||
<FloodSwitcher />
|
||||
<ConservationAreaSwitcher onSubmit={conservationSwitch} currentDisplay={conservation} />
|
||||
<HistoricDataSwitcher onSubmit={historicDataSwitch} currentDisplay={historicData} />
|
||||
<VistaSwitcher onSubmit={vistaSwitch} currentDisplay={vista} />
|
||||
<HousingSwitcher onSubmit={housingSwitch} currentDisplay={housing} />
|
||||
<CreativeSwitcher onSubmit={creativeSwitch} currentDisplay={creative} />
|
||||
<VistaSwitcher />
|
||||
<HousingSwitcher />
|
||||
<CreativeSwitcher />
|
||||
<SearchBox onLocate={handleLocate} />
|
||||
</>
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ const ParcelSwitcher: React.FC<ParcelSwitcherProps> = (props) => (
|
||||
<form className={`parcel-switcher ${props.currentDisplay}`} onSubmit={props.onSubmit}>
|
||||
<button className="btn btn-outline btn-outline-dark"
|
||||
type="submit">
|
||||
Switch parcel overlay ({(props.currentDisplay === 'enabled')? 'Enabled' : 'Disabled'})
|
||||
{(props.currentDisplay === 'enabled')? 'Switch off Parcel overlay' : 'Switch on Parcel overlay'}
|
||||
</button>
|
||||
</form>
|
||||
);
|
||||
|
@ -1,19 +1,21 @@
|
||||
import React from 'react';
|
||||
|
||||
import './vista-switcher.css';
|
||||
import { useDisplayPreferences } from '../displayPreferences-context';
|
||||
|
||||
interface VistaSwitcherProps {
|
||||
currentDisplay: string;
|
||||
onSubmit: (e: React.FormEvent<HTMLFormElement>) => void;
|
||||
}
|
||||
|
||||
const VistaSwitcherProps: React.FC<VistaSwitcherProps> = (props) => (
|
||||
<form className={`vista-switcher ${props.currentDisplay}`} onSubmit={props.onSubmit}>
|
||||
const VistaSwitcherProps: React.FC<VistaSwitcherProps> = (props) => {
|
||||
const { vista, vistaSwitch } = useDisplayPreferences();
|
||||
return (
|
||||
<form className={`vista-switcher ${vista}`} onSubmit={vistaSwitch}>
|
||||
<button className="btn btn-outline btn-outline-dark"
|
||||
type="submit">
|
||||
Protected Vistas ({(props.currentDisplay === 'enabled')? 'Enabled' : 'Disabled'})
|
||||
Protected Vistas ({(vista === 'enabled')? 'Enabled' : 'Disabled'})
|
||||
</button>
|
||||
</form>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
export default VistaSwitcherProps;
|
||||
export default VistaSwitcherProps; // TODO remove
|
||||
|
Loading…
Reference in New Issue
Block a user