diff --git a/frontend/package.json b/frontend/package.json
index b10313263..ac87fe727 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -126,30 +126,16 @@
]
},
"devDependencies": {
+ "@react-pdf/types": "^2.1.0",
"@testing-library/dom": "^6.15.0",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
- "eslint": "^6.8.0",
- "eslint-config-airbnb": "^18.0.1",
- "eslint-config-prettier": "^6.11.0",
- "eslint-config-react-app": "^5.2.0",
- "eslint-plugin-flowtype": "^3.0",
- "eslint-plugin-fp": "^2.3.0",
- "eslint-plugin-import": "^2.20.1",
- "eslint-plugin-jsx-a11y": "^6.2.3",
- "eslint-plugin-prettier": "^3.1.4",
- "eslint-plugin-react": "^7.19.0",
- "eslint-plugin-react-hooks": "^1.7",
- "typescript": "^3.9.7",
- "@react-pdf/types": "^2.1.0",
"@turf/helpers": "^6.5.0",
"@types/chart.js": "^2.9.21",
- "@types/dompurify": "^2.2.3",
- "@typescript-eslint/eslint-plugin": "^2.23.0",
- "@typescript-eslint/parser": "^2.25.0",
"@types/colormap": "^2.3.1",
"@types/d3": "^5.7.2",
+ "@types/dompurify": "^2.2.3",
"@types/geojson": "^7946.0.7",
"@types/jest": "^24.0.0",
"@types/lodash": "^4.14.149",
@@ -157,14 +143,28 @@
"@types/marked": "^4.0.2",
"@types/node": "^16.0.0",
"@types/papaparse": "^5.0.3",
- "@types/react": "^16.9.0",
+ "@types/react": "^16.13.0",
"@types/react-datepicker": "^2.11.0",
"@types/react-dom": "^16.9.0",
"@types/react-pdf": "^5.7.2",
"@types/react-redux": "^7.1.7",
"@types/react-router-dom": "^5.1.3",
+ "@typescript-eslint/eslint-plugin": "^2.23.0",
+ "@typescript-eslint/parser": "^2.25.0",
"cross-env": "^7.0.2",
- "eslint-import-resolver-typescript": "^2.0.0"
+ "eslint": "^6.8.0",
+ "eslint-config-airbnb": "^18.0.1",
+ "eslint-config-prettier": "^6.11.0",
+ "eslint-config-react-app": "^5.2.0",
+ "eslint-import-resolver-typescript": "^2.0.0",
+ "eslint-plugin-flowtype": "^3.0",
+ "eslint-plugin-fp": "^2.3.0",
+ "eslint-plugin-import": "^2.20.1",
+ "eslint-plugin-jsx-a11y": "^6.2.3",
+ "eslint-plugin-prettier": "^3.1.4",
+ "eslint-plugin-react": "^7.19.0",
+ "eslint-plugin-react-hooks": "^1.7",
+ "typescript": "^3.9.7"
},
"engines": {
"node": "16.x"
diff --git a/frontend/src/components/404Page/__snapshots__/index.test.tsx.snap b/frontend/src/components/404Page/__snapshots__/index.test.tsx.snap
index 00d441465..135e6d308 100644
--- a/frontend/src/components/404Page/__snapshots__/index.test.tsx.snap
+++ b/frontend/src/components/404Page/__snapshots__/index.test.tsx.snap
@@ -35,13 +35,15 @@ exports[`renders as expected 1`] = `
-
- Back To Home
-
+
+ Back To Home
+
+
{
- const { container } = render();
+ const { container } = render(
+
+
+ ,
+ );
expect(container).toMatchSnapshot();
});
diff --git a/frontend/src/components/404Page/index.tsx b/frontend/src/components/404Page/index.tsx
index 484019e57..2af4859d7 100644
--- a/frontend/src/components/404Page/index.tsx
+++ b/frontend/src/components/404Page/index.tsx
@@ -32,9 +32,9 @@ function NotFound({ classes }: NotFoundProps) {
-
+
+
+
diff --git a/frontend/src/components/MapView/LeftPanel/layersPanel/MenuSwitch/SwitchItem/LayerDownloadOptions.tsx b/frontend/src/components/MapView/LeftPanel/layersPanel/MenuSwitch/SwitchItem/LayerDownloadOptions.tsx
index 4e4a8edb8..c33df1a3a 100644
--- a/frontend/src/components/MapView/LeftPanel/layersPanel/MenuSwitch/SwitchItem/LayerDownloadOptions.tsx
+++ b/frontend/src/components/MapView/LeftPanel/layersPanel/MenuSwitch/SwitchItem/LayerDownloadOptions.tsx
@@ -38,6 +38,7 @@ function LayerDownloadOptions({
layer,
extent,
selected,
+ size,
}: LayerDownloadOptionsProps) {
const { t } = useSafeTranslation();
const dispatch = useDispatch();
@@ -131,8 +132,9 @@ function LayerDownloadOptions({
-
+
)}
@@ -172,6 +174,7 @@ interface LayerDownloadOptionsProps {
layer: LayerType;
extent: Extent | undefined;
selected: boolean;
+ size?: 'small' | undefined;
}
export default LayerDownloadOptions;
diff --git a/frontend/src/components/MapView/LeftPanel/layersPanel/MenuSwitch/SwitchItem/index.tsx b/frontend/src/components/MapView/LeftPanel/layersPanel/MenuSwitch/SwitchItem/index.tsx
index d9c911f7e..bfe2ea9d2 100644
--- a/frontend/src/components/MapView/LeftPanel/layersPanel/MenuSwitch/SwitchItem/index.tsx
+++ b/frontend/src/components/MapView/LeftPanel/layersPanel/MenuSwitch/SwitchItem/index.tsx
@@ -22,26 +22,18 @@ import React, {
} from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { LayerKey, LayerType } from 'config/types';
-import {
- getDisplayBoundaryLayers,
- LayerDefinitions,
- ReportsDefinitions,
-} from 'config/utils';
+import { LayerDefinitions, ReportsDefinitions } from 'config/utils';
import { clearDataset } from 'context/datasetStateSlice';
-import { removeLayer } from 'context/mapStateSlice';
import { layersSelector, mapSelector } from 'context/mapStateSlice/selectors';
import { useSafeTranslation } from 'i18n';
-import {
- refreshBoundaries,
- safeDispatchAddLayer,
- safeDispatchRemoveLayer,
-} from 'utils/map-utils';
+import { refreshBoundaries } from 'utils/map-utils';
import { getUrlKey, useUrlHistory } from 'utils/url-utils';
import { handleChangeOpacity } from 'components/MapView/Legends/handleChangeOpacity';
import { Extent } from 'components/MapView/Layers/raster-utils';
import { availableDatesSelector } from 'context/serverStateSlice';
import { checkLayerAvailableDatesAndContinueOrRemove } from 'components/MapView/utils';
import { LocalError } from 'utils/error-utils';
+import { toggleRemoveLayer } from './utils';
import LayerDownloadOptions from './LayerDownloadOptions';
import ExposureAnalysisOption from './ExposureAnalysisOption';
@@ -131,32 +123,13 @@ const SwitchItem = memo(({ classes, layer, extent }: SwitchItemProps) => {
const urlLayerKey = getUrlKey(selectedLayer);
if (!checked) {
- removeLayerFromUrl(urlLayerKey, selectedLayer.id);
- dispatch(removeLayer(selectedLayer));
-
- // For admin boundary layers with boundary property
- // we have to de-activate the unique boundary and re-activate
- // default boundaries
- if (!('boundary' in selectedLayer)) {
- return;
- }
- const boundaryId = selectedLayer.boundary || '';
-
- if (!Object.keys(LayerDefinitions).includes(boundaryId)) {
- return;
- }
- const displayBoundaryLayers = getDisplayBoundaryLayers();
- const uniqueBoundaryLayer = LayerDefinitions[boundaryId as LayerKey];
-
- if (
- !displayBoundaryLayers.map(l => l.id).includes(uniqueBoundaryLayer.id)
- ) {
- safeDispatchRemoveLayer(map, uniqueBoundaryLayer, dispatch);
- }
-
- displayBoundaryLayers.forEach(l => {
- safeDispatchAddLayer(map, l, dispatch);
- });
+ toggleRemoveLayer(
+ selectedLayer,
+ map,
+ urlLayerKey,
+ dispatch,
+ removeLayerFromUrl,
+ );
return;
}
try {
diff --git a/frontend/src/components/MapView/LeftPanel/layersPanel/MenuSwitch/SwitchItem/utils.ts b/frontend/src/components/MapView/LeftPanel/layersPanel/MenuSwitch/SwitchItem/utils.ts
new file mode 100644
index 000000000..11a485088
--- /dev/null
+++ b/frontend/src/components/MapView/LeftPanel/layersPanel/MenuSwitch/SwitchItem/utils.ts
@@ -0,0 +1,44 @@
+import { Map as MapBoxMap } from 'mapbox-gl';
+import { UrlLayerKey } from '../../../../../../utils/url-utils';
+import { LayerKey, LayerType } from '../../../../../../config/types';
+import { removeLayer } from '../../../../../../context/mapStateSlice';
+import {
+ getDisplayBoundaryLayers,
+ LayerDefinitions,
+} from '../../../../../../config/utils';
+import {
+ safeDispatchAddLayer,
+ safeDispatchRemoveLayer,
+} from '../../../../../../utils/map-utils';
+
+export function toggleRemoveLayer(
+ layer: LayerType,
+ _map: MapBoxMap | undefined,
+ urlLayerKey: UrlLayerKey,
+ dispatcher: Function,
+ removeLayerFromUrl: Function,
+) {
+ removeLayerFromUrl(urlLayerKey, layer.id);
+ dispatcher(removeLayer(layer));
+
+ // For admin boundary layers with boundary property
+ // we have to de-activate the unique boundary and re-activate
+ // default boundaries
+ if (!('boundary' in layer)) {
+ return;
+ }
+ const boundaryId = layer.boundary || '';
+ if (!Object.keys(LayerDefinitions).includes(boundaryId)) {
+ return;
+ }
+ const displayBoundaryLayers = getDisplayBoundaryLayers();
+ const uniqueBoundaryLayer = LayerDefinitions[boundaryId as LayerKey];
+
+ if (!displayBoundaryLayers.map(l => l.id).includes(uniqueBoundaryLayer.id)) {
+ safeDispatchRemoveLayer(_map, uniqueBoundaryLayer, dispatcher);
+ }
+
+ displayBoundaryLayers.forEach(l => {
+ safeDispatchAddLayer(_map, l, dispatcher);
+ });
+}
diff --git a/frontend/src/components/MapView/Legends/AnalysisDownloadButton.tsx b/frontend/src/components/MapView/Legends/AnalysisDownloadButton.tsx
index 90b3221f3..4fb0605d5 100644
--- a/frontend/src/components/MapView/Legends/AnalysisDownloadButton.tsx
+++ b/frontend/src/components/MapView/Legends/AnalysisDownloadButton.tsx
@@ -1,4 +1,5 @@
-import React, { useCallback, useMemo } from 'react';
+import { IconButton, Menu, MenuItem, Tooltip } from '@material-ui/core';
+import React, { useCallback, useMemo, useState } from 'react';
import { useSelector } from 'react-redux';
import {
analysisResultSelector,
@@ -18,7 +19,6 @@ import {
PolygonAnalysisResult,
useAnalysisTableColumns,
} from 'utils/analysis-utils';
-import MultiOptionsButton from 'components/Common/MultiOptionsButton';
import {
downloadToFile,
getExposureAnalysisColumnsToRender,
@@ -27,6 +27,7 @@ import {
} from 'components/MapView/utils';
import { snakeCase } from 'lodash';
import { getExposureAnalysisCsvData } from 'utils/csv-utils';
+import GetAppIcon from '@material-ui/icons/GetApp';
function AnalysisDownloadButton() {
const analysisResult = useSelector(analysisResultSelector);
@@ -42,6 +43,19 @@ function AnalysisDownloadButton() {
);
const analysisDefinition = useSelector(getCurrentDefinition);
+ const [
+ downloadMenuAnchorEl,
+ setDownloadMenuAnchorEl,
+ ] = useState(null);
+
+ const handleDownloadMenuOpen = (event: React.MouseEvent) => {
+ setDownloadMenuAnchorEl(event.currentTarget);
+ };
+
+ const handleDownloadMenuClose = () => {
+ setDownloadMenuAnchorEl(null);
+ };
+
const exposureAnalysisTableData = getExposureAnalysisTableData(
(analysisResult?.tableData || []) as TableRow[],
exposureAnalysisResultSortByKey,
@@ -91,9 +105,11 @@ function AnalysisDownloadButton() {
fileName ?? 'prism_extract',
'application/json',
);
+ handleDownloadMenuClose();
}, [featureCollection, fileName]);
const handleAnalysisDownloadCsv = useCallback((): void => {
+ handleDownloadMenuClose();
if (!analysisResult) {
return;
}
@@ -132,19 +148,30 @@ function AnalysisDownloadButton() {
]);
return (
-
+ <>
+
+
+
+
+
+
+ >
);
}
diff --git a/frontend/src/components/MapView/Legends/LegendItem/__snapshots__/index.test.tsx.snap b/frontend/src/components/MapView/Legends/LegendItem/__snapshots__/index.test.tsx.snap
index b67fda684..1b3e8b19c 100644
--- a/frontend/src/components/MapView/Legends/LegendItem/__snapshots__/index.test.tsx.snap
+++ b/frontend/src/components/MapView/Legends/LegendItem/__snapshots__/index.test.tsx.snap
@@ -30,14 +30,14 @@ exports[`renders as expected 1`] = `
/>
+
+
+
+
+
+
+
+
+ 50%
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/components/MapView/Legends/LegendItem/index.test.tsx b/frontend/src/components/MapView/Legends/LegendItem/index.test.tsx
index 301800044..338e211c6 100644
--- a/frontend/src/components/MapView/Legends/LegendItem/index.test.tsx
+++ b/frontend/src/components/MapView/Legends/LegendItem/index.test.tsx
@@ -3,25 +3,28 @@ import { render } from '@testing-library/react';
import { Provider } from 'react-redux';
import { store } from 'context/store';
+import { BrowserRouter } from 'react-router-dom';
import LegendItem from '.';
test('renders as expected', () => {
const { container } = render(
-
-
- Test Children
-
- ,
+
+
+
+ Test Children
+
+
+ ,
);
expect(container).toMatchSnapshot();
});
diff --git a/frontend/src/components/MapView/Legends/LegendItem/index.tsx b/frontend/src/components/MapView/Legends/LegendItem/index.tsx
index 0ae9f2594..b7d657d20 100644
--- a/frontend/src/components/MapView/Legends/LegendItem/index.tsx
+++ b/frontend/src/components/MapView/Legends/LegendItem/index.tsx
@@ -11,23 +11,36 @@ import {
createStyles,
Divider,
Grid,
+ IconButton,
ListItem,
Paper,
+ Popover,
Slider,
+ Tooltip,
Typography,
withStyles,
WithStyles,
} from '@material-ui/core';
+import { Close, Opacity } from '@material-ui/icons';
import { useDispatch, useSelector } from 'react-redux';
import { LayerType, LegendDefinitionItem } from 'config/types';
-import { mapSelector } from 'context/mapStateSlice/selectors';
+import { mapSelector, layersSelector } from 'context/mapStateSlice/selectors';
+import { clearDataset } from 'context/datasetStateSlice';
import { useSafeTranslation } from 'i18n';
-import { setAnalysisLayerOpacity } from 'context/analysisResultStateSlice';
+import {
+ clearAnalysisResult,
+ setAnalysisLayerOpacity,
+} from 'context/analysisResultStateSlice';
import LayerContentPreview from 'components/MapView/Legends/layerContentPreview';
import { handleChangeOpacity } from 'components/MapView/Legends/handleChangeOpacity';
import ColorIndicator from 'components/MapView/Legends/ColorIndicator';
import { getLegendItemLabel } from 'components/MapView/utils';
-import LoadingBar from 'components/MapView/Legends/LoadingBar';
+import { Extent } from 'components/MapView/Layers/raster-utils';
+import { getUrlKey, useUrlHistory } from 'utils/url-utils';
+import LayerDownloadOptions from 'components/MapView/LeftPanel/layersPanel/MenuSwitch/SwitchItem/LayerDownloadOptions';
+import AnalysisDownloadButton from 'components/MapView/Legends//AnalysisDownloadButton';
+import { toggleRemoveLayer } from 'components/MapView/LeftPanel/layersPanel/MenuSwitch/SwitchItem/utils';
+import LoadingBar from '../LoadingBar';
// Children here is legendText
const LegendItem = memo(
@@ -40,11 +53,14 @@ const LegendItem = memo(
opacity: initialOpacity,
children,
legendUrl,
- displayOpacitySlider,
+ isAnalysis,
fillPattern,
+ extent,
}: LegendItemProps) => {
const dispatch = useDispatch();
+ const { removeLayerFromUrl } = useUrlHistory();
const map = useSelector(mapSelector);
+ const [opacityEl, setOpacityEl] = useState(null);
const [opacity, setOpacityValue] = useState(
initialOpacity || 0,
);
@@ -55,50 +71,94 @@ const LegendItem = memo(
const { t } = useSafeTranslation();
+ const openOpacity = (event: React.MouseEvent) => {
+ setOpacityEl(event.currentTarget);
+ };
+
+ const closeOpacity = () => {
+ setOpacityEl(null);
+ };
+
+ const open = Boolean(opacityEl);
+ const opacityId = open ? 'opacity-popover' : undefined;
+
const handleChangeOpacityValue = useCallback(
val => {
setOpacityValue(val);
- dispatch(setAnalysisLayerOpacity(val));
+ if (isAnalysis) {
+ dispatch(setAnalysisLayerOpacity(val));
+ }
},
- [dispatch],
+ [dispatch, isAnalysis],
);
+ const selectedLayers = useSelector(layersSelector);
+ const layer = useMemo(() => {
+ return selectedLayers.find(l => l.id === id);
+ }, [id, selectedLayers]);
+
const renderedOpacitySlider = useMemo(() => {
- if (!displayOpacitySlider) {
- return null;
- }
return (
-
-
-
- handleChangeOpacity(
- e,
- newValue as number,
- map,
- id,
- type,
- handleChangeOpacityValue,
- )
- }
- />
-
-
+
+
+ {`${Math.round((opacity as number) * 100)}%`}
+
+
+ handleChangeOpacity(
+ e,
+ newValue as number,
+ map,
+ id,
+ type,
+ handleChangeOpacityValue,
+ )
+ }
+ />
+
);
- }, [
- classes.slider,
- displayOpacitySlider,
- handleChangeOpacityValue,
- id,
- map,
- opacity,
- type,
- ]);
+ }, [classes, handleChangeOpacityValue, id, map, opacity, type]);
+
+ const layerDownloadOptions = useMemo(() => {
+ return layer ? (
+
+ ) : null;
+ }, [layer, extent]);
+
+ const remove = useCallback(() => {
+ if (isAnalysis) {
+ dispatch(clearAnalysisResult());
+ }
+ if (layer) {
+ // reset opacity value
+ setOpacityValue(initialOpacity || 0);
+ // clear previous table dataset loaded first
+ // to close the dataseries and thus close chart
+ dispatch(clearDataset());
+ const urlLayerKey = getUrlKey(layer);
+ toggleRemoveLayer(
+ layer,
+ map,
+ urlLayerKey,
+ dispatch,
+ removeLayerFromUrl,
+ );
+ }
+ }, [layer, map, dispatch, removeLayerFromUrl, initialOpacity, isAnalysis]);
const getColorIndicatorKey = useCallback((item: LegendDefinitionItem) => {
return (
@@ -154,10 +214,37 @@ const LegendItem = memo(
- {renderedOpacitySlider}
{renderedLegend}
{renderedChildren}
+
+
+
+
+
+
+
+ <>
+
+ {renderedOpacitySlider}
+
+ {isAnalysis ? : layerDownloadOptions}
+
+
+
+
+
+ >
+
);
@@ -173,6 +260,25 @@ const styles = () =>
slider: {
padding: '0 5px',
},
+ opacityBox: {
+ backgroundColor: '#fff',
+ width: 172,
+ overflow: 'hidden',
+ },
+ opacitySliderRoot: {
+ color: '#4CA1AD',
+ flexGrow: 1,
+ padding: '18px 0',
+ },
+ opacitySliderThumb: {
+ backgroundColor: '#4CA1AD',
+ },
+ opacityText: {
+ color: '#4CA1AD',
+ marginRight: 5,
+ width: 28,
+ lineHeight: '36px',
+ },
});
interface LegendItemProps
@@ -184,8 +290,9 @@ interface LegendItemProps
legendUrl?: string;
type?: LayerType['type'];
opacity: LayerType['opacity'];
- displayOpacitySlider?: boolean;
+ isAnalysis?: boolean;
fillPattern?: 'left' | 'right';
+ extent?: Extent;
}
export default withStyles(styles)(LegendItem);
diff --git a/frontend/src/components/MapView/Legends/index.tsx b/frontend/src/components/MapView/Legends/index.tsx
index 21742745a..b01149ede 100644
--- a/frontend/src/components/MapView/Legends/index.tsx
+++ b/frontend/src/components/MapView/Legends/index.tsx
@@ -1,7 +1,6 @@
import {
Button,
createStyles,
- Divider,
Grid,
Hidden,
List,
@@ -22,12 +21,12 @@ import {
import { LayerType } from 'config/types';
import { BaselineLayerResult } from 'utils/analysis-utils';
import { useSafeTranslation } from 'i18n';
+import { Extent } from 'components/MapView/Layers/raster-utils';
-import AnalysisDownloadButton from './AnalysisDownloadButton';
import LegendItem from './LegendItem';
import LegendImpactResult from './LegendImpactResult';
-const Legends = memo(({ classes, layers }: LegendsProps) => {
+const Legends = memo(({ classes, extent, layers }: LegendsProps) => {
// Selectors
const isAnalysisLayerActive = useSelector(isAnalysisLayerActiveSelector);
const analysisResult = useSelector(analysisResultSelector);
@@ -75,12 +74,13 @@ const Legends = memo(({ classes, layers }: LegendsProps) => {
type={layer.type}
opacity={layer.opacity}
fillPattern={layer.fillPattern}
+ extent={extent}
>
{t(layer.legendText)}
);
});
- }, [getLayerLegendUrl, layers, t]);
+ }, [getLayerLegendUrl, layers, t, extent]);
const renderedLegendImpactResult = useMemo(() => {
if (!(analysisResult instanceof BaselineLayerResult)) {
@@ -114,13 +114,9 @@ const Legends = memo(({ classes, layers }: LegendsProps) => {
opacity={analysisLayerOpacity} // TODO: initial opacity value
// Control opacity only for analysis
// for the other layers it is controlled from the left panel
- displayOpacitySlider={isAnalysisLayerActive && hasData}
+ isAnalysis={isAnalysisLayerActive && hasData}
>
{renderedLegendImpactResult}
-
-
-
-
,
];
}, [
@@ -195,6 +191,7 @@ const styles = () =>
});
export interface LegendsProps extends WithStyles {
+ extent?: Extent;
layers: LayerType[];
}
diff --git a/frontend/src/components/MapView/index.tsx b/frontend/src/components/MapView/index.tsx
index ecee060d5..bacff07f1 100644
--- a/frontend/src/components/MapView/index.tsx
+++ b/frontend/src/components/MapView/index.tsx
@@ -545,12 +545,13 @@ const MapView = memo(({ classes }: MapViewProps) => {
-
+
);
}, [
+ adminBoundariesExtent,
classes.buttonContainer,
isShowingExtraFeatures,
renderedGridItemAlertForm,
diff --git a/frontend/src/components/NavBar/__snapshots__/index.test.tsx.snap b/frontend/src/components/NavBar/__snapshots__/index.test.tsx.snap
index 1f47a5e33..561eee67b 100644
--- a/frontend/src/components/NavBar/__snapshots__/index.test.tsx.snap
+++ b/frontend/src/components/NavBar/__snapshots__/index.test.tsx.snap
@@ -18,14 +18,16 @@ exports[`renders as expected 1`] = `
-
- PRISM
-
+
+ PRISM
+
+
'mock-PrintImage');
test('renders as expected', () => {
const { container } = render(
-
-
- ,
+
+
+
+
+ ,
);
expect(container).toMatchSnapshot();
});
diff --git a/frontend/src/components/NavBar/index.tsx b/frontend/src/components/NavBar/index.tsx
index 49db6aad1..a27ca09fe 100644
--- a/frontend/src/components/NavBar/index.tsx
+++ b/frontend/src/components/NavBar/index.tsx
@@ -63,14 +63,11 @@ function NavBar({ classes }: NavBarProps) {
{logo && }
{title && (
-
- {t(title)}
-
+
+
+ {t(title)}
+
+
)}
{subtitle && (
diff --git a/frontend/src/types/custom.d.ts b/frontend/src/types/custom.d.ts
index 4ce95f992..3b66a4fdb 100644
--- a/frontend/src/types/custom.d.ts
+++ b/frontend/src/types/custom.d.ts
@@ -4,6 +4,7 @@
// https://stackoverflow.com/questions/44717164/unable-to-import-svg-files-in-typescript
declare module '*.svg' {
import React = require('react');
+
export const ReactComponent: React.FC>;
const content: string;
export default content;
diff --git a/frontend/yarn.lock b/frontend/yarn.lock
index 2b41ee19c..ba48e8905 100644
--- a/frontend/yarn.lock
+++ b/frontend/yarn.lock
@@ -2690,7 +2690,7 @@
dependencies:
"@types/react" "*"
-"@types/react@*", "@types/react@^16.9.0":
+"@types/react@*":
version "16.9.23"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.23.tgz#1a66c6d468ba11a8943ad958a8cb3e737568271c"
integrity sha512-SsGVT4E7L2wLN3tPYLiF20hmZTPGuzaayVunfgXzUn1x4uHVsKH6QDJQ/TdpHqwsTLd4CwrmQ2vOgxN7gE24gw==
@@ -2698,6 +2698,20 @@
"@types/prop-types" "*"
csstype "^2.2.0"
+"@types/react@^16.13.0":
+ version "16.14.50"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.50.tgz#ec9c30f2f0c7d9aa748949536d88e3439526a25d"
+ integrity sha512-7TWZ/HjhXsRK3BbhSFxTinbSft3sUXJAU3ONngT0rpcKJaIOlxkRke4bidqQTopUbEv1ApC5nlSEkIpX43MkTg==
+ dependencies:
+ "@types/prop-types" "*"
+ "@types/scheduler" "*"
+ csstype "^3.0.2"
+
+"@types/scheduler@*":
+ version "0.16.5"
+ resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.5.tgz#4751153abbf8d6199babb345a52e1eb4167d64af"
+ integrity sha512-s/FPdYRmZR8SjLWGMCuax7r3qCWQw9QKHzXVukAuuIJkXkDRwp+Pu5LMIVFi0Fxbav35WURicYr8u1QsoybnQw==
+
"@types/stack-utils@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
@@ -9313,13 +9327,6 @@ lru-cache@^5.1.1:
dependencies:
yallist "^3.0.2"
-lru-cache@^6.0.0:
- version "6.0.0"
- resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
- integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
- dependencies:
- yallist "^4.0.0"
-
make-cancellable-promise@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/make-cancellable-promise/-/make-cancellable-promise-1.1.0.tgz#b4e9fcb31db3a27417e44f80cffa598ec9ac9f4e"
@@ -11813,9 +11820,9 @@ react-is@^16.8.4:
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-mapbox-gl@^4.8.2:
- version "4.8.6"
- resolved "https://registry.yarnpkg.com/react-mapbox-gl/-/react-mapbox-gl-4.8.6.tgz#c3841bac882a297f60efce50cac4060e3a1c3f81"
- integrity sha512-e6rJ4GFye2AIu10I0a0OfleIWYkigIMIysoSKCA4Wg5YHa52JRHq2F3x0c0cnhqfz1txnUhXUbkx2qqs8B6kKQ==
+ version "4.8.2"
+ resolved "https://registry.yarnpkg.com/react-mapbox-gl/-/react-mapbox-gl-4.8.2.tgz#3814a42d35adc53194d3920eeac72910dbcebd65"
+ integrity sha512-NAN1dgVDpjxTtqQuhPX1OUkVhS1o8KJ+jRoAN0Q/8gSWLaQlYLkC1ZOYRRj8KcoRP3Px/ya0DJsORiStz0P+eA==
dependencies:
"@turf/bbox" "4.7.3"
"@turf/helpers" "4.7.3"
@@ -12668,11 +12675,11 @@ semver-regex@^2.0.0:
integrity sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==
"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0, semver@^5.7.1:
- version "5.7.2"
- resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8"
- integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==
+ version "5.7.1"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
+ integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
-semver@6.3.0:
+semver@6.3.0, semver@^6.0.0, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
@@ -12682,17 +12689,10 @@ semver@7.0.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e"
integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==
-semver@^6.0.0, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0:
- version "6.3.1"
- resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
- integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
-
semver@^7.3.2:
- version "7.5.4"
- resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
- integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
- dependencies:
- lru-cache "^6.0.0"
+ version "7.3.2"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938"
+ integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==
send@0.18.0:
version "0.18.0"
@@ -14472,9 +14472,9 @@ which@^2.0.1:
isexe "^2.0.0"
word-wrap@~1.2.3:
- version "1.2.4"
- resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.4.tgz#cb4b50ec9aca570abd1f52f33cd45b6c61739a9f"
- integrity sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
+ integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
workbox-background-sync@^4.3.1:
version "4.3.1"