@eeacms/volto-eea-map 4.1.0 → 5.0.0

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 (73) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/package.json +5 -2
  3. package/src/Arcgis/Editor/Editor.jsx +130 -0
  4. package/src/Arcgis/Editor/EditorContext.jsx +2 -0
  5. package/src/Arcgis/Editor/Fold/Fold.jsx +56 -0
  6. package/src/Arcgis/Editor/Panels/Panel.jsx +8 -0
  7. package/src/Arcgis/Editor/Panels/SettingsGeneralPanel.jsx +217 -0
  8. package/src/Arcgis/Editor/Panels/SettingsLayersPanel.jsx +216 -0
  9. package/src/Arcgis/Editor/Panels/StructureBaseLayerPanel.jsx +60 -0
  10. package/src/Arcgis/Editor/Panels/StructureLayersPanel.jsx +394 -0
  11. package/src/Arcgis/Editor/Panels/StructureWidgetsPanel.jsx +181 -0
  12. package/src/Arcgis/Editor/Panels/index.js +6 -0
  13. package/src/Arcgis/Editor/SidebarGroup.jsx +62 -0
  14. package/src/Arcgis/Layer/Layer.jsx +247 -0
  15. package/src/Arcgis/Map/Map.jsx +287 -0
  16. package/src/Arcgis/Map/MapBuilder.jsx +111 -0
  17. package/src/Arcgis/Map/MapContext.jsx +3 -0
  18. package/src/Arcgis/Widget/Widget.jsx +170 -0
  19. package/src/Arcgis/helpers.js +140 -0
  20. package/src/Blocks/EmbedEEAMap/Edit.jsx +40 -0
  21. package/src/Blocks/EmbedEEAMap/View.jsx +122 -0
  22. package/src/Blocks/EmbedEEAMap/helpers.js +12 -0
  23. package/src/Blocks/EmbedEEAMap/schema.js +126 -0
  24. package/src/{components → Toolbar}/Share.jsx +1 -1
  25. package/src/{components/ExtraViews.jsx → Toolbar/Toolbar.jsx} +14 -16
  26. package/src/{components/visualization → Views}/VisualizationView.jsx +8 -9
  27. package/src/Widgets/ArcgisColorPickerWidget.jsx +95 -0
  28. package/src/Widgets/ArcgisRendererWidget/ArcgisRendererWidget.jsx +106 -0
  29. package/src/Widgets/ArcgisRendererWidget/RendererEditor/ClassBreaks.jsx +8 -0
  30. package/src/Widgets/ArcgisRendererWidget/RendererEditor/Dictionary.jsx +8 -0
  31. package/src/Widgets/ArcgisRendererWidget/RendererEditor/DotDensity.jsx +8 -0
  32. package/src/Widgets/ArcgisRendererWidget/RendererEditor/Heatmap.jsx +8 -0
  33. package/src/Widgets/ArcgisRendererWidget/RendererEditor/PieChart.jsx +8 -0
  34. package/src/Widgets/ArcgisRendererWidget/RendererEditor/Simple.jsx +109 -0
  35. package/src/Widgets/ArcgisRendererWidget/RendererEditor/UniqueValue.jsx +8 -0
  36. package/src/Widgets/ArcgisRendererWidget/RendererEditor/_Editor.jsx +29 -0
  37. package/src/Widgets/ArcgisRendererWidget/RendererEditor/_EditorModal.jsx +88 -0
  38. package/src/Widgets/ArcgisRendererWidget/RendererEditor/_defaults.js +30 -0
  39. package/src/Widgets/ArcgisSliderWidget.jsx +79 -0
  40. package/src/Widgets/ArcgisViewpointWidget.jsx +112 -0
  41. package/src/{components/visualization → Widgets}/VisualizationViewWidget.jsx +9 -10
  42. package/src/Widgets/VisualizationWidget.jsx +200 -0
  43. package/src/arcgis.js +48 -0
  44. package/src/constants.js +225 -7
  45. package/src/hocs/withArcgis.jsx +27 -0
  46. package/src/hooks/useChangedProps.jsx +24 -0
  47. package/src/hooks/useClass.jsx +17 -0
  48. package/src/hooks/useCopyToClipboard.jsx +25 -0
  49. package/src/index.js +16 -16
  50. package/src/jsoneditor.js +72 -0
  51. package/src/styles/editor.less +446 -0
  52. package/src/styles/map.less +3 -0
  53. package/src/components/Blocks/EmbedEEAMap/Edit.jsx +0 -161
  54. package/src/components/Blocks/EmbedEEAMap/Schema.js +0 -161
  55. package/src/components/Blocks/EmbedEEAMap/View.jsx +0 -79
  56. package/src/components/Blocks/EmbedEEAMap/helpers.js +0 -45
  57. package/src/components/LegendView.jsx +0 -150
  58. package/src/components/Webmap.jsx +0 -371
  59. package/src/components/index.js +0 -6
  60. package/src/components/visualization/VisualizationEditorWidget.jsx +0 -122
  61. package/src/components/visualization/panelsSchema.js +0 -229
  62. package/src/components/widgets/DataQueryWidget.jsx +0 -51
  63. package/src/components/widgets/LayerSelectWidget.jsx +0 -463
  64. package/src/components/widgets/LayersPanelWidget.jsx +0 -59
  65. package/src/components/widgets/SimpleColorPickerWidget.jsx +0 -121
  66. package/src/hocs/index.js +0 -3
  67. package/src/hocs/withDeviceSize.jsx +0 -45
  68. package/src/less/global.less +0 -253
  69. package/src/less/variables.less +0 -5
  70. package/src/utils.js +0 -151
  71. /package/src/{components → Toolbar}/FigureNote.jsx +0 -0
  72. /package/src/{components → Toolbar}/MoreInfoLink.jsx +0 -0
  73. /package/src/{components → Toolbar}/Sources.jsx +0 -0
