@defra/interactive-map 0.0.29-alpha → 0.0.31-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.
Files changed (195) hide show
  1. package/dist/css/index.css +1 -1
  2. package/dist/esm/im-core.js +1 -1
  3. package/dist/esm/im-shell.js +1 -1
  4. package/dist/umd/im-core.js +1 -1
  5. package/dist/umd/index.js +1 -1
  6. package/docs/api/context.md +4 -4
  7. package/docs/api.md +111 -37
  8. package/docs/assets/css/docusaurus.scss +20 -4
  9. package/docs/assets/images/basic-map.jpg +0 -0
  10. package/docs/assets/images/button-first.jpg +0 -0
  11. package/docs/assets/images/deuteranopia-ozs-map-thumb.jpg +0 -0
  12. package/docs/assets/images/draw.jpg +0 -0
  13. package/docs/assets/images/marker-panel.jpg +0 -0
  14. package/docs/assets/images/night-ozs-map-thumb.jpg +0 -0
  15. package/docs/assets/images/outdoor-ozs-map-thumb.jpg +0 -0
  16. package/docs/assets/images/search.jpg +0 -0
  17. package/docs/assets/images/select-feature.jpg +0 -0
  18. package/docs/assets/images/style-switcher.jpg +0 -0
  19. package/docs/assets/images/toggle-marker-label.jpg +0 -0
  20. package/docs/assets/images/tritanopia-ozs-map-thumb.jpg +0 -0
  21. package/docs/examples/add-marker-with-panel.mdx +2 -2
  22. package/docs/examples/basic-map.mdx +2 -2
  23. package/docs/examples/draw.mdx +271 -0
  24. package/docs/examples/index.mdx +58 -10
  25. package/docs/examples/search-control.mdx +71 -0
  26. package/docs/examples/select-feature.mdx +146 -0
  27. package/docs/examples/style-switcher.mdx +135 -0
  28. package/docs/examples/toggle-marker-label.mdx +3 -3
  29. package/docs/plugins/datasets.md +15 -28
  30. package/docusaurus.config.cjs +5 -1
  31. package/package.json +1 -1
  32. package/plugins/beta/datasets/dist/css/index.css +4 -0
  33. package/plugins/beta/datasets/dist/esm/im-datasets-ml-adapter.js +1 -0
  34. package/plugins/beta/datasets/dist/esm/im-datasets-plugin.js +1 -1
  35. package/plugins/beta/datasets/dist/esm/index.js +1 -1
  36. package/plugins/beta/datasets/dist/umd/im-datasets-ml-adapter.js +2 -0
  37. package/plugins/beta/datasets/dist/umd/im-datasets-plugin.js +2 -0
  38. package/plugins/beta/datasets/dist/umd/index.js +2 -0
  39. package/plugins/beta/datasets/src/adapters/loadLayerAdapter.js +33 -0
  40. package/plugins/beta/datasets/src/adapters/maplibre/layerBuilders.js +44 -120
  41. package/plugins/beta/datasets/src/adapters/maplibre/maplibreLayerAdapter.js +145 -245
  42. package/plugins/beta/datasets/src/adapters/maplibre/maplibreLayerAdapter.test.js +516 -0
  43. package/plugins/beta/datasets/src/adapters/maplibre/registry/mapLibreDataset.js +191 -0
  44. package/plugins/beta/datasets/src/adapters/maplibre/registry/mapLibreDataset.test.js +441 -0
  45. package/plugins/beta/datasets/src/api/addDataset.js +2 -5
  46. package/plugins/beta/datasets/src/api/addDataset.test.js +16 -0
  47. package/plugins/beta/datasets/src/api/getOpacity.js +14 -14
  48. package/plugins/beta/datasets/src/api/getOpacity.test.js +72 -0
  49. package/plugins/beta/datasets/src/api/getStyle.js +8 -9
  50. package/plugins/beta/datasets/src/api/getStyle.test.js +42 -0
  51. package/plugins/beta/datasets/src/api/removeDataset.js +7 -7
  52. package/plugins/beta/datasets/src/api/removeDataset.test.js +45 -0
  53. package/plugins/beta/datasets/src/api/setData.js +9 -3
  54. package/plugins/beta/datasets/src/api/setData.test.js +62 -0
  55. package/plugins/beta/datasets/src/api/setDatasetVisibility.js +5 -30
  56. package/plugins/beta/datasets/src/api/setDatasetVisibility.test.js +31 -0
  57. package/plugins/beta/datasets/src/api/setFeatureVisibility.js +3 -21
  58. package/plugins/beta/datasets/src/api/setFeatureVisibility.test.js +32 -0
  59. package/plugins/beta/datasets/src/api/setGlobals.js +20 -0
  60. package/plugins/beta/datasets/src/api/setGlobals.test.js +63 -0
  61. package/plugins/beta/datasets/src/api/setOpacity.js +8 -27
  62. package/plugins/beta/datasets/src/api/setOpacity.test.js +31 -0
  63. package/plugins/beta/datasets/src/api/setStyle.js +5 -21
  64. package/plugins/beta/datasets/src/api/setStyle.test.js +53 -0
  65. package/plugins/beta/datasets/src/components/Key/Key.jsx +51 -0
  66. package/plugins/beta/datasets/src/components/Key/KeyGroupItem.jsx +18 -0
  67. package/plugins/beta/datasets/src/components/Key/KeyItem.jsx +20 -0
  68. package/plugins/beta/datasets/src/components/Key/KeySvg.jsx +22 -0
  69. package/plugins/beta/datasets/src/components/Key/KeySvg.test.jsx +87 -0
  70. package/plugins/beta/datasets/src/components/Key/KeySvgLine.jsx +19 -0
  71. package/plugins/beta/datasets/src/components/Key/KeySvgLine.test.jsx +71 -0
  72. package/plugins/beta/datasets/src/components/{KeySvgPattern.jsx → Key/KeySvgPattern.jsx} +3 -4
  73. package/plugins/beta/datasets/src/components/Key/KeySvgPattern.test.jsx +55 -0
  74. package/plugins/beta/datasets/src/components/Key/KeySvgRect.jsx +22 -0
  75. package/plugins/beta/datasets/src/components/Key/KeySvgRect.test.jsx +85 -0
  76. package/plugins/beta/datasets/src/components/{KeySvgSymbol.jsx → Key/KeySvgSymbol.jsx} +5 -5
  77. package/plugins/beta/datasets/src/components/Key/KeySvgSymbol.test.jsx +80 -0
  78. package/plugins/beta/datasets/src/components/Key/svgProperties.test.js +61 -0
  79. package/plugins/beta/datasets/src/{panels → components/LayersMenu}/Layers.module.scss +4 -0
  80. package/plugins/beta/datasets/src/components/LayersMenu/LayersMenu.jsx +33 -0
  81. package/plugins/beta/datasets/src/components/LayersMenu/LayersMenuCheckbox.jsx +31 -0
  82. package/plugins/beta/datasets/src/components/LayersMenu/LayersMenuGroupWrapper.jsx +19 -0
  83. package/plugins/beta/datasets/src/datasets.scss +2 -2
  84. package/plugins/beta/datasets/src/fetch/createDynamicSource.js +8 -8
  85. package/plugins/beta/datasets/src/{DatasetsInit.jsx → initialise/DatasetsInit.jsx} +19 -21
  86. package/plugins/beta/datasets/src/{defaults.js → initialise/defaults.js} +17 -2
  87. package/plugins/beta/datasets/src/initialise/defaults.test.js +127 -0
  88. package/plugins/beta/datasets/src/{datasets.js → initialise/initialiseDatasets.js} +30 -26
  89. package/plugins/beta/datasets/src/initialise/initialiseDatasets.test.js +273 -0
  90. package/plugins/beta/datasets/src/manifest.js +8 -6
  91. package/plugins/beta/datasets/src/reducers/__data__/demoDatasets.js +253 -0
  92. package/plugins/beta/datasets/src/reducers/datasetsToMenu.js +78 -0
  93. package/plugins/beta/datasets/src/reducers/datasetsToMenu.test.js +35 -0
  94. package/plugins/beta/datasets/src/reducers/mappedDatasetsReducer.js +34 -0
  95. package/plugins/beta/datasets/src/reducers/mappedDatasetsReducer.test.js +117 -0
  96. package/plugins/beta/datasets/src/reducers/pluginState.js +206 -0
  97. package/plugins/beta/datasets/src/reducers/pluginState.test.js +386 -0
  98. package/plugins/beta/datasets/src/registry/__mocks__/datasetRegistry.js +29 -0
  99. package/plugins/beta/datasets/src/registry/createDataset.js +5 -0
  100. package/plugins/beta/datasets/src/registry/dataset.js +172 -0
  101. package/plugins/beta/datasets/src/registry/dataset.test.js +483 -0
  102. package/plugins/beta/datasets/src/registry/datasetDefinitionCache.js +35 -0
  103. package/plugins/beta/datasets/src/registry/datasetRegistry.js +116 -0
  104. package/plugins/beta/datasets/src/registry/datasetRegistry.test.js +335 -0
  105. package/plugins/beta/datasets/src/registry/dynamicGeoJson.js +17 -0
  106. package/plugins/beta/datasets/src/registry/globalDataset.js +36 -0
  107. package/plugins/beta/draw-ml/dist/esm/im-draw-ml-plugin.js +1 -1
  108. package/plugins/beta/draw-ml/dist/umd/im-draw-ml-plugin.js +1 -1
  109. package/plugins/beta/draw-ml/src/events.js +13 -1
  110. package/plugins/beta/draw-ml/src/index.js +1 -1
  111. package/plugins/beta/draw-ml/src/manifest.js +3 -0
  112. package/plugins/interact/dist/esm/im-interact-plugin.js +1 -1
  113. package/plugins/interact/dist/umd/im-interact-plugin.js +1 -1
  114. package/plugins/interact/src/InteractInit.jsx +2 -2
  115. package/plugins/interact/src/InteractInit.test.js +1 -1
  116. package/plugins/interact/src/events.js +2 -29
  117. package/plugins/interact/src/events.test.js +4 -102
  118. package/plugins/interact/src/hooks/useAttachEvents.js +3 -4
  119. package/plugins/interact/src/hooks/useAttachEvents.test.js +1 -3
  120. package/plugins/interact/src/hooks/useInteractionHandlers.js +10 -1
  121. package/plugins/interact/src/hooks/useInteractionHandlers.test.js +23 -4
  122. package/plugins/interact/src/manifest.js +0 -35
  123. package/plugins/interact/src/manifest.test.js +3 -43
  124. package/providers/beta/esri/dist/esm/im-esri-provider.js +1 -1
  125. package/providers/beta/esri/src/esriProvider.js +4 -0
  126. package/providers/beta/openlayers/dist/esm/im-openlayers-provider.js +1 -1
  127. package/providers/beta/openlayers/dist/umd/im-openlayers-provider.js +1 -1
  128. package/providers/beta/openlayers/src/openlayersProvider.js +4 -0
  129. package/providers/beta/openlayers/src/openlayersProvider.test.js +5 -0
  130. package/providers/maplibre/dist/esm/im-maplibre-provider.js +1 -1
  131. package/providers/maplibre/dist/umd/im-maplibre-provider.js +1 -1
  132. package/providers/maplibre/src/maplibreProvider.js +6 -4
  133. package/providers/maplibre/src/maplibreProvider.test.js +5 -0
  134. package/providers/maplibre/src/utils/highlightFeatures.js +74 -25
  135. package/providers/maplibre/src/utils/highlightFeatures.test.js +132 -0
  136. package/providers/maplibre/src/utils/patternImages.js +2 -4
  137. package/providers/maplibre/src/utils/symbolImages.js +1 -4
  138. package/rollup.esm.mjs +2 -8
  139. package/src/App/components/MapButton/MapButton.jsx +16 -1
  140. package/src/App/components/MapButton/MapButton.module.scss +12 -1
  141. package/src/App/components/MapButton/MapButton.test.jsx +40 -1
  142. package/src/App/components/Tooltip/getTooltipPosition.js +2 -2
  143. package/src/App/hooks/useContinueEnabledEvaluator.js +31 -0
  144. package/src/App/hooks/useContinueEnabledEvaluator.test.js +118 -0
  145. package/src/App/hooks/useEvaluateProp.js +15 -15
  146. package/src/App/hooks/useEvaluateProp.test.js +80 -76
  147. package/src/App/hooks/useLayoutMeasurements.js +1 -3
  148. package/src/App/hooks/useResizeObserver.js +12 -1
  149. package/src/App/hooks/useResizeObserver.test.js +1 -0
  150. package/src/App/renderer/PluginInits.jsx +2 -0
  151. package/src/App/renderer/mapButtons.js +21 -1
  152. package/src/App/renderer/mapButtons.test.js +46 -1
  153. package/src/App/store/appReducer.js +1 -1
  154. package/src/App/store/appReducer.test.js +37 -0
  155. package/src/InteractiveMap/InteractiveMap.js +10 -0
  156. package/src/InteractiveMap/InteractiveMap.test.js +8 -0
  157. package/src/InteractiveMap/polyfills.js +37 -6
  158. package/src/InteractiveMap/polyfills.test.js +132 -101
  159. package/src/config/appConfig.js +25 -0
  160. package/src/config/appConfig.test.js +50 -0
  161. package/src/config/defaults.js +1 -0
  162. package/src/scss/settings/_dimensions.scss +1 -0
  163. package/src/services/patternRegistry.js +8 -4
  164. package/src/types.js +7 -0
  165. package/src/utils/patternUtils.js +1 -2
  166. package/src/utils/patternUtils.test.js +9 -0
  167. package/webpack.dev.mjs +10 -0
  168. package/webpack.umd.mjs +1 -1
  169. package/plugins/beta/datasets/dist/adapters/maplibre/esm/im-datasets-ml-adapter.js +0 -1
  170. package/plugins/beta/datasets/dist/adapters/maplibre/esm/index.js +0 -1
  171. package/plugins/beta/datasets/dist/umd/maplibre/im-datasets-maplibre-adapter.js +0 -2
  172. package/plugins/beta/datasets/dist/umd/maplibre/im-datasets-plugin.js +0 -2
  173. package/plugins/beta/datasets/dist/umd/maplibre/index.js +0 -2
  174. package/plugins/beta/datasets/src/adapters/maplibre/index.js +0 -18
  175. package/plugins/beta/datasets/src/adapters/maplibre/layerIds.js +0 -75
  176. package/plugins/beta/datasets/src/adapters/maplibre/patternImages.js +0 -27
  177. package/plugins/beta/datasets/src/adapters/maplibre/symbolImages.js +0 -31
  178. package/plugins/beta/datasets/src/components/KeySvg.jsx +0 -24
  179. package/plugins/beta/datasets/src/components/KeySvgLine.jsx +0 -19
  180. package/plugins/beta/datasets/src/components/KeySvgRect.jsx +0 -22
  181. package/plugins/beta/datasets/src/index.maplibre.umd.js +0 -23
  182. package/plugins/beta/datasets/src/panels/Key.jsx +0 -62
  183. package/plugins/beta/datasets/src/panels/Layers.jsx +0 -141
  184. package/plugins/beta/datasets/src/reducer.js +0 -219
  185. package/plugins/beta/datasets/src/reducers/keyReducer.js +0 -34
  186. package/plugins/beta/datasets/src/utils/filters.js +0 -34
  187. package/plugins/beta/datasets/src/utils/mergeSublayer.js +0 -86
  188. package/plugins/beta/draw-ml/dist/css/index.css +0 -21
  189. /package/plugins/beta/datasets/dist/umd/{maplibre/im-datasets-maplibre-adapter.js.LICENSE.txt → im-datasets-ml-adapter.js.LICENSE.txt} +0 -0
  190. /package/plugins/beta/datasets/dist/umd/{maplibre/im-datasets-plugin.js.LICENSE.txt → im-datasets-plugin.js.LICENSE.txt} +0 -0
  191. /package/plugins/beta/datasets/dist/umd/{maplibre/index.js.LICENSE.txt → index.js.LICENSE.txt} +0 -0
  192. /package/plugins/beta/datasets/src/components/{EmptyKey.jsx → Key/EmptyKey.jsx} +0 -0
  193. /package/plugins/beta/datasets/src/components/{EmptyKey.test.jsx → Key/EmptyKey.test.jsx} +0 -0
  194. /package/plugins/beta/datasets/src/{panels → components/Key}/Key.module.scss +0 -0
  195. /package/plugins/beta/datasets/src/components/{svgProperties.js → Key/svgProperties.js} +0 -0
