@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.
- package/CHANGELOG.md +29 -0
- package/package.json +5 -2
- package/src/Arcgis/Editor/Editor.jsx +130 -0
- package/src/Arcgis/Editor/EditorContext.jsx +2 -0
- package/src/Arcgis/Editor/Fold/Fold.jsx +56 -0
- package/src/Arcgis/Editor/Panels/Panel.jsx +8 -0
- package/src/Arcgis/Editor/Panels/SettingsGeneralPanel.jsx +217 -0
- package/src/Arcgis/Editor/Panels/SettingsLayersPanel.jsx +216 -0
- package/src/Arcgis/Editor/Panels/StructureBaseLayerPanel.jsx +60 -0
- package/src/Arcgis/Editor/Panels/StructureLayersPanel.jsx +394 -0
- package/src/Arcgis/Editor/Panels/StructureWidgetsPanel.jsx +181 -0
- package/src/Arcgis/Editor/Panels/index.js +6 -0
- package/src/Arcgis/Editor/SidebarGroup.jsx +62 -0
- package/src/Arcgis/Layer/Layer.jsx +247 -0
- package/src/Arcgis/Map/Map.jsx +287 -0
- package/src/Arcgis/Map/MapBuilder.jsx +111 -0
- package/src/Arcgis/Map/MapContext.jsx +3 -0
- package/src/Arcgis/Widget/Widget.jsx +170 -0
- package/src/Arcgis/helpers.js +140 -0
- package/src/Blocks/EmbedEEAMap/Edit.jsx +40 -0
- package/src/Blocks/EmbedEEAMap/View.jsx +122 -0
- package/src/Blocks/EmbedEEAMap/helpers.js +12 -0
- package/src/Blocks/EmbedEEAMap/schema.js +126 -0
- package/src/{components → Toolbar}/Share.jsx +1 -1
- package/src/{components/ExtraViews.jsx → Toolbar/Toolbar.jsx} +14 -16
- package/src/{components/visualization → Views}/VisualizationView.jsx +8 -9
- package/src/Widgets/ArcgisColorPickerWidget.jsx +95 -0
- package/src/Widgets/ArcgisRendererWidget/ArcgisRendererWidget.jsx +106 -0
- package/src/Widgets/ArcgisRendererWidget/RendererEditor/ClassBreaks.jsx +8 -0
- package/src/Widgets/ArcgisRendererWidget/RendererEditor/Dictionary.jsx +8 -0
- package/src/Widgets/ArcgisRendererWidget/RendererEditor/DotDensity.jsx +8 -0
- package/src/Widgets/ArcgisRendererWidget/RendererEditor/Heatmap.jsx +8 -0
- package/src/Widgets/ArcgisRendererWidget/RendererEditor/PieChart.jsx +8 -0
- package/src/Widgets/ArcgisRendererWidget/RendererEditor/Simple.jsx +109 -0
- package/src/Widgets/ArcgisRendererWidget/RendererEditor/UniqueValue.jsx +8 -0
- package/src/Widgets/ArcgisRendererWidget/RendererEditor/_Editor.jsx +29 -0
- package/src/Widgets/ArcgisRendererWidget/RendererEditor/_EditorModal.jsx +88 -0
- package/src/Widgets/ArcgisRendererWidget/RendererEditor/_defaults.js +30 -0
- package/src/Widgets/ArcgisSliderWidget.jsx +79 -0
- package/src/Widgets/ArcgisViewpointWidget.jsx +112 -0
- package/src/{components/visualization → Widgets}/VisualizationViewWidget.jsx +9 -10
- package/src/Widgets/VisualizationWidget.jsx +200 -0
- package/src/arcgis.js +48 -0
- package/src/constants.js +225 -7
- package/src/hocs/withArcgis.jsx +27 -0
- package/src/hooks/useChangedProps.jsx +24 -0
- package/src/hooks/useClass.jsx +17 -0
- package/src/hooks/useCopyToClipboard.jsx +25 -0
- package/src/index.js +16 -16
- package/src/jsoneditor.js +72 -0
- package/src/styles/editor.less +446 -0
- package/src/styles/map.less +3 -0
- package/src/components/Blocks/EmbedEEAMap/Edit.jsx +0 -161
- package/src/components/Blocks/EmbedEEAMap/Schema.js +0 -161
- package/src/components/Blocks/EmbedEEAMap/View.jsx +0 -79
- package/src/components/Blocks/EmbedEEAMap/helpers.js +0 -45
- package/src/components/LegendView.jsx +0 -150
- package/src/components/Webmap.jsx +0 -371
- package/src/components/index.js +0 -6
- package/src/components/visualization/VisualizationEditorWidget.jsx +0 -122
- package/src/components/visualization/panelsSchema.js +0 -229
- package/src/components/widgets/DataQueryWidget.jsx +0 -51
- package/src/components/widgets/LayerSelectWidget.jsx +0 -463
- package/src/components/widgets/LayersPanelWidget.jsx +0 -59
- package/src/components/widgets/SimpleColorPickerWidget.jsx +0 -121
- package/src/hocs/index.js +0 -3
- package/src/hocs/withDeviceSize.jsx +0 -45
- package/src/less/global.less +0 -253
- package/src/less/variables.less +0 -5
- package/src/utils.js +0 -151
- /package/src/{components → Toolbar}/FigureNote.jsx +0 -0
- /package/src/{components → Toolbar}/MoreInfoLink.jsx +0 -0
- /package/src/{components → Toolbar}/Sources.jsx +0 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { useContext, useEffect, useMemo, memo } from 'react';
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
3
|
+
|
|
4
|
+
import MapContext from '../Map/MapContext';
|
|
5
|
+
|
|
6
|
+
import useClass from '@eeacms/volto-eea-map/hooks/useClass';
|
|
7
|
+
|
|
8
|
+
const modules = {};
|
|
9
|
+
|
|
10
|
+
const TIMEOUT = 2000;
|
|
11
|
+
|
|
12
|
+
class $Widget extends EventEmitter {
|
|
13
|
+
#isReady = false;
|
|
14
|
+
#props = {};
|
|
15
|
+
#name = '';
|
|
16
|
+
#order = -1;
|
|
17
|
+
#initiate = false;
|
|
18
|
+
#widget = null;
|
|
19
|
+
#expand = null;
|
|
20
|
+
#modulesLoaded = false;
|
|
21
|
+
#clock = null;
|
|
22
|
+
|
|
23
|
+
constructor(props) {
|
|
24
|
+
super();
|
|
25
|
+
|
|
26
|
+
this.#props = props;
|
|
27
|
+
this.#name = props.name;
|
|
28
|
+
this.#order = props.order || 1;
|
|
29
|
+
|
|
30
|
+
if (this.order <= 1) {
|
|
31
|
+
this.#initiate = true;
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
this.#props.$map.on('widget-added', (widget) => {
|
|
36
|
+
if (this.#isReady) return;
|
|
37
|
+
if (this.#order - widget.order === 1) {
|
|
38
|
+
this.#initiate = true;
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
get isReady() {
|
|
44
|
+
return this.#isReady && !!this.#widget;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
get widget() {
|
|
48
|
+
return this.#widget;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
get order() {
|
|
52
|
+
return this.#order;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async loadModules() {
|
|
56
|
+
const $arcgis = __CLIENT__ ? window.$arcgis : null;
|
|
57
|
+
if (__SERVER__ || !$arcgis || !this.#name) return Promise.reject();
|
|
58
|
+
if (!this.#modulesLoaded) {
|
|
59
|
+
const AgWidget = modules[`Ag${this.#name}`];
|
|
60
|
+
modules[`Ag${this.#name}`] =
|
|
61
|
+
AgWidget || (await $arcgis.import(`esri/widgets/${this.#name}`));
|
|
62
|
+
modules.AgExpand = await $arcgis.import('esri/widgets/Expand');
|
|
63
|
+
this.#modulesLoaded = true;
|
|
64
|
+
}
|
|
65
|
+
return Promise.resolve();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
init() {
|
|
69
|
+
const {
|
|
70
|
+
$map,
|
|
71
|
+
expand,
|
|
72
|
+
position = 'top-left',
|
|
73
|
+
ExpandProperties = {},
|
|
74
|
+
} = this.#props;
|
|
75
|
+
const AgWidget = modules[`Ag${this.#name}`];
|
|
76
|
+
const AgExpand = modules.AgExpand;
|
|
77
|
+
if (!this.#modulesLoaded || !$map.isReady) return;
|
|
78
|
+
if (!AgWidget || !AgExpand) {
|
|
79
|
+
throw new Error('$Widget modules not loaded');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
this.#widget = new AgWidget({
|
|
83
|
+
view: $map.view,
|
|
84
|
+
...(!this.#expand ? { id: this.#name } : {}),
|
|
85
|
+
...(this.#props || {}),
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
if (expand) {
|
|
89
|
+
this.#expand = new AgExpand({
|
|
90
|
+
view: $map.view,
|
|
91
|
+
content: this.#widget,
|
|
92
|
+
id: this.#name,
|
|
93
|
+
mode: 'floating',
|
|
94
|
+
...ExpandProperties,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const content = this.#expand || this.#widget;
|
|
99
|
+
|
|
100
|
+
$map.view.ui.add(content, position);
|
|
101
|
+
|
|
102
|
+
this.#isReady = true;
|
|
103
|
+
this.#initiate = false;
|
|
104
|
+
|
|
105
|
+
this.emit('connected');
|
|
106
|
+
$map.emit('widget-added', this);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
connect() {
|
|
110
|
+
clearInterval(this.#clock);
|
|
111
|
+
this.loadModules()
|
|
112
|
+
.then(() => {
|
|
113
|
+
if (this.#order <= 1) {
|
|
114
|
+
this.init();
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
let time = 0;
|
|
118
|
+
this.#clock = setInterval(() => {
|
|
119
|
+
if (time >= TIMEOUT || this.#isReady) {
|
|
120
|
+
clearInterval(this.#clock);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
time += 50;
|
|
124
|
+
if (!this.#initiate) return;
|
|
125
|
+
clearInterval(this.#clock);
|
|
126
|
+
this.init();
|
|
127
|
+
}, 50);
|
|
128
|
+
})
|
|
129
|
+
.catch(() => {});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
disconnect() {
|
|
133
|
+
if (!this.#isReady) return;
|
|
134
|
+
if (this.#widget) {
|
|
135
|
+
this.#widget.destroy();
|
|
136
|
+
}
|
|
137
|
+
if (this.#expand) {
|
|
138
|
+
this.#expand.destroy();
|
|
139
|
+
}
|
|
140
|
+
this.#widget = null;
|
|
141
|
+
this.#expand = null;
|
|
142
|
+
this.#isReady = false;
|
|
143
|
+
clearInterval(this.#clock);
|
|
144
|
+
this.emit('disconnected');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Widget.html
|
|
149
|
+
function Widget(props) {
|
|
150
|
+
const { $map } = useContext(MapContext);
|
|
151
|
+
const context = useMemo(() => ({ ...props, $map }), [props, $map]);
|
|
152
|
+
|
|
153
|
+
const $widget = useClass($Widget, context);
|
|
154
|
+
|
|
155
|
+
useEffect(() => {
|
|
156
|
+
if (!$widget) return;
|
|
157
|
+
|
|
158
|
+
if ($map.isReady) {
|
|
159
|
+
$widget.connect();
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return () => {
|
|
163
|
+
$widget.disconnect();
|
|
164
|
+
};
|
|
165
|
+
}, [$map, $widget]);
|
|
166
|
+
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export default memo(Widget);
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { isArray } from 'lodash';
|
|
2
|
+
import { formatQuery as $formatQuery } from 'react-querybuilder';
|
|
3
|
+
import { getDefaultWidgets } from '@eeacms/volto-eea-map/constants';
|
|
4
|
+
|
|
5
|
+
const timer = {};
|
|
6
|
+
|
|
7
|
+
export function formatQuery(...args) {
|
|
8
|
+
let query = args[0];
|
|
9
|
+
const data_query = args[1];
|
|
10
|
+
if (query?.rules) {
|
|
11
|
+
query = {
|
|
12
|
+
...query,
|
|
13
|
+
rules: query.rules
|
|
14
|
+
.map((rule) => {
|
|
15
|
+
if (!data_query) return rule;
|
|
16
|
+
data_query.forEach((query) => {
|
|
17
|
+
if (rule.dataQuery.includes(query.i)) {
|
|
18
|
+
rule.value = query.v;
|
|
19
|
+
if (
|
|
20
|
+
isArray(rule.value) &&
|
|
21
|
+
rule.value.length > 1 &&
|
|
22
|
+
rule.operator === '='
|
|
23
|
+
) {
|
|
24
|
+
rule.operator = 'in';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
return rule;
|
|
29
|
+
})
|
|
30
|
+
.filter((rule) => rule.value),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
return $formatQuery(query, ...args.slice(2));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function debounce(func, wait = 300, id) {
|
|
37
|
+
if (typeof func !== 'function') return;
|
|
38
|
+
const name = id || func.name || 'generic';
|
|
39
|
+
if (timer[name]) clearTimeout(timer[name]);
|
|
40
|
+
timer[name] = setTimeout(func, wait);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function omitBy(obj, keys = []) {
|
|
44
|
+
return Object.keys(obj).reduce((acc, key) => {
|
|
45
|
+
if (!keys.includes(key)) {
|
|
46
|
+
acc[key] = obj[key];
|
|
47
|
+
}
|
|
48
|
+
return acc;
|
|
49
|
+
}, {});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function getBasemap(data) {
|
|
53
|
+
if (!data) return {};
|
|
54
|
+
return {
|
|
55
|
+
name: data.basemap?.name || data.base?.base_layer,
|
|
56
|
+
url_template: data.basemap?.url_template || data.base?.custom_base_layer,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function getLayers(data = {}, parseQuery = true) {
|
|
61
|
+
if (!data?.layers) return [];
|
|
62
|
+
const { data_query } = data;
|
|
63
|
+
const renderer = getOldRenderer(data.styles);
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
(
|
|
67
|
+
(Array.isArray(data.layers) ? data.layers : data.layers?.map_layers) || []
|
|
68
|
+
)?.map(($layer) => {
|
|
69
|
+
const layer = $layer.map_layer ? $layer.map_layer?.layer : $layer;
|
|
70
|
+
const url = $layer.url ?? $layer.map_layer?.map_service_url;
|
|
71
|
+
const subLayers = getLayers({ layers: $layer.subLayers, data_query });
|
|
72
|
+
|
|
73
|
+
let definitionExpression =
|
|
74
|
+
layer.definitionExpression || data.definitionExpression;
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
definitionExpression =
|
|
78
|
+
parseQuery && definitionExpression
|
|
79
|
+
? formatQuery(definitionExpression, data_query, 'sql')
|
|
80
|
+
: definitionExpression;
|
|
81
|
+
} catch {}
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
...(renderer ? { renderer } : {}),
|
|
85
|
+
...omitBy(layer, ['geometryType', 'blendMode', 'definitionExpression']),
|
|
86
|
+
...(definitionExpression ? { definitionExpression } : {}),
|
|
87
|
+
blendMode: layer.blendMode ?? 'normal',
|
|
88
|
+
url,
|
|
89
|
+
title: layer.name,
|
|
90
|
+
subLayers: subLayers.length > 0 ? subLayers : null,
|
|
91
|
+
};
|
|
92
|
+
}) || []
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function getLayerDefaults(layer = {}) {
|
|
97
|
+
const renderer = layer.drawingInfo?.renderer;
|
|
98
|
+
return {
|
|
99
|
+
minScale: layer.minScale,
|
|
100
|
+
maxScale: layer.maxScale,
|
|
101
|
+
renderer: renderer ? { ...renderer, autocast: false } : undefined,
|
|
102
|
+
blendMode: layer.blendMode || 'normal',
|
|
103
|
+
opacity: 1,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function getWidgets(data = {}) {
|
|
108
|
+
return data.widgets ?? getDefaultWidgets(data.settings?.map?.dimension);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function getOldRenderer(styles) {
|
|
112
|
+
if (!styles) return;
|
|
113
|
+
return {
|
|
114
|
+
type: 'simple',
|
|
115
|
+
autocast: true,
|
|
116
|
+
symbol: {
|
|
117
|
+
type: 'simple-fill',
|
|
118
|
+
color: styles?.symbol_color
|
|
119
|
+
? styles?.symbol_color?.rgb
|
|
120
|
+
: {
|
|
121
|
+
r: 0,
|
|
122
|
+
g: 0,
|
|
123
|
+
b: 0,
|
|
124
|
+
a: 1,
|
|
125
|
+
},
|
|
126
|
+
style: 'solid',
|
|
127
|
+
outline: {
|
|
128
|
+
color: styles?.outline_color
|
|
129
|
+
? styles?.outline_color?.rgb
|
|
130
|
+
: {
|
|
131
|
+
r: 0,
|
|
132
|
+
g: 0,
|
|
133
|
+
b: 0,
|
|
134
|
+
a: 1,
|
|
135
|
+
},
|
|
136
|
+
width: styles?.outline_width ? styles?.outline_width : 1,
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
|
+
import { Message } from 'semantic-ui-react';
|
|
3
|
+
|
|
4
|
+
import { SidebarPortal } from '@plone/volto/components';
|
|
5
|
+
import { flattenToAppURL } from '@plone/volto/helpers';
|
|
6
|
+
import BlockDataForm from '@plone/volto/components/manage/Form/BlockDataForm';
|
|
7
|
+
|
|
8
|
+
import { schema } from './schema';
|
|
9
|
+
import View from './View';
|
|
10
|
+
|
|
11
|
+
const Edit = (props) => {
|
|
12
|
+
const { block, onChangeBlock, selected, data } = props;
|
|
13
|
+
|
|
14
|
+
const url = useMemo(() => flattenToAppURL(data.vis_url), [data.vis_url]);
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<>
|
|
18
|
+
{!url && (
|
|
19
|
+
<Message>Please select a "Map (simple)" from block editor.</Message>
|
|
20
|
+
)}
|
|
21
|
+
<View {...props} mode="edit" />
|
|
22
|
+
<SidebarPortal selected={selected}>
|
|
23
|
+
<BlockDataForm
|
|
24
|
+
block={block}
|
|
25
|
+
title={schema.title}
|
|
26
|
+
schema={schema}
|
|
27
|
+
onChangeField={(id, value) => {
|
|
28
|
+
onChangeBlock(block, {
|
|
29
|
+
...data,
|
|
30
|
+
[id]: value,
|
|
31
|
+
});
|
|
32
|
+
}}
|
|
33
|
+
formData={data}
|
|
34
|
+
/>
|
|
35
|
+
</SidebarPortal>
|
|
36
|
+
</>
|
|
37
|
+
);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export default Edit;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import React, { useMemo, useEffect } from 'react';
|
|
2
|
+
import { v4 as uuid } from 'uuid';
|
|
3
|
+
import { connect } from 'react-redux';
|
|
4
|
+
import { compose } from 'redux';
|
|
5
|
+
import { flattenToAppURL } from '@plone/volto/helpers';
|
|
6
|
+
import { getContent } from '@plone/volto/actions';
|
|
7
|
+
import { PrivacyProtection } from '@eeacms/volto-embed';
|
|
8
|
+
import { getLayers } from '@eeacms/volto-eea-map/Arcgis/helpers';
|
|
9
|
+
import MapBuilder from '@eeacms/volto-eea-map/Arcgis/Map/MapBuilder';
|
|
10
|
+
import Toolbar from '@eeacms/volto-eea-map/Toolbar/Toolbar';
|
|
11
|
+
|
|
12
|
+
import { getMapData } from './helpers';
|
|
13
|
+
|
|
14
|
+
const View = (props) => {
|
|
15
|
+
const { id, mode, data, getContent, content } = props;
|
|
16
|
+
const {
|
|
17
|
+
vis_url,
|
|
18
|
+
data_query_params,
|
|
19
|
+
enable_queries,
|
|
20
|
+
show_note = true,
|
|
21
|
+
show_more_info = true,
|
|
22
|
+
show_share = true,
|
|
23
|
+
dataprotection = { enabled: true },
|
|
24
|
+
height = '',
|
|
25
|
+
} = data;
|
|
26
|
+
|
|
27
|
+
const url = useMemo(() => flattenToAppURL(vis_url), [vis_url]);
|
|
28
|
+
|
|
29
|
+
const mapData = useMemo(() => getMapData({ content, data }), [content, data]);
|
|
30
|
+
|
|
31
|
+
const mapServiceURL = useMemo(() => {
|
|
32
|
+
const url = getLayers(mapData)?.[0]?.url;
|
|
33
|
+
|
|
34
|
+
if (url) {
|
|
35
|
+
return `${url}?f=jsapi`;
|
|
36
|
+
}
|
|
37
|
+
return '';
|
|
38
|
+
}, [mapData]);
|
|
39
|
+
|
|
40
|
+
const definitionExpression = useMemo(
|
|
41
|
+
() =>
|
|
42
|
+
enable_queries
|
|
43
|
+
? {
|
|
44
|
+
id: uuid(),
|
|
45
|
+
combinator: 'and',
|
|
46
|
+
not: false,
|
|
47
|
+
rules: data_query_params
|
|
48
|
+
.map((query) => {
|
|
49
|
+
if (!query.alias || !query.i) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
id: uuid(),
|
|
54
|
+
dataQuery: [query.i],
|
|
55
|
+
field: query.alias,
|
|
56
|
+
operator: '=',
|
|
57
|
+
value: '',
|
|
58
|
+
valueSource: 'value',
|
|
59
|
+
};
|
|
60
|
+
})
|
|
61
|
+
.filter((query) => {
|
|
62
|
+
return query?.field;
|
|
63
|
+
}),
|
|
64
|
+
}
|
|
65
|
+
: null,
|
|
66
|
+
[data_query_params, enable_queries],
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
if (mode !== 'edit') return;
|
|
71
|
+
const mapPath = flattenToAppURL(mapData['@id'] || '');
|
|
72
|
+
if (!mapData?.error && url && url !== mapPath) {
|
|
73
|
+
getContent(url, null, id);
|
|
74
|
+
}
|
|
75
|
+
}, [id, mode, url, mapData, getContent]);
|
|
76
|
+
|
|
77
|
+
if (!mapData || !url) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (mapData?.error) {
|
|
82
|
+
return <p dangerouslySetInnerHTML={{ __html: mapData.error }} />;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<PrivacyProtection
|
|
87
|
+
{...props}
|
|
88
|
+
data={mapServiceURL ? { ...data, url: mapServiceURL } : data}
|
|
89
|
+
>
|
|
90
|
+
<div className="embed-map-visualization">
|
|
91
|
+
<MapBuilder
|
|
92
|
+
data={mapData}
|
|
93
|
+
properties={{ ...(props.properties || {}), definitionExpression }}
|
|
94
|
+
height={height}
|
|
95
|
+
/>
|
|
96
|
+
<Toolbar
|
|
97
|
+
style={{ marginTop: '1rem' }}
|
|
98
|
+
data={{
|
|
99
|
+
...data,
|
|
100
|
+
show_note,
|
|
101
|
+
show_sources: true,
|
|
102
|
+
show_more_info,
|
|
103
|
+
show_share,
|
|
104
|
+
dataprotection,
|
|
105
|
+
mapData,
|
|
106
|
+
}}
|
|
107
|
+
/>
|
|
108
|
+
</div>
|
|
109
|
+
</PrivacyProtection>
|
|
110
|
+
);
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export default compose(
|
|
114
|
+
connect(
|
|
115
|
+
(state, props) => {
|
|
116
|
+
return {
|
|
117
|
+
content: state.content.subrequests?.[props.id]?.data,
|
|
118
|
+
};
|
|
119
|
+
},
|
|
120
|
+
{ getContent },
|
|
121
|
+
),
|
|
122
|
+
)(View);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { pickMetadata } from '@eeacms/volto-embed/helpers';
|
|
2
|
+
|
|
3
|
+
function getMapData({ content = {}, data }) {
|
|
4
|
+
const map_visualization_data =
|
|
5
|
+
content?.map_visualization_data || data?.map_visualization_data || {};
|
|
6
|
+
return {
|
|
7
|
+
...pickMetadata(content),
|
|
8
|
+
...map_visualization_data,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export { getMapData };
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
const protectionSchema = {
|
|
2
|
+
title: 'Data Protection',
|
|
3
|
+
|
|
4
|
+
fieldsets: [
|
|
5
|
+
{
|
|
6
|
+
id: 'default',
|
|
7
|
+
title: 'Default',
|
|
8
|
+
fields: [
|
|
9
|
+
'privacy_statement',
|
|
10
|
+
'privacy_cookie_key',
|
|
11
|
+
'enabled',
|
|
12
|
+
'background_image',
|
|
13
|
+
],
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
|
|
17
|
+
properties: {
|
|
18
|
+
privacy_statement: {
|
|
19
|
+
title: 'Privacy statement',
|
|
20
|
+
description: 'Defined in template. Change only if necessary',
|
|
21
|
+
widget: 'slate_richtext',
|
|
22
|
+
className: 'slate-Widget',
|
|
23
|
+
defaultValue: [
|
|
24
|
+
{
|
|
25
|
+
children: [
|
|
26
|
+
{
|
|
27
|
+
text: 'This map is hosted by a third party, Environmental Systems Research Institute. By showing the external content you accept the terms and conditions of ',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
type: 'a',
|
|
31
|
+
url: 'https://www.esri.com',
|
|
32
|
+
children: [
|
|
33
|
+
{
|
|
34
|
+
text: 'esri.com',
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
text: '. This includes their cookie policies, which we have no control over.',
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
privacy_cookie_key: {
|
|
46
|
+
title: 'Privacy cookie key',
|
|
47
|
+
description: 'Use default for Esri maps, otherwise change',
|
|
48
|
+
defaultValue: 'esri-maps',
|
|
49
|
+
},
|
|
50
|
+
enabled: {
|
|
51
|
+
title: 'Data protection disclaimer enabled',
|
|
52
|
+
description: 'Enable/disable the privacy protection',
|
|
53
|
+
type: 'boolean',
|
|
54
|
+
},
|
|
55
|
+
background_image: {
|
|
56
|
+
title: 'Static map preview image',
|
|
57
|
+
widget: 'file',
|
|
58
|
+
required: true,
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
required: ['background_image'],
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export const schema = {
|
|
66
|
+
title: 'Embed Map layers (ArcGis)',
|
|
67
|
+
fieldsets: [
|
|
68
|
+
{
|
|
69
|
+
id: 'default',
|
|
70
|
+
title: 'Default',
|
|
71
|
+
fields: ['vis_url', 'description', 'height'],
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: 'toolbar',
|
|
75
|
+
title: 'Toolbar',
|
|
76
|
+
fields: ['show_note', 'show_more_info', 'show_share'],
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
fields: ['dataprotection'],
|
|
80
|
+
title: 'Data Protection',
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
properties: {
|
|
84
|
+
vis_url: {
|
|
85
|
+
widget: 'internal_url',
|
|
86
|
+
title: 'Visualization',
|
|
87
|
+
},
|
|
88
|
+
height: {
|
|
89
|
+
title: 'Height',
|
|
90
|
+
description:
|
|
91
|
+
'Map block height in px. Default is 500px. Change only if necessary',
|
|
92
|
+
type: 'number',
|
|
93
|
+
},
|
|
94
|
+
description: {
|
|
95
|
+
title: 'Description',
|
|
96
|
+
widget: 'slate',
|
|
97
|
+
},
|
|
98
|
+
show_note: {
|
|
99
|
+
title: 'Show note',
|
|
100
|
+
type: 'boolean',
|
|
101
|
+
defaultValue: true,
|
|
102
|
+
},
|
|
103
|
+
show_sources: {
|
|
104
|
+
title: 'Show sources',
|
|
105
|
+
description: 'Will show sources set in this page Data provenance',
|
|
106
|
+
type: 'boolean',
|
|
107
|
+
defaultValue: true,
|
|
108
|
+
},
|
|
109
|
+
show_more_info: {
|
|
110
|
+
title: 'Show more info',
|
|
111
|
+
type: 'boolean',
|
|
112
|
+
defaultValue: true,
|
|
113
|
+
},
|
|
114
|
+
show_share: {
|
|
115
|
+
title: 'Show share button',
|
|
116
|
+
type: 'boolean',
|
|
117
|
+
defaultValue: true,
|
|
118
|
+
},
|
|
119
|
+
dataprotection: {
|
|
120
|
+
widget: 'object',
|
|
121
|
+
schema: protectionSchema,
|
|
122
|
+
default: { enabled: true },
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
required: [],
|
|
126
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Popup, Input, Button } from 'semantic-ui-react';
|
|
3
|
-
import
|
|
3
|
+
import useCopyToClipboard from '@eeacms/volto-eea-map/hooks/useCopyToClipboard';
|
|
4
4
|
import cx from 'classnames';
|
|
5
5
|
|
|
6
6
|
const Share = ({ contentTypeLink = '' }) => {
|
|
@@ -8,29 +8,26 @@ import {
|
|
|
8
8
|
MoreInfo,
|
|
9
9
|
Share,
|
|
10
10
|
} from '@eeacms/volto-embed/Toolbar';
|
|
11
|
-
import LegendView from '@eeacms/volto-eea-map/components/LegendView';
|
|
12
11
|
|
|
13
12
|
import '@eeacms/volto-embed/Toolbar/styles.less';
|
|
14
13
|
|
|
15
|
-
const
|
|
16
|
-
const
|
|
14
|
+
const Toolbar = ({ data, screen, style }) => {
|
|
15
|
+
const el = useRef();
|
|
17
16
|
const [mobile, setMobile] = useState(false);
|
|
18
17
|
const {
|
|
19
|
-
|
|
18
|
+
mapData = {},
|
|
20
19
|
description,
|
|
21
|
-
show_legend,
|
|
22
|
-
show_viewer,
|
|
23
20
|
show_note = true,
|
|
24
21
|
show_sources = true,
|
|
25
22
|
show_more_info = true,
|
|
26
23
|
show_share = true,
|
|
27
24
|
} = data;
|
|
28
25
|
|
|
29
|
-
const { data_provenance = {}, figure_note = [] } =
|
|
26
|
+
const { data_provenance = {}, figure_note = [] } = mapData;
|
|
30
27
|
|
|
31
28
|
useEffect(() => {
|
|
32
|
-
if (
|
|
33
|
-
const toolbarParentWidth =
|
|
29
|
+
if (el.current) {
|
|
30
|
+
const toolbarParentWidth = el.current.parentElement.offsetWidth;
|
|
34
31
|
|
|
35
32
|
if (toolbarParentWidth < 600 && !mobile) {
|
|
36
33
|
setMobile(true);
|
|
@@ -42,17 +39,18 @@ const ExtraViews = ({ data, screen }) => {
|
|
|
42
39
|
|
|
43
40
|
return (
|
|
44
41
|
<>
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
42
|
+
<div
|
|
43
|
+
className={cx('visualization-toolbar', { mobile })}
|
|
44
|
+
style={style}
|
|
45
|
+
ref={el}
|
|
46
|
+
>
|
|
49
47
|
<div className="left-col">
|
|
50
48
|
{show_note && <FigureNote notes={figure_note || []} />}
|
|
51
49
|
{show_sources && <Sources sources={data_provenance?.data} />}
|
|
52
|
-
{show_more_info && <MoreInfo href={
|
|
50
|
+
{show_more_info && <MoreInfo href={mapData['@id']} />}
|
|
53
51
|
</div>
|
|
54
52
|
<div className="right-col">
|
|
55
|
-
{show_share && <Share href={
|
|
53
|
+
{show_share && <Share href={mapData['@id']} />}
|
|
56
54
|
</div>
|
|
57
55
|
</div>
|
|
58
56
|
{description && serializeNodes(description)}
|
|
@@ -62,4 +60,4 @@ const ExtraViews = ({ data, screen }) => {
|
|
|
62
60
|
|
|
63
61
|
export default connect((state) => ({
|
|
64
62
|
screen: state.screen,
|
|
65
|
-
}))(
|
|
63
|
+
}))(Toolbar);
|