@defra/interactive-map 0.0.40-alpha → 0.0.42-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/button-definition.md +7 -8
- package/docs/api/control-definition.md +17 -1
- package/docs/api/panel-definition.md +5 -0
- package/docs/api/slots.md +50 -6
- package/docs/assets/images/slot-map.svg +61 -262
- package/docs/examples/add-polygons.mdx +8 -2
- package/docs/examples/add-symbols.mdx +8 -2
- package/docs/examples/draw-tools.mdx +3 -3
- package/docs/plugins/datasets.md +23 -15
- package/docs/plugins/draw.md +79 -16
- package/docs/plugins/map-key.md +147 -0
- package/docs/plugins/search.md +1 -1
- package/docs/plugins.md +5 -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/umd/im-map-styles-plugin.js +1 -1
- package/plugins/beta/map-styles/dist/umd/index.js +1 -1
- package/plugins/beta/use-location/dist/esm/im-use-location-plugin.js +1 -1
- package/plugins/beta/use-location/dist/umd/im-use-location-plugin.js +1 -1
- package/plugins/beta/use-location/src/manifest.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.test.js +175 -0
- package/plugins/datasets/src/adapters/esri/registry/esriDataset.test.js +55 -0
- package/plugins/datasets/src/adapters/loadLayerAdapter.test.js +61 -0
- package/plugins/datasets/src/adapters/maplibre/maplibreLayerAdapter.test.js +14 -0
- 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 -4
- 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 +13 -1
- package/plugins/datasets/src/registry/dataset.test.js +61 -0
- package/plugins/datasets/src/registry/datasetRegistry.js +12 -6
- package/plugins/datasets/src/registry/datasetRegistry.test.js +16 -4
- 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 +10 -2
- package/plugins/draw/src/DrawInit.test.jsx +51 -10
- package/plugins/draw/src/adapters/maplibre/MaplibreDrawAdapter.js +91 -11
- 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/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 +4 -27
- 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 +3 -53
- 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 +10 -3
- 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.test.js +12 -0
- package/plugins/draw/src/adapters/openlayers/draw/drawInput.js +8 -2
- package/plugins/draw/src/adapters/openlayers/edit/EditMode.test.js +31 -0
- package/plugins/draw/src/adapters/openlayers/edit/keyboardHandler.js +9 -5
- package/plugins/draw/src/adapters/openlayers/edit/keyboardHandler.test.js +33 -0
- 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 +10 -3
- package/plugins/draw/src/adapters/openlayers/edit/nudge.test.js +24 -1
- 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/createNewShape.js +41 -0
- package/plugins/draw/src/api/createNewShape.test.js +63 -0
- package/plugins/draw/src/api/editFeature.js +7 -4
- package/plugins/draw/src/api/editFeature.test.js +16 -0
- package/plugins/draw/src/api/newLine.js +2 -40
- package/plugins/draw/src/api/newPoint.js +42 -0
- package/plugins/draw/src/api/newPoint.test.js +117 -0
- package/plugins/draw/src/api/newPolygon.js +2 -40
- 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 +17 -10
- package/plugins/draw/src/events.test.js +14 -0
- 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/useHighlightSync.js +33 -12
- package/plugins/interact/src/hooks/useHighlightSync.test.js +96 -25
- package/plugins/interact/src/manifest.js +1 -1
- 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 +68 -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 +43 -0
- package/plugins/{datasets → map-key}/src/components/Key/Key.module.scss +21 -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 +26 -0
- package/plugins/map-key/src/components/Key/KeyItem.test.jsx +67 -0
- package/plugins/map-key/src/components/Key/KeySvg.jsx +41 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvg.test.jsx +14 -12
- package/plugins/map-key/src/components/Key/KeySvgLine.jsx +22 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgLine.test.jsx +1 -1
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgPattern.jsx +7 -2
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgPattern.test.jsx +8 -2
- package/plugins/map-key/src/components/Key/KeySvgRect.jsx +26 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgRect.test.jsx +1 -1
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgSymbol.jsx +8 -3
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgSymbol.test.jsx +17 -6
- package/plugins/map-key/src/components/Key/MapKey.jsx +53 -0
- package/plugins/map-key/src/components/Key/MapKey.test.jsx +147 -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 +2 -3
- 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/src/App/components/Actions/Actions.test.jsx +47 -0
- package/src/App/components/Hints/Hints.test.jsx +13 -0
- package/src/App/components/KeyboardHelp/KeyboardHelp.jsx +25 -23
- package/src/App/components/KeyboardHelp/KeyboardHelp.test.jsx +22 -5
- package/src/App/components/MoveControls/MoveControls.module.scss +41 -10
- package/src/App/components/Panel/Panel.jsx +65 -8
- package/src/App/components/Panel/Panel.module.scss +49 -15
- package/src/App/components/Panel/Panel.test.jsx +114 -1
- package/src/App/components/Tabs/Tabs.jsx +43 -17
- package/src/App/components/Tabs/Tabs.module.scss +32 -5
- package/src/App/components/Tabs/Tabs.test.jsx +40 -10
- package/src/App/components/Tooltip/Tooltip.test.jsx +12 -14
- 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/layout/Layout.jsx +9 -10
- package/src/App/layout/Layout.test.jsx +2 -0
- package/src/App/layout/layout.module.scss +31 -17
- package/src/App/registry/pluginRegistry.js +1 -1
- package/src/App/registry/pluginRegistry.test.js +12 -0
- package/src/App/renderer/HtmlElementHost.jsx +18 -5
- package/src/App/renderer/HtmlElementHost.test.jsx +54 -0
- package/src/App/renderer/groupByKey.js +28 -0
- package/src/App/renderer/groupByKey.test.js +39 -0
- package/src/App/renderer/groupIntoTabs.js +42 -0
- package/src/App/renderer/groupIntoTabs.test.js +95 -0
- package/src/App/renderer/mapButtons.js +97 -129
- package/src/App/renderer/mapButtons.test.js +67 -83
- package/src/App/renderer/mapControls.js +4 -1
- package/src/App/renderer/mapControls.test.js +32 -0
- package/src/App/renderer/mapPanels.js +53 -11
- package/src/App/renderer/mapPanels.test.js +95 -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 +1 -0
- package/src/App/store/appDispatchMiddleware.js +1 -1
- package/src/App/store/appDispatchMiddleware.test.js +8 -0
- package/src/config/appConfig.js +2 -2
- package/src/config/events.js +2 -0
- 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/types.js +31 -3
- 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/KeySvgRect.jsx +0 -22
- 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 ────────────────────────────────────────────────────
|
|
@@ -108,7 +108,7 @@ export class Dataset {
|
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
get keyVisibility () {
|
|
111
|
-
return this.visibility === 'visible'
|
|
111
|
+
return this.showInKey && this.visibility === 'visible'
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
get symbolAnchor () {
|
|
@@ -201,4 +201,16 @@ export class Dataset {
|
|
|
201
201
|
}
|
|
202
202
|
return styleSymbols
|
|
203
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
|
+
}
|
|
204
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
|
|
@@ -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
|
|
|
@@ -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'])
|
|
@@ -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
|
+
})
|