@@ -0,0 +1,112 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { toNumber } from 'lodash';
3
+ import { FormFieldWrapper, InlineForm } from '@plone/volto/components';
4
+
5
+ export default function ArcgisViewpointWidget(props) {
6
+ const [watchViewpoint, setWatchViewpoint] = useState(false);
7
+ const { $map, id, value, onChange } = props;
8
+
9
+ useEffect(() => {
10
+ if (!$map.current?.isReady) return;
11
+ const homeWidget = $map.current.view.ui.find('Home');
12
+ if (!homeWidget) return;
13
+ homeWidget.viewpoint = new $map.current.modules.AgViewpoint({
14
+ center: [value.longitude, value.latitude],
15
+ zoom: value.zoom,
16
+ });
17
+ }, [$map, value]);
18
+
19
+ useEffect(() => {
20
+ if (watchViewpoint && $map.current?.isReady) {
21
+ const reactiveUtils = $map.current.modules.agReactiveUtils;
22
+
23
+ reactiveUtils.when(
24
+ () => $map.current.view.stationary,
25
+ (stationary) => {
26
+ if (stationary) {
27
+ const { longitude, latitude } = $map.current.view.center;
28
+ const zoom = $map.current.view.zoom;
29
+ onChange(id, {
30
+ ...value,
31
+ longitude,
32
+ latitude,
33
+ zoom,
34
+ });
35
+ }
36
+ setWatchViewpoint(false);
37
+ },
38
+ {
39
+ once: true,
40
+ },
41
+ );
42
+ }
43
+ }, [$map, watchViewpoint, id, value, onChange]);
44
+
45
+ return (
46
+ <>
47
+ <FormFieldWrapper {...props}>
48
+ <div style={{ display: 'flex', alignItems: 'center', width: '100%' }}>
49
+ <button
50
+ className="btn-primary"
51
+ style={{
52
+ fontSize: 'var(--font-size-small)',
53
+ width: '100%',
54
+ display: 'inline-block',
55
+ textAlign: 'center',
56
+ }}
57
+ onClick={() => {
58
+ setWatchViewpoint(true);
59
+ }}
60
+ >
61
+ {watchViewpoint ? 'Waiting...' : 'Drag on map'}
62
+ </button>
63
+ </div>
64
+ </FormFieldWrapper>
65
+ <div className="arcgis-viewpoint-editor">
66
+ <InlineForm
67
+ schema={{
68
+ title: 'Initial viewpoint',
69
+ fieldsets: [
70
+ {
71
+ id: 'default',
72
+ title: 'Default',
73
+ fields: ['longitude', 'latitude', 'zoom'],
74
+ },
75
+ ],
76
+ properties: {
77
+ longitude: {
78
+ title: 'Longitude',
79
+ type: 'number',
80
+ minimum: 0,
81
+ },
82
+ latitude: {
83
+ title: 'Latitude',
84
+ type: 'number',
85
+ minimum: 0,
86
+ },
87
+ zoom: {
88
+ title: 'Zoom',
89
+ type: 'number',
90
+ minimum: 0,
91
+ },
92
+ },
93
+ required: [],
94
+ }}
95
+ formData={value}
96
+ onChangeField={(fieldId, fieldValue) => {
97
+ let $fieldValue = fieldValue;
98
+
99
+ if (['longitude', 'latitude', 'zoom'].includes(fieldId)) {
100
+ $fieldValue = Math.max(toNumber($fieldValue) || 0, 0);
101
+ }
102
+
103
+ onChange(id, {
104
+ ...value,
105
+ [fieldId]: $fieldValue,
106
+ });
107
+ }}
108
+ />
109
+ </div>
110
+ </>
111
+ );
112
+ }
@@ -1,25 +1,24 @@
1
1
  import { connect } from 'react-redux';
