@defra/interactive-map 0.0.39-alpha → 0.0.41-alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/css/index.css +1 -1
- package/dist/esm/im-core.js +1 -1
- package/dist/esm/im-shell.js +1 -1
- package/dist/umd/im-core.js +1 -1
- package/dist/umd/index.js +1 -1
- package/docs/api/control-definition.md +9 -1
- package/docs/api/slots.md +26 -5
- package/docs/api.md +4 -4
- package/docs/assets/images/slot-map.svg +61 -262
- package/docs/examples/draw-tools.mdx +3 -3
- package/docs/plugins/draw.md +80 -17
- package/docs/plugins/search.md +1 -1
- package/govuk-prototype-kit.config.json +2 -0
- package/jest.setup.js +5 -0
- package/package.json +9 -1
- package/plugins/beta/draw-es/dist/esm/im-draw-es-plugin.js +1 -1
- package/plugins/beta/draw-ml/dist/esm/im-draw-ml-plugin.js +1 -1
- package/plugins/beta/draw-ml/dist/umd/im-draw-ml-plugin.js +1 -1
- package/plugins/beta/draw-ol/dist/esm/im-draw-ol-plugin.js +1 -1
- package/plugins/beta/map-styles/dist/esm/im-map-styles-plugin.js +1 -1
- package/plugins/beta/map-styles/dist/umd/im-map-styles-plugin.js +1 -1
- package/plugins/beta/map-styles/dist/umd/index.js +1 -1
- package/plugins/datasets/dist/css/index.css +1 -1
- package/plugins/datasets/dist/esm/esriLayerAdapter.js +1 -1
- package/plugins/datasets/dist/esm/im-datasets-ml-adapter.js +1 -1
- package/plugins/datasets/dist/esm/im-datasets-plugin.js +1 -1
- package/plugins/datasets/dist/umd/im-datasets-esri-adapter.js +1 -1
- package/plugins/datasets/dist/umd/im-datasets-ml-adapter.js +1 -1
- package/plugins/datasets/dist/umd/im-datasets-plugin.js +1 -1
- package/plugins/datasets/dist/umd/index.js +1 -1
- package/plugins/datasets/src/adapters/esri/esriLayerAdapter.js +2 -3
- package/plugins/datasets/src/adapters/esri/esriLayerAdapter.test.js +175 -0
- package/plugins/datasets/src/adapters/esri/registry/esriDataset.js +1 -1
- package/plugins/datasets/src/adapters/esri/registry/esriDataset.test.js +55 -0
- package/plugins/datasets/src/adapters/loadLayerAdapter.js +1 -1
- package/plugins/datasets/src/adapters/loadLayerAdapter.test.js +61 -0
- package/plugins/datasets/src/adapters/maplibre/maplibreLayerAdapter.js +1 -3
- package/plugins/datasets/src/adapters/maplibre/maplibreLayerAdapter.test.js +17 -3
- package/plugins/datasets/src/api/setOpacity.test.js +9 -0
- package/plugins/datasets/src/components/LayersMenu/LayersMenu.jsx +10 -25
- package/plugins/datasets/src/components/LayersMenu/LayersMenu.test.jsx +0 -42
- package/plugins/datasets/src/datasets.scss +0 -1
- package/plugins/datasets/src/fetch/createDynamicSource.js +135 -129
- package/plugins/datasets/src/fetch/createDynamicSource.test.js +318 -0
- package/plugins/datasets/src/fetch/fetchGeoJSON.test.js +83 -0
- package/plugins/datasets/src/index.test.js +36 -0
- package/plugins/datasets/src/initialise/DatasetsInit.jsx +17 -7
- package/plugins/datasets/src/initialise/DatasetsInit.test.jsx +262 -0
- package/plugins/datasets/src/initialise/initialiseDatasets.js +16 -5
- package/plugins/datasets/src/initialise/initialiseDatasets.test.js +42 -0
- package/plugins/datasets/src/manifest.js +0 -38
- package/plugins/datasets/src/manifest.test.js +49 -0
- package/plugins/datasets/src/reducers/datasetsToMenu.test.js +54 -1
- package/plugins/datasets/src/reducers/pluginState.js +3 -16
- package/plugins/datasets/src/reducers/pluginState.test.js +23 -0
- package/plugins/datasets/src/registry/dataset.js +15 -4
- package/plugins/datasets/src/registry/dataset.test.js +61 -0
- package/plugins/datasets/src/registry/datasetRegistry.js +12 -9
- package/plugins/datasets/src/registry/datasetRegistry.test.js +17 -5
- package/plugins/datasets/src/registry/globalDataset.js +0 -3
- package/plugins/datasets/src/registry/isVisibleWhen.js +6 -3
- package/plugins/datasets/src/registry/isVisibleWhen.test.js +11 -1
- package/plugins/datasets/src/utils/bbox.test.js +125 -0
- package/plugins/draw/dist/esm/im-draw-ml-adapter.js +1 -1
- package/plugins/draw/dist/esm/im-draw-ol-adapter.js +1 -1
- package/plugins/draw/dist/esm/im-draw-plugin.js +1 -1
- package/plugins/draw/dist/esm/index.js +1 -1
- package/plugins/draw/dist/umd/im-draw-ml-adapter.js +2 -1
- package/plugins/draw/dist/umd/im-draw-ml-adapter.js.LICENSE.txt +1 -0
- package/plugins/draw/dist/umd/im-draw-ol-adapter.js +1 -1
- package/plugins/draw/dist/umd/im-draw-plugin.js +1 -1
- package/plugins/draw/dist/umd/index.js +1 -1
- package/plugins/draw/src/DrawInit.jsx +12 -4
- package/plugins/draw/src/DrawInit.test.jsx +51 -10
- package/plugins/draw/src/adapters/maplibre/MaplibreDrawAdapter.js +92 -12
- package/plugins/draw/src/adapters/maplibre/MaplibreDrawAdapter.test.js +246 -4
- package/plugins/draw/src/adapters/maplibre/mapboxDraw.js +109 -14
- package/plugins/draw/src/adapters/maplibre/mapboxDraw.test.js +174 -11
- package/plugins/draw/src/adapters/maplibre/modes/drawMode/clickHandlers.test.js +12 -0
- package/plugins/draw/src/adapters/maplibre/modes/drawMode/lifecycle.js +9 -1
- package/plugins/draw/src/adapters/maplibre/modes/drawMode/lifecycle.test.js +24 -3
- package/plugins/draw/src/adapters/maplibre/modes/drawMode/pointerHandlers.js +1 -1
- package/plugins/draw/src/adapters/maplibre/modes/drawMode/pointerHandlers.test.js +1 -1
- package/plugins/draw/src/adapters/maplibre/modes/drawPointMode.js +194 -0
- package/plugins/draw/src/adapters/maplibre/modes/drawPointMode.test.js +457 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/__helpers__/harness.js +102 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/keyboardHandlers.js +82 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/keyboardHandlers.test.js +83 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/pointOperations.js +55 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/pointOperations.test.js +62 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/pointerHandlers.js +138 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/pointerHandlers.test.js +197 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/touchHandlers.js +92 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/touchHandlers.test.js +101 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/undoHandlers.js +46 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/undoHandlers.test.js +42 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode.js +151 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode.test.js +156 -0
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/keyboardHandlers.js +5 -28
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/keyboardHandlers.test.js +24 -39
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/pointerHandlers.js +4 -5
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/touchHandlers.js +20 -23
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/touchHandlers.test.js +25 -5
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/undoHandlers.js +6 -36
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/undoHandlers.test.js +7 -49
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/vertexOperations.js +4 -54
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/vertexOperations.test.js +8 -33
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode.js +29 -72
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode.test.js +11 -4
- package/plugins/draw/src/adapters/maplibre/pointSymbolImages.js +158 -0
- package/plugins/draw/src/adapters/maplibre/pointSymbolImages.test.js +314 -0
- package/plugins/draw/src/adapters/maplibre/snap/prototypePatches.js +6 -1
- package/plugins/draw/src/adapters/maplibre/snap/prototypePatches.test.js +21 -0
- package/plugins/draw/src/adapters/maplibre/snap/snapInstance.js +6 -2
- package/plugins/draw/src/adapters/maplibre/snap/snapInstance.test.js +12 -0
- package/plugins/draw/src/adapters/maplibre/styles.js +38 -11
- package/plugins/draw/src/adapters/maplibre/styles.test.js +39 -0
- package/plugins/draw/src/adapters/maplibre/utils/editModeEvents.js +79 -0
- package/plugins/draw/src/adapters/maplibre/utils/editModeEvents.test.js +135 -0
- package/plugins/draw/src/adapters/maplibre/utils/geometryValidation.js +42 -0
- package/plugins/draw/src/adapters/maplibre/utils/geometryValidation.test.js +85 -0
- package/plugins/draw/src/adapters/maplibre/utils/keyboardShortcuts.js +34 -0
- package/plugins/draw/src/adapters/maplibre/utils/keyboardShortcuts.test.js +78 -0
- package/plugins/draw/src/adapters/maplibre/utils/snapHelpers.js +16 -3
- package/plugins/draw/src/adapters/maplibre/utils/snapHelpers.test.js +21 -3
- package/plugins/draw/src/adapters/maplibre/utils/snapMovement.js +59 -0
- package/plugins/draw/src/adapters/maplibre/utils/snapMovement.test.js +73 -0
- package/plugins/draw/src/adapters/maplibre/utils/touchDragMath.js +33 -0
- package/plugins/draw/src/adapters/maplibre/utils/touchDragMath.test.js +70 -0
- package/plugins/draw/src/adapters/openlayers/OLDrawAdapter.js +27 -2
- package/plugins/draw/src/adapters/openlayers/OLDrawAdapter.test.js +93 -0
- package/plugins/draw/src/adapters/openlayers/__helpers__/harness.js +9 -0
- package/plugins/draw/src/adapters/openlayers/core/OLDrawManager.js +19 -1
- package/plugins/draw/src/adapters/openlayers/core/OLDrawManager.test.js +34 -1
- package/plugins/draw/src/adapters/openlayers/core/styles.js +73 -1
- package/plugins/draw/src/adapters/openlayers/core/styles.test.js +122 -3
- package/plugins/draw/src/adapters/openlayers/draw/DrawMode.js +1 -0
- package/plugins/draw/src/adapters/openlayers/draw/DrawMode.test.js +27 -1
- package/plugins/draw/src/adapters/openlayers/draw/drawInput.js +24 -4
- package/plugins/draw/src/adapters/openlayers/draw/drawInput.test.js +47 -3
- package/plugins/draw/src/adapters/openlayers/edit/EditMode.js +1 -1
- package/plugins/draw/src/adapters/openlayers/edit/EditMode.test.js +32 -1
- package/plugins/draw/src/adapters/openlayers/edit/keyboardHandler.js +9 -5
- package/plugins/draw/src/adapters/openlayers/edit/keyboardHandler.test.js +34 -1
- package/plugins/draw/src/adapters/openlayers/edit/modifyInteraction.js +5 -3
- package/plugins/draw/src/adapters/openlayers/edit/modifyInteraction.test.js +11 -0
- package/plugins/draw/src/adapters/openlayers/edit/nudge.js +12 -5
- package/plugins/draw/src/adapters/openlayers/edit/nudge.test.js +26 -3
- package/plugins/draw/src/adapters/openlayers/edit/touchHandler.js +18 -13
- package/plugins/draw/src/adapters/openlayers/edit/touchHandler.test.js +46 -1
- package/plugins/draw/src/adapters/openlayers/olDraw.js +11 -4
- package/plugins/draw/src/adapters/openlayers/olDraw.test.js +48 -6
- package/plugins/draw/src/adapters/openlayers/point/drawPointMode.js +156 -0
- package/plugins/draw/src/adapters/openlayers/point/drawPointMode.test.js +246 -0
- package/plugins/draw/src/adapters/openlayers/point/editPointMode.js +267 -0
- package/plugins/draw/src/adapters/openlayers/point/editPointMode.test.js +327 -0
- package/plugins/draw/src/adapters/openlayers/point/pointDragInteraction.js +71 -0
- package/plugins/draw/src/adapters/openlayers/point/pointOps.js +34 -0
- package/plugins/draw/src/adapters/openlayers/point/pointOps.test.js +32 -0
- package/plugins/draw/src/adapters/openlayers/point/pointSelectionState.js +82 -0
- package/plugins/draw/src/adapters/openlayers/point/pointSelectionState.test.js +107 -0
- package/plugins/draw/src/adapters/openlayers/point/pointSymbolImages.js +83 -0
- package/plugins/draw/src/adapters/openlayers/point/pointSymbolImages.test.js +214 -0
- package/plugins/draw/src/adapters/openlayers/snap/snapIndicator.js +3 -1
- package/plugins/draw/src/adapters/openlayers/snap/snapInteraction.js +6 -9
- package/plugins/draw/src/adapters/openlayers/snap/snapInteraction.test.js +15 -4
- package/plugins/draw/src/adapters/openlayers/utils/olCoords.js +1 -1
- package/plugins/draw/src/api/addFeature.js +16 -1
- package/plugins/draw/src/api/addFeature.test.js +62 -5
- package/plugins/draw/src/api/editFeature.js +7 -4
- package/plugins/draw/src/api/editFeature.test.js +16 -0
- package/plugins/draw/src/api/newPoint.js +42 -0
- package/plugins/draw/src/api/newPoint.test.js +117 -0
- package/plugins/draw/src/api/setStyle.js +43 -0
- package/plugins/draw/src/api/setStyle.test.js +75 -0
- package/plugins/draw/src/events.js +21 -14
- package/plugins/draw/src/events.test.js +15 -1
- package/plugins/draw/src/manifest.js +18 -6
- package/plugins/draw/src/manifest.test.js +32 -1
- package/plugins/draw/src/reducer.test.js +7 -0
- package/plugins/draw/src/utils/stripInternalProperties.js +19 -0
- package/plugins/draw/src/utils/stripInternalProperties.test.js +50 -0
- package/plugins/draw/src/utils/symbolKeys.js +5 -0
- package/plugins/draw/src/validation/liveDrawChecks.test.js +54 -0
- package/plugins/draw/src/validation/liveStroke.test.js +64 -1
- package/plugins/interact/dist/esm/im-interact-plugin.js +1 -1
- package/plugins/interact/dist/umd/im-interact-plugin.js +1 -1
- package/plugins/interact/dist/umd/index.js +1 -1
- package/plugins/interact/src/hooks/useCrossHairVisibility.js +12 -4
- package/plugins/interact/src/hooks/useCrossHairVisibility.test.js +88 -1
- package/plugins/interact/src/hooks/useHighlightSync.js +33 -12
- package/plugins/interact/src/hooks/useHighlightSync.test.js +96 -25
- package/plugins/interact/src/utils/featureQueries.js +18 -0
- package/plugins/interact/src/utils/featureQueries.test.js +15 -0
- package/plugins/interact/src/utils/spatial.js +9 -3
- package/plugins/interact/src/utils/spatial.test.js +12 -1
- package/plugins/map-key/dist/css/index.css +62 -0
- package/plugins/map-key/dist/esm/im-map-key-plugin.js +1 -0
- package/plugins/map-key/dist/esm/index.js +1 -0
- package/plugins/map-key/dist/umd/im-map-key-plugin.js +2 -0
- package/plugins/map-key/dist/umd/im-map-key-plugin.js.LICENSE.txt +1 -0
- package/plugins/map-key/dist/umd/index.js +2 -0
- package/plugins/map-key/dist/umd/index.js.LICENSE.txt +1 -0
- package/plugins/map-key/package.json +28 -0
- package/plugins/map-key/src/components/Key/EmptyKey.jsx +7 -0
- package/plugins/{datasets → map-key}/src/components/Key/EmptyKey.test.jsx +2 -2
- package/plugins/map-key/src/components/Key/Key.jsx +41 -0
- package/plugins/{datasets → map-key}/src/components/Key/Key.module.scss +15 -14
- package/plugins/map-key/src/components/Key/Key.test.jsx +73 -0
- package/plugins/map-key/src/components/Key/KeyGroupItem.jsx +16 -0
- package/plugins/map-key/src/components/Key/KeyGroupItem.test.jsx +53 -0
- package/plugins/map-key/src/components/Key/KeyItem.jsx +29 -0
- package/plugins/map-key/src/components/Key/KeyItem.test.jsx +67 -0
- package/plugins/map-key/src/components/Key/KeySvg.jsx +42 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvg.test.jsx +14 -12
- package/plugins/map-key/src/components/Key/KeySvgLine.jsx +28 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgLine.test.jsx +1 -1
- package/plugins/map-key/src/components/Key/KeySvgPattern.jsx +23 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgPattern.test.jsx +2 -2
- package/plugins/map-key/src/components/Key/KeySvgRect.jsx +33 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgRect.test.jsx +1 -1
- package/plugins/map-key/src/components/Key/KeySvgSymbol.jsx +27 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgSymbol.test.jsx +5 -6
- package/plugins/map-key/src/components/Key/MapKey.jsx +50 -0
- package/plugins/map-key/src/components/Key/MapKey.test.jsx +130 -0
- package/plugins/{datasets → map-key}/src/components/Key/svgProperties.js +2 -2
- package/plugins/{datasets → map-key}/src/components/Key/svgProperties.test.js +2 -2
- package/plugins/map-key/src/index.js +13 -0
- package/plugins/map-key/src/index.test.js +31 -0
- package/plugins/map-key/src/initialise/MapKeyInit.jsx +15 -0
- package/plugins/map-key/src/initialise/MapKeyInit.test.jsx +39 -0
- package/plugins/map-key/src/manifest.js +30 -0
- package/plugins/map-key/src/manifest.test.js +63 -0
- package/plugins/map-key/src/mapKey.scss +4 -0
- package/plugins/map-key/src/registry/getDatasetRegistry.js +6 -0
- package/plugins/map-key/src/registry/getDatasetRegistry.test.js +23 -0
- package/plugins/map-key/src/registry/index.js +3 -0
- package/plugins/map-key/src/registry/index.test.js +15 -0
- package/plugins/menu/dist/css/index.css +80 -0
- package/plugins/menu/dist/esm/im-menu-plugin.js +1 -0
- package/plugins/menu/dist/esm/index.js +1 -0
- package/plugins/menu/dist/umd/im-menu-plugin.js +1 -0
- package/plugins/menu/dist/umd/index.js +2 -0
- package/plugins/menu/dist/umd/index.js.LICENSE.txt +1 -0
- package/plugins/menu/package.json +28 -0
- package/plugins/menu/src/components/Menu/CheckboxGroupWrapper.jsx +21 -0
- package/plugins/menu/src/components/Menu/GroupLegend.jsx +17 -0
- package/plugins/menu/src/components/Menu/GroupLegend.test.jsx +68 -0
- package/plugins/menu/src/components/Menu/Menu.jsx +19 -0
- package/plugins/menu/src/components/Menu/Menu.module.scss +90 -0
- package/plugins/menu/src/components/Menu/Menu.test.jsx +161 -0
- package/plugins/menu/src/components/Menu/MenuCheckbox.jsx +35 -0
- package/plugins/menu/src/components/Menu/MenuCheckbox.test.jsx +93 -0
- package/plugins/menu/src/components/Menu/MenuGroup.jsx +11 -0
- package/plugins/{datasets/src/components/LayersMenu/LayersMenuRadio.jsx → menu/src/components/Menu/MenuRadio.jsx} +6 -4
- package/plugins/{datasets/src/components/LayersMenu/LayersMenuRadio.test.jsx → menu/src/components/Menu/MenuRadio.test.jsx} +18 -18
- package/plugins/menu/src/components/Menu/RadioGroupWrapper.jsx +32 -0
- package/plugins/{datasets/src/components/LayersMenu/LayersRadioGroupWrapper.test.jsx → menu/src/components/Menu/RadioGroupWrapper.test.jsx} +21 -21
- package/plugins/menu/src/components/Menu/useIdPrefix.jsx +4 -0
- package/plugins/menu/src/index.js +13 -0
- package/plugins/menu/src/index.test.js +31 -0
- package/plugins/menu/src/initialise/MenuInit.jsx +24 -0
- package/plugins/menu/src/initialise/MenuInit.test.jsx +50 -0
- package/plugins/menu/src/initialise/createMenu.js +10 -0
- package/plugins/menu/src/initialise/createMenu.test.js +37 -0
- package/plugins/menu/src/manifest.js +35 -0
- package/plugins/menu/src/manifest.test.js +63 -0
- package/plugins/menu/src/menu.scss +4 -0
- package/plugins/menu/src/reducers/menuStateReducer.test.js +38 -0
- package/plugins/menu/src/reducers/pluginState.js +35 -0
- package/plugins/menu/src/reducers/pluginState.test.js +57 -0
- package/plugins/menu/src/registry/getDatasetRegistry.js +9 -0
- package/plugins/menu/src/registry/getDatasetRegistry.test.js +23 -0
- package/plugins/menu/src/registry/index.js +3 -0
- package/plugins/menu/src/registry/index.test.js +15 -0
- package/plugins/menu/src/registry/isVisibleWhen.js +43 -0
- package/plugins/menu/src/registry/isVisibleWhen.test.js +48 -0
- package/plugins/search/dist/css/index.css +1 -1
- package/plugins/search/dist/esm/im-search-plugin.js +1 -1
- package/plugins/search/dist/esm/index.js +1 -1
- package/plugins/search/dist/umd/im-search-plugin.js +1 -1
- package/plugins/search/dist/umd/index.js +1 -1
- package/plugins/search/src/Search.jsx +7 -5
- package/plugins/search/src/components/Form/Form.module.scss +9 -20
- package/plugins/search/src/index.js +0 -1
- package/plugins/search/src/index.test.js +2 -4
- package/plugins/search/src/manifest.js +1 -1
- package/plugins/search/src/search.scss +17 -16
- package/providers/beta/openlayers/dist/esm/im-openlayers-provider.js +1 -1
- package/providers/beta/openlayers/dist/umd/im-openlayers-provider.js +1 -1
- package/providers/beta/openlayers/dist/umd/index.js +1 -1
- package/providers/beta/openlayers/src/openlayersProvider.js +4 -1
- package/providers/beta/openlayers/src/openlayersProvider.test.js +18 -0
- package/providers/beta/openlayers/src/utils/highlightFeatures.js +52 -5
- package/providers/beta/openlayers/src/utils/highlightFeatures.test.js +176 -0
- package/providers/beta/openlayers/src/utils/symbolImages.js +40 -0
- package/providers/beta/openlayers/src/utils/symbolImages.test.js +58 -0
- package/providers/maplibre/dist/esm/im-maplibre-provider.js +1 -1
- package/providers/maplibre/dist/umd/im-maplibre-provider.js +1 -1
- package/providers/maplibre/dist/umd/index.js +1 -1
- package/providers/maplibre/src/utils/drawLayerBuckets.js +14 -0
- package/providers/maplibre/src/utils/drawLayerBuckets.test.js +18 -0
- package/providers/maplibre/src/utils/highlightFeatures.js +80 -55
- package/providers/maplibre/src/utils/highlightFeatures.test.js +156 -17
- package/providers/maplibre/src/utils/hoverCursor.js +30 -14
- package/providers/maplibre/src/utils/hoverCursor.test.js +35 -0
- package/providers/maplibre/src/utils/patternImages.js +1 -1
- package/providers/maplibre/src/utils/symbolImages.js +41 -3
- package/providers/maplibre/src/utils/symbolImages.test.js +40 -6
- package/rollup.esm.mjs +11 -1
- package/sonar-project.properties +7 -1
- package/src/App/components/Actions/Actions.test.jsx +47 -0
- package/src/App/components/Attributions/Attributions.module.scss +10 -0
- package/src/App/components/Hints/Hints.jsx +7 -2
- package/src/App/components/Hints/Hints.test.jsx +13 -0
- package/src/App/components/KeyboardHelp/KeyboardHelp.jsx +2 -3
- package/src/App/components/KeyboardHelp/KeyboardHelp.test.jsx +3 -6
- package/src/App/components/{MoveControl/MoveControl.jsx → MoveControls/MoveControls.jsx} +10 -10
- package/src/App/components/{MoveControl/MoveControl.module.scss → MoveControls/MoveControls.module.scss} +60 -29
- package/src/App/components/{MoveControl/MoveControl.test.jsx → MoveControls/MoveControls.test.jsx} +48 -48
- package/src/App/components/Panel/Panel.jsx +18 -3
- package/src/App/components/Panel/Panel.module.scss +18 -8
- package/src/App/components/Panel/Panel.test.jsx +34 -0
- package/src/App/components/Tooltip/Tooltip.test.jsx +12 -14
- package/src/App/components/Viewport/Viewport.jsx +9 -1
- package/src/App/components/Viewport/Viewport.test.jsx +11 -0
- package/src/App/hooks/useFeatureItems.js +16 -7
- package/src/App/hooks/useFeatureItems.test.js +57 -0
- package/src/App/hooks/useLayoutMeasurements.js +95 -84
- package/src/App/hooks/useLayoutMeasurements.test.js +61 -1
- package/src/App/initialiseApp.js +11 -8
- package/src/App/initialiseApp.test.js +15 -3
- package/src/App/layout/Layout.jsx +12 -11
- package/src/App/layout/Layout.test.jsx +2 -0
- package/src/App/layout/layout.module.scss +31 -17
- package/src/App/registry/keyboardShortcutRegistry.js +25 -13
- package/src/App/registry/keyboardShortcutRegistry.test.js +49 -32
- package/src/App/registry/pluginRegistry.js +2 -3
- package/src/App/registry/pluginRegistry.test.js +16 -3
- package/src/App/renderer/HtmlElementHost.jsx +18 -5
- package/src/App/renderer/HtmlElementHost.test.jsx +54 -0
- package/src/App/renderer/mapButtons.js +28 -12
- package/src/App/renderer/mapButtons.test.js +17 -4
- package/src/App/renderer/mapControls.js +3 -1
- package/src/App/renderer/mapControls.test.js +16 -0
- package/src/App/renderer/mapPanels.js +44 -9
- package/src/App/renderer/mapPanels.test.js +51 -2
- package/src/App/renderer/orderItems.js +28 -0
- package/src/App/renderer/orderItems.test.js +50 -0
- package/src/App/renderer/slotAggregator.js +2 -18
- package/src/App/renderer/slotHelpers.js +3 -1
- package/src/App/renderer/slotHelpers.test.js +5 -0
- package/src/App/renderer/slots.js +3 -0
- package/src/App/store/AppProvider.jsx +4 -2
- package/src/App/store/appDispatchMiddleware.js +1 -1
- package/src/App/store/appDispatchMiddleware.test.js +8 -0
- package/src/InteractiveMap/InteractiveMap.js +8 -2
- package/src/InteractiveMap/InteractiveMap.test.js +20 -3
- package/src/config/appConfig.js +17 -15
- package/src/config/appConfig.test.js +22 -22
- package/src/config/defaults.js +3 -1
- package/src/config/events.js +2 -0
- package/src/config/mergeConfig.js +7 -0
- package/src/config/mergeConfig.test.js +20 -0
- package/src/scss/main.scss +1 -1
- package/src/scss/settings/_colors.scss +1 -0
- package/src/scss/settings/_dimensions.scss +2 -3
- package/src/scss/settings/_transition.scss +1 -1
- package/src/services/eventBus.js +44 -0
- package/src/services/eventBus.test.js +83 -0
- package/src/services/symbolRegistry.js +1 -1
- package/src/test-utils.js +5 -0
- package/src/types.js +25 -7
- package/webpack.umd.mjs +2 -0
- package/plugins/datasets/src/components/Key/EmptyKey.jsx +0 -7
- package/plugins/datasets/src/components/Key/Key.jsx +0 -50
- package/plugins/datasets/src/components/Key/KeyGroupItem.jsx +0 -18
- package/plugins/datasets/src/components/Key/KeyItem.jsx +0 -23
- package/plugins/datasets/src/components/Key/KeySvg.jsx +0 -22
- package/plugins/datasets/src/components/Key/KeySvgLine.jsx +0 -19
- package/plugins/datasets/src/components/Key/KeySvgPattern.jsx +0 -13
- package/plugins/datasets/src/components/Key/KeySvgRect.jsx +0 -22
- package/plugins/datasets/src/components/Key/KeySvgSymbol.jsx +0 -16
- package/plugins/datasets/src/components/LayersMenu/LayersRadioGroupWrapper.jsx +0 -41
- /package/plugins/{datasets → menu}/src/reducers/menuStateReducer.js +0 -0
- /package/{providers/maplibre/src → src}/utils/rasteriseToImageData.js +0 -0
- /package/{providers/maplibre/src → src}/utils/rasteriseToImageData.test.js +0 -0
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
datasetsWithGroups, expectedDatasetsMenuConfigWithGroups
|
|
4
4
|
} from './__data__/demoDatasets.js'
|
|
5
5
|
|
|
6
|
-
import { datasetsToMenu } from './datasetsToMenu'
|
|
6
|
+
import { datasetsToMenu, addDatasetToMenu, removeDatasetsFromMenu } from './datasetsToMenu'
|
|
7
7
|
|
|
8
8
|
describe('datasetsToMenu', () => {
|
|
9
9
|
describe('Missing or empty datasets', () => {
|
|
@@ -80,5 +80,58 @@ describe('datasetsToMenu', () => {
|
|
|
80
80
|
const result = datasetsToMenu({ datasets: [sublayerDataset(true, false)] })
|
|
81
81
|
expect(result).toEqual([{ id: 'test', items: [{ id: 'test', label: 'Test' }], type: 'checkbox', visibleWhen: true }])
|
|
82
82
|
})
|
|
83
|
+
|
|
84
|
+
it('skips a parent with showInMenu:false when no sublayers are visible', () => {
|
|
85
|
+
// Contrived: a getter that returns true on the first access (outer filter's `some`)
|
|
86
|
+
// and false on subsequent accesses (inner filter), hitting the early-return guard.
|
|
87
|
+
let calls = 0
|
|
88
|
+
const dataset = {
|
|
89
|
+
id: 'tricky',
|
|
90
|
+
label: 'Tricky',
|
|
91
|
+
showInMenu: false,
|
|
92
|
+
sublayers: [{ id: 'tricky-a', label: 'A', get showInMenu () { return calls++ === 0 } }]
|
|
93
|
+
}
|
|
94
|
+
const result = datasetsToMenu({ datasets: [dataset] })
|
|
95
|
+
expect(result).toEqual([])
|
|
96
|
+
})
|
|
97
|
+
})
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
describe('addDatasetToMenu', () => {
|
|
101
|
+
it('appends to an existing menu group with matching groupLabel', () => {
|
|
102
|
+
const state = {
|
|
103
|
+
menu: [{ id: 'Layers', groupLabel: 'Layers', type: 'checkbox', visibleWhen: true, items: [{ id: 'roads', label: 'Roads' }] }]
|
|
104
|
+
}
|
|
105
|
+
const dataset = { id: 'rivers', label: 'Rivers', showInMenu: true, groupLabel: 'Layers' }
|
|
106
|
+
const result = addDatasetToMenu(state, dataset)
|
|
107
|
+
expect(result[0].items).toHaveLength(2)
|
|
108
|
+
expect(result[0].items[1]).toEqual({ id: 'rivers', label: 'Rivers' })
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
it('pushes a new group when no matching groupLabel exists', () => {
|
|
112
|
+
const state = { menu: [] }
|
|
113
|
+
const dataset = { id: 'parks', label: 'Parks', showInMenu: true }
|
|
114
|
+
const result = addDatasetToMenu(state, dataset)
|
|
115
|
+
expect(result).toHaveLength(1)
|
|
116
|
+
expect(result[0].items[0].id).toBe('parks')
|
|
117
|
+
})
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
describe('removeDatasetsFromMenu', () => {
|
|
121
|
+
it('keeps groups that still have items after filtering', () => {
|
|
122
|
+
const menu = [
|
|
123
|
+
{ id: 'Layers', items: [{ id: 'roads' }, { id: 'rivers' }] }
|
|
124
|
+
]
|
|
125
|
+
const result = removeDatasetsFromMenu(menu, ['roads'])
|
|
126
|
+
expect(result).toHaveLength(1)
|
|
127
|
+
expect(result[0].items).toEqual([{ id: 'rivers' }])
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
it('removes groups that are left with no items', () => {
|
|
131
|
+
const menu = [
|
|
132
|
+
{ id: 'Layers', items: [{ id: 'roads' }] }
|
|
133
|
+
]
|
|
134
|
+
const result = removeDatasetsFromMenu(menu, ['roads'])
|
|
135
|
+
expect(result).toHaveLength(0)
|
|
83
136
|
})
|
|
84
137
|
})
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { addDatasetToMenu, removeDatasetsFromMenu } from './datasetsToMenu.js'
|
|
2
|
-
import { buildMenuState } from './menuStateReducer.js'
|
|
3
2
|
import { mappedDatasetsReducer } from './mappedDatasetsReducer.js'
|
|
4
3
|
import { logger } from '../../../../src/services/logger.js'
|
|
5
4
|
|
|
@@ -19,8 +18,7 @@ const initialState = {
|
|
|
19
18
|
mappedDatasets: {},
|
|
20
19
|
orderedDatasets: [],
|
|
21
20
|
actionsArray: [],
|
|
22
|
-
menu: []
|
|
23
|
-
menuState: {}
|
|
21
|
+
menu: []
|
|
24
22
|
}
|
|
25
23
|
|
|
26
24
|
const validateDatasetExists = (state, datasetId, prefix, suffix = 'not found') => {
|
|
@@ -46,21 +44,11 @@ const setGlobalState = (state, payload) => {
|
|
|
46
44
|
})
|
|
47
45
|
}
|
|
48
46
|
|
|
49
|
-
const updateMenuState = (state, payload) => {
|
|
50
|
-
return addAction('applyGlobalVisibility', [], {
|
|
51
|
-
...state,
|
|
52
|
-
menuState: { ...state.menuState, ...payload }
|
|
53
|
-
})
|
|
54
|
-
}
|
|
55
|
-
|
|
56
47
|
const setMenu = (state, payload) => {
|
|
57
48
|
const { menu } = payload
|
|
58
|
-
// build the initial menuState for radios from the menu
|
|
59
|
-
const menuState = buildMenuState(menu)
|
|
60
49
|
return {
|
|
61
50
|
...state,
|
|
62
|
-
menu
|
|
63
|
-
menuState
|
|
51
|
+
menu
|
|
64
52
|
}
|
|
65
53
|
}
|
|
66
54
|
|
|
@@ -223,8 +211,7 @@ const actions = {
|
|
|
223
211
|
SHOW_FEATURES: showFeatures,
|
|
224
212
|
REMOVE_ADAPTER_ACTIONS: removeAdapterActions,
|
|
225
213
|
SET_GLOBAL_STATE: setGlobalState,
|
|
226
|
-
SET_MENU: setMenu
|
|
227
|
-
UPDATE_MENU_STATE: updateMenuState
|
|
214
|
+
SET_MENU: setMenu
|
|
228
215
|
}
|
|
229
216
|
|
|
230
217
|
export {
|
|
@@ -172,6 +172,29 @@ describe('SET_DATASET_VISIBILITY', () => {
|
|
|
172
172
|
expect(logger.error).toHaveBeenCalledWith(expect.stringContaining("'unknown'"))
|
|
173
173
|
expect(result).toBe(state)
|
|
174
174
|
})
|
|
175
|
+
|
|
176
|
+
it('returns unchanged state when visibility already matches', () => {
|
|
177
|
+
const state = makeStateWithDataset('roads')
|
|
178
|
+
const result = actions.SET_DATASET_VISIBILITY(state, { datasetId: 'roads', visible: true })
|
|
179
|
+
expect(result).toBe(state)
|
|
180
|
+
})
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
// ─── SET_MENU ────────────────────────────────────────────────────────────────
|
|
184
|
+
|
|
185
|
+
describe('SET_MENU', () => {
|
|
186
|
+
it('sets menu from payload', () => {
|
|
187
|
+
const state = makeState()
|
|
188
|
+
const menu = [{ id: 'layers', items: [] }]
|
|
189
|
+
const result = actions.SET_MENU(state, { menu })
|
|
190
|
+
expect(result.menu).toBe(menu)
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
it('does not add to actionsArray', () => {
|
|
194
|
+
const state = makeState()
|
|
195
|
+
const result = actions.SET_MENU(state, { menu: [] })
|
|
196
|
+
expect(result.actionsArray).toEqual([])
|
|
197
|
+
})
|
|
175
198
|
})
|
|
176
199
|
|
|
177
200
|
// ─── SET_GLOBAL_VISIBILITY ────────────────────────────────────────────────────
|
|
@@ -67,12 +67,11 @@ export class Dataset {
|
|
|
67
67
|
get hasHiddenFeatures () { return Boolean(this.hiddenFeatures?.length > 0 || this.parent?.hasHiddenFeatures) }
|
|
68
68
|
|
|
69
69
|
get filter () {
|
|
70
|
-
return null
|
|
70
|
+
return null
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
// Returns true if either the parent (if it has one) or global visibility is hidden , otherwise returns true.
|
|
74
74
|
// This is used to determine whether to show a tooltip
|
|
75
|
-
// TODO: also work out how to convey datasets hidden by zoom filter.
|
|
76
75
|
get isHiddenByInheritance () {
|
|
77
76
|
if (this.isSublayer) {
|
|
78
77
|
return !this.parent?.visible
|
|
@@ -109,7 +108,7 @@ export class Dataset {
|
|
|
109
108
|
}
|
|
110
109
|
|
|
111
110
|
get keyVisibility () {
|
|
112
|
-
return this.visibility === 'visible'
|
|
111
|
+
return this.showInKey && this.visibility === 'visible'
|
|
113
112
|
}
|
|
114
113
|
|
|
115
114
|
get symbolAnchor () {
|
|
@@ -165,7 +164,7 @@ export class Dataset {
|
|
|
165
164
|
// any child with a parent opacity only would be multiplied by itself
|
|
166
165
|
return {
|
|
167
166
|
...parentStyle,
|
|
168
|
-
opacity: undefined,
|
|
167
|
+
opacity: undefined, // NOSONAR - we need to set this to undefined so that the opacity getter can calculate the correct opacity
|
|
169
168
|
...this._datasetDefinition.style,
|
|
170
169
|
symbolDescription: this.symbolDescription
|
|
171
170
|
}
|
|
@@ -202,4 +201,16 @@ export class Dataset {
|
|
|
202
201
|
}
|
|
203
202
|
return styleSymbols
|
|
204
203
|
}
|
|
204
|
+
|
|
205
|
+
get keyDefinition () {
|
|
206
|
+
return {
|
|
207
|
+
id: this.id,
|
|
208
|
+
type: 'dataset',
|
|
209
|
+
label: this.label,
|
|
210
|
+
hasSymbol: this.hasSymbol,
|
|
211
|
+
hasPattern: this.hasPattern,
|
|
212
|
+
style: this.style,
|
|
213
|
+
symbolDescription: this.symbolDescription
|
|
214
|
+
}
|
|
215
|
+
}
|
|
205
216
|
}
|
|
@@ -494,4 +494,65 @@ describe('Dataset class', () => {
|
|
|
494
494
|
expect(new Dataset(childDef).sourceLayer).toBe('parent_layer')
|
|
495
495
|
})
|
|
496
496
|
})
|
|
497
|
+
|
|
498
|
+
describe('isHiddenByInheritance', () => {
|
|
499
|
+
it('returns true for a sublayer whose parent is not visible', () => {
|
|
500
|
+
const parentDef = { id: 'parent', visible: false, style: {} }
|
|
501
|
+
const childDef = { id: 'child', parentId: 'parent', visible: true, style: {} }
|
|
502
|
+
datasetRegistry.attach({ parent: parentDef, child: childDef })
|
|
503
|
+
expect(new Dataset(childDef).isHiddenByInheritance).toBe(true)
|
|
504
|
+
})
|
|
505
|
+
|
|
506
|
+
it('returns false for a sublayer whose parent is visible', () => {
|
|
507
|
+
const parentDef = { id: 'parent', visible: true, style: {} }
|
|
508
|
+
const childDef = { id: 'child', parentId: 'parent', visible: true, style: {} }
|
|
509
|
+
datasetRegistry.attach({ parent: parentDef, child: childDef })
|
|
510
|
+
expect(new Dataset(childDef).isHiddenByInheritance).toBe(false)
|
|
511
|
+
})
|
|
512
|
+
|
|
513
|
+
it('returns false for a top-level dataset when global visibility is true', () => {
|
|
514
|
+
const dataset = new Dataset({ id: 'top', visible: true, style: {} })
|
|
515
|
+
expect(dataset.isHiddenByInheritance).toBe(false)
|
|
516
|
+
})
|
|
517
|
+
})
|
|
518
|
+
|
|
519
|
+
describe('isLocallyVisible', () => {
|
|
520
|
+
it('returns the raw visible flag from the definition when not visible', () => {
|
|
521
|
+
const dataset = new Dataset({ visible: false })
|
|
522
|
+
expect(dataset.isLocallyVisible).toBe(false)
|
|
523
|
+
})
|
|
524
|
+
|
|
525
|
+
it('returns undefined when visible is not set and dataset is not visible', () => {
|
|
526
|
+
const dataset = new Dataset({})
|
|
527
|
+
expect(dataset.isLocallyVisible).toBeUndefined()
|
|
528
|
+
})
|
|
529
|
+
|
|
530
|
+
it('returns true when isVisible is truthy (subclass override scenario)', () => {
|
|
531
|
+
const dataset = new Dataset({ visible: false })
|
|
532
|
+
Object.defineProperty(dataset, 'isVisible', { get: () => true, configurable: true })
|
|
533
|
+
expect(dataset.isLocallyVisible).toBe(true)
|
|
534
|
+
})
|
|
535
|
+
})
|
|
536
|
+
|
|
537
|
+
describe('dynamicGeoJSON getter', () => {
|
|
538
|
+
it('returns a DynamicGeoJson with idProperty set', () => {
|
|
539
|
+
const dataset = new Dataset({
|
|
540
|
+
id: 'parcels',
|
|
541
|
+
dynamicGeoJSON: { url: 'http://example.com', idProperty: 'parcel_id' }
|
|
542
|
+
})
|
|
543
|
+
const dg = dataset.dynamicGeoJSON
|
|
544
|
+
expect(dg.source.promoteId).toBe('parcel_id')
|
|
545
|
+
expect(dg.source.generateId).toBeUndefined()
|
|
546
|
+
})
|
|
547
|
+
|
|
548
|
+
it('returns a DynamicGeoJson with generateId when no idProperty', () => {
|
|
549
|
+
const dataset = new Dataset({
|
|
550
|
+
id: 'parcels',
|
|
551
|
+
dynamicGeoJSON: { url: 'http://example.com' }
|
|
552
|
+
})
|
|
553
|
+
const dg = dataset.dynamicGeoJSON
|
|
554
|
+
expect(dg.source.generateId).toBe(true)
|
|
555
|
+
expect(dg.source.promoteId).toBeUndefined()
|
|
556
|
+
})
|
|
557
|
+
})
|
|
497
558
|
})
|
|
@@ -83,7 +83,12 @@ const datasetRegistry = {
|
|
|
83
83
|
}, { patternConfigs: [], symbolConfigs: [] })
|
|
84
84
|
},
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
_lastMenuState: {},
|
|
87
|
+
invalidateKeyItemsOnMenuStateChange (menuState) {
|
|
88
|
+
if (menuState === this._lastMenuState) {
|
|
89
|
+
return
|
|
90
|
+
}
|
|
91
|
+
this._lastMenuState = menuState
|
|
87
92
|
this._lastKeyItemsDatasets = null
|
|
88
93
|
},
|
|
89
94
|
_lastKeyItems: {},
|
|
@@ -101,8 +106,9 @@ const datasetRegistry = {
|
|
|
101
106
|
}
|
|
102
107
|
const groupObject = {
|
|
103
108
|
type: 'group',
|
|
109
|
+
id: groupLabel.toLowerCase().replaceAll(/\s+/g, '-'),
|
|
104
110
|
groupLabel,
|
|
105
|
-
|
|
111
|
+
keyDefinitions: []
|
|
106
112
|
}
|
|
107
113
|
groups.set(groupLabel, groupObject)
|
|
108
114
|
_items.push(groupObject)
|
|
@@ -110,22 +116,22 @@ const datasetRegistry = {
|
|
|
110
116
|
}
|
|
111
117
|
|
|
112
118
|
this.forEach((dataset) => {
|
|
113
|
-
if (!
|
|
119
|
+
if (!dataset.keyVisibility) {
|
|
114
120
|
return
|
|
115
121
|
}
|
|
116
122
|
const isGroup = dataset.hasSublayers || dataset.groupLabel
|
|
117
123
|
if (!isGroup) {
|
|
118
|
-
_items.push({ type: 'flat', dataset })
|
|
124
|
+
_items.push({ type: 'flat', id: dataset.id, keyDefinition: dataset.keyDefinition })
|
|
119
125
|
return
|
|
120
126
|
}
|
|
121
127
|
|
|
122
128
|
const groupLabel = dataset.groupLabel || dataset.label
|
|
123
129
|
const groupObject = getOrCreateGroup(groupLabel)
|
|
124
130
|
if (!dataset.hasSublayers) {
|
|
125
|
-
groupObject.
|
|
131
|
+
groupObject.keyDefinitions.push(dataset.keyDefinition)
|
|
126
132
|
}
|
|
127
133
|
})
|
|
128
|
-
const items = _items.filter((item) => item.type === 'flat' || Boolean(item.
|
|
134
|
+
const items = _items.filter((item) => item.type === 'flat' || Boolean(item.keyDefinitions?.length))
|
|
129
135
|
const hasGroups = items.some(item => item.type === 'group')
|
|
130
136
|
this._lastKeyItems = { items, hasGroups }
|
|
131
137
|
return this._lastKeyItems
|
|
@@ -134,7 +140,4 @@ const datasetRegistry = {
|
|
|
134
140
|
|
|
135
141
|
Object.defineProperty(datasetRegistry, 'datasets', { get: () => datasetRegistry._datasets })
|
|
136
142
|
|
|
137
|
-
// TODO remove this global reference once development is finished
|
|
138
|
-
window.datasetRegistry = datasetRegistry
|
|
139
|
-
|
|
140
143
|
export { datasetRegistry }
|
|
@@ -148,6 +148,7 @@ describe('datasetRegistry', () => {
|
|
|
148
148
|
const { mappedDatasets: singleHiddenSublayer, orderedDatasets } = mappedDatasetsReducer({
|
|
149
149
|
datasets: [{
|
|
150
150
|
id: 'single-sublayer-dataset',
|
|
151
|
+
label: 'Single Layer',
|
|
151
152
|
showInKey: true,
|
|
152
153
|
visible: true,
|
|
153
154
|
style: {},
|
|
@@ -162,7 +163,7 @@ describe('datasetRegistry', () => {
|
|
|
162
163
|
it('only includes visible sublayers in group items', () => {
|
|
163
164
|
const { items } = datasetRegistry.keyItems()
|
|
164
165
|
const landCoversItem = items.find(item => item.type === 'group' && item.groupLabel === 'Land covers')
|
|
165
|
-
const sublayerIds = landCoversItem.
|
|
166
|
+
const sublayerIds = landCoversItem.keyDefinitions.map(s => s.id)
|
|
166
167
|
expect(sublayerIds).not.toContain('land-covers-379') // land-covers-379 has visible: false
|
|
167
168
|
})
|
|
168
169
|
|
|
@@ -180,7 +181,7 @@ describe('datasetRegistry', () => {
|
|
|
180
181
|
datasetRegistry.attach(grouped, orderedDatasets)
|
|
181
182
|
const { items } = datasetRegistry.keyItems()
|
|
182
183
|
const groupLabels = items.filter(i => i.type === 'group').map(i => i.groupLabel)
|
|
183
|
-
expect(groupLabels
|
|
184
|
+
expect(groupLabels).toHaveLength(new Set(groupLabels).size)
|
|
184
185
|
})
|
|
185
186
|
|
|
186
187
|
it('populates group item datasets with matching showInKey datasets', () => {
|
|
@@ -188,7 +189,7 @@ describe('datasetRegistry', () => {
|
|
|
188
189
|
datasetRegistry.attach(grouped, orderedDatasets)
|
|
189
190
|
const { items } = datasetRegistry.keyItems()
|
|
190
191
|
const groupItem = items.find(item => item.type === 'group' && item.groupLabel === 'Test group')
|
|
191
|
-
const ids = groupItem.
|
|
192
|
+
const ids = groupItem.keyDefinitions.map(d => d.id)
|
|
192
193
|
expect(ids).toContain('existing-fields')
|
|
193
194
|
expect(ids).toContain('hedge-control')
|
|
194
195
|
})
|
|
@@ -199,13 +200,24 @@ describe('datasetRegistry', () => {
|
|
|
199
200
|
expect(result1).toBe(result2)
|
|
200
201
|
})
|
|
201
202
|
|
|
202
|
-
it('recalculates
|
|
203
|
+
it('recalculates the keyItems when invalidateKeyItemsOnMenuStateChange is called with new menuState', () => {
|
|
204
|
+
const menuState = { someMenuKey: 'someValue' }
|
|
205
|
+
datasetRegistry.invalidateKeyItemsOnMenuStateChange({})
|
|
203
206
|
const result1 = datasetRegistry.keyItems()
|
|
204
|
-
datasetRegistry.
|
|
207
|
+
datasetRegistry.invalidateKeyItemsOnMenuStateChange(menuState)
|
|
205
208
|
const result2 = datasetRegistry.keyItems()
|
|
206
209
|
expect(result1).not.toBe(result2)
|
|
207
210
|
})
|
|
208
211
|
|
|
212
|
+
it('keeps the cached keyItems when invalidateKeyItemsOnMenuStateChange is called with the same menuState', () => {
|
|
213
|
+
const menuState = { someMenuKey: 'someOtherValue' }
|
|
214
|
+
datasetRegistry.invalidateKeyItemsOnMenuStateChange(menuState)
|
|
215
|
+
const result1 = datasetRegistry.keyItems()
|
|
216
|
+
datasetRegistry.invalidateKeyItemsOnMenuStateChange(menuState)
|
|
217
|
+
const result2 = datasetRegistry.keyItems()
|
|
218
|
+
expect(result1).toBe(result2)
|
|
219
|
+
})
|
|
220
|
+
|
|
209
221
|
it('recomputes when the datasets ref changes', () => {
|
|
210
222
|
const result1 = datasetRegistry.keyItems()
|
|
211
223
|
datasetRegistry.attach({ simple: { id: 'simple', showInKey: true, visible: true, style: {} } }, ['simple'])
|
|
@@ -4,9 +4,6 @@ export const attachGlobalState = (globalStateRef) => {
|
|
|
4
4
|
globalState = globalStateRef
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
// TODO - remove this once testing finishes
|
|
8
|
-
window.getGlobalState = () => Object.freeze(globalState)
|
|
9
|
-
|
|
10
7
|
const calculateLocalOpacity = (opacityValue, parentOpacityValue) => {
|
|
11
8
|
if (opacityValue === undefined) {
|
|
12
9
|
if (parentOpacityValue === undefined) {
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { datasetRegistry } from './datasetRegistry.js'
|
|
2
2
|
|
|
3
|
-
let
|
|
4
|
-
export const
|
|
3
|
+
let _menuStateRef = {}
|
|
4
|
+
export const attachMenuStateRef = (menuStateRef) => {
|
|
5
|
+
_menuStateRef = menuStateRef
|
|
6
|
+
}
|
|
5
7
|
|
|
6
8
|
const _isVisibleWhenMenuCheck = (menuVisibleWhen) => {
|
|
9
|
+
const menuState = _menuStateRef?.current?.menuState || {}
|
|
7
10
|
for (const [key, valueArray] of Object.entries(menuVisibleWhen)) {
|
|
8
|
-
const menuValue =
|
|
11
|
+
const menuValue = menuState[key]
|
|
9
12
|
if (!valueArray.includes(menuValue)) {
|
|
10
13
|
return false
|
|
11
14
|
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import { isVisibleWhen,
|
|
1
|
+
import { isVisibleWhen, attachMenuStateRef } from './isVisibleWhen.js'
|
|
2
2
|
import { datasetRegistry } from './datasetRegistry.js'
|
|
3
3
|
|
|
4
|
+
const setMenuState = (menuState) => {
|
|
5
|
+
attachMenuStateRef({ current: { menuState } })
|
|
6
|
+
}
|
|
7
|
+
|
|
4
8
|
describe('isVisibleWhen', () => {
|
|
5
9
|
beforeEach(() => {
|
|
6
10
|
// reset menu state before each test
|
|
@@ -64,4 +68,10 @@ describe('isVisibleWhen', () => {
|
|
|
64
68
|
const visibleWhen = 'incorrectly-configured'
|
|
65
69
|
expect(isVisibleWhen(visibleWhen)).toBe(true)
|
|
66
70
|
})
|
|
71
|
+
|
|
72
|
+
it('returns false when menu condition is checked and menuState has not been set up', () => {
|
|
73
|
+
attachMenuStateRef({}) // current is undefined — exercises the || {} fallback
|
|
74
|
+
const visibleWhen = { menu: { datasets: ['floodZones'] } }
|
|
75
|
+
expect(isVisibleWhen(visibleWhen)).toBe(false)
|
|
76
|
+
})
|
|
67
77
|
})
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { getBboxArray, bboxContains, expandBbox, bboxIntersects, getGeometryBbox } from './bbox.js'
|
|
2
|
+
|
|
3
|
+
// ─── getBboxArray ─────────────────────────────────────────────────────────────
|
|
4
|
+
|
|
5
|
+
describe('getBboxArray', () => {
|
|
6
|
+
it('returns [west, south, east, north] from a map bounds object', () => {
|
|
7
|
+
const map = {
|
|
8
|
+
getBounds: () => ({
|
|
9
|
+
getWest: () => -1,
|
|
10
|
+
getSouth: () => 50,
|
|
11
|
+
getEast: () => 1,
|
|
12
|
+
getNorth: () => 52
|
|
13
|
+
})
|
|
14
|
+
}
|
|
15
|
+
expect(getBboxArray(map)).toEqual([-1, 50, 1, 52])
|
|
16
|
+
})
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
// ─── bboxContains ─────────────────────────────────────────────────────────────
|
|
20
|
+
|
|
21
|
+
describe('bboxContains', () => {
|
|
22
|
+
const outer = [-2, 49, 2, 53]
|
|
23
|
+
|
|
24
|
+
it('returns false when outer is null', () => {
|
|
25
|
+
expect(bboxContains(null, [-1, 50, 1, 52])).toBe(false)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('returns false when inner is null', () => {
|
|
29
|
+
expect(bboxContains(outer, null)).toBe(false)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it('returns true when inner is fully inside outer', () => {
|
|
33
|
+
expect(bboxContains(outer, [-1, 50, 1, 52])).toBe(true)
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it('returns false when inner extends outside outer', () => {
|
|
37
|
+
expect(bboxContains(outer, [-3, 50, 1, 52])).toBe(false)
|
|
38
|
+
})
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
// ─── expandBbox ───────────────────────────────────────────────────────────────
|
|
42
|
+
|
|
43
|
+
describe('expandBbox', () => {
|
|
44
|
+
it('returns a copy of addition when existing is null', () => {
|
|
45
|
+
expect(expandBbox(null, [1, 2, 3, 4])).toEqual([1, 2, 3, 4])
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it('returns the bounding union of existing and addition', () => {
|
|
49
|
+
expect(expandBbox([-1, 49, 1, 51], [-2, 50, 2, 52])).toEqual([-2, 49, 2, 52])
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
// ─── bboxIntersects ───────────────────────────────────────────────────────────
|
|
54
|
+
|
|
55
|
+
describe('bboxIntersects', () => {
|
|
56
|
+
it('returns false when a is null', () => {
|
|
57
|
+
expect(bboxIntersects(null, [0, 0, 1, 1])).toBe(false)
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it('returns false when b is null', () => {
|
|
61
|
+
expect(bboxIntersects([0, 0, 1, 1], null)).toBe(false)
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('returns true when bboxes overlap', () => {
|
|
65
|
+
expect(bboxIntersects([0, 0, 2, 2], [1, 1, 3, 3])).toBe(true)
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it('returns false when bboxes do not overlap', () => {
|
|
69
|
+
expect(bboxIntersects([0, 0, 1, 1], [2, 2, 3, 3])).toBe(false)
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
// ─── getGeometryBbox ──────────────────────────────────────────────────────────
|
|
74
|
+
|
|
75
|
+
describe('getGeometryBbox', () => {
|
|
76
|
+
it('handles a Point', () => {
|
|
77
|
+
expect(getGeometryBbox({ type: 'Point', coordinates: [10, 20] }))
|
|
78
|
+
.toEqual([10, 20, 10, 20])
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
it('handles a LineString', () => {
|
|
82
|
+
expect(getGeometryBbox({ type: 'LineString', coordinates: [[0, 0], [2, 4]] }))
|
|
83
|
+
.toEqual([0, 0, 2, 4])
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it('handles a MultiPoint', () => {
|
|
87
|
+
expect(getGeometryBbox({ type: 'MultiPoint', coordinates: [[1, 2], [3, 4]] }))
|
|
88
|
+
.toEqual([1, 2, 3, 4])
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
it('handles a Polygon', () => {
|
|
92
|
+
const ring = [[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]]
|
|
93
|
+
expect(getGeometryBbox({ type: 'Polygon', coordinates: [ring] }))
|
|
94
|
+
.toEqual([0, 0, 5, 5])
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
it('handles a MultiLineString', () => {
|
|
98
|
+
expect(getGeometryBbox({
|
|
99
|
+
type: 'MultiLineString',
|
|
100
|
+
coordinates: [[[0, 0], [1, 1]], [[2, 2], [3, 3]]]
|
|
101
|
+
})).toEqual([0, 0, 3, 3])
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
it('handles a MultiPolygon', () => {
|
|
105
|
+
const poly1 = [[[0, 0], [0, 2], [2, 2], [2, 0], [0, 0]]]
|
|
106
|
+
const poly2 = [[[3, 3], [3, 5], [5, 5], [5, 3], [3, 3]]]
|
|
107
|
+
expect(getGeometryBbox({ type: 'MultiPolygon', coordinates: [poly1, poly2] }))
|
|
108
|
+
.toEqual([0, 0, 5, 5])
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
it('handles a GeometryCollection', () => {
|
|
112
|
+
expect(getGeometryBbox({
|
|
113
|
+
type: 'GeometryCollection',
|
|
114
|
+
geometries: [
|
|
115
|
+
{ type: 'Point', coordinates: [1, 2] },
|
|
116
|
+
{ type: 'Point', coordinates: [5, 6] }
|
|
117
|
+
]
|
|
118
|
+
})).toEqual([1, 2, 5, 6])
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
it('throws for an unsupported geometry type', () => {
|
|
122
|
+
expect(() => getGeometryBbox({ type: 'Triangle', coordinates: [] }))
|
|
123
|
+
.toThrow('Unsupported geometry type: Triangle')
|
|
124
|
+
})
|
|
125
|
+
})
|