@eeacms/volto-eea-map 4.0.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 +36 -1
  2. package/package.json +6 -3
  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 -365
  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 -456
  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
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
+ }
@@ -0,0 +1,25 @@
1
+ import { useState, useEffect, useCallback } from 'react';
2
+
3
+ const useCopyToClipboard = (text) => {
4
+ const [copyStatus, setCopyStatus] = useState('inactive');
5
+ const copy = useCallback(() => {
6
+ navigator.clipboard.writeText(text).then(
7
+ () => setCopyStatus('copied'),
8
+ () => setCopyStatus('failed'),
9
+ );
10
+ }, [text]);
11
+
12
+ useEffect(() => {
13
+ if (copyStatus === 'inactive') {
14
+ return;
15
+ }
16
+
17
+ const timeout = setTimeout(() => setCopyStatus('inactive'), 3000);
18
+
19
+ return () => clearTimeout(timeout);
20
+ }, [copyStatus]);
21
+
22
+ return [copyStatus, copy];
23
+ };
24
+
25
+ export default useCopyToClipboard;
package/src/index.js CHANGED
@@ -1,20 +1,20 @@
1
1
  import { uniqBy } from 'lodash';
2
2
 
3
- import EmbedMapView from './components/Blocks/EmbedEEAMap/View';
4
- import EmbedMapEdit from './components/Blocks/EmbedEEAMap/Edit';
3
+ import EmbedMapView from './Blocks/EmbedEEAMap/View';
4
+ import EmbedMapEdit from './Blocks/EmbedEEAMap/Edit';
5
5
 
6
6
  import world from '@plone/volto/icons/world.svg';
7
7
 
8
- import DataQueryWidget from './components/widgets/DataQueryWidget';
9
- import LayerSelectWidget from './components/widgets/LayerSelectWidget';
8
+ import VisualizationWidget from './Widgets/VisualizationWidget';
10
9
 
11
- import VisualizationEditorWidget from './components/visualization/VisualizationEditorWidget';
12
- import VisualizationViewWidget from './components/visualization/VisualizationViewWidget';
13
- import VisualizationView from './components/visualization/VisualizationView';
10
+ import ArcgisRendererWidget from './Widgets/ArcgisRendererWidget/ArcgisRendererWidget';
11
+ import ArcgisColorPickerWidget from './Widgets/ArcgisColorPickerWidget';
12
+ import ArcgisSliderWidget from './Widgets/ArcgisSliderWidget';
13
+ import ArcgisViewpointWidget from './Widgets/ArcgisViewpointWidget';
14
14
 
15
- import SimpleColorPickerWidget from './components/widgets/SimpleColorPickerWidget';
15
+ import VisualizationViewWidget from './Widgets/VisualizationViewWidget';
16
16
 
17
- import './less/global.less';
17
+ import VisualizationView from './Views/VisualizationView';
18
18
 
19
19
  const applyConfig = (config) => {
20
20
  config.settings.allowed_cors_destinations = [
@@ -64,15 +64,15 @@ const applyConfig = (config) => {
64
64
  'id',
65
65
  );
66
66
 
67
- config.widgets.widget.map_layers_widget = LayerSelectWidget;
68
- config.widgets.widget.data_query_widget = DataQueryWidget;
69
- config.widgets.widget.simple_color_picker_widget = SimpleColorPickerWidget;
67
+ config.views.contentTypesViews.map_visualization = VisualizationView;
68
+
69
+ config.widgets.widget.arcgis_renderer = ArcgisRendererWidget;
70
+ config.widgets.widget.arcgis_color_picker = ArcgisColorPickerWidget;
71
+ config.widgets.widget.arcgis_slider = ArcgisSliderWidget;
72
+ config.widgets.widget.arcgis_viewpoint = ArcgisViewpointWidget;
70
73
 
71
- //map editor for the visualization(content-type)
72
- config.widgets.id.map_visualization_data = VisualizationEditorWidget;
74
+ config.widgets.id.map_visualization_data = VisualizationWidget;
73
75
  config.widgets.views.id.map_visualization_data = VisualizationViewWidget;
74
- //map viewer for the visualization(content-type)
75
- config.views.contentTypesViews.map_visualization = VisualizationView;
76
76
 
77
77
  return config;
78
78
  };
@@ -0,0 +1,72 @@
1
+ import { isString } from 'lodash';
2
+ import { toast } from 'react-toastify';
3
+ import { Toast } from '@plone/volto/components';
4
+
5
+ import loadable from '@loadable/component';
6
+
7
+ const LoadableJsonEditor = loadable.lib(() => import('jsoneditor'));
8
+
9
+ const jsoneditor = __CLIENT__ && LoadableJsonEditor;
10
+
11
+ export async function initEditor({ el, editor, dflt, options, onInit }) {
12
+ if (!jsoneditor) return;
13
+ const module = await jsoneditor.load();
14
+ const { default: JSONEditor } = module;
15
+ // create the editor
16
+ const container = isString(el) ? document.getElementById(el) : el;
17
+
18
+ if (!container) {
19
+ return;
20
+ }
21
+
22
+ container.innerHTML = '';
23
+
24
+ const _options = {
25
+ mode: 'code',
26
+ enableTransform: false,
27
+ schema: {
28
+ type: 'array',
29
+ items: {
30
+ type: 'object',
31
+ },
32
+ },
33
+ ...options,
34
+ };
35
+
36
+ editor.current = new JSONEditor(container, _options);
37
+ // set initial json
38
+ editor.current.set(dflt);
39
+
40
+ if (onInit) onInit();
41
+ }
42
+
43
+ export function destroyEditor(editor) {
44
+ if (editor) {
45
+ editor.destroy();
46
+ editor = null;
47
+ }
48
+ }
49
+
50
+ export async function validateEditor(editor) {
51
+ const err = await editor.current.validate();
52
+
53
+ if (err.length) {
54
+ toast.warn(
55
+ <Toast
56
+ error
57
+ title={'JSON validation'}
58
+ content={'Please make sure all the fields are in the correct format'}
59
+ />,
60
+ );
61
+ return false;
62
+ }
63
+
64
+ return true;
65
+ }
66
+
67
+ export function onPasteEditor(editor) {
68
+ try {
69
+ editor.current.repair();
70
+ editor.current.format();
71
+ } catch {}
72
+ }