@@ -0,0 +1,34 @@
1
+ import { applyDatasetDefaultsWithoutFlattening } from '../initialise/defaults.js'
2
+
3
+ const flattenSublayer = (parentId, sublayer) => {
4
+ const id = `${parentId}-${sublayer.id}`
5
+ const sublayerId = sublayer.id
6
+ if (sublayer.visibility !== 'hidden') {
7
+ sublayer.visibility = 'visible'
8
+ }
9
+ return { ...sublayer, id, parentId, sublayerId }
10
+ }
11
+
12
+ const reduceDatasets = (acc, dataset) => {
13
+ const { id } = dataset
14
+ acc[id] = applyDatasetDefaultsWithoutFlattening(dataset)
15
+ const { orderedDatasets } = acc
16
+ orderedDatasets.push(id)
17
+ const flattenedSublayers = dataset.sublayers?.map((sublayer) => flattenSublayer(id, sublayer))
18
+ if (flattenedSublayers?.length) {
19
+ const sublayerIds = flattenedSublayers?.map(sublayer => sublayer.id)
20
+ const sublayers = flattenedSublayers?.reduce(reduceDatasets, { orderedDatasets })
21
+ acc[id].sublayerIds = sublayerIds
22
+ delete acc[id].sublayers
23
+ return { ...acc, ...sublayers, orderedDatasets }
24
+ }
25
+ return { ...acc, orderedDatasets }
26
+ }
27
+
28
+ export const mappedDatasetsReducer = (state) => {
29
+ const datasets = state.datasets || []
30
+ const mappedDatasets = datasets.reduce(reduceDatasets, { orderedDatasets: [] })
31
+ const { orderedDatasets } = mappedDatasets
32
+ delete mappedDatasets.orderedDatasets
33
+ return { ...state, mappedDatasets, orderedDatasets }
34
+ }
@@ -0,0 +1,117 @@
1
+ import { mappedDatasetsReducer } from './mappedDatasetsReducer'
2
+ import { datasetDefaults } from '../initialise/defaults.js'
3
+
4
+ describe('mappedDatasetsReducer', () => {
5
+ it('handles empty datasets', () => {
6
+ const result = mappedDatasetsReducer({ datasets: [] })
7
+ expect(result.mappedDatasets).toEqual({})
8
+ expect(result.orderedDatasets).toEqual([])
9
+ })
10
+
11
+ it('handles missing datasets', () => {
12
+ const result = mappedDatasetsReducer({})
13
+ expect(result.mappedDatasets).toEqual({})
14
+ expect(result.orderedDatasets).toEqual([])
15
+ })
16
+
17
+ it('maps a single dataset with no sublayers', () => {
18
+ const state = {
19
+ datasets: [{ id: 'roads', label: 'Roads', minZoom: 10 }]
20
+ }
21
+ const result = mappedDatasetsReducer(state)
22
+ expect(result.mappedDatasets).toEqual({
23
+ roads: { ...datasetDefaults, id: 'roads', label: 'Roads', minZoom: 10 }
24
+ })
25
+ expect(result.orderedDatasets).toEqual(['roads'])
26
+ })
27
+
28
+ it('maps multiple datasets preserving order', () => {
29
+ const state = {
30
+ datasets: [
31
+ { id: 'alpha', label: 'Alpha' },
32
+ { id: 'beta', label: 'Beta' },
33
+ { id: 'gamma', label: 'Gamma' }
34
+ ]
35
+ }
36
+ const result = mappedDatasetsReducer(state)
37
+ expect(result.orderedDatasets).toEqual(['alpha', 'beta', 'gamma'])
38
+ expect(Object.keys(result.mappedDatasets)).toEqual(['alpha', 'beta', 'gamma'])
39
+ })
40
+
41
+ it('preserves other state properties', () => {
42
+ const state = {
43
+ datasets: [],
44
+ someOtherProp: 'value',
45
+ nested: { foo: 'bar' }
46
+ }
47
+ const result = mappedDatasetsReducer(state)
48
+ expect(result.someOtherProp).toBe('value')
49
+ expect(result.nested).toEqual({ foo: 'bar' })
50
+ })
51
+
52
+ describe('with sublayers', () => {
53
+ const state = {
54
+ datasets: [{
55
+ id: 'land-covers',
56
+ label: 'Land covers',
57
+ sublayers: [
58
+ { id: 'grassland', label: 'Grassland' },
59
+ { id: 'woodland', label: 'Woodland', visibility: 'hidden' }
60
+ ]
61
+ }]
62
+ }
63
+
64
+ it('removes the sublayers property from the parent dataset', () => {
65
+ const result = mappedDatasetsReducer(state)
66
+ expect(result.mappedDatasets['land-covers'].sublayers).toBeUndefined()
67
+ })
68
+
69
+ it('adds sublayerIds to the parent dataset', () => {
70
+ const result = mappedDatasetsReducer(state)
71
+ expect(result.mappedDatasets['land-covers'].sublayerIds).toEqual([
72
+ 'land-covers-grassland',
73
+ 'land-covers-woodland'
74
+ ])
75
+ })
76
+
77
+ it('adds flattened sublayers to mappedDatasets', () => {
78
+ const result = mappedDatasetsReducer(state)
79
+ expect(result.mappedDatasets['land-covers-grassland']).toBeDefined()
80
+ expect(result.mappedDatasets['land-covers-woodland']).toBeDefined()
81
+ })
82
+
83
+ it('sets compound id on flattened sublayer', () => {
84
+ const result = mappedDatasetsReducer(state)
85
+ expect(result.mappedDatasets['land-covers-grassland'].id).toBe('land-covers-grassland')
86
+ })
87
+
88
+ it('sets parentId on flattened sublayer', () => {
89
+ const result = mappedDatasetsReducer(state)
90
+ expect(result.mappedDatasets['land-covers-grassland'].parentId).toBe('land-covers')
91
+ })
92
+
93
+ it('sets sublayerId to the original sublayer id', () => {
94
+ const result = mappedDatasetsReducer(state)
95
+ expect(result.mappedDatasets['land-covers-grassland'].sublayerId).toBe('grassland')
96
+ })
97
+
98
+ it('sets visibility to visible for sublayers without explicit visibility', () => {
99
+ const result = mappedDatasetsReducer(state)
100
+ expect(result.mappedDatasets['land-covers-grassland'].visibility).toBe('visible')
101
+ })
102
+
103
+ it('preserves hidden visibility on sublayers', () => {
104
+ const result = mappedDatasetsReducer(state)
105
+ expect(result.mappedDatasets['land-covers-woodland'].visibility).toBe('hidden')
106
+ })
107
+
108
+ it('includes sublayers in orderedDatasets after their parent', () => {
109
+ const result = mappedDatasetsReducer(state)
110
+ expect(result.orderedDatasets).toEqual([
111
+ 'land-covers',
112
+ 'land-covers-grassland',
113
+ 'land-covers-woodland'
114
+ ])
115
+ })
116
+ })
117
+ })
@@ -0,0 +1,206 @@
1
+ import { datasetsToMenu, addDatasetToMenu, removeDatasetsFromMenu } from './datasetsToMenu.js'
2
+ import { mappedDatasetsReducer } from './mappedDatasetsReducer.js'
3
+ import { logger } from '../../../../../src/services/logger.js'
4
+
5
+ const initialState = {
6
+ globals: {
7
+ visible: true,
8
+ opacity: 1,
9
+ opacityMode: 'dataset'
10
+ // 'dataset': registryDataset opacity is used instead if set;
11
+ // 'global': registryDataset opacity is ignored
12
+ // 'multiply': registryDataset opacity is multiplied by parent opacity and global opacity
13
+ },
14
+ key: {
15
+ items: [],
16
+ hasGroups: false
17
+ },
18
+ actionsArray: []
19
+ }
20
+
21
+ const validateDatasetExists = (state, datasetId, prefix, suffix = 'not found') => {
22
+ if (!state.mappedDatasets[datasetId]) {
23
+ logger.error(`${prefix}: Dataset with id '${datasetId}' ${suffix}`)
24
+ return false
25
+ }
26
+ return true
27
+ }
28
+
29
+ let actionId = 0
30
+ const addAction = (method, parameters, state) => {
31
+ actionId = state.actionsArray.length ? actionId + 1 : 0
32
+ return { ...state, actionsArray: [...state.actionsArray, { method, parameters, actionId }] }
33
+ }
34
+
35
+ const setGlobalState = (state, payload) => {
36
+ // For now we only have opacityMode, but if we add more global state
37
+ // properties we may not require applyGlobalOpacity to be triggered here.
38
+ return addAction('applyGlobalOpacity', [], {
39
+ ...state,
40
+ globals: { ...state.globals, ...payload }
41
+ })
42
+ }
43
+
44
+ const setDatasets = (state, payload) => {
45
+ const { datasets, mappedDatasets, orderedDatasets } = payload
46
+ const menu = payload.menu || datasetsToMenu({ datasets })
47
+ return {
48
+ ...state,
49
+ mappedDatasets,
50
+ orderedDatasets,
51
+ menu
52
+ }
53
+ }
54
+
55
+ const addDataset = (state, payload) => {
56
+ const { dataset, mapStyle } = payload
57
+ if (state.mappedDatasets[dataset.id]) {
58
+ logger.error(`addDataset: Dataset with id '${dataset.id}' already exists`)
59
+ return state
60
+ }
61
+ const { mappedDatasets: newDatasets, orderedDatasets: newOrderedDatasets } = mappedDatasetsReducer({ datasets: [dataset] })
62
+ const menu = addDatasetToMenu(state, dataset)
63
+
64
+ return addAction('addDataset', [dataset.id, mapStyle], {
65
+ ...state,
66
+ mappedDatasets: { ...state.mappedDatasets, ...newDatasets },
67
+ orderedDatasets: [...state.orderedDatasets, ...newOrderedDatasets],
68
+ menu
69
+ })
70
+ }
71
+
72
+ const removeDataset = (state, payload) => {
73
+ const { id } = payload
74
+ if (!validateDatasetExists(state, id, 'removeDataset')) {
75
+ return state
76
+ }
77
+ const mappedDatasets = { ...state.mappedDatasets }
78
+ const datasetsToRemove = [id, ...(mappedDatasets[id]?.sublayerIds || [])]
79
+ datasetsToRemove.forEach((datasetId) => delete mappedDatasets[datasetId])
80
+ // Remove from orderedDatasets
81
+ const orderedDatasets = state.orderedDatasets.filter(datasetId => !datasetsToRemove.includes(datasetId))
82
+ // Remove from menu, and remove any menu groups that are left with no items
83
+ return {
84
+ ...state,
85
+ mappedDatasets,
86
+ orderedDatasets,
87
+ menu: removeDatasetsFromMenu(state.menu, datasetsToRemove)
88
+ }
89
+ }
90
+
91
+ const setDatasetVisibility = (state, payload) => {
92
+ const { datasetId, visible } = payload
93
+ if (!validateDatasetExists(state, datasetId, 'setDatasetVisibility')) {
94
+ return state
95
+ }
96
+
97
+ return addAction('applyDatasetVisibility', [datasetId, visible], {
98
+ ...state,
99
+ mappedDatasets: { ...state.mappedDatasets, [datasetId]: { ...state.mappedDatasets[datasetId], visible } }
100
+ })
101
+ }
102
+
103
+ const setGlobalVisibility = (state, payload) => {
104
+ const { visible } = payload
105
+
106
+ return addAction('applyGlobalVisibility', [visible], {
107
+ ...state,
108
+ globals: { ...state.globals, visible }
109
+ })
110
+ }
111
+
112
+ const hideFeatures = (state, payload) => {
113
+ const { datasetId, featureIds } = payload
114
+ if (!validateDatasetExists(state, datasetId, 'setFeatureVisibility - hideFeatures')) {
115
+ return state
116
+ }
117
+ const mappedDataset = { ...state.mappedDatasets[datasetId] }
118
+ const existingIds = mappedDataset.hiddenFeatures || []
119
+ const newIds = [...new Set([...existingIds, ...featureIds])]
120
+ mappedDataset.hiddenFeatures = newIds
121
+
122
+ return addAction('applyFeatureFilter', [datasetId], {
123
+ ...state,
124
+ mappedDatasets: { ...state.mappedDatasets, [datasetId]: mappedDataset }
125
+ })
126
+ }
127
+
128
+ const showFeatures = (state, payload) => {
129
+ const { datasetId, featureIds } = payload
130
+ if (!validateDatasetExists(state, datasetId, 'setFeatureVisibility - showFeatures')) {
131
+ return state
132
+ }
133
+ const mappedDataset = { ...state.mappedDatasets[datasetId] }
134
+ const existingIds = mappedDataset.hiddenFeatures || []
135
+ const newIds = existingIds.filter(id => !featureIds.includes(id))
136
+ mappedDataset.hiddenFeatures = newIds.length ? newIds : [-1] // If no features are hidden, set to -1 to force a filter update
137
+
138
+ return addAction('applyFeatureFilter', [datasetId], {
139
+ ...state,
140
+ mappedDatasets: { ...state.mappedDatasets, [datasetId]: mappedDataset }
141
+ })
142
+ }
143
+
144
+ const removeAdapterActions = (state, completedActions) => {
145
+ if (!completedActions?.length) { return state }
146
+ return {
147
+ ...state,
148
+ actionsArray: state.actionsArray.filter((current) => !completedActions.includes(current))
149
+ }
150
+ }
151
+
152
+ const setDatasetStyle = (state, payload) => {
153
+ const { datasetId, styleChanges, mapStyle } = payload
154
+ if (!validateDatasetExists(state, datasetId, 'setDatasetStyle')) {
155
+ return state
156
+ }
157
+ const style = { ...state.mappedDatasets[datasetId].style, ...styleChanges }
158
+ const dataset = { ...state.mappedDatasets[datasetId], ...styleChanges, style }
159
+
160
+ return addAction('applyStyle', [datasetId, mapStyle], {
161
+ ...state,
162
+ mappedDatasets: { ...state.mappedDatasets, [datasetId]: dataset }
163
+ })
164
+ }
165
+
166
+ const setOpacity = (state, payload) => {
167
+ const { datasetId, opacity } = payload
168
+ if (!validateDatasetExists(state, datasetId, 'setOpacity')) {
169
+ return state
170
+ }
171
+ const style = { ...state.mappedDatasets[datasetId].style, opacity }
172
+ const dataset = { ...state.mappedDatasets[datasetId], style }
173
+
174
+ return addAction('applyDatasetOpacity', [datasetId], {
175
+ ...state,
176
+ mappedDatasets: { ...state.mappedDatasets, [datasetId]: dataset }
177
+ })
178
+ }
179
+
180
+ const setGlobalOpacity = (state, payload) => {
181
+ const { opacity } = payload
182
+ return addAction('applyGlobalOpacity', [], {
183
+ ...state,
184
+ globals: { ...state.globals, opacity }
185
+ })
186
+ }
187
+
188
+ const actions = {
189
+ SET_DATASETS: setDatasets,
190
+ ADD_DATASET: addDataset,
191
+ REMOVE_DATASET: removeDataset,
192
+ SET_DATASET_VISIBILITY: setDatasetVisibility,
193
+ SET_GLOBAL_VISIBILITY: setGlobalVisibility,
194
+ SET_DATASET_STYLE: setDatasetStyle,
195
+ SET_OPACITY: setOpacity,
196
+ SET_GLOBAL_OPACITY: setGlobalOpacity,
197
+ HIDE_FEATURES: hideFeatures,
198
+ SHOW_FEATURES: showFeatures,
199
+ REMOVE_ADAPTER_ACTIONS: removeAdapterActions,
200
+ SET_GLOBAL_STATE: setGlobalState
201
+ }
202
+
203
+ export {
204
+ initialState,
205
+ actions
206
+ }