@defra/interactive-map 0.0.14-alpha → 0.0.16-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/assets/css/docusaurus.css +104 -0
- package/assets/images/favicon.svg +1 -0
- package/assets/images/hero.png +0 -0
- package/dist/css/index.css +1 -1
- package/dist/esm/im-core.js +1 -1
- package/dist/umd/im-core.js +1 -1
- package/dist/umd/index.js +1 -1
- package/docs/api/slot-map.svg +1 -0
- package/docs/api/slots.md +89 -6
- package/docs/api.md +1 -1
- package/docs/architecture.md +3 -1
- package/docs/{demo.mdx → examples.mdx} +1 -1
- package/docs/getting-started.md +1 -3
- package/docs/index.mdx +42 -0
- package/docs/plugins/interact.md +176 -55
- package/docs/plugins/map-styles.md +64 -7
- package/docs/plugins/search.md +207 -63
- package/docs/plugins.md +7 -15
- package/docusaurus.config.cjs +34 -34
- package/jest.setup.js +1 -1
- package/package.json +5 -4
- package/plugins/beta/datasets/dist/esm/im-datasets-plugin.js +1 -1
- package/plugins/beta/datasets/dist/umd/im-datasets-plugin.js +1 -1
- package/plugins/beta/datasets/src/DatasetsInit.jsx +1 -1
- package/plugins/beta/datasets/src/api/addDataset.js +1 -1
- package/plugins/beta/datasets/src/api/hideDataset.js +1 -1
- package/plugins/beta/datasets/src/api/hideFeatures.js +1 -1
- package/plugins/beta/datasets/src/api/removeDataset.js +1 -1
- package/plugins/beta/datasets/src/api/showDataset.js +1 -1
- package/plugins/beta/datasets/src/api/showFeatures.js +1 -1
- package/plugins/beta/datasets/src/datasets.js +4 -4
- package/plugins/beta/datasets/src/defaults.js +1 -1
- package/plugins/beta/datasets/src/fetch/createDynamicSource.js +5 -5
- package/plugins/beta/datasets/src/handleSetMapStyle.js +1 -1
- package/plugins/beta/datasets/src/manifest.js +7 -7
- package/plugins/beta/datasets/src/mapLayers.js +2 -3
- package/plugins/beta/datasets/src/panels/Key.jsx +31 -29
- package/plugins/beta/datasets/src/panels/Layers.jsx +8 -9
- package/plugins/beta/datasets/src/utils/bbox.js +4 -4
- package/plugins/beta/draw-es/dist/esm/im-draw-es-plugin.js +1 -1
- package/plugins/beta/draw-es/src/DrawInit.jsx +16 -16
- package/plugins/beta/draw-es/src/api/addFeature.js +3 -3
- package/plugins/beta/draw-es/src/api/deleteFeature.js +3 -3
- package/plugins/beta/draw-es/src/api/editFeature.js +3 -3
- package/plugins/beta/draw-es/src/api/newPolygon.js +3 -3
- package/plugins/beta/draw-es/src/events.js +52 -20
- package/plugins/beta/draw-es/src/events.test.js +301 -0
- package/plugins/beta/draw-es/src/graphic.js +1 -1
- package/plugins/beta/draw-es/src/manifest.js +4 -4
- package/plugins/beta/draw-es/src/reducer.js +1 -1
- package/plugins/beta/draw-es/src/sketchViewModel.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-ml/src/DrawInit.jsx +49 -52
- package/plugins/beta/draw-ml/src/api/deleteFeature.js +1 -1
- package/plugins/beta/draw-ml/src/api/editFeature.js +8 -5
- package/plugins/beta/draw-ml/src/api/newLine.js +0 -1
- package/plugins/beta/draw-ml/src/api/newPolygon.js +0 -1
- package/plugins/beta/draw-ml/src/api/split.js +4 -4
- package/plugins/beta/draw-ml/src/defaults.js +1 -1
- package/plugins/beta/draw-ml/src/events.js +8 -6
- package/plugins/beta/draw-ml/src/manifest.js +15 -15
- package/plugins/beta/draw-ml/src/mapboxDraw.js +1 -1
- package/plugins/beta/draw-ml/src/mapboxSnap.js +17 -18
- package/plugins/beta/draw-ml/src/modes/createDrawMode.js +31 -31
- package/plugins/beta/draw-ml/src/modes/disabledMode.js +1 -1
- package/plugins/beta/draw-ml/src/modes/editVertex/touchHandlers.js +11 -11
- package/plugins/beta/draw-ml/src/modes/editVertex/undoHandlers.js +7 -7
- package/plugins/beta/draw-ml/src/modes/editVertex/vertexOperations.js +8 -8
- package/plugins/beta/draw-ml/src/modes/editVertex/vertexQueries.js +7 -7
- package/plugins/beta/draw-ml/src/modes/editVertexMode.js +32 -24
- package/plugins/beta/draw-ml/src/reducer.js +1 -1
- package/plugins/beta/draw-ml/src/undoStack.js +4 -4
- package/plugins/beta/draw-ml/src/utils/snapHelpers.js +12 -12
- package/plugins/beta/draw-ml/src/utils/spatial.js +11 -11
- package/plugins/beta/frame/src/Frame.jsx +4 -4
- package/plugins/beta/frame/src/FrameInit.jsx +4 -4
- package/plugins/beta/frame/src/api/addFrame.js +1 -1
- package/plugins/beta/frame/src/api/editFeature.js +1 -1
- package/plugins/beta/frame/src/config.js +1 -1
- package/plugins/beta/frame/src/manifest.js +3 -3
- package/plugins/beta/frame/src/reducer.js +1 -1
- package/plugins/beta/frame/src/utils.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/src/MapStyles.jsx +18 -18
- package/plugins/beta/map-styles/src/manifest.js +2 -2
- package/plugins/beta/scale-bar/src/ScaleBar.jsx +5 -5
- package/plugins/beta/use-location/src/UseLocation.jsx +1 -1
- package/plugins/beta/use-location/src/defaults.js +1 -1
- package/plugins/beta/use-location/src/events.js +3 -3
- package/plugins/interact/src/InteractInit.jsx +1 -2
- package/plugins/interact/src/api/enable.js +8 -5
- package/plugins/interact/src/api/enable.test.js +2 -2
- package/plugins/interact/src/api/selectFeature.js +4 -4
- package/plugins/interact/src/api/unselectFeature.js +5 -5
- package/plugins/interact/src/defaults.js +0 -1
- package/plugins/interact/src/events.test.js +15 -15
- package/plugins/interact/src/hooks/useHighlightSync.js +1 -1
- package/plugins/interact/src/hooks/useInteractionHandlers.js +2 -2
- package/plugins/interact/src/hooks/useInteractionHandlers.test.js +5 -5
- package/plugins/interact/src/manifest.js +2 -2
- package/plugins/interact/src/manifest.test.js +3 -4
- package/plugins/interact/src/reducer.js +3 -3
- package/plugins/interact/src/reducer.test.js +0 -1
- package/plugins/interact/src/utils/spatial.js +10 -10
- package/plugins/interact/src/utils/spatial.test.js +14 -14
- 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 -6
- package/plugins/search/src/Search.test.jsx +23 -23
- package/plugins/search/src/components/CloseButton/CloseButton.jsx +15 -15
- package/plugins/search/src/components/CloseButton/CloseButton.test.jsx +2 -2
- package/plugins/search/src/components/Form/Form.jsx +14 -14
- package/plugins/search/src/components/Form/Form.test.jsx +11 -11
- package/plugins/search/src/components/OpenButton/OpenButton.jsx +16 -15
- package/plugins/search/src/components/OpenButton/OpenButton.test.jsx +6 -2
- package/plugins/search/src/components/SubmitButton/SubmitButton.jsx +15 -15
- package/plugins/search/src/components/Suggestions/Suggestions.jsx +6 -6
- package/plugins/search/src/components/Suggestions/Suggestions.test.jsx +4 -4
- package/plugins/search/src/datasets.js +12 -13
- package/plugins/search/src/datasets.test.js +1 -1
- package/plugins/search/src/defaults.js +1 -1
- package/plugins/search/src/events/fetchSuggestions.js +4 -4
- package/plugins/search/src/events/fetchSuggestions.test.js +5 -5
- package/plugins/search/src/events/formHandlers.js +3 -3
- package/plugins/search/src/events/formHandlers.test.js +1 -1
- package/plugins/search/src/events/index.js +2 -2
- package/plugins/search/src/events/index.test.js +2 -2
- package/plugins/search/src/events/inputHandlers.js +4 -4
- package/plugins/search/src/events/inputHandlers.test.js +1 -1
- package/plugins/search/src/events/suggestionHandlers.js +2 -2
- package/plugins/search/src/events/suggestionHandlers.test.js +1 -1
- package/plugins/search/src/index.js +2 -1
- package/plugins/search/src/index.test.js +3 -3
- package/plugins/search/src/manifest.js +6 -4
- package/plugins/search/src/reducer.js +1 -2
- package/plugins/search/src/reducer.test.js +2 -2
- package/plugins/search/src/search.scss +18 -6
- package/plugins/search/src/utils/parseOsNamesResults.js +1 -2
- package/plugins/search/src/utils/parseOsNamesResults.test.js +2 -2
- package/plugins/search/src/utils/updateMap.js +1 -1
- package/plugins/search/src/utils/updateMap.test.js +5 -5
- package/providers/beta/esri/dist/esm/im-esri-provider.js +1 -1
- package/providers/beta/esri/src/esriProvider.js +5 -5
- package/providers/beta/esri/src/utils/coords.js +1 -1
- package/providers/beta/esri/src/utils/esriFixes.js +1 -1
- package/providers/beta/esri/src/utils/query.js +4 -4
- package/providers/beta/esri/src/utils/spatial.js +1 -2
- package/providers/beta/esri/src/utils/spatial.test.js +4 -1
- package/providers/beta/open-names/src/utils/mapToLocationModel.test.js +1 -1
- package/providers/maplibre/src/appEvents.test.js +1 -1
- package/providers/maplibre/src/index.js +1 -1
- package/providers/maplibre/src/index.test.js +3 -5
- package/providers/maplibre/src/mapEvents.test.js +15 -5
- package/providers/maplibre/src/maplibreProvider.test.js +6 -2
- package/providers/maplibre/src/utils/calculateLinearTextSize.js +4 -4
- package/providers/maplibre/src/utils/calculateLinearTextSize.test.js +3 -3
- package/providers/maplibre/src/utils/detectWebgl.test.js +1 -1
- package/providers/maplibre/src/utils/highlightFeatures.js +2 -2
- package/providers/maplibre/src/utils/highlightFeatures.test.js +12 -6
- package/providers/maplibre/src/utils/labels.js +19 -20
- package/providers/maplibre/src/utils/labels.test.js +15 -13
- package/providers/maplibre/src/utils/maplibreFixes.test.js +1 -1
- package/providers/maplibre/src/utils/queryFeatures.js +6 -6
- package/providers/maplibre/src/utils/queryFeatures.test.js +13 -13
- package/providers/maplibre/src/utils/spatial.js +0 -1
- package/providers/maplibre/src/utils/spatial.test.js +26 -27
- package/src/App/components/Panel/Panel.module.scss +1 -0
- package/src/App/hooks/useLayoutMeasurements.js +1 -10
- package/src/App/hooks/useLayoutMeasurements.test.js +2 -5
- package/src/App/hooks/useVisibleGeometry.js +7 -13
- package/src/App/hooks/useVisibleGeometry.test.js +72 -47
- package/src/App/layout/Layout.jsx +0 -3
- package/src/App/layout/Layout.test.jsx +0 -1
- package/src/App/layout/layout.module.scss +11 -77
- package/src/App/registry/pluginRegistry.js +17 -0
- package/src/App/registry/pluginRegistry.test.js +33 -0
- package/src/App/renderer/HtmlElementHost.jsx +0 -1
- package/src/App/renderer/HtmlElementHost.test.jsx +20 -11
- package/src/App/renderer/mapButtons.js +3 -2
- package/src/App/renderer/mapPanels.test.js +3 -3
- package/src/App/renderer/slotHelpers.js +2 -2
- package/src/App/renderer/slotHelpers.test.js +3 -3
- package/src/App/renderer/slots.js +0 -3
- package/src/App/store/AppProvider.jsx +0 -1
- package/src/App/store/appDispatchMiddleware.js +33 -1
- package/src/App/store/appDispatchMiddleware.test.js +250 -222
- package/src/config/appConfig.js +4 -4
- package/src/utils/getSafeZoneInset.js +139 -42
- package/src/utils/getSafeZoneInset.test.js +298 -122
- package/src/utils/logger.js +6 -0
- package/src/utils/logger.test.js +32 -0
- package/webpack.dev.mjs +22 -18
- package/docs/govuk-prototype.md +0 -23
- package/docs/index.md +0 -19
|
@@ -2,14 +2,14 @@ import { useEffect } from 'react'
|
|
|
2
2
|
import { createSketchViewModel } from './sketchViewModel.js'
|
|
3
3
|
import { attachEvents } from './events.js'
|
|
4
4
|
|
|
5
|
-
export const DrawInit = ({
|
|
6
|
-
appState,
|
|
7
|
-
mapState,
|
|
8
|
-
pluginConfig,
|
|
9
|
-
pluginState,
|
|
10
|
-
services,
|
|
11
|
-
mapProvider,
|
|
12
|
-
buttonConfig
|
|
5
|
+
export const DrawInit = ({
|
|
6
|
+
appState,
|
|
7
|
+
mapState,
|
|
8
|
+
pluginConfig,
|
|
9
|
+
pluginState,
|
|
10
|
+
services,
|
|
11
|
+
mapProvider,
|
|
12
|
+
buttonConfig
|
|
13
13
|
}) => {
|
|
14
14
|
const { events, eventBus } = services
|
|
15
15
|
const { mapColorScheme } = mapState.mapStyle || {}
|
|
@@ -22,9 +22,9 @@ export const DrawInit = ({
|
|
|
22
22
|
// Initialize sketch components once
|
|
23
23
|
useEffect(() => {
|
|
24
24
|
if (!isActive || mapProvider.sketchViewModel) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
return
|
|
26
|
+
}
|
|
27
|
+
|
|
28
28
|
const { sketchViewModel, sketchLayer, emptySketchLayer } = createSketchViewModel({
|
|
29
29
|
pluginState,
|
|
30
30
|
mapProvider,
|
|
@@ -33,21 +33,21 @@ export const DrawInit = ({
|
|
|
33
33
|
|
|
34
34
|
mapProvider.sketchViewModel = sketchViewModel
|
|
35
35
|
mapProvider.sketchLayer = sketchLayer
|
|
36
|
-
|
|
36
|
+
mapProvider.emptySketchLayer = emptySketchLayer
|
|
37
37
|
eventBus.emit('draw:ready')
|
|
38
38
|
|
|
39
39
|
return () => {
|
|
40
40
|
mapProvider.sketchViewModel = null
|
|
41
41
|
mapProvider.sketchLayer = null
|
|
42
|
-
|
|
42
|
+
mapProvider.emptySketchLayer = null
|
|
43
43
|
}
|
|
44
44
|
}, [mapState.isMapReady, appState.mode])
|
|
45
45
|
|
|
46
46
|
// Attach/detach events
|
|
47
47
|
useEffect(() => {
|
|
48
48
|
if (!isActive || !mapProvider.sketchViewModel) {
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
51
|
|
|
52
52
|
const cleanup = attachEvents({
|
|
53
53
|
pluginState,
|
|
@@ -62,4 +62,4 @@ export const DrawInit = ({
|
|
|
62
62
|
cleanup()
|
|
63
63
|
}
|
|
64
64
|
}, [isActive, mapColorScheme, pluginState])
|
|
65
|
-
}
|
|
65
|
+
}
|
|
@@ -7,7 +7,7 @@ export const addFeature = ({ pluginState, mapState, mapProvider, services }, fea
|
|
|
7
7
|
const { eventBus } = services
|
|
8
8
|
|
|
9
9
|
const graphic = createGraphic(feature.id, feature.geometry.coordinates, mapStyle.mapColorScheme)
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
// Add the graphic to the layer
|
|
12
12
|
sketchLayer.add(graphic)
|
|
13
13
|
|
|
@@ -15,7 +15,7 @@ export const addFeature = ({ pluginState, mapState, mapProvider, services }, fea
|
|
|
15
15
|
sketchViewModel.layer = emptySketchLayer
|
|
16
16
|
|
|
17
17
|
// Store initial feature in plugin state
|
|
18
|
-
dispatch({ type: 'SET_FEATURE', payload: { feature }})
|
|
18
|
+
dispatch({ type: 'SET_FEATURE', payload: { feature } })
|
|
19
19
|
|
|
20
20
|
eventBus.emit('draw:add', feature)
|
|
21
|
-
}
|
|
21
|
+
}
|
|
@@ -10,13 +10,13 @@ export const deleteFeature = ({ pluginState, mapProvider, services }, featureId)
|
|
|
10
10
|
sketchViewModel.cancel()
|
|
11
11
|
sketchLayer.remove(graphic)
|
|
12
12
|
sketchViewModel.layer = emptySketchLayer
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
// Reset state
|
|
15
|
-
dispatch({ type: 'SET_FEATURE', payload: { feature: null, tempFeature: null }})
|
|
15
|
+
dispatch({ type: 'SET_FEATURE', payload: { feature: null, tempFeature: null } })
|
|
16
16
|
|
|
17
17
|
// Emit event
|
|
18
18
|
eventBus.emit('draw:delete', { featureId })
|
|
19
19
|
|
|
20
20
|
// Clear mode
|
|
21
21
|
dispatch({ type: 'SET_MODE', payload: null })
|
|
22
|
-
}
|
|
22
|
+
}
|
|
@@ -18,12 +18,12 @@ export const editFeature = ({ pluginState, mapProvider }, featureId) => {
|
|
|
18
18
|
tool: 'reshape',
|
|
19
19
|
toggleToolOnClick: false,
|
|
20
20
|
enableRotation: false,
|
|
21
|
-
enableScaling: false
|
|
21
|
+
enableScaling: false
|
|
22
22
|
})
|
|
23
23
|
|
|
24
24
|
// Set original feature
|
|
25
25
|
const feature = graphicToGeoJSON(graphic)
|
|
26
|
-
dispatch({ type: 'SET_FEATURE', payload: { feature }})
|
|
26
|
+
dispatch({ type: 'SET_FEATURE', payload: { feature } })
|
|
27
27
|
|
|
28
28
|
dispatch({ type: 'SET_MODE', payload: 'edit-feature' })
|
|
29
|
-
}
|
|
29
|
+
}
|
|
@@ -12,7 +12,7 @@ export const newPolygon = ({ mapState, pluginState, mapProvider, services }, fea
|
|
|
12
12
|
const handleCreateComplete = sketchViewModel.on('create', (e) => {
|
|
13
13
|
if (e.state === 'complete') {
|
|
14
14
|
e.graphic.attributes = { id: featureId }
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
// Fix: to address calling some sketchViewModel methods syncronously
|
|
17
17
|
requestAnimationFrame(() => {
|
|
18
18
|
sketchViewModel.update(e.graphic, {
|
|
@@ -24,7 +24,7 @@ export const newPolygon = ({ mapState, pluginState, mapProvider, services }, fea
|
|
|
24
24
|
// Store temp feature in state and emit create
|
|
25
25
|
const tempFeature = graphicToGeoJSON(e.graphic)
|
|
26
26
|
eventBus.emit('draw:created', tempFeature)
|
|
27
|
-
dispatch({ type: 'SET_FEATURE', payload: { tempFeature }})
|
|
27
|
+
dispatch({ type: 'SET_FEATURE', payload: { tempFeature } })
|
|
28
28
|
|
|
29
29
|
handleCreateComplete.remove()
|
|
30
30
|
}
|
|
@@ -34,4 +34,4 @@ export const newPolygon = ({ mapState, pluginState, mapProvider, services }, fea
|
|
|
34
34
|
sketchViewModel.create('polygon')
|
|
35
35
|
|
|
36
36
|
dispatch({ type: 'SET_MODE', payload: 'new-polygon' })
|
|
37
|
-
}
|
|
37
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import * as simplifyOperator from
|
|
1
|
+
import * as simplifyOperator from '@arcgis/core/geometry/operators/simplifyOperator.js'
|
|
2
2
|
import { createGraphic, createSymbol, graphicToGeoJSON } from './graphic.js'
|
|
3
3
|
|
|
4
4
|
const MODE_CHANGE_DELAY = 50
|
|
5
5
|
|
|
6
|
-
export function attachEvents({ pluginState, mapProvider, events, eventBus, buttonConfig, mapColorScheme }) {
|
|
6
|
+
export function attachEvents ({ pluginState, mapProvider, events, eventBus, buttonConfig, mapColorScheme }) {
|
|
7
7
|
const { view, sketchViewModel, sketchLayer, emptySketchLayer } = mapProvider
|
|
8
8
|
|
|
9
9
|
if (!sketchViewModel) {
|
|
@@ -12,36 +12,36 @@ export function attachEvents({ pluginState, mapProvider, events, eventBus, butto
|
|
|
12
12
|
|
|
13
13
|
const { drawDone, drawCancel } = buttonConfig
|
|
14
14
|
const { dispatch, mode, feature } = pluginState
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
// Re-colour graphics when map style changes
|
|
17
17
|
const reColour = async () => {
|
|
18
18
|
const activeGraphicId = pluginState.feature?.properties?.id
|
|
19
19
|
let activeGraphic = null
|
|
20
20
|
const isCreating = sketchViewModel.state === 'active' && !activeGraphicId
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
// Cancel and wait, but only if we're in update mode (not create mode)
|
|
23
23
|
if (sketchViewModel.state === 'active' && activeGraphicId) {
|
|
24
24
|
sketchViewModel.cancel()
|
|
25
25
|
await new Promise(resolve => setTimeout(resolve, MODE_CHANGE_DELAY))
|
|
26
26
|
}
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
// Update the default symbol for new polygons
|
|
29
29
|
sketchViewModel.polygonSymbol = createSymbol(mapColorScheme)
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
// Update existing graphics
|
|
32
32
|
sketchLayer?.graphics.items.forEach(graphic => {
|
|
33
33
|
const newGraphic = createGraphic(
|
|
34
|
-
graphic.attributes.id,
|
|
35
|
-
graphic.geometry.rings,
|
|
34
|
+
graphic.attributes.id,
|
|
35
|
+
graphic.geometry.rings,
|
|
36
36
|
mapColorScheme
|
|
37
37
|
)
|
|
38
38
|
graphic.symbol = newGraphic.symbol
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
if (activeGraphicId === graphic.attributes.id) {
|
|
41
41
|
activeGraphic = graphic
|
|
42
42
|
}
|
|
43
43
|
})
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
// Re-enter update mode only if we were editing (not creating)
|
|
46
46
|
if (activeGraphic && !isCreating && sketchViewModel.layer === sketchLayer) {
|
|
47
47
|
try {
|
|
@@ -68,10 +68,19 @@ export function attachEvents({ pluginState, mapProvider, events, eventBus, butto
|
|
|
68
68
|
// Event handlers
|
|
69
69
|
const handleMapStyleChange = () => reColour()
|
|
70
70
|
|
|
71
|
+
const onGraphicChanged = (graphic) => {
|
|
72
|
+
if (!graphic) {
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
const tempFeature = graphicToGeoJSON(graphic)
|
|
76
|
+
eventBus.emit('draw:updated', tempFeature)
|
|
77
|
+
dispatch({ type: 'SET_FEATURE', payload: { tempFeature } })
|
|
78
|
+
}
|
|
79
|
+
|
|
71
80
|
const handleSketchUpdate = (e) => {
|
|
72
81
|
const toolInfoType = e.toolEventInfo?.type
|
|
73
82
|
const graphic = e.graphics[0]
|
|
74
|
-
|
|
83
|
+
|
|
75
84
|
// Prevent polygon move
|
|
76
85
|
if (toolInfoType === 'move-start') {
|
|
77
86
|
sketchViewModel.cancel()
|
|
@@ -87,10 +96,8 @@ export function attachEvents({ pluginState, mapProvider, events, eventBus, butto
|
|
|
87
96
|
}
|
|
88
97
|
|
|
89
98
|
// Emit event on update
|
|
90
|
-
if (toolInfoType === 'reshape-stop') {
|
|
91
|
-
|
|
92
|
-
eventBus.emit('draw:updated', tempFeature)
|
|
93
|
-
dispatch({ type: 'SET_FEATURE', payload: { tempFeature }})
|
|
99
|
+
if (toolInfoType === 'reshape-stop' || toolInfoType === 'vertex-remove') {
|
|
100
|
+
onGraphicChanged(graphic)
|
|
94
101
|
}
|
|
95
102
|
}
|
|
96
103
|
|
|
@@ -108,17 +115,38 @@ export function attachEvents({ pluginState, mapProvider, events, eventBus, butto
|
|
|
108
115
|
updateGraphic()
|
|
109
116
|
}
|
|
110
117
|
|
|
118
|
+
const handleCreate = async (event) => {
|
|
119
|
+
const { toolEventInfo } = event
|
|
120
|
+
const graphic = event?.graphic
|
|
121
|
+
if (graphic && toolEventInfo?.type === 'vertex-add') {
|
|
122
|
+
const rings = graphic.geometry?.rings
|
|
123
|
+
// rings.length is > 1 occurs when the shape becomes complex (ie self intersects)
|
|
124
|
+
// setTimeout is required to cause the undo to be called after handleCreate completes
|
|
125
|
+
// otherwise the previous change, rather than this one, is undone
|
|
126
|
+
if (rings?.length > 1) {
|
|
127
|
+
setTimeout(() => sketchViewModel.undo(), 0)
|
|
128
|
+
} else if (rings?.[0]?.length > 3) {
|
|
129
|
+
onGraphicChanged(graphic) // emit a graphic update on draw, once the graphic is 2D
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const handleUndo = async (event) => {
|
|
135
|
+
const graphic = event?.graphics?.[0]
|
|
136
|
+
onGraphicChanged(graphic)
|
|
137
|
+
}
|
|
138
|
+
|
|
111
139
|
const handleDone = () => {
|
|
112
140
|
sketchViewModel.cancel()
|
|
113
141
|
sketchViewModel.layer = emptySketchLayer
|
|
114
142
|
dispatch({ type: 'SET_MODE', payload: null })
|
|
115
|
-
dispatch({ type: 'SET_FEATURE', payload: { feature: null, tempFeature: null }})
|
|
143
|
+
dispatch({ type: 'SET_FEATURE', payload: { feature: null, tempFeature: null } })
|
|
116
144
|
eventBus.emit('draw:done', { newFeature: pluginState.tempFeature })
|
|
117
145
|
}
|
|
118
146
|
|
|
119
147
|
const handleCancel = () => {
|
|
120
148
|
sketchViewModel.cancel()
|
|
121
|
-
|
|
149
|
+
|
|
122
150
|
// Clear all graphics
|
|
123
151
|
sketchLayer.removeAll()
|
|
124
152
|
|
|
@@ -143,10 +171,12 @@ export function attachEvents({ pluginState, mapProvider, events, eventBus, butto
|
|
|
143
171
|
eventBus.on(events.MAP_STYLE_CHANGE, handleMapStyleChange)
|
|
144
172
|
const sketchUpdateHandler = sketchViewModel.on('update', handleSketchUpdate)
|
|
145
173
|
const viewClickHandler = view.on('click', handleViewClick)
|
|
146
|
-
|
|
174
|
+
const createHandler = sketchViewModel.on('create', handleCreate)
|
|
175
|
+
const undoHandler = sketchViewModel.on('undo', handleUndo)
|
|
176
|
+
|
|
147
177
|
const prevDoneClick = drawDone.onClick
|
|
148
178
|
const prevCancelClick = drawCancel.onClick
|
|
149
|
-
|
|
179
|
+
|
|
150
180
|
drawDone.onClick = handleDone
|
|
151
181
|
drawCancel.onClick = handleCancel
|
|
152
182
|
|
|
@@ -155,7 +185,9 @@ export function attachEvents({ pluginState, mapProvider, events, eventBus, butto
|
|
|
155
185
|
eventBus.off(events.MAP_STYLE_CHANGE, handleMapStyleChange)
|
|
156
186
|
sketchUpdateHandler.remove()
|
|
157
187
|
viewClickHandler.remove()
|
|
188
|
+
createHandler.remove()
|
|
189
|
+
undoHandler.remove()
|
|
158
190
|
drawDone.onClick = prevDoneClick
|
|
159
191
|
drawCancel.onClick = prevCancelClick
|
|
160
192
|
}
|
|
161
|
-
}
|
|
193
|
+
}
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import { attachEvents } from './events.js'
|
|
2
|
+
import { EVENTS as events } from '../../../../src/config/events.js'
|
|
3
|
+
|
|
4
|
+
import * as graphicJs from './graphic.js'
|
|
5
|
+
jest.mock('./graphic.js')
|
|
6
|
+
const createGraphic = jest.spyOn(graphicJs, 'createGraphic')
|
|
7
|
+
const createSymbol = jest.spyOn(graphicJs, 'createSymbol')
|
|
8
|
+
// const graphicToGeoJSON = jest.spyOn(graphicJs, 'graphicToGeoJSON')
|
|
9
|
+
|
|
10
|
+
const dispatch = jest.fn()
|
|
11
|
+
|
|
12
|
+
const createMockEventHandler = (type) => {
|
|
13
|
+
const callbackSpies = {}
|
|
14
|
+
const removeSpy = jest.fn()
|
|
15
|
+
const onSpy = jest.fn((eventType, callback) => {
|
|
16
|
+
callbackSpies[eventType] = callback
|
|
17
|
+
return { remove: () => removeSpy(eventType) }
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
// returns an async function that runs asserts
|
|
21
|
+
const assertOnCalls = (methodArray) => async () => {
|
|
22
|
+
expect(onSpy.mock.calls, `${type}.on should be called ${methodArray.length} times`)
|
|
23
|
+
.toHaveLength(methodArray.length)
|
|
24
|
+
methodArray.forEach((method) =>
|
|
25
|
+
expect(onSpy, `${type}.on should be called with ${method} and a callback`)
|
|
26
|
+
.toHaveBeenCalledWith(method, callbackSpies[method]))
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const assertRemoveCalls = (methodArray) => async () => {
|
|
30
|
+
expect(removeSpy.mock.calls, `${type}.remove/off should be called ${methodArray.length} times`)
|
|
31
|
+
.toHaveLength(methodArray.length)
|
|
32
|
+
methodArray.forEach((method) => {
|
|
33
|
+
const removeParams = type === 'eventBus' ? [method, callbackSpies[[method]]] : [method]
|
|
34
|
+
expect(removeSpy, `${type}.remove/off should be called with ${removeParams} `).toHaveBeenCalledWith(...removeParams)
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
removeSpy,
|
|
40
|
+
callbackSpies,
|
|
41
|
+
emit: jest.fn(),
|
|
42
|
+
off: removeSpy,
|
|
43
|
+
on: onSpy,
|
|
44
|
+
assertOnCalls,
|
|
45
|
+
assertRemoveCalls,
|
|
46
|
+
triggerEvent: (eventType, event) => callbackSpies[eventType](event)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const coordinates = [[[337560, 504846], [337580, 504855], [337587, 504838], [337565, 504833], [337560, 504846]]]
|
|
50
|
+
const feature = {
|
|
51
|
+
type: 'Feature',
|
|
52
|
+
geometry: {
|
|
53
|
+
type: 'Polygon',
|
|
54
|
+
coordinates
|
|
55
|
+
},
|
|
56
|
+
properties: { id: 'boundary' }
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const mockSymbol = { color: 'blue' }
|
|
60
|
+
const newGraphicMock = { symbol: { color: 'red' } }
|
|
61
|
+
|
|
62
|
+
const mockGraphic = {
|
|
63
|
+
attributes: { id: 'boundary' },
|
|
64
|
+
geometry: { rings: coordinates },
|
|
65
|
+
symbol: null
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const sketchLayer = {
|
|
69
|
+
removeAll: jest.fn(),
|
|
70
|
+
add: jest.fn(),
|
|
71
|
+
graphics: { items: [mockGraphic] }
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
class ButtonConfigMock {
|
|
75
|
+
constructor (name) {
|
|
76
|
+
this.name = name
|
|
77
|
+
this._onClick = 'Initial Value'
|
|
78
|
+
this._initialOnClick = this._onClick
|
|
79
|
+
this.assignOnClickSpy = jest.spyOn(this, 'onClick', 'set')
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
set onClick (onClick) {
|
|
83
|
+
this._onClick = onClick
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
get onClick () {
|
|
87
|
+
return this._onClick
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
assertOnClickAssignment () {
|
|
91
|
+
return async () => {
|
|
92
|
+
expect(this.assignOnClickSpy.mock.calls, `${this.name}.onClick should have been reassigned once`)
|
|
93
|
+
.toHaveLength(1)
|
|
94
|
+
expect(this._onClick, `${this.name}.onClick should have changed`)
|
|
95
|
+
.not.toEqual(this._initialOnClick)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
assertOnClickReset () {
|
|
100
|
+
return async () => {
|
|
101
|
+
expect(this.assignOnClickSpy.mock.calls, `${this.name}.onClick should have been assigned twice`)
|
|
102
|
+
.toHaveLength(2)
|
|
103
|
+
expect(this._onClick, `${this.name}.onClick should been set back to its initial value`)
|
|
104
|
+
.toEqual(this._initialOnClick)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const emptySketchLayer = {}
|
|
109
|
+
|
|
110
|
+
const buildParams = (overrides = {}) => {
|
|
111
|
+
return {
|
|
112
|
+
pluginState: {
|
|
113
|
+
dispatch,
|
|
114
|
+
mode: 'new-polygon', // or: edit-feature
|
|
115
|
+
feature,
|
|
116
|
+
...overrides.pluginState
|
|
117
|
+
},
|
|
118
|
+
mapProvider: {
|
|
119
|
+
view: createMockEventHandler('view'),
|
|
120
|
+
sketchViewModel: {
|
|
121
|
+
...createMockEventHandler('sketchViewModel'),
|
|
122
|
+
layer: sketchLayer,
|
|
123
|
+
cancel: jest.fn(),
|
|
124
|
+
state: 'idle',
|
|
125
|
+
polygonSymbol: null,
|
|
126
|
+
update: jest.fn().mockResolvedValue(undefined)
|
|
127
|
+
},
|
|
128
|
+
// sketchViewModel: { ...sketchViewModel, ...overrides.sketchViewModel },
|
|
129
|
+
sketchLayer,
|
|
130
|
+
emptySketchLayer,
|
|
131
|
+
...overrides.mapProvider
|
|
132
|
+
},
|
|
133
|
+
events,
|
|
134
|
+
eventBus: createMockEventHandler('eventBus'),
|
|
135
|
+
buttonConfig: {
|
|
136
|
+
drawDone: new ButtonConfigMock('Done'),
|
|
137
|
+
drawCancel: new ButtonConfigMock('Cancel')
|
|
138
|
+
},
|
|
139
|
+
mapColorScheme: 'MOCK_COLOUR_SCHEME'
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
describe('attachEvents - draw-es', () => {
|
|
144
|
+
beforeEach(() => {
|
|
145
|
+
jest.useFakeTimers()
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
afterEach(() => {
|
|
149
|
+
jest.useRealTimers()
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
describe('listeners', () => {
|
|
153
|
+
const params = buildParams()
|
|
154
|
+
const { drawDone, drawCancel } = params.buttonConfig
|
|
155
|
+
const { eventBus } = params
|
|
156
|
+
const { sketchViewModel, view } = params.mapProvider
|
|
157
|
+
const teardown = attachEvents(params)
|
|
158
|
+
describe('attach', () => {
|
|
159
|
+
it('should add view listeners', view.assertOnCalls(['click']))
|
|
160
|
+
it('should add sketchViewModel listeners', sketchViewModel.assertOnCalls(['update', 'create', 'undo']))
|
|
161
|
+
it('should add eventBus listeners', eventBus.assertOnCalls([events.MAP_STYLE_CHANGE]))
|
|
162
|
+
it('should assign a Done click handler', drawDone.assertOnClickAssignment())
|
|
163
|
+
it('should assign a Cancel click handler', drawCancel.assertOnClickAssignment())
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
describe('teardown', () => {
|
|
167
|
+
beforeAll(teardown)
|
|
168
|
+
it('should teardown the view listeners', view.assertRemoveCalls(['click']))
|
|
169
|
+
it('should teardown the sketchViewModel listeners', sketchViewModel.assertRemoveCalls(['update', 'create', 'undo']))
|
|
170
|
+
it('should teardown the eventBus listeners', eventBus.assertRemoveCalls([events.MAP_STYLE_CHANGE]))
|
|
171
|
+
it('should reset the Done click handler', drawDone.assertOnClickReset())
|
|
172
|
+
it('should reset the Cancel click handler', drawCancel.assertOnClickReset())
|
|
173
|
+
})
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
describe('internal methods', () => {
|
|
177
|
+
beforeEach(jest.clearAllMocks)
|
|
178
|
+
|
|
179
|
+
it('should return null if sketchViewModel is not set', async () => {
|
|
180
|
+
const response = attachEvents(buildParams({
|
|
181
|
+
mapProvider: { sketchViewModel: null }
|
|
182
|
+
}))
|
|
183
|
+
expect(response).toBeNull()
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
it('should call handleDone when Done is clicked', async () => {
|
|
187
|
+
const params = buildParams()
|
|
188
|
+
params.pluginState.tempFeature = 'Test Feature'
|
|
189
|
+
attachEvents(params)
|
|
190
|
+
params.buttonConfig.drawDone.onClick()
|
|
191
|
+
expect(params.mapProvider.sketchViewModel.cancel).toHaveBeenCalled()
|
|
192
|
+
expect(params.mapProvider.sketchViewModel.layer).toEqual(emptySketchLayer)
|
|
193
|
+
expect(dispatch).toHaveBeenCalledWith({ type: 'SET_MODE', payload: null })
|
|
194
|
+
expect(dispatch).toHaveBeenCalledWith({ type: 'SET_FEATURE', payload: { feature: null, tempFeature: null } })
|
|
195
|
+
expect(params.eventBus.emit).toHaveBeenCalledWith('draw:done', { newFeature: 'Test Feature' })
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
it('should call handleCancel when Cancel is clicked', async () => {
|
|
199
|
+
const params = buildParams()
|
|
200
|
+
params.pluginState.tempFeature = 'Test Feature'
|
|
201
|
+
// params.pluginState.feature = { properties: { id: 'boundary' } }
|
|
202
|
+
const { drawCancel } = params.buttonConfig
|
|
203
|
+
const { sketchViewModel, sketchLayer } = params.mapProvider
|
|
204
|
+
const { eventBus } = params
|
|
205
|
+
attachEvents(params)
|
|
206
|
+
drawCancel.onClick()
|
|
207
|
+
expect(sketchViewModel.cancel).toHaveBeenCalled()
|
|
208
|
+
expect(sketchLayer.removeAll).toHaveBeenCalled()
|
|
209
|
+
expect(createGraphic).toHaveBeenCalled()
|
|
210
|
+
expect(sketchLayer.add).toHaveBeenCalled()
|
|
211
|
+
expect(sketchViewModel.layer).toEqual(emptySketchLayer)
|
|
212
|
+
expect(dispatch).toHaveBeenCalledWith({ type: 'SET_MODE', payload: null })
|
|
213
|
+
expect(eventBus.emit).toHaveBeenCalledWith('draw:cancelled')
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
describe('reColour', () => {
|
|
217
|
+
beforeEach(() => {
|
|
218
|
+
createSymbol.mockReturnValue(mockSymbol)
|
|
219
|
+
createGraphic.mockReturnValue(newGraphicMock)
|
|
220
|
+
mockGraphic.symbol = null
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
it('should update polygonSymbol and graphic symbols when state is not active', async () => {
|
|
224
|
+
const params = buildParams()
|
|
225
|
+
attachEvents(params)
|
|
226
|
+
params.eventBus.triggerEvent(events.MAP_STYLE_CHANGE)
|
|
227
|
+
await Promise.resolve()
|
|
228
|
+
expect(params.mapProvider.sketchViewModel.polygonSymbol).toEqual(mockSymbol)
|
|
229
|
+
expect(createGraphic).toHaveBeenCalledWith('boundary', mockGraphic.geometry.rings, params.mapColorScheme)
|
|
230
|
+
expect(mockGraphic.symbol).toEqual(newGraphicMock.symbol)
|
|
231
|
+
expect(params.mapProvider.sketchViewModel.cancel).not.toHaveBeenCalled()
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
it('should cancel and re-enter update mode when state is active and activeGraphicId is set (edit mode)', async () => {
|
|
235
|
+
const params = buildParams()
|
|
236
|
+
params.mapProvider.sketchViewModel.state = 'active'
|
|
237
|
+
attachEvents(params)
|
|
238
|
+
params.eventBus.triggerEvent(events.MAP_STYLE_CHANGE)
|
|
239
|
+
expect(params.mapProvider.sketchViewModel.cancel).toHaveBeenCalled()
|
|
240
|
+
jest.advanceTimersByTime(50)
|
|
241
|
+
await Promise.resolve()
|
|
242
|
+
await Promise.resolve()
|
|
243
|
+
expect(params.mapProvider.sketchViewModel.update).toHaveBeenCalledWith(mockGraphic, {
|
|
244
|
+
tool: 'reshape',
|
|
245
|
+
toggleToolOnClick: false
|
|
246
|
+
})
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
it('should not cancel or re-enter update mode when isCreating (active state, no activeGraphicId)', async () => {
|
|
250
|
+
const params = buildParams({
|
|
251
|
+
pluginState: { feature: null }
|
|
252
|
+
})
|
|
253
|
+
attachEvents(params)
|
|
254
|
+
params.eventBus.triggerEvent(events.MAP_STYLE_CHANGE)
|
|
255
|
+
await Promise.resolve()
|
|
256
|
+
expect(params.mapProvider.sketchViewModel.cancel).not.toHaveBeenCalled()
|
|
257
|
+
expect(params.mapProvider.sketchViewModel.update).not.toHaveBeenCalled()
|
|
258
|
+
})
|
|
259
|
+
|
|
260
|
+
it('should not call sketchViewModel.update if layer is not sketchLayer', async () => {
|
|
261
|
+
const params = buildParams()
|
|
262
|
+
params.mapProvider.sketchViewModel.layer = emptySketchLayer
|
|
263
|
+
attachEvents(params)
|
|
264
|
+
params.eventBus.triggerEvent(events.MAP_STYLE_CHANGE)
|
|
265
|
+
await Promise.resolve()
|
|
266
|
+
expect(params.mapProvider.sketchViewModel.update).not.toHaveBeenCalled()
|
|
267
|
+
})
|
|
268
|
+
|
|
269
|
+
it('should swallow AbortError thrown by sketchViewModel.update', async () => {
|
|
270
|
+
const abortError = Object.assign(new Error('Aborted'), { name: 'AbortError' })
|
|
271
|
+
const params = buildParams()
|
|
272
|
+
params.mapProvider.sketchViewModel.update.mockRejectedValue(abortError)
|
|
273
|
+
const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {})
|
|
274
|
+
attachEvents(params)
|
|
275
|
+
params.eventBus.triggerEvent(events.MAP_STYLE_CHANGE)
|
|
276
|
+
jest.advanceTimersByTime(50)
|
|
277
|
+
await Promise.resolve()
|
|
278
|
+
await Promise.resolve()
|
|
279
|
+
await Promise.resolve()
|
|
280
|
+
expect(consoleSpy).not.toHaveBeenCalled()
|
|
281
|
+
consoleSpy.mockRestore()
|
|
282
|
+
})
|
|
283
|
+
|
|
284
|
+
it('should log non-AbortError thrown by sketchViewModel.update', async () => {
|
|
285
|
+
const genericError = new Error('Something went wrong')
|
|
286
|
+
const params = buildParams()
|
|
287
|
+
params.mapProvider.sketchViewModel.state = 'active'
|
|
288
|
+
params.mapProvider.sketchViewModel.update.mockRejectedValue(genericError)
|
|
289
|
+
const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {})
|
|
290
|
+
attachEvents(params)
|
|
291
|
+
params.eventBus.triggerEvent(events.MAP_STYLE_CHANGE)
|
|
292
|
+
jest.advanceTimersByTime(50)
|
|
293
|
+
await Promise.resolve()
|
|
294
|
+
await Promise.resolve()
|
|
295
|
+
await Promise.resolve()
|
|
296
|
+
expect(consoleSpy).toHaveBeenCalledWith('Error updating sketch:', genericError)
|
|
297
|
+
consoleSpy.mockRestore()
|
|
298
|
+
})
|
|
299
|
+
})
|
|
300
|
+
})
|
|
301
|
+
})
|
|
@@ -7,8 +7,8 @@ import { addFeature } from './api/addFeature.js'
|
|
|
7
7
|
import { deleteFeature } from './api/deleteFeature.js'
|
|
8
8
|
|
|
9
9
|
const buttonSlots = {
|
|
10
|
-
mobile:
|
|
11
|
-
tablet:
|
|
10
|
+
mobile: { slot: 'actions', showLabel: true },
|
|
11
|
+
tablet: { slot: 'actions', showLabel: true },
|
|
12
12
|
desktop: { slot: 'actions', showLabel: true }
|
|
13
13
|
}
|
|
14
14
|
|
|
@@ -27,7 +27,7 @@ export const manifest = {
|
|
|
27
27
|
hiddenWhen: ({ pluginState }) => !pluginState.mode,
|
|
28
28
|
enableWhen: ({ pluginState }) => !!pluginState.tempFeature,
|
|
29
29
|
...buttonSlots
|
|
30
|
-
},{
|
|
30
|
+
}, {
|
|
31
31
|
id: 'drawCancel',
|
|
32
32
|
label: 'Cancel',
|
|
33
33
|
variant: 'tertiary',
|
|
@@ -48,4 +48,4 @@ export const manifest = {
|
|
|
48
48
|
addFeature,
|
|
49
49
|
deleteFeature
|
|
50
50
|
}
|
|
51
|
-
}
|
|
51
|
+
}
|