2
2
  import { pickMetadata } from '@eeacms/volto-embed/helpers';
3
- import Webmap from '../Webmap';
4
- import ExtraViews from '../ExtraViews';
3
+ import MapBuilder from '@eeacms/volto-eea-map/Arcgis/Map/MapBuilder';
4
+ import Toolbar from '../Toolbar/Toolbar';
5
5
 
6
6
  function VisualizationViewWidget(props) {
7
- const { value: map_visualization_data = {} } = props;
7
+ const { value: mapData = {}, content } = props;
8
8
 
9
9
  return (
10
10
  <>
11
- <Webmap data={map_visualization_data} />
12
- <ExtraViews
11
+ <MapBuilder data={mapData} />
12
+ <Toolbar
13
+ style={{ marginTop: '1rem' }}
13
14
  data={{
14
- show_viewer: true,
15
- show_legend: true,
16
15
  show_note: false,
17
16
  show_sources: false,
18
17
  show_more_info: false,
19
18
  show_share: true,
20
- map_visualization_data: {
21
- ...map_visualization_data,
22
- ...pickMetadata(props.content),
19
+ mapData: {
20
+ ...mapData,
21
+ ...pickMetadata(content),
23
22
  },
24
23
  }}
25
24
  />
@@ -0,0 +1,200 @@
1
+ import React, { useState, useRef, useEffect } from 'react';
2
+ import { Modal, Button, Grid } from 'semantic-ui-react';
3
+ import { toast } from 'react-toastify';
4
+
5
+ import { FormFieldWrapper, Icon, Toast } from '@plone/volto/components';
6
+
7
+ import MapBuilder from '@eeacms/volto-eea-map/Arcgis/Map/MapBuilder';
8
+ import {
9
+ initEditor,
10
+ destroyEditor,
11
+ validateEditor,
12
+ onPasteEditor,
13
+ } from '@eeacms/volto-eea-map/jsoneditor';
14
+
15
+ import editSVG from '@plone/volto/icons/editing.svg';
16
+
17
+ import '@eeacms/volto-eea-map/styles/editor.less';
18
+ import MapEditor from '../Arcgis/Editor/Editor';
19
+
20
+ function JsonEditorModal(props) {
21
+ const { value, onClose, onChange } = props;
22
+ const editor = useRef();
23
+ const initailValue = useRef(props.value);
24
+
25
+ async function getValue() {
26
+ const valid = await validateEditor(editor);
27
+ if (!valid) {
28
+ throw new Error('Invalid JSON');
29
+ }
30
+ try {
31
+ return editor.current.get();
32
+ } catch {
33
+ throw new Error('Invalid JSON');
34
+ }
35
+ }
36
+
37
+ useEffect(() => {
38
+ initEditor({
39
+ el: 'jsoneditor-plotlyjson',
40
+ editor,
41
+ options: {
42
+ schema: undefined,
43
+ },
44
+ dflt: initailValue.current,
45
+ });
46
+
47
+ const editorCurr = editor.current;
48
+
49
+ return () => {
50
+ destroyEditor(editorCurr);
51
+ };
52
+ }, []);
53
+
54
+ return (
55
+ <Modal size="fullscreen" open={true} className="plotly-json-modal">
56
+ <Modal.Content scrolling>
57
+ <div
58
+ id="jsoneditor-plotlyjson"
59
+ style={{ width: '100%', height: '100%' }}
60
+ onPaste={(e) => {
61
+ onPasteEditor(editor);
62
+ }}
63
+ />
64
+ </Modal.Content>
65
+ <Modal.Actions>
66
+ <Button
67
+ onClick={() => {
68
+ onChange(initailValue.current);
69
+ onClose();
70
+ }}
71
+ >
72
+ Close
73
+ </Button>
74
+ <Button
75
+ primary
76
+ onClick={async () => {
77
+ try {
78
+ const newValue = {
79
+ ...value,
80
+ ...(await getValue()),
81
+ };
82
+ onChange(newValue);
83
+ onClose();
84
+ } catch (error) {
85
+ toast.error(
86
+ <Toast error title={'JSON error'} content={error.message} />,
87
+ );
88
+ }
89
+ }}
90
+ >
91
+ Apply
92
+ </Button>
93
+ </Modal.Actions>
94
+ </Modal>
95
+ );
96
+ }
97
+
98
+ function MapEditorModal(props) {
99
+ const [value, setValue] = useState(props.value);
100
+ const [open, setOpen] = useState(false);
101
+
102
+ const properties = props.formData;
103
+
104
+ return (
105
+ <>
106
+ <Modal open={true} size="fullscreen" className="chart-editor-modal">
107
+ <Modal.Content scrolling>
108
+ <MapEditor
109
+ value={value}
110
+ properties={properties}
111
+ onChangeValue={(value) => {
112
+ setValue(value);
113
+ }}
114
+ />
115
+ </Modal.Content>
116
+ <Modal.Actions>
117
+ <Grid>
118
+ <Grid.Row>
119
+ <Grid.Column
120
+ verticalAlign="middle"
121
+ style={{
122
+ display: 'inline-flex',
123
+ flexFlow: 'row',
124
+ justifyContent: 'space-between',
125
+ }}
126
+ >
127
+ <Button
128
+ secondary
129
+ className="json-btn"
130
+ onClick={() => setOpen(true)}
131
+ >
132
+ <Icon name={editSVG} size="20px" />
133
+ JSON
134
+ </Button>
135
+ <div style={{ display: 'flex' }}>
136
+ <Button floated="right" onClick={props.onClose}>
137
+ Close
138
+ </Button>
139
+ <Button
140
+ primary
141
+ floated="right"
142
+ onClick={() => {
143
+ props.onChange(props.id, value);
144
+ props.onClose();
145
+ }}
146
+ >
147
+ Apply
148
+ </Button>
149
+ </div>
150
+ </Grid.Column>
151
+ </Grid.Row>
152
+ </Grid>
153
+ </Modal.Actions>
154
+ </Modal>
155
+ {open && (
156
+ <JsonEditorModal
157
+ value={value}
158
+ onChange={setValue}
159
+ onClose={() => setOpen(false)}
160
+ />
161
+ )}
162
+ </>
163
+ );
164
+ }
165
+
166
+ const VisualizationWidget = (props) => {
167
+ const { id, title, description, value } = props;
168
+ const [showMapEditor, setShowMapEditor] = useState(false);
169
+
170
+ if (__SERVER__) return '';
171
+
172
+ return (
173
+ <FormFieldWrapper {...props} columns={1}>
174
+ <div className="wrapper">
175
+ <label htmlFor={`field-${id}`}>{title}</label>
176
+ <Button
177
+ floated="right"
178
+ onClick={(e) => {
179
+ e.preventDefault();
180
+ e.stopPropagation();
181
+ setShowMapEditor(true);
182
+ }}
183
+ >
184
+ Open Map Editor
185
+ </Button>
186
+ </div>
187
+ {description && <p className="help">{description}</p>}
188
+ <MapBuilder data={value} />
189
+ {showMapEditor && (
190
+ <MapEditorModal
191
+ {...props}
192
+ value={value || {}}
193
+ onClose={() => setShowMapEditor(false)}
194
+ />
195
+ )}
196
+ </FormFieldWrapper>
197
+ );
198
+ };
199
+
200
+ export default VisualizationWidget;
package/src/arcgis.js ADDED
@@ -0,0 +1,48 @@
1
+ export default function arcgis(version = '4.29') {
2
+ if (__SERVER__) return null;
3
+
4
+ const getId = (type) => {
5
+ return `arcgis${type}-${version}`;
6
+ };
7
+
8
+ const linkId = getId('css');
9
+ const scriptId = getId('js');
10
+
11
+ function loadCss() {
12
+ let link = document.getElementById(linkId);
13
+ if (!link) {
14
+ link = document.createElement('link');
15
+ link.rel = 'stylesheet';
16
+ link.href = `https://js.arcgis.com/${version}/esri/themes/light/main.css`;
17
+ link.id = getId('css');
18
+ document.head.appendChild(link);
19
+ link.addEventListener('load', () => {
20
+ loadScript();
21
+ });
22
+ }
23
+ }
24
+
25
+ function loadScript() {
26
+ let script = document.getElementById(scriptId);
27
+ if (!script) {
28
+ script = document.createElement('script');
29
+ script.src = `https://js.arcgis.com/${version}/init.js`;
30
+ script.id = scriptId;
31
+ document.body.appendChild(script);
32
+ script.addEventListener('load', () => {
33
+ if (window.$arcgis) {
34
+ window.postMessage({
35
+ type: 'arcgis-loaded',
36
+ });
37
+ }
38
+ });
39
+ }
40
+ }
41
+
42
+ if (window.$arcgis) {
43
+ return window.$arcgis;
44
+ } else {
45
+ loadCss();
46
+ return null;
47
+ }
48
+ }
package/src/constants.js CHANGED
@@ -1,10 +1,17 @@
1
- const positions = ['bottom-right', 'bottom-left', 'top-right', 'top-left'].map(
2
- (n) => {
3
- return { key: n, value: n, text: n };
4
- },
5
- );
1
+ import { capitalize } from 'lodash';
2
+
3
+ export const positions = [
4
+ 'top-left',
5
+ 'top-right',
6
+ 'bottom-right',
7
+ 'bottom-left',
8
+ ].map((n) => {
9
+ return [n, capitalize(n.replaceAll('-', ' '))];
10
+ });
6
11
 
7
- const base_layers = [
12
+ export const basemaps = [
13
+ 'positron-composite',
14
+ 'blossom-composite',
8
15
  'dark-gray',
9
16
  'dark-gray-vector',
10
17
  'gray',
@@ -22,8 +29,219 @@ const base_layers = [
22
29
  'terrain',
23
30
  'topo',
24
31
  'topo-vector',
32
+ ].map((n) => {
33
+ return [n, capitalize(n.replaceAll('-', ' '))];
34
+ });
35
+
36
+ export const widgets = [
37
+ 'AreaMeasurement2D',
38
+ 'AreaMeasurement3D',
39
+ 'Attachments',
40
+ 'Attribution',
41
+ 'BasemapGallery',
42
+ 'BasemapLayerList',
43
+ 'BasemapToggle',
44
+ 'Bookmarks',
45
+ 'BuildingExplorer',
46
+ 'Compass',
47
+ 'CoordinateConversion',
48
+ 'Daylight',
49
+ 'DirectLineMeasurement3D',
50
+ 'DirectionalPad',
51
+ 'Directions',
52
+ 'DistanceMeasurement2D',
53
+ 'Editor',
54
+ 'ElevationProfile',
55
+ 'Feature',
56
+ 'FeatureForm',
57
+ 'FeatureTable',
58
+ 'FeatureTemplates',
59
+ 'Features',
60
+ 'FloorFilter',
61
+ 'Fullscreen',
62
+ 'Histogram',
63
+ 'HistogramRangeSlider',
64
+ 'Home',
65
+ 'LayerList',
66
+ 'Legend',
67
+ 'LineOfSight',
68
+ 'Locate',
69
+ 'Measurement',
70
+ 'NavigationToggle',
71
+ 'OrientedImageryViewer',
72
+ 'Print',
73
+ 'ScaleBar',
74
+ 'ScaleRangeSlider',
75
+ 'Search',
76
+ 'ShadowCast',
77
+ 'Sketch',
78
+ 'Slice',
79
+ 'Slider',
80
+ 'TableList',
81
+ 'TimeSlider',
82
+ 'TimeZoneLabel',
83
+ 'Track',
84
+ 'UtilityNetworkAssociations',
85
+ 'UtilityNetworkTrace',
86
+ 'UtilityNetworkValidateTopology',
87
+ 'ValuePicker',
88
+ 'Weather',
89
+ 'Zoom',
25
90
  ].map((n) => {
26
91
  return [n, n];
27
92
  });
28
93
 
29
- export { positions, base_layers };
94
+ export const blendModes = [
95
+ 'average',
96
+ 'color-burn',
97
+ 'color-dodge',
98
+ 'color',
99
+ 'darken',
100
+ 'destination-atop',
101
+ 'destination-in',
102
+ 'destination-out',
103
+ 'destination-over',
104
+ 'difference',
105
+ 'exclusion',
106
+ 'hard-light',
107
+ 'hue',
108
+ 'invert',
109
+ 'lighten',
110
+ 'lighter',
111
+ 'luminosity',
112
+ 'minus',
113
+ 'multiply',
114
+ 'normal',
115
+ 'overlay',
116
+ 'plus',
117
+ 'reflect',
118
+ 'saturation',
119
+ 'screen',
120
+ 'soft-light',
121
+ 'source-atop',
122
+ 'source-in',
123
+ 'source-out',
124
+ 'vivid-light',
125
+ 'xor',
126
+ ].map((n) => {
127
+ return [n, capitalize(n.replaceAll('-', ' '))];
128
+ });
129
+
130
+ export const geometryTypes = [
131
+ 'point',
132
+ 'multipoint',
133
+ 'polyline',
134
+ 'polygon',
135
+ 'multipatch',
136
+ 'mesh',
137
+ ].map((n) => {
138
+ return [n, capitalize(n.replaceAll('-', ' '))];
139
+ });
140
+
141
+ export const rendererTypes = [
142
+ 'simple',
143
+ 'unique-value',
144
+ 'heatmap',
145
+ 'class-breaks',
146
+ 'dictionary',
147
+ 'dot-density',
148
+ 'pie-chart',
149
+ ].map((n) => ({ value: n, label: capitalize(n.replaceAll('-', ' ')) }));
150
+
151
+ export const simpleSymbols = [
152
+ 'simple-fill',
153
+ 'simple-marker',
154
+ 'simple-line',
155
+ ].map((n) => {
156
+ return [n, capitalize(n.replaceAll('-', ' '))];
157
+ });
158
+
159
+ export const expandKeys = ['expandTooltip'];
160
+
161
+ export const getDefaultWidgets = (dimension = '2d') => [
162
+ { name: 'Zoom', position: 'top-left' },
163
+ ...(dimension === '3d'
164
+ ? [{ name: 'NavigationToggle', position: 'top-left' }]
165
+ : []),
166
+ {
167
+ name: 'Home',
168
+ position: 'top-left',
169
+ },
170
+ {
171
+ name: 'Compass',
172
+ position: 'top-left',
173
+ },
174
+ {
175
+ name: 'LayerList',
176
+ position: 'top-right',
177
+ expand: true,
178
+ ExpandProperties: {
179
+ expandTooltip: 'Layers',
180
+ },
181
+ },
182
+ {
183
+ name: 'Print',
184
+ position: 'top-right',
185
+ expand: true,
186
+ ExpandProperties: {
187
+ expandTooltip: 'Print',
188
+ },
189
+ },
190
+ {
191
+ name: 'Fullscreen',
192
+ position: 'top-right',
193
+ },
194
+ {
195
+ name: 'Legend',
196
+ position: 'bottom-left',
197
+ expand: true,
198
+ respectLayerVisibility: false,
199
+ ExpandProperties: {
200
+ expandTooltip: 'Legend',
201
+ },
202
+ },
203
+ {
204
+ name: 'ScaleBar',
205
+ position: 'bottom-right',
206
+ unit: 'dual',
207
+ },
208
+ ];
209
+
210
+ export const widgetsSchema = {
211
+ ScaleBar: {
212
+ unit: {
213
+ title: 'Unit',
214
+ choices: [
215
+ ['metric', 'Metric'],
216
+ ['imperial', 'Imperial'],
217
+ ['dual', 'Dual'],
218
+ ['non-metric', 'Non metric'],
219
+ ],
220
+ },
221
+ },
222
+ Legend: {
223
+ respectLayerVisibility: {
224
+ title: 'Respect layer visibility',
225
+ type: 'boolean',
226
+ },
227
+ },
228
+ };
229
+
230
+ export const withSublayers = ['MapImageLayer'];
231
+
232
+ export const layersMapping = {
233
+ 'Raster Layer': 'MapImageLayer',
234
+ };
235
+
236
+ export const geometryTypeMapping = {
237
+ esriGeometryPoint: 'point',
238
+ esriGeometryMultipoint: 'multipoint',
239
+ esriGeometryPolyline: 'polyline',
240
+ esriGeometryPolygon: 'polygon',
241
+ esriGeometryMultipatch: 'multipatch',
242
+ esriGeometryMesh: 'mesh',
243
+ };
244
+
245
+ export const renderersMapping = {
246
+ uniqueValue: 'unique-value',
247
+ };
@@ -0,0 +1,27 @@
1
+ import React, { forwardRef, useEffect, useState } from 'react';
2
+ import loadArcgis from '@eeacms/volto-eea-map/arcgis';
3
+
4
+ export default function withArcgis(WrappedComponent) {
5
+ return forwardRef((props, ref) => {
6
+ const [agLoaded, setAgLoaded] = useState(false);
7
+
8
+ const interceptArcgis = (event) => {
9
+ if (event.type === 'message' && event.data.type === 'arcgis-loaded') {
10
+ setAgLoaded(true);
11
+ }
12
+ };
13
+
14
+ useEffect(() => {
15
+ if (window.$arcgis) {
16
+ setAgLoaded(true);
17
+ }
18
+ loadArcgis();
19
+ window.addEventListener('message', interceptArcgis);
20
+ return () => {
21
+ window.removeEventListener('message', interceptArcgis);
22
+ };
23
+ }, []);
24
+
25
+ return <WrappedComponent {...props} agLoaded={agLoaded} ref={ref} />;
26
+ });
27
+ }
@@ -0,0 +1,24 @@
1
+ import { useEffect, useRef } from 'react';
2
+ import { isFunction, isEqual } from 'lodash';
3
+
4
+ export default function useChangedEffect(callback, props) {
5
+ const prevPropsRef = useRef(props);
6
+
7
+ useEffect(() => {
8
+ const currentChangedProps = Object.keys(props).reduce((acc, key) => {
9
+ if (
10
+ !['children'].includes(key) &&
11
+ !isEqual(props[key], prevPropsRef.current[key])
12
+ ) {
13
+ acc[key] = props[key];
14
+ }
15
+ return acc;
16
+ }, {});
17
+
18
+ if (isFunction(callback)) {
19
+ callback(currentChangedProps);
20
+ }
21
+
22
+ prevPropsRef.current = props;
23
+ }, [callback, props]);
24
+ }
@@ -0,0 +1,17 @@
1
+ import { useEffect, useRef } from 'react';
2
+
3
+ export default function useClass(Class, ...props) {
4
+ const refObject = useRef(null);
5
+
6
+ useEffect(() => {
7
+ return () => {
8
+ refObject.current = null;
9
+ };
10
+ }, []);
11
+
12
+ if (refObject.current === null) {
13
+ refObject.current = new Class(...props);
14
+ }
15
+
16
+ return refObject.current;
17
+ }