@eeacms/volto-eea-map 0.1.7 → 0.1.10
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 +37 -0
- package/package.json +2 -1
- package/src/actions.js +12 -0
- package/src/components/Blocks/EEAMap/Edit.jsx +2 -3
- package/src/components/Blocks/EEAMap/Schema.js +7 -7
- package/src/components/Blocks/EEAMap/View.jsx +27 -6
- package/src/components/Blocks/EEAMap/components/Webmap.jsx +20 -13
- package/src/components/Blocks/EEAMap/components/widgets/ExtraViews.jsx +59 -36
- package/src/components/Blocks/EEAMap/components/widgets/LayerSelectWidget.jsx +124 -62
- package/src/components/Blocks/EEAMap/components/widgets/MapEditorWidget.jsx +23 -20
- package/src/components/Blocks/EEAMap/components/widgets/ObjectTypesWidget.jsx +11 -3
- package/src/components/Blocks/EEAMap/components/widgets/VisualizationView.jsx +2 -2
- package/src/components/Blocks/EEAMap/components/widgets/panelsSchema.js +3 -11
- package/src/components/Blocks/EEAMap/styles/map.css +106 -0
- package/src/components/Blocks/EmbedEEAMap/Edit.jsx +34 -0
- package/src/components/Blocks/EmbedEEAMap/Schema.js +51 -0
- package/src/components/Blocks/EmbedEEAMap/View.jsx +57 -0
- package/src/components/Blocks/EmbedEEAMap/styles/map.css +22 -0
- package/src/components/index.js +4 -1
- package/src/constants.js +1 -0
- package/src/hocs/index.js +3 -0
- package/src/hocs/withDeviceSize.jsx +45 -0
- package/src/index.js +48 -2
- package/src/middlewares/index.js +14 -0
- package/src/middlewares/map_visualizations.js +1 -0
- package/src/reducers/index.js +3 -0
- package/src/reducers/map_visualizations.js +48 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,8 +4,45 @@ All notable changes to this project will be documented in this file. Dates are d
|
|
|
4
4
|
|
|
5
5
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
6
6
|
|
|
7
|
+
#### [0.1.10](https://github.com/eea/volto-eea-map/compare/0.1.9...0.1.10)
|
|
8
|
+
|
|
9
|
+
- EEA core metadata adaptation for map block to [`5fb5724`](https://github.com/eea/volto-eea-map/commit/5fb5724164e1e9b1ae5143f9bd565c28118be253)
|
|
10
|
+
- EEA core metadata adaptation [`03b62a3`](https://github.com/eea/volto-eea-map/commit/03b62a35165670743d649282ae697dbf71c56a56)
|
|
11
|
+
|
|
12
|
+
#### [0.1.9](https://github.com/eea/volto-eea-map/compare/0.1.8...0.1.9)
|
|
13
|
+
|
|
14
|
+
> 12 August 2022
|
|
15
|
+
|
|
16
|
+
- Query builder for map layers queries [`#9`](https://github.com/eea/volto-eea-map/pull/9)
|
|
17
|
+
- pinpoint query builder [`6184b0e`](https://github.com/eea/volto-eea-map/commit/6184b0e1dcee48e7d34bf56bc1c878438d07f987)
|
|
18
|
+
- build query widget [`7a9d74a`](https://github.com/eea/volto-eea-map/commit/7a9d74a6fdac32a8b424c5ca97edd42df436cbe2)
|
|
19
|
+
|
|
20
|
+
#### [0.1.8](https://github.com/eea/volto-eea-map/compare/0.1.7...0.1.8)
|
|
21
|
+
|
|
22
|
+
> 11 August 2022
|
|
23
|
+
|
|
24
|
+
- Integration & new block for Map Visualization content-type [`#8`](https://github.com/eea/volto-eea-map/pull/8)
|
|
25
|
+
- remove title on map edit widget [`1d00707`](https://github.com/eea/volto-eea-map/commit/1d0070716a743ea7f26c5f877b723492319fcecd)
|
|
26
|
+
- update query by stored value [`c0f6ddd`](https://github.com/eea/volto-eea-map/commit/c0f6dddadaaf28de5b9914214acf735a166fae88)
|
|
27
|
+
- stylelint [`511845a`](https://github.com/eea/volto-eea-map/commit/511845a319137dfe4e1c0c9846ee5ccb7656b32b)
|
|
28
|
+
- visual candy [`2b24975`](https://github.com/eea/volto-eea-map/commit/2b249758f30133d8080793e892d0771e9b63dea5)
|
|
29
|
+
- responsive hoc only keep device size [`444f8b3`](https://github.com/eea/volto-eea-map/commit/444f8b3df2dd58a1f1e5bd6c6a90c1e9919696a1)
|
|
30
|
+
- responsive improvements on edit widget [`1dcdda0`](https://github.com/eea/volto-eea-map/commit/1dcdda077f5aaa8ddd256d2bec2f1018a15e066d)
|
|
31
|
+
- map is sticky [`64f3874`](https://github.com/eea/volto-eea-map/commit/64f3874648f0ede23502998e9165e86538e44728)
|
|
32
|
+
- simplified layer edit [`b64348c`](https://github.com/eea/volto-eea-map/commit/b64348c962647cdfc48d3328c5effb3b02b6217c)
|
|
33
|
+
- no consoles [`1387128`](https://github.com/eea/volto-eea-map/commit/1387128037abb314798326fa3c47b52a13d0415f)
|
|
34
|
+
- show if zoom/print position [`c4d7107`](https://github.com/eea/volto-eea-map/commit/c4d7107e874616c2246ec883d07eb59fad76b21e)
|
|
35
|
+
- lint fix [`cc497bd`](https://github.com/eea/volto-eea-map/commit/cc497bd8fe61d8867b74a8a16bc4868ccf088d55)
|
|
36
|
+
- fixes on webmap [`1c4506b`](https://github.com/eea/volto-eea-map/commit/1c4506b227d3a0ad0f919e3ff826700304b0620a)
|
|
37
|
+
- new embed eea map block to work with visualizations [`be4f2b0`](https://github.com/eea/volto-eea-map/commit/be4f2b00f92ea9dedc359e8c2620a9a31f4b5b6b)
|
|
38
|
+
- remove vis_url logic, will be moved in a new block [`13ebe94`](https://github.com/eea/volto-eea-map/commit/13ebe94c6c339fc827c019aab0a698aa431c5b78)
|
|
39
|
+
- Updates for map visualization [`895d463`](https://github.com/eea/volto-eea-map/commit/895d46313e9b65c6a5f420284fb9459296ed83f4)
|
|
40
|
+
|
|
7
41
|
#### [0.1.7](https://github.com/eea/volto-eea-map/compare/0.1.6...0.1.7)
|
|
8
42
|
|
|
43
|
+
> 9 August 2022
|
|
44
|
+
|
|
45
|
+
- Develop [`#7`](https://github.com/eea/volto-eea-map/pull/7)
|
|
9
46
|
- fix height coming through in view [`39d4d28`](https://github.com/eea/volto-eea-map/commit/39d4d287a4fe86890f5fad8d9050130b496dfe70)
|
|
10
47
|
- Connected visualization view-edit [`52a8e21`](https://github.com/eea/volto-eea-map/commit/52a8e2187cb2e3a7db660ae4b6b5610c88be5083)
|
|
11
48
|
- map_view is map_editor_widget, add view component for content-type [`dc227f9`](https://github.com/eea/volto-eea-map/commit/dc227f9bbb259b59739a3694dc69f0fcca661137)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eeacms/volto-eea-map",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"description": "@eeacms/volto-eea-map: Volto add-on",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"author": "European Environment Agency: IDM2 A-Team",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"@eeacms/volto-embed": "^2.0.1",
|
|
25
25
|
"@plone/scripts": "*",
|
|
26
26
|
"esri-loader": "3.5.0",
|
|
27
|
+
"react-querybuilder": "4.2.3",
|
|
27
28
|
"volto-slate": "*"
|
|
28
29
|
},
|
|
29
30
|
"devDependencies": {
|
package/src/actions.js
ADDED
|
@@ -7,13 +7,12 @@ import { addPrivacyProtectionToSchema } from '@eeacms/volto-embed';
|
|
|
7
7
|
import './styles/map.css';
|
|
8
8
|
|
|
9
9
|
const Edit = (props) => {
|
|
10
|
-
const { block, data, onChangeBlock, selected } = props;
|
|
10
|
+
const { block, data, onChangeBlock, selected, id } = props;
|
|
11
11
|
const schema = React.useMemo(() => Schema(props), [props]);
|
|
12
12
|
|
|
13
|
-
if (__SERVER__) return '';
|
|
14
13
|
return (
|
|
15
14
|
<div>
|
|
16
|
-
<View data={data} />
|
|
15
|
+
<View data={data} id={id} />
|
|
17
16
|
<SidebarPortal selected={selected}>
|
|
18
17
|
<BlockDataForm
|
|
19
18
|
block={block}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const Schema = () => {
|
|
1
|
+
export const Schema = (props) => {
|
|
2
2
|
return {
|
|
3
3
|
title: 'EEA Map Block',
|
|
4
4
|
fieldsets: [
|
|
@@ -6,17 +6,21 @@ export const Schema = () => {
|
|
|
6
6
|
id: 'default',
|
|
7
7
|
title: 'Default',
|
|
8
8
|
fields: [
|
|
9
|
+
'map_data',
|
|
9
10
|
'description',
|
|
10
11
|
'height',
|
|
11
|
-
'map_data',
|
|
12
|
-
'show_sources',
|
|
13
12
|
'show_legend',
|
|
14
13
|
'show_download',
|
|
15
14
|
'show_viewer',
|
|
15
|
+
'show_sources',
|
|
16
16
|
],
|
|
17
17
|
},
|
|
18
18
|
],
|
|
19
19
|
properties: {
|
|
20
|
+
show_sources: {
|
|
21
|
+
title: 'Show sources',
|
|
22
|
+
type: 'boolean',
|
|
23
|
+
},
|
|
20
24
|
height: {
|
|
21
25
|
title: 'Height',
|
|
22
26
|
type: 'number',
|
|
@@ -30,10 +34,6 @@ export const Schema = () => {
|
|
|
30
34
|
description: 'Open the map customization interface',
|
|
31
35
|
widget: 'map_edit_widget',
|
|
32
36
|
},
|
|
33
|
-
show_sources: {
|
|
34
|
-
title: 'Show sources',
|
|
35
|
-
type: 'boolean',
|
|
36
|
-
},
|
|
37
37
|
show_legend: {
|
|
38
38
|
title: 'Show legend',
|
|
39
39
|
type: 'boolean',
|
|
@@ -1,22 +1,43 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { connect } from 'react-redux';
|
|
4
|
+
import { compose } from 'redux';
|
|
5
|
+
|
|
2
6
|
import Webmap from './components/Webmap';
|
|
3
7
|
import ExtraViews from './components/widgets/ExtraViews';
|
|
4
8
|
import { PrivacyProtection } from '@eeacms/volto-embed';
|
|
9
|
+
import { getContent } from '@plone/volto/actions';
|
|
5
10
|
|
|
6
11
|
const View = (props) => {
|
|
7
|
-
const { data } = props || {};
|
|
8
|
-
|
|
12
|
+
const { data, id, path, data_provenance } = props || {};
|
|
9
13
|
const { map_data = {}, height = '' } = data;
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
React.useEffect(() => {
|
|
16
|
+
// get content from document
|
|
17
|
+
if (path) {
|
|
18
|
+
props.getContent(path, null, id);
|
|
19
|
+
}
|
|
20
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
21
|
+
}, [path]);
|
|
22
|
+
|
|
12
23
|
return (
|
|
13
24
|
<div>
|
|
14
25
|
<PrivacyProtection data={data} {...props}>
|
|
15
|
-
<Webmap data={map_data} height={height} />
|
|
16
|
-
<ExtraViews data={data} />
|
|
26
|
+
<Webmap data={map_data} height={height} id={id} />
|
|
27
|
+
<ExtraViews data={{ ...data, data_provenance }} />
|
|
17
28
|
</PrivacyProtection>
|
|
18
29
|
</div>
|
|
19
30
|
);
|
|
20
31
|
};
|
|
21
32
|
|
|
22
|
-
export default
|
|
33
|
+
export default compose(
|
|
34
|
+
connect(
|
|
35
|
+
(state, props) => ({
|
|
36
|
+
data_provenance:
|
|
37
|
+
state.content.subrequests?.[props.id]?.data?.data_provenance,
|
|
38
|
+
}),
|
|
39
|
+
{
|
|
40
|
+
getContent,
|
|
41
|
+
},
|
|
42
|
+
),
|
|
43
|
+
)(View);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/* eslint-disable */
|
|
2
2
|
import React from 'react';
|
|
3
|
+
import { withDeviceSize } from '@eeacms/volto-eea-map/hocs';
|
|
3
4
|
import { loadModules } from 'esri-loader';
|
|
5
|
+
import { formatQuery } from 'react-querybuilder';
|
|
4
6
|
|
|
5
7
|
const MODULES = [
|
|
6
8
|
'esri/Map',
|
|
@@ -15,9 +17,10 @@ const MODULES = [
|
|
|
15
17
|
];
|
|
16
18
|
|
|
17
19
|
const Webmap = (props) => {
|
|
18
|
-
const { editMode, height } = props;
|
|
20
|
+
const { editMode, height, id } = props;
|
|
19
21
|
|
|
20
22
|
const data = React.useMemo(() => props.data || {}, [props.data]);
|
|
23
|
+
const device = React.useMemo(() => props.device || {}, [props.device]);
|
|
21
24
|
|
|
22
25
|
const { base = {}, layers = {}, legend = {}, general = {} } = data;
|
|
23
26
|
|
|
@@ -89,7 +92,6 @@ const Webmap = (props) => {
|
|
|
89
92
|
.filter(({ map_service_url, layer }) => map_service_url && layer)
|
|
90
93
|
.map(({ map_service_url, layer, query = '' }) => {
|
|
91
94
|
const url = `${map_service_url}/${layer}`;
|
|
92
|
-
|
|
93
95
|
let mapLayer;
|
|
94
96
|
switch (layer.type) {
|
|
95
97
|
case 'Raster Layer':
|
|
@@ -100,7 +102,7 @@ const Webmap = (props) => {
|
|
|
100
102
|
case 'Feature Layer':
|
|
101
103
|
mapLayer = new FeatureLayer({
|
|
102
104
|
url,
|
|
103
|
-
definitionExpression: query,
|
|
105
|
+
definitionExpression: query ? formatQuery(query, 'sql') : '',
|
|
104
106
|
});
|
|
105
107
|
break;
|
|
106
108
|
case 'Group Layer':
|
|
@@ -139,9 +141,10 @@ const Webmap = (props) => {
|
|
|
139
141
|
});
|
|
140
142
|
}
|
|
141
143
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
144
|
+
const zoomPosition =
|
|
145
|
+
general && general.zoom_position ? general.zoom_position : '';
|
|
146
|
+
|
|
147
|
+
if (zoomPosition) {
|
|
145
148
|
const zoomWidget = new Zoom({
|
|
146
149
|
view: view,
|
|
147
150
|
});
|
|
@@ -168,11 +171,10 @@ const Webmap = (props) => {
|
|
|
168
171
|
view.ui.add(legendWidget, legendPosition);
|
|
169
172
|
}
|
|
170
173
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
: 'top-right';
|
|
174
|
+
const printPosition =
|
|
175
|
+
general && general.print_position ? general.print_position : '';
|
|
176
|
+
|
|
177
|
+
if (printPosition) {
|
|
176
178
|
const printWidget = new Expand({
|
|
177
179
|
content: new Print({
|
|
178
180
|
view: view,
|
|
@@ -197,7 +199,12 @@ const Webmap = (props) => {
|
|
|
197
199
|
<div>
|
|
198
200
|
<div
|
|
199
201
|
style={{
|
|
200
|
-
height:
|
|
202
|
+
height:
|
|
203
|
+
height && !editMode
|
|
204
|
+
? `${height}px`
|
|
205
|
+
: device === 'tablet' || device === 'mobile'
|
|
206
|
+
? '300px'
|
|
207
|
+
: '500px',
|
|
201
208
|
}}
|
|
202
209
|
ref={mapRef}
|
|
203
210
|
className="esri-map"
|
|
@@ -206,4 +213,4 @@ const Webmap = (props) => {
|
|
|
206
213
|
);
|
|
207
214
|
};
|
|
208
215
|
|
|
209
|
-
export default React.memo(Webmap);
|
|
216
|
+
export default withDeviceSize(React.memo(Webmap));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Button } from 'semantic-ui-react';
|
|
3
|
-
import { Icon } from '@plone/volto/components';
|
|
3
|
+
import { Icon, UniversalLink } from '@plone/volto/components';
|
|
4
4
|
|
|
5
5
|
import LegendWidget from './LegendWidget';
|
|
6
6
|
import { serializeNodes } from 'volto-slate/editor/render';
|
|
@@ -15,46 +15,69 @@ const ExtraViews = ({ data }) => {
|
|
|
15
15
|
show_legend,
|
|
16
16
|
show_download,
|
|
17
17
|
show_viewer,
|
|
18
|
+
show_sources,
|
|
19
|
+
data_provenance = {},
|
|
18
20
|
} = data;
|
|
19
|
-
|
|
20
21
|
return (
|
|
21
22
|
<div className="extra-eea-map-content">
|
|
22
|
-
{map_data
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
23
|
+
{map_data &&
|
|
24
|
+
map_data.layers?.map_layers[0] &&
|
|
25
|
+
(show_download || show_viewer) && (
|
|
26
|
+
<div
|
|
27
|
+
style={{ display: 'flex', justifyContent: 'end', margin: '10px 0' }}
|
|
28
|
+
>
|
|
29
|
+
{show_download && (
|
|
30
|
+
<a
|
|
31
|
+
target="_blank"
|
|
32
|
+
rel="noreferrer"
|
|
33
|
+
href={`${map_data.layers.map_layers[0].map_layer.map_service_url}?f=lyr&v=9.3`}
|
|
34
|
+
>
|
|
35
|
+
<Button size="tiny">
|
|
36
|
+
<Button.Content>
|
|
37
|
+
<Icon name={downloadSVG} title="Download" size="25px" />
|
|
38
|
+
</Button.Content>
|
|
39
|
+
</Button>
|
|
40
|
+
</a>
|
|
41
|
+
)}
|
|
42
|
+
{show_viewer && (
|
|
43
|
+
<a
|
|
44
|
+
target="_blank"
|
|
45
|
+
rel="noreferrer"
|
|
46
|
+
href={
|
|
47
|
+
`https://www.arcgis.com/home/webmap/viewer.html?url=` +
|
|
48
|
+
`${map_data.layers.map_layers[0].map_layer.map_service_url}&source=sd`
|
|
49
|
+
}
|
|
50
|
+
>
|
|
51
|
+
<Button size="tiny">
|
|
52
|
+
<Button.Content>
|
|
53
|
+
<Icon name={worldSVG} title="View map" size="25px" />
|
|
54
|
+
</Button.Content>
|
|
55
|
+
</Button>
|
|
56
|
+
</a>
|
|
57
|
+
)}
|
|
58
|
+
</div>
|
|
59
|
+
)}
|
|
60
|
+
{show_legend && map_data && <LegendWidget data={map_data} />}
|
|
61
|
+
{show_sources && (
|
|
62
|
+
<>
|
|
63
|
+
{data_provenance &&
|
|
64
|
+
data_provenance.data &&
|
|
65
|
+
data_provenance.data.length > 0 ? (
|
|
66
|
+
<div>
|
|
67
|
+
<h3>Sources:</h3>
|
|
68
|
+
{data_provenance.data.map((data, i) => (
|
|
69
|
+
<div key={i}>
|
|
70
|
+
<p className="map_source_title">{data.title}</p>
|
|
71
|
+
<p className="map_source_description">{data.organisation}</p>
|
|
72
|
+
<UniversalLink href={data.link}>{data.link} </UniversalLink>
|
|
73
|
+
</div>
|
|
74
|
+
))}
|
|
75
|
+
</div>
|
|
76
|
+
) : (
|
|
77
|
+
<p>Data provenance is not set for visualization used or page</p>
|
|
54
78
|
)}
|
|
55
|
-
|
|
79
|
+
</>
|
|
56
80
|
)}
|
|
57
|
-
{show_legend && <LegendWidget data={map_data} />}
|
|
58
81
|
{description && serializeNodes(description)}
|
|
59
82
|
</div>
|
|
60
83
|
);
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Icon } from '@plone/volto/components';
|
|
3
3
|
import { Input, Select, Button, Grid } from 'semantic-ui-react';
|
|
4
|
+
import { QueryBuilder } from 'react-querybuilder';
|
|
5
|
+
import 'react-querybuilder/dist/query-builder.css';
|
|
4
6
|
|
|
5
7
|
import checkSVG from '@plone/volto/icons/check.svg';
|
|
6
8
|
import closeSVG from '@plone/volto/icons/clear.svg';
|
|
7
9
|
import aheadSVG from '@plone/volto/icons/ahead.svg';
|
|
10
|
+
import resetSVG from '@plone/volto/icons/reset.svg';
|
|
8
11
|
|
|
9
12
|
import { fetchArcgisData } from '../../utils';
|
|
10
13
|
|
|
@@ -30,7 +33,8 @@ const LayerSelectWidget = (props) => {
|
|
|
30
33
|
const [availableLayers, setAvailableLayers] = React.useState(
|
|
31
34
|
available_layers,
|
|
32
35
|
);
|
|
33
|
-
|
|
36
|
+
|
|
37
|
+
const [builtQuery, setBuiltQuery] = React.useState(query);
|
|
34
38
|
|
|
35
39
|
const handleServiceUrlCheck = async () => {
|
|
36
40
|
// fetch url, save it, populate layers options
|
|
@@ -78,14 +82,34 @@ const LayerSelectWidget = (props) => {
|
|
|
78
82
|
map_data: mapData,
|
|
79
83
|
query: '',
|
|
80
84
|
});
|
|
81
|
-
|
|
85
|
+
setBuiltQuery('');
|
|
82
86
|
};
|
|
83
87
|
|
|
84
88
|
const handleQueryLayer = () => {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
+
if (builtQuery) {
|
|
90
|
+
onChange(id, {
|
|
91
|
+
...value,
|
|
92
|
+
query: builtQuery,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const handleChangeServiceUrl = (value) => {
|
|
98
|
+
setServiceUrlError('');
|
|
99
|
+
setCheckColor('');
|
|
100
|
+
setServiceUrl(value);
|
|
101
|
+
setAvailableLayers('');
|
|
102
|
+
setBuiltQuery('');
|
|
103
|
+
setSelectedLayer('');
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const handleReset = () => {
|
|
107
|
+
setServiceUrlError('');
|
|
108
|
+
setServiceUrl(map_service_url);
|
|
109
|
+
setCheckColor('');
|
|
110
|
+
setAvailableLayers(available_layers);
|
|
111
|
+
setBuiltQuery('');
|
|
112
|
+
setSelectedLayer(layer);
|
|
89
113
|
};
|
|
90
114
|
|
|
91
115
|
return (
|
|
@@ -95,74 +119,112 @@ const LayerSelectWidget = (props) => {
|
|
|
95
119
|
}}
|
|
96
120
|
>
|
|
97
121
|
<Grid>
|
|
98
|
-
<
|
|
122
|
+
<h5 style={{ padding: '0', margin: '15px 0px 5px 0px' }}>
|
|
123
|
+
Service URL
|
|
124
|
+
</h5>
|
|
99
125
|
<Grid.Row>
|
|
100
126
|
<Input
|
|
101
127
|
type="text"
|
|
102
|
-
onChange={(e, { value }) =>
|
|
103
|
-
style={{ width: '
|
|
128
|
+
onChange={(e, { value }) => handleChangeServiceUrl(value)}
|
|
129
|
+
style={{ width: '100%' }}
|
|
130
|
+
error={serviceUrlError}
|
|
104
131
|
value={serviceUrl}
|
|
105
|
-
action
|
|
106
|
-
actionPosition="right"
|
|
107
|
-
>
|
|
108
|
-
|
|
132
|
+
// action
|
|
133
|
+
// actionPosition="right"
|
|
134
|
+
></Input>
|
|
135
|
+
|
|
136
|
+
<span style={{ fontSize: '12px', color: 'darkred' }}>
|
|
137
|
+
{serviceUrlError.error}
|
|
138
|
+
</span>
|
|
139
|
+
</Grid.Row>
|
|
140
|
+
{serviceUrl && (
|
|
141
|
+
<Grid.Row>
|
|
142
|
+
{serviceUrl !== map_service_url && (
|
|
143
|
+
<Button
|
|
144
|
+
size="small"
|
|
145
|
+
compact
|
|
146
|
+
className="layer-reset-button"
|
|
147
|
+
onClick={handleReset}
|
|
148
|
+
>
|
|
149
|
+
<Icon name={resetSVG} title="Reset" size="20px" />
|
|
150
|
+
</Button>
|
|
151
|
+
)}
|
|
109
152
|
<Button
|
|
110
|
-
|
|
111
|
-
size="tiny"
|
|
112
|
-
compact
|
|
153
|
+
size="small"
|
|
113
154
|
color={checkColor}
|
|
155
|
+
compact
|
|
156
|
+
className="layer-check-button"
|
|
114
157
|
onClick={handleServiceUrlCheck}
|
|
115
158
|
>
|
|
116
159
|
<Icon
|
|
117
160
|
name={serviceUrlError ? closeSVG : checkSVG}
|
|
118
|
-
title="
|
|
119
|
-
size="
|
|
161
|
+
title="Submit"
|
|
162
|
+
size="20px"
|
|
120
163
|
/>
|
|
121
164
|
</Button>
|
|
122
|
-
</
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
165
|
+
</Grid.Row>
|
|
166
|
+
)}
|
|
167
|
+
{availableLayers && availableLayers.length > 0 && (
|
|
168
|
+
<>
|
|
169
|
+
<h5 style={{ padding: '0', margin: '15px 0px 5px 0px' }}>Layer</h5>
|
|
170
|
+
<Grid.Row>
|
|
171
|
+
<Select
|
|
172
|
+
onChange={(e, { value }) => handleSelectLayer(value)}
|
|
173
|
+
options={availableLayers}
|
|
174
|
+
style={{ width: '100%' }}
|
|
175
|
+
placeholder="Select layer"
|
|
176
|
+
value={selectedLayer}
|
|
177
|
+
/>
|
|
178
|
+
</Grid.Row>
|
|
179
|
+
</>
|
|
180
|
+
)}
|
|
181
|
+
{availableLayers && fields && fields.length > 0 && (
|
|
182
|
+
<>
|
|
183
|
+
<h5 style={{ padding: '0', margin: '15px 0px 5px 0px' }}>
|
|
184
|
+
Query Layer
|
|
185
|
+
</h5>
|
|
186
|
+
<Grid.Row>
|
|
187
|
+
<QueryBuilder
|
|
188
|
+
fields={fields.map((fi, i) => {
|
|
189
|
+
return { name: fi.name, label: fi.name };
|
|
190
|
+
})}
|
|
191
|
+
query={builtQuery}
|
|
192
|
+
onQueryChange={(q) => setBuiltQuery(q)}
|
|
193
|
+
enableDragAndDrop={false}
|
|
194
|
+
/>
|
|
195
|
+
</Grid.Row>
|
|
196
|
+
{builtQuery && (
|
|
197
|
+
<Grid.Row>
|
|
198
|
+
<Button
|
|
199
|
+
type="submit"
|
|
200
|
+
size="tiny"
|
|
201
|
+
compact
|
|
202
|
+
className="layer-submit-button "
|
|
203
|
+
color={'green'}
|
|
204
|
+
onClick={handleQueryLayer}
|
|
205
|
+
>
|
|
206
|
+
<Icon name={aheadSVG} title="Check Url" size="20px" />
|
|
207
|
+
</Button>
|
|
208
|
+
</Grid.Row>
|
|
209
|
+
)}
|
|
210
|
+
<Grid.Row>
|
|
211
|
+
<p
|
|
212
|
+
style={{
|
|
213
|
+
fontSize: '13px',
|
|
214
|
+
fontWeight: 'bold',
|
|
215
|
+
color: 'darkgray',
|
|
216
|
+
}}
|
|
217
|
+
>
|
|
218
|
+
Available Fields:
|
|
219
|
+
</p>
|
|
220
|
+
</Grid.Row>
|
|
221
|
+
{fields.map((field, id) => (
|
|
222
|
+
<p style={{ fontSize: '12px', padding: '0 5px' }}>
|
|
223
|
+
<strong>{field.alias}</strong> ({field.type})
|
|
224
|
+
</p>
|
|
225
|
+
))}
|
|
226
|
+
</>
|
|
227
|
+
)}
|
|
166
228
|
</Grid>
|
|
167
229
|
</div>
|
|
168
230
|
);
|
|
@@ -42,7 +42,7 @@ const MapEditorWidget = (props) => {
|
|
|
42
42
|
<FormFieldWrapper {...props}>
|
|
43
43
|
<Modal
|
|
44
44
|
id="map-editor-modal"
|
|
45
|
-
|
|
45
|
+
className="map-editor-modal"
|
|
46
46
|
onClose={handleClose}
|
|
47
47
|
onOpen={() => setOpen(true)}
|
|
48
48
|
open={open}
|
|
@@ -53,35 +53,38 @@ const MapEditorWidget = (props) => {
|
|
|
53
53
|
}
|
|
54
54
|
>
|
|
55
55
|
<Modal.Content scrolling>
|
|
56
|
-
<Grid>
|
|
57
|
-
<Grid.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
56
|
+
<Grid stackable reversed="mobile vertically tablet vertically">
|
|
57
|
+
<Grid.Column
|
|
58
|
+
mobile={12}
|
|
59
|
+
tablet={12}
|
|
60
|
+
computer={5}
|
|
61
|
+
className="map-editor-column"
|
|
62
|
+
>
|
|
63
|
+
<InlineForm
|
|
64
|
+
block={block}
|
|
65
|
+
schema={schema}
|
|
66
|
+
onChangeField={(id, value) => {
|
|
67
|
+
handleChangeField(id, value);
|
|
68
|
+
}}
|
|
69
|
+
formData={dataForm}
|
|
70
|
+
/>
|
|
71
|
+
</Grid.Column>
|
|
72
|
+
<Grid.Column mobile={12} tablet={12} computer={7}>
|
|
73
|
+
<div className="webmap-container">
|
|
70
74
|
<Webmap data={intValue} editMode={true} />
|
|
71
|
-
</
|
|
72
|
-
</Grid.
|
|
75
|
+
</div>
|
|
76
|
+
</Grid.Column>
|
|
73
77
|
</Grid>
|
|
74
78
|
</Modal.Content>
|
|
75
79
|
<Modal.Actions>
|
|
76
80
|
<Grid>
|
|
77
81
|
<Grid.Row>
|
|
78
|
-
<
|
|
79
|
-
<Grid.Column width={4}>
|
|
82
|
+
<div className="map-edit-actions-container">
|
|
80
83
|
<Button onClick={handleClose}>Close</Button>
|
|
81
84
|
<Button color="green" onClick={handleApplyChanges}>
|
|
82
85
|
Apply changes
|
|
83
86
|
</Button>
|
|
84
|
-
</
|
|
87
|
+
</div>
|
|
85
88
|
</Grid.Row>
|
|
86
89
|
</Grid>
|
|
87
90
|
</Modal.Actions>
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Menu, Tab } from 'semantic-ui-react';
|
|
3
3
|
import { ObjectWidget } from '@plone/volto/components';
|
|
4
|
+
import { withDeviceSize } from '@eeacms/volto-eea-map/hocs';
|
|
4
5
|
|
|
5
6
|
export const ObjectTypesWidget = (props) => {
|
|
6
|
-
const { schemas, value = {}, onChange, errors = {}, id } = props;
|
|
7
|
+
const { schemas, value = {}, onChange, errors = {}, id, device } = props;
|
|
7
8
|
const objectId = id;
|
|
8
9
|
|
|
9
10
|
const defaultActiveTab = 0;
|
|
@@ -11,6 +12,7 @@ export const ObjectTypesWidget = (props) => {
|
|
|
11
12
|
const [activeTab, setActiveTab] = React.useState(
|
|
12
13
|
defaultActiveTab > -1 ? defaultActiveTab : 0,
|
|
13
14
|
);
|
|
15
|
+
|
|
14
16
|
const createTab = ({ schema, id, icon }, index) => {
|
|
15
17
|
return {
|
|
16
18
|
menuItem: () => (
|
|
@@ -42,7 +44,13 @@ export const ObjectTypesWidget = (props) => {
|
|
|
42
44
|
|
|
43
45
|
return (
|
|
44
46
|
<Tab
|
|
45
|
-
menu={{
|
|
47
|
+
menu={{
|
|
48
|
+
vertical:
|
|
49
|
+
device === 'computer' || device === 'tablet' || device === 'mobile'
|
|
50
|
+
? false
|
|
51
|
+
: true,
|
|
52
|
+
tabular: true,
|
|
53
|
+
}}
|
|
46
54
|
panes={schemas.map(createTab)}
|
|
47
55
|
activeIndex={activeTab}
|
|
48
56
|
grid={{ paneWidth: 9, tabWidth: 3 }}
|
|
@@ -50,4 +58,4 @@ export const ObjectTypesWidget = (props) => {
|
|
|
50
58
|
);
|
|
51
59
|
};
|
|
52
60
|
|
|
53
|
-
export default ObjectTypesWidget;
|
|
61
|
+
export default withDeviceSize(ObjectTypesWidget);
|
|
@@ -4,11 +4,11 @@ import Webmap from '../Webmap';
|
|
|
4
4
|
const VisualizationView = (props) => {
|
|
5
5
|
const { content = {} } = props;
|
|
6
6
|
|
|
7
|
-
const {
|
|
7
|
+
const { map_visualization_data = {} } = content;
|
|
8
8
|
|
|
9
9
|
return (
|
|
10
10
|
<div>
|
|
11
|
-
<Webmap data={
|
|
11
|
+
<Webmap data={map_visualization_data} />
|
|
12
12
|
</div>
|
|
13
13
|
);
|
|
14
14
|
};
|
|
@@ -66,25 +66,20 @@ const GeneralSchema = ({ data = {} }) => {
|
|
|
66
66
|
id: 'default',
|
|
67
67
|
title: 'Zoom',
|
|
68
68
|
fields: [
|
|
69
|
-
'show_print',
|
|
70
69
|
'print_position',
|
|
71
|
-
'show_zoom',
|
|
72
|
-
'centerOnExtent',
|
|
73
70
|
'zoom_position',
|
|
71
|
+
'centerOnExtent',
|
|
74
72
|
...(!centerOnExtent ? ['zoom_level', 'long', 'lat'] : []),
|
|
75
73
|
],
|
|
76
74
|
},
|
|
77
75
|
],
|
|
78
76
|
properties: {
|
|
79
|
-
show_zoom: {
|
|
80
|
-
title: 'Show zoom',
|
|
81
|
-
type: 'boolean',
|
|
82
|
-
},
|
|
83
77
|
centerOnExtent: {
|
|
84
78
|
title: 'Center on extent',
|
|
85
79
|
type: 'boolean',
|
|
86
80
|
description:
|
|
87
81
|
'This will override latitude/longitude/zoom level and will lock zoom/moving the map.',
|
|
82
|
+
default: true,
|
|
88
83
|
},
|
|
89
84
|
zoom_position: {
|
|
90
85
|
title: 'Zoom position',
|
|
@@ -106,10 +101,7 @@ const GeneralSchema = ({ data = {} }) => {
|
|
|
106
101
|
title: 'Latitude',
|
|
107
102
|
type: 'number',
|
|
108
103
|
},
|
|
109
|
-
|
|
110
|
-
title: 'Show print',
|
|
111
|
-
type: 'boolean',
|
|
112
|
-
},
|
|
104
|
+
|
|
113
105
|
print_position: {
|
|
114
106
|
title: 'Print position',
|
|
115
107
|
choices: ['bottom-right', 'bottom-left', 'top-right', 'top-left'].map(
|
|
@@ -20,3 +20,109 @@
|
|
|
20
20
|
display: flex;
|
|
21
21
|
padding: 1rem 0;
|
|
22
22
|
}
|
|
23
|
+
|
|
24
|
+
.map-editor-modal {
|
|
25
|
+
width: '95% !important';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.webmap-container {
|
|
29
|
+
position: sticky;
|
|
30
|
+
top: 10px;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.map-edit-actions-container {
|
|
34
|
+
padding: 5px 0;
|
|
35
|
+
margin-right: 10px;
|
|
36
|
+
margin-left: auto;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.layer-reset-button {
|
|
40
|
+
margin-top: 5px !important;
|
|
41
|
+
animation: fadeDown 0.2s ease-in;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.layer-check-button {
|
|
45
|
+
margin-top: 5px !important;
|
|
46
|
+
margin-left: auto !important;
|
|
47
|
+
animation: fadeDown 0.2s ease-in;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.layer-submit-button {
|
|
51
|
+
margin-top: 5px !important;
|
|
52
|
+
margin-left: auto !important;
|
|
53
|
+
animation: fadeDown 0.2s ease-in;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.ruleGroup {
|
|
57
|
+
border: 1px solid lightgray !important;
|
|
58
|
+
margin: 10px 0;
|
|
59
|
+
background-color: transparent !important;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.ruleGroup-addRule {
|
|
63
|
+
padding: 7px 10px !important;
|
|
64
|
+
background-color: darkgray !important;
|
|
65
|
+
border-radius: 5px;
|
|
66
|
+
color: white;
|
|
67
|
+
cursor: pointer;
|
|
68
|
+
font-size: 12px;
|
|
69
|
+
font-weight: bold;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.ruleGroup-addGroup {
|
|
73
|
+
padding: 7px 10px !important;
|
|
74
|
+
background-color: darkgray !important;
|
|
75
|
+
border-radius: 5px;
|
|
76
|
+
color: white;
|
|
77
|
+
cursor: pointer;
|
|
78
|
+
font-size: 12px;
|
|
79
|
+
font-weight: bold;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.ruleGroup-combinators {
|
|
83
|
+
padding: 0.3em 0 !important;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.rule-operators {
|
|
87
|
+
padding: 0.3em 0 !important;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.rule-value {
|
|
91
|
+
padding: 0.3em 0 !important;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.rule-fields {
|
|
95
|
+
padding: 0.3em 0 !important;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.rule-remove {
|
|
99
|
+
padding: 1px 6px !important;
|
|
100
|
+
border: 2px solid #d02144 !important;
|
|
101
|
+
border-radius: 50px;
|
|
102
|
+
color: #d02144;
|
|
103
|
+
cursor: pointer;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.map_source_title {
|
|
107
|
+
margin-top: 15px !important;
|
|
108
|
+
margin-bottom: 5px !important;
|
|
109
|
+
font-size: 18px;
|
|
110
|
+
font-weight: bold;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.map_source_description {
|
|
114
|
+
margin: 5px 0 !important;
|
|
115
|
+
font-size: 14px;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
@keyframes fadeDown {
|
|
119
|
+
from {
|
|
120
|
+
opacity: 0;
|
|
121
|
+
transform: translate3d(0, -20%, 0);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
to {
|
|
125
|
+
opacity: 1;
|
|
126
|
+
transform: translate3d(0, 0, 0);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { SidebarPortal } from '@plone/volto/components';
|
|
3
|
+
import BlockDataForm from '@plone/volto/components/manage/Form/BlockDataForm';
|
|
4
|
+
import { Schema } from './Schema';
|
|
5
|
+
import View from './View';
|
|
6
|
+
import { addPrivacyProtectionToSchema } from '@eeacms/volto-embed';
|
|
7
|
+
import './styles/map.css';
|
|
8
|
+
|
|
9
|
+
const Edit = (props) => {
|
|
10
|
+
const { block, data, onChangeBlock, selected, id } = props;
|
|
11
|
+
const schema = React.useMemo(() => Schema(props), [props]);
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<div>
|
|
15
|
+
<View data={data} id={id} />
|
|
16
|
+
<SidebarPortal selected={selected}>
|
|
17
|
+
<BlockDataForm
|
|
18
|
+
block={block}
|
|
19
|
+
title={schema.title}
|
|
20
|
+
schema={addPrivacyProtectionToSchema(schema)}
|
|
21
|
+
onChangeField={(id, value) => {
|
|
22
|
+
onChangeBlock(block, {
|
|
23
|
+
...data,
|
|
24
|
+
[id]: value,
|
|
25
|
+
});
|
|
26
|
+
}}
|
|
27
|
+
formData={data}
|
|
28
|
+
/>
|
|
29
|
+
</SidebarPortal>
|
|
30
|
+
</div>
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default Edit;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export const Schema = (props) => {
|
|
2
|
+
return {
|
|
3
|
+
title: 'Embed EEA Map Block',
|
|
4
|
+
fieldsets: [
|
|
5
|
+
{
|
|
6
|
+
id: 'default',
|
|
7
|
+
title: 'Default',
|
|
8
|
+
fields: [
|
|
9
|
+
'vis_url',
|
|
10
|
+
'description',
|
|
11
|
+
'height',
|
|
12
|
+
'show_legend',
|
|
13
|
+
'show_download',
|
|
14
|
+
'show_viewer',
|
|
15
|
+
'show_sources',
|
|
16
|
+
],
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
properties: {
|
|
20
|
+
vis_url: {
|
|
21
|
+
widget: 'object_by_path',
|
|
22
|
+
title: 'Visualization',
|
|
23
|
+
},
|
|
24
|
+
height: {
|
|
25
|
+
title: 'Height',
|
|
26
|
+
type: 'number',
|
|
27
|
+
},
|
|
28
|
+
description: {
|
|
29
|
+
title: 'Description',
|
|
30
|
+
widget: 'slate',
|
|
31
|
+
},
|
|
32
|
+
show_sources: {
|
|
33
|
+
title: 'Show sources',
|
|
34
|
+
type: 'boolean',
|
|
35
|
+
},
|
|
36
|
+
show_legend: {
|
|
37
|
+
title: 'Show legend',
|
|
38
|
+
type: 'boolean',
|
|
39
|
+
},
|
|
40
|
+
show_download: {
|
|
41
|
+
title: 'Show download',
|
|
42
|
+
type: 'boolean',
|
|
43
|
+
},
|
|
44
|
+
show_viewer: {
|
|
45
|
+
title: 'Show web viewer',
|
|
46
|
+
type: 'boolean',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
required: [],
|
|
50
|
+
};
|
|
51
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { connect } from 'react-redux';
|
|
4
|
+
import { compose } from 'redux';
|
|
5
|
+
|
|
6
|
+
import { PrivacyProtection } from '@eeacms/volto-embed';
|
|
7
|
+
import Webmap from '../EEAMap/components/Webmap';
|
|
8
|
+
import ExtraViews from '../EEAMap/components/widgets/ExtraViews';
|
|
9
|
+
import { getContent } from '@plone/volto/actions';
|
|
10
|
+
|
|
11
|
+
const View = (props) => {
|
|
12
|
+
const { data, viz_content = {}, id } = props || {};
|
|
13
|
+
const { height = '', vis_url = '' } = data;
|
|
14
|
+
|
|
15
|
+
const { map_visualization_data = '', data_provenance = {} } =
|
|
16
|
+
viz_content || {};
|
|
17
|
+
|
|
18
|
+
React.useEffect(() => {
|
|
19
|
+
if (vis_url) {
|
|
20
|
+
props.getContent(vis_url, null, id);
|
|
21
|
+
}
|
|
22
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
23
|
+
}, [vis_url]);
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<div>
|
|
27
|
+
<PrivacyProtection data={data} {...props}>
|
|
28
|
+
{map_visualization_data && (
|
|
29
|
+
<div>
|
|
30
|
+
<Webmap data={map_visualization_data} height={height} />
|
|
31
|
+
<ExtraViews
|
|
32
|
+
data={{
|
|
33
|
+
...data,
|
|
34
|
+
data_provenance,
|
|
35
|
+
map_data: map_visualization_data,
|
|
36
|
+
}}
|
|
37
|
+
/>
|
|
38
|
+
</div>
|
|
39
|
+
)}
|
|
40
|
+
{!map_visualization_data && (
|
|
41
|
+
<p>No map view to show. Set visualization in block configuration.</p>
|
|
42
|
+
)}
|
|
43
|
+
</PrivacyProtection>
|
|
44
|
+
</div>
|
|
45
|
+
);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export default compose(
|
|
49
|
+
connect(
|
|
50
|
+
(state, props) => ({
|
|
51
|
+
viz_content: state.content.subrequests?.[props.id]?.data,
|
|
52
|
+
}),
|
|
53
|
+
{
|
|
54
|
+
getContent,
|
|
55
|
+
},
|
|
56
|
+
),
|
|
57
|
+
)(View);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
.map-edit-container {
|
|
2
|
+
display: flex;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.map-modal-trigger-button {
|
|
6
|
+
margin-bottom: 10px !important;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
#map-editor-modal {
|
|
10
|
+
top: auto;
|
|
11
|
+
left: auto !important;
|
|
12
|
+
width: 95% !important;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
#map-widget-toggle {
|
|
16
|
+
color: blue !important;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.map-text-view {
|
|
20
|
+
display: flex;
|
|
21
|
+
padding: 1rem 0;
|
|
22
|
+
}
|
package/src/components/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import EEAMapView from './Blocks/EEAMap/View';
|
|
2
2
|
import EEAMapEdit from './Blocks/EEAMap/Edit';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
import EmbedMapView from './Blocks/EmbedEEAMap/View';
|
|
5
|
+
import EmbedMapEdit from './Blocks/EmbedEEAMap/Edit';
|
|
6
|
+
|
|
7
|
+
export { EEAMapEdit, EEAMapView, EmbedMapView, EmbedMapEdit };
|
package/src/constants.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const GET_MAP_VISUALIZATION = 'GET_MAP_VISUALIZATION';
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
export default function withDeviceSize(WrappedComponent) {
|
|
4
|
+
return (props) => {
|
|
5
|
+
const [device, setDevice] = React.useState(null);
|
|
6
|
+
|
|
7
|
+
const updateScreenSize = () => {
|
|
8
|
+
if (__CLIENT__) {
|
|
9
|
+
const screenWidth =
|
|
10
|
+
window.innerWidth ||
|
|
11
|
+
document.documentElement.clientWidth ||
|
|
12
|
+
document.body.clientWidth ||
|
|
13
|
+
0;
|
|
14
|
+
|
|
15
|
+
setDevice(getDeviceConfig(screenWidth));
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const getDeviceConfig = (width) => {
|
|
20
|
+
// semantic ui breakpoints
|
|
21
|
+
if (width < 320) {
|
|
22
|
+
return 'mobile';
|
|
23
|
+
} else if (width >= 320 && width < 768) {
|
|
24
|
+
return 'tablet';
|
|
25
|
+
} else if (width >= 768 && width < 992) {
|
|
26
|
+
return 'computer';
|
|
27
|
+
} else if (width >= 992 && width < 1280) {
|
|
28
|
+
return 'large';
|
|
29
|
+
} else if (width >= 1280) {
|
|
30
|
+
return 'widescreen';
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
React.useEffect(() => {
|
|
35
|
+
updateScreenSize();
|
|
36
|
+
window.addEventListener('resize', updateScreenSize);
|
|
37
|
+
return () => {
|
|
38
|
+
window.removeEventListener('resize', updateScreenSize);
|
|
39
|
+
};
|
|
40
|
+
/* eslint-disable-next-line */
|
|
41
|
+
}, []);
|
|
42
|
+
|
|
43
|
+
return <WrappedComponent {...props} device={device} />;
|
|
44
|
+
};
|
|
45
|
+
}
|
package/src/index.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
EEAMapEdit,
|
|
3
|
+
EEAMapView,
|
|
4
|
+
EmbedMapView,
|
|
5
|
+
EmbedMapEdit,
|
|
6
|
+
} from '@eeacms/volto-eea-map/components';
|
|
2
7
|
import world from '@plone/volto/icons/world.svg';
|
|
3
8
|
import LayerSelectWidget from './components/Blocks/EEAMap/components/widgets/LayerSelectWidget';
|
|
4
9
|
import MapEditorWidget from './components/Blocks/EEAMap/components/widgets/MapEditorWidget';
|
|
@@ -6,6 +11,9 @@ import ObjectTypesWidget from './components/Blocks/EEAMap/components/widgets/Obj
|
|
|
6
11
|
import VisualizationEditorWidget from './components/Blocks/EEAMap/components/widgets/VisualizationEditorWidget';
|
|
7
12
|
import VisualizationView from './components/Blocks/EEAMap/components/widgets/VisualizationView';
|
|
8
13
|
|
|
14
|
+
import { data_visualizations } from './middlewares';
|
|
15
|
+
import * as addonReducers from './reducers';
|
|
16
|
+
|
|
9
17
|
export default (config) => {
|
|
10
18
|
config.settings.allowed_cors_destinations = [
|
|
11
19
|
...(config.settings.allowed_cors_destinations || []),
|
|
@@ -50,14 +58,52 @@ export default (config) => {
|
|
|
50
58
|
],
|
|
51
59
|
};
|
|
52
60
|
|
|
61
|
+
config.blocks.blocksConfig.embed_eea_map_block = {
|
|
62
|
+
id: 'embed_eea_map_block', // The name (id) of the block
|
|
63
|
+
title: 'Embed EEA Map', // The display name of the block
|
|
64
|
+
icon: world, // The icon used in the block chooser
|
|
65
|
+
group: 'common', // The group (blocks can be grouped, displayed in the chooser)
|
|
66
|
+
view: EmbedMapView, // The view mode component
|
|
67
|
+
edit: EmbedMapEdit, // The edit mode component
|
|
68
|
+
sidebarTab: 1, // The sidebar tab you want to be selected when selecting the block
|
|
69
|
+
security: {
|
|
70
|
+
addPermission: [], // Future proof (not implemented yet) add user permission role(s)
|
|
71
|
+
view: [], // Future proof (not implemented yet) view user role(s)
|
|
72
|
+
},
|
|
73
|
+
variations: [
|
|
74
|
+
{
|
|
75
|
+
id: 'default',
|
|
76
|
+
title: 'EEA Map (default)',
|
|
77
|
+
isDefault: true,
|
|
78
|
+
view: EEAMapView,
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
id: 'extra',
|
|
82
|
+
title: 'Extra variation (expand if needed)',
|
|
83
|
+
isDefault: true,
|
|
84
|
+
view: EEAMapView,
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
};
|
|
88
|
+
|
|
53
89
|
config.widgets.widget.map_edit_widget = MapEditorWidget;
|
|
54
90
|
config.widgets.widget.map_layers_widget = LayerSelectWidget;
|
|
55
91
|
config.widgets.widget.object_types_widget = ObjectTypesWidget;
|
|
56
92
|
|
|
57
93
|
//map editor for the visualization(content-type)
|
|
58
|
-
config.widgets.id.
|
|
94
|
+
config.widgets.id.map_visualization_data = VisualizationEditorWidget;
|
|
59
95
|
//map viewer for the visualization(content-type)
|
|
60
96
|
config.views.contentTypesViews.map_visualization = VisualizationView;
|
|
61
97
|
|
|
98
|
+
config.settings.storeExtenders = [
|
|
99
|
+
...(config.settings.storeExtenders || []),
|
|
100
|
+
data_visualizations,
|
|
101
|
+
];
|
|
102
|
+
|
|
103
|
+
config.addonReducers = {
|
|
104
|
+
...config.addonReducers,
|
|
105
|
+
...addonReducers,
|
|
106
|
+
};
|
|
107
|
+
|
|
62
108
|
return config;
|
|
63
109
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { GET_MAP_VISUALIZATION } from '@eeacms/volto-eea-map/constants';
|
|
2
|
+
|
|
3
|
+
export const data_visualizations = (middlewares) => [
|
|
4
|
+
(store) => (next) => (action) => {
|
|
5
|
+
if (action.type === GET_MAP_VISUALIZATION) {
|
|
6
|
+
store.dispatch({
|
|
7
|
+
type: `${GET_MAP_VISUALIZATION}_PENDING`,
|
|
8
|
+
path: action.path,
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
return next(action);
|
|
12
|
+
},
|
|
13
|
+
...middlewares,
|
|
14
|
+
];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './map_visualizations';
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { GET_MAP_VISUALIZATION } from '@eeacms/volto-eea-map/constants';
|
|
2
|
+
|
|
3
|
+
const initialState = {
|
|
4
|
+
data: {},
|
|
5
|
+
error: null,
|
|
6
|
+
loaded: false,
|
|
7
|
+
loading: false,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export default function data_providers(state = initialState, action = {}) {
|
|
11
|
+
const path = action.path
|
|
12
|
+
? action.path.replace(`/@map-visualization`, '')
|
|
13
|
+
: undefined;
|
|
14
|
+
|
|
15
|
+
switch (action.type) {
|
|
16
|
+
case `${GET_MAP_VISUALIZATION}_PENDING`:
|
|
17
|
+
return {
|
|
18
|
+
...state,
|
|
19
|
+
error: null,
|
|
20
|
+
loaded: false,
|
|
21
|
+
loading: true,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
case `${GET_MAP_VISUALIZATION}_SUCCESS`:
|
|
25
|
+
return {
|
|
26
|
+
...state,
|
|
27
|
+
error: null,
|
|
28
|
+
data: {
|
|
29
|
+
...state.data,
|
|
30
|
+
[path]: action.result.map_visualization,
|
|
31
|
+
},
|
|
32
|
+
loaded: true,
|
|
33
|
+
loading: false,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
case `${GET_MAP_VISUALIZATION}_FAIL`:
|
|
37
|
+
return {
|
|
38
|
+
...state,
|
|
39
|
+
error: action.error,
|
|
40
|
+
data: { ...state.data },
|
|
41
|
+
loaded: false,
|
|
42
|
+
loading: false,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
default:
|
|
46
|
+
return state;
|
|
47
|
+
}
|
|
48
|
+
}
|