@eeacms/volto-marine-policy 2.0.4 → 2.0.6
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 +23 -0
- package/package.json +1 -1
- package/src/components/Blocks/DemoSitesExplorer/DemoSitesExplorerView.js +21 -43
- package/src/components/Blocks/DemoSitesExplorer/DemoSitesFilters.jsx +35 -30
- package/src/components/Blocks/DemoSitesExplorer/DemoSitesListing.jsx +3 -8
- package/src/components/Blocks/DemoSitesExplorer/DemoSitesMap.jsx +27 -38
- package/src/components/Blocks/DemoSitesExplorer/FeatureDisplay.jsx +7 -7
- package/src/components/Blocks/DemoSitesExplorer/FeatureInteraction.jsx +9 -14
- package/src/components/Blocks/DemoSitesExplorer/InfoOverlay.jsx +3 -6
- package/src/components/Blocks/DemoSitesExplorer/styles.less +1 -1
- package/src/components/Blocks/DemoSitesExplorer/utils.js +92 -47
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,29 @@ 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
|
+
### [2.0.6](https://github.com/eea/volto-marine-policy/compare/2.0.5...2.0.6) - 14 April 2025
|
|
8
|
+
|
|
9
|
+
#### :house: Internal changes
|
|
10
|
+
|
|
11
|
+
- style: Automated code fix [eea-jenkins - [`ae829bf`](https://github.com/eea/volto-marine-policy/commit/ae829bf49e357dc02128ff0dc4227e146ed06c0d)]
|
|
12
|
+
|
|
13
|
+
#### :hammer_and_wrench: Others
|
|
14
|
+
|
|
15
|
+
- fix eslint [laszlocseh - [`6e84248`](https://github.com/eea/volto-marine-policy/commit/6e8424833cbe25badb6bc4ba040048422878895f)]
|
|
16
|
+
- updates to demo sites map viewer [laszlocseh - [`19dc3da`](https://github.com/eea/volto-marine-policy/commit/19dc3dac8ac9ef8f91961d0ecf7878cf7b9660a4)]
|
|
17
|
+
### [2.0.5](https://github.com/eea/volto-marine-policy/compare/2.0.4...2.0.5) - 11 April 2025
|
|
18
|
+
|
|
19
|
+
#### :house: Internal changes
|
|
20
|
+
|
|
21
|
+
- style: Automated code fix [eea-jenkins - [`3f5d2ae`](https://github.com/eea/volto-marine-policy/commit/3f5d2ae0b755628580ddb0976c113be5300f2bfc)]
|
|
22
|
+
- style: Automated code fix [eea-jenkins - [`6b67afb`](https://github.com/eea/volto-marine-policy/commit/6b67afba55d6aeefc36af776e33833f40552f3c6)]
|
|
23
|
+
- style: Automated code fix [eea-jenkins - [`532ca8a`](https://github.com/eea/volto-marine-policy/commit/532ca8afa6cc4a6f9e93a09bc107eef37328b326)]
|
|
24
|
+
|
|
25
|
+
#### :hammer_and_wrench: Others
|
|
26
|
+
|
|
27
|
+
- eslint [laszlocseh - [`188282d`](https://github.com/eea/volto-marine-policy/commit/188282d7d80201395f7025eb3540a2df8bf70275)]
|
|
28
|
+
- demo sites map indicators filter [laszlocseh - [`7d97ac7`](https://github.com/eea/volto-marine-policy/commit/7d97ac772e308c0b18a49034067925fb72abecc0)]
|
|
29
|
+
- updates to demo sites map [laszlocseh - [`ab5ac18`](https://github.com/eea/volto-marine-policy/commit/ab5ac1874f97ceeafce6c639ec033b9f7dde09ab)]
|
|
7
30
|
### [2.0.4](https://github.com/eea/volto-marine-policy/compare/2.0.3...2.0.4) - 8 April 2025
|
|
8
31
|
|
|
9
32
|
#### :rocket: New Features
|
package/package.json
CHANGED
|
@@ -3,8 +3,7 @@ import { Grid } from 'semantic-ui-react'; // Dropdown,
|
|
|
3
3
|
import { addAppURL } from '@plone/volto/helpers';
|
|
4
4
|
import config from '@plone/volto/registry';
|
|
5
5
|
import DemoSitesMap from './DemoSitesMap';
|
|
6
|
-
import { ActiveFilters, DemoSitesFilters
|
|
7
|
-
// import DemoSitesList from './DemoSitesListing';
|
|
6
|
+
import { ActiveFilters, DemoSitesFilters } from './DemoSitesFilters';
|
|
8
7
|
|
|
9
8
|
import { filterCases, getFilters } from './utils';
|
|
10
9
|
import { useCases } from './hooks';
|
|
@@ -15,12 +14,12 @@ export default function DemoSitesExplorerView(props) {
|
|
|
15
14
|
const cases_url = config.settings.prefixPath
|
|
16
15
|
? '/@@demo-sites-map.arcgis.json'
|
|
17
16
|
: '/marine/@@demo-sites-map.arcgis.json';
|
|
18
|
-
|
|
19
17
|
let cases = useCases(addAppURL(cases_url));
|
|
20
|
-
const { demoSitesIds } = props; // case studies from measure view
|
|
21
18
|
const [selectedCase, onSelectedCase] = React.useState(null);
|
|
22
|
-
|
|
23
|
-
const
|
|
19
|
+
|
|
20
|
+
const { properties } = props;
|
|
21
|
+
const hideFilters = properties['@type'] === 'indicator_mo' ? true : false;
|
|
22
|
+
const indicatorOnly = hideFilters ? properties['title'] : null;
|
|
24
23
|
|
|
25
24
|
const [activeFilters, setActiveFilters] = React.useState({
|
|
26
25
|
objective_filter: [],
|
|
@@ -34,7 +33,7 @@ export default function DemoSitesExplorerView(props) {
|
|
|
34
33
|
const [map, setMap] = React.useState();
|
|
35
34
|
|
|
36
35
|
React.useEffect(() => {
|
|
37
|
-
const _filters = getFilters(cases);
|
|
36
|
+
const _filters = getFilters(cases, indicatorOnly);
|
|
38
37
|
setFilters(_filters);
|
|
39
38
|
}, [
|
|
40
39
|
cases,
|
|
@@ -43,54 +42,34 @@ export default function DemoSitesExplorerView(props) {
|
|
|
43
42
|
activeFilters.project_filter,
|
|
44
43
|
activeFilters.country_filter,
|
|
45
44
|
activeItems.length,
|
|
45
|
+
indicatorOnly,
|
|
46
46
|
]);
|
|
47
47
|
|
|
48
48
|
React.useEffect(() => {
|
|
49
|
-
let activeItems = filterCases(
|
|
50
|
-
cases,
|
|
51
|
-
activeFilters,
|
|
52
|
-
demoSitesIds,
|
|
53
|
-
searchInput,
|
|
54
|
-
);
|
|
49
|
+
let activeItems = filterCases(cases, activeFilters, indicatorOnly);
|
|
55
50
|
|
|
56
51
|
setActiveItems(activeItems);
|
|
57
|
-
}, [
|
|
52
|
+
}, [activeFilters, cases, indicatorOnly]);
|
|
58
53
|
|
|
59
54
|
if (__SERVER__) return '';
|
|
60
55
|
|
|
61
56
|
return (
|
|
62
57
|
<div className="searchlib-block">
|
|
63
58
|
<Grid.Row>
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
searchInput={searchInput}
|
|
70
|
-
setSearchInput={setSearchInput}
|
|
71
|
-
onSelectedCase={onSelectedCase}
|
|
72
|
-
map={map}
|
|
73
|
-
/>
|
|
74
|
-
)}
|
|
75
|
-
</Grid.Row>
|
|
76
|
-
<Grid.Row>
|
|
77
|
-
{hideFilters ? null : (
|
|
78
|
-
<ActiveFilters
|
|
79
|
-
filters={filters}
|
|
80
|
-
activeFilters={activeFilters}
|
|
81
|
-
setActiveFilters={setActiveFilters}
|
|
82
|
-
/>
|
|
83
|
-
)}
|
|
59
|
+
<ActiveFilters
|
|
60
|
+
filters={filters}
|
|
61
|
+
activeFilters={activeFilters}
|
|
62
|
+
setActiveFilters={setActiveFilters}
|
|
63
|
+
/>
|
|
84
64
|
</Grid.Row>
|
|
85
65
|
<Grid.Row stretched={true} id="cse-filter">
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
)}
|
|
66
|
+
<DemoSitesFilters
|
|
67
|
+
filters={filters}
|
|
68
|
+
activeFilters={activeFilters}
|
|
69
|
+
hideFilters={hideFilters}
|
|
70
|
+
setActiveFilters={setActiveFilters}
|
|
71
|
+
map={map}
|
|
72
|
+
/>
|
|
94
73
|
</Grid.Row>
|
|
95
74
|
<Grid.Row>
|
|
96
75
|
{cases.length ? (
|
|
@@ -102,7 +81,6 @@ export default function DemoSitesExplorerView(props) {
|
|
|
102
81
|
hideFilters={hideFilters}
|
|
103
82
|
selectedCase={selectedCase}
|
|
104
83
|
onSelectedCase={onSelectedCase}
|
|
105
|
-
searchInput={searchInput}
|
|
106
84
|
map={map}
|
|
107
85
|
setMap={setMap}
|
|
108
86
|
/>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
import { centerAndResetMapZoom
|
|
3
|
+
import { centerAndResetMapZoom } from './utils';
|
|
4
4
|
|
|
5
5
|
const normalizeSearchInput = (searchInput) => {
|
|
6
6
|
let normInput = searchInput
|
|
@@ -87,7 +87,7 @@ export function DemoSitesFilter(props) {
|
|
|
87
87
|
});
|
|
88
88
|
}
|
|
89
89
|
setActiveFilters(temp);
|
|
90
|
-
scrollToElement('search-input');
|
|
90
|
+
// scrollToElement('search-input');
|
|
91
91
|
centerAndResetMapZoom(map);
|
|
92
92
|
}}
|
|
93
93
|
/>
|
|
@@ -101,7 +101,7 @@ export function DemoSitesFilter(props) {
|
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
export function DemoSitesFilters(props) {
|
|
104
|
-
const { filters, activeFilters, setActiveFilters, map } = props;
|
|
104
|
+
const { filters, activeFilters, hideFilters, setActiveFilters, map } = props;
|
|
105
105
|
|
|
106
106
|
React.useEffect(() => {
|
|
107
107
|
window.addEventListener('click', (event) => {
|
|
@@ -117,24 +117,30 @@ export function DemoSitesFilters(props) {
|
|
|
117
117
|
|
|
118
118
|
return (
|
|
119
119
|
<>
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
120
|
+
{!hideFilters ? (
|
|
121
|
+
<DemoSitesFilter
|
|
122
|
+
filterTitle="Objective"
|
|
123
|
+
filterName="objective_filter"
|
|
124
|
+
filters={filters}
|
|
125
|
+
activeFilters={activeFilters}
|
|
126
|
+
setActiveFilters={setActiveFilters}
|
|
127
|
+
map={map}
|
|
128
|
+
/>
|
|
129
|
+
) : (
|
|
130
|
+
''
|
|
131
|
+
)}
|
|
132
|
+
{!hideFilters ? (
|
|
133
|
+
<DemoSitesFilter
|
|
134
|
+
filterTitle="Indicator"
|
|
135
|
+
filterName="indicator_filter"
|
|
136
|
+
filters={filters}
|
|
137
|
+
activeFilters={activeFilters}
|
|
138
|
+
setActiveFilters={setActiveFilters}
|
|
139
|
+
map={map}
|
|
140
|
+
/>
|
|
141
|
+
) : (
|
|
142
|
+
''
|
|
143
|
+
)}
|
|
138
144
|
<DemoSitesFilter
|
|
139
145
|
filterTitle="Project"
|
|
140
146
|
filterName="project_filter"
|
|
@@ -143,7 +149,6 @@ export function DemoSitesFilters(props) {
|
|
|
143
149
|
setActiveFilters={setActiveFilters}
|
|
144
150
|
map={map}
|
|
145
151
|
/>
|
|
146
|
-
|
|
147
152
|
<DemoSitesFilter
|
|
148
153
|
filterTitle="Country"
|
|
149
154
|
filterName="country_filter"
|
|
@@ -181,7 +186,7 @@ export function SearchBox(props) {
|
|
|
181
186
|
// const popupOverlay = document.getElementById('popup-overlay');
|
|
182
187
|
// popupOverlay.style.visibility = 'hidden';
|
|
183
188
|
setSearchInput(searchInput);
|
|
184
|
-
scrollToElement('search-input');
|
|
189
|
+
// scrollToElement('search-input');
|
|
185
190
|
centerAndResetMapZoom(map);
|
|
186
191
|
}}
|
|
187
192
|
></input>
|
|
@@ -199,7 +204,7 @@ export function SearchBox(props) {
|
|
|
199
204
|
searchInputElement.value = '';
|
|
200
205
|
setSearchInput('');
|
|
201
206
|
setShowClearButton(false);
|
|
202
|
-
scrollToElement('search-input');
|
|
207
|
+
// scrollToElement('search-input');
|
|
203
208
|
centerAndResetMapZoom(map);
|
|
204
209
|
}}
|
|
205
210
|
></i>
|
|
@@ -219,7 +224,7 @@ export function SearchBox(props) {
|
|
|
219
224
|
);
|
|
220
225
|
|
|
221
226
|
setSearchInput(searchInputVal);
|
|
222
|
-
scrollToElement('search-input');
|
|
227
|
+
// scrollToElement('search-input');
|
|
223
228
|
centerAndResetMapZoom(map);
|
|
224
229
|
}}
|
|
225
230
|
onKeyDown={() => {}}
|
|
@@ -261,7 +266,7 @@ export function ActiveFilters(props) {
|
|
|
261
266
|
project_filter: [],
|
|
262
267
|
country_filter: [],
|
|
263
268
|
});
|
|
264
|
-
scrollToElement('search-input');
|
|
269
|
+
// scrollToElement('search-input');
|
|
265
270
|
};
|
|
266
271
|
|
|
267
272
|
const removeFilter = (filterName, filterCode) => {
|
|
@@ -310,7 +315,7 @@ export function ActiveFilters(props) {
|
|
|
310
315
|
onKeyPress={() => {}}
|
|
311
316
|
onClick={() => {
|
|
312
317
|
removeFilter('objective_filter', filterCode);
|
|
313
|
-
scrollToElement('search-input');
|
|
318
|
+
// scrollToElement('search-input');
|
|
314
319
|
}}
|
|
315
320
|
role="button"
|
|
316
321
|
className="close icon"
|
|
@@ -335,7 +340,7 @@ export function ActiveFilters(props) {
|
|
|
335
340
|
onKeyPress={() => {}}
|
|
336
341
|
onClick={() => {
|
|
337
342
|
removeFilter('indicator_filter', filterCode);
|
|
338
|
-
scrollToElement('search-input');
|
|
343
|
+
// scrollToElement('search-input');
|
|
339
344
|
}}
|
|
340
345
|
role="button"
|
|
341
346
|
className="close icon"
|
|
@@ -360,7 +365,7 @@ export function ActiveFilters(props) {
|
|
|
360
365
|
onKeyPress={() => {}}
|
|
361
366
|
onClick={() => {
|
|
362
367
|
removeFilter('project_filter', filterCode);
|
|
363
|
-
scrollToElement('search-input');
|
|
368
|
+
// scrollToElement('search-input');
|
|
364
369
|
}}
|
|
365
370
|
role="button"
|
|
366
371
|
className="close icon"
|
|
@@ -385,7 +390,7 @@ export function ActiveFilters(props) {
|
|
|
385
390
|
onKeyPress={() => {}}
|
|
386
391
|
onClick={() => {
|
|
387
392
|
removeFilter('country_filter', filterCode);
|
|
388
|
-
scrollToElement('search-input');
|
|
393
|
+
// scrollToElement('search-input');
|
|
389
394
|
}}
|
|
390
395
|
role="button"
|
|
391
396
|
className="close icon"
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
centerAndResetMapZoom,
|
|
4
|
-
scrollToElement,
|
|
5
|
-
zoomMapToFeatures,
|
|
6
|
-
isValidURL,
|
|
7
|
-
} from './utils';
|
|
2
|
+
import { centerAndResetMapZoom, zoomMapToFeatures, isValidURL } from './utils';
|
|
8
3
|
|
|
9
4
|
const showPageNr = (pageNr, currentPage, numberOfPages) => {
|
|
10
5
|
// show first 5 pages
|
|
@@ -157,7 +152,7 @@ export default function DemoSitesList(props) {
|
|
|
157
152
|
onKeyDown={() => {}}
|
|
158
153
|
onClick={() => {
|
|
159
154
|
// scroll to the map
|
|
160
|
-
scrollToElement('search-input');
|
|
155
|
+
// scrollToElement('search-input');
|
|
161
156
|
// reset map zoom
|
|
162
157
|
onSelectedCase(null);
|
|
163
158
|
centerAndResetMapZoom(map);
|
|
@@ -274,7 +269,7 @@ export default function DemoSitesList(props) {
|
|
|
274
269
|
.array_[9].getFeatures()
|
|
275
270
|
.clear();
|
|
276
271
|
// scroll to the map
|
|
277
|
-
scrollToElement('ol-map-container');
|
|
272
|
+
// scrollToElement('ol-map-container');
|
|
278
273
|
|
|
279
274
|
zoomMapToFeatures(map, [item], 5000);
|
|
280
275
|
onSelectedCase(item.values_);
|
|
@@ -7,10 +7,9 @@ import { openlayers as ol } from '@eeacms/volto-openlayers-map';
|
|
|
7
7
|
|
|
8
8
|
import InfoOverlay from './InfoOverlay';
|
|
9
9
|
import FeatureInteraction from './FeatureInteraction';
|
|
10
|
-
import DemoSitesList from './DemoSitesListing';
|
|
11
10
|
import { useMapContext } from '@eeacms/volto-openlayers-map/api';
|
|
12
11
|
|
|
13
|
-
import { centerAndResetMapZoom, getFeatures
|
|
12
|
+
import { centerAndResetMapZoom, getFeatures } from './utils';
|
|
14
13
|
|
|
15
14
|
const styleCache = {};
|
|
16
15
|
const MapContextGateway = ({ setMap }) => {
|
|
@@ -28,7 +27,6 @@ export default function DemoSitesMap(props) {
|
|
|
28
27
|
hideFilters,
|
|
29
28
|
selectedCase,
|
|
30
29
|
onSelectedCase,
|
|
31
|
-
searchInput,
|
|
32
30
|
map,
|
|
33
31
|
setMap,
|
|
34
32
|
} = props;
|
|
@@ -128,23 +126,21 @@ export default function DemoSitesMap(props) {
|
|
|
128
126
|
>
|
|
129
127
|
<Controls attribution={false} />
|
|
130
128
|
<Layers>
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
>
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
</button>
|
|
147
|
-
)}
|
|
129
|
+
<button
|
|
130
|
+
className={cx(
|
|
131
|
+
'reset-map-button ui button secondary',
|
|
132
|
+
String(resetMapButtonClass),
|
|
133
|
+
)}
|
|
134
|
+
onClick={() => {
|
|
135
|
+
// scrollToElement('search-input');
|
|
136
|
+
onSelectedCase(null);
|
|
137
|
+
centerAndResetMapZoom(map);
|
|
138
|
+
map.getInteractions().array_[9].getFeatures().clear();
|
|
139
|
+
}}
|
|
140
|
+
>
|
|
141
|
+
<span className="result-info-title">Reset map</span>
|
|
142
|
+
<i className="icon ri-map-2-line"></i>
|
|
143
|
+
</button>
|
|
148
144
|
<InfoOverlay
|
|
149
145
|
selectedFeature={selectedCase}
|
|
150
146
|
onFeatureSelect={onSelectedCase}
|
|
@@ -153,8 +149,8 @@ export default function DemoSitesMap(props) {
|
|
|
153
149
|
/>
|
|
154
150
|
<FeatureInteraction
|
|
155
151
|
onFeatureSelect={onSelectedCase}
|
|
156
|
-
hideFilters={hideFilters}
|
|
157
|
-
selectedCase={selectedCase}
|
|
152
|
+
// hideFilters={hideFilters}
|
|
153
|
+
// selectedCase={selectedCase}
|
|
158
154
|
/>
|
|
159
155
|
<Layer.Tile source={tileWMSSources[0]} zIndex={0} />
|
|
160
156
|
<Layer.Vector
|
|
@@ -165,22 +161,12 @@ export default function DemoSitesMap(props) {
|
|
|
165
161
|
<MapContextGateway setMap={setMap} />
|
|
166
162
|
</Layers>
|
|
167
163
|
</MapWithSelection>
|
|
168
|
-
{hideFilters ? null : (
|
|
169
|
-
<DemoSitesList
|
|
170
|
-
map={map}
|
|
171
|
-
activeItems={activeItems}
|
|
172
|
-
selectedCase={selectedCase}
|
|
173
|
-
onSelectedCase={onSelectedCase}
|
|
174
|
-
pointsSource={pointsSource}
|
|
175
|
-
searchInput={searchInput}
|
|
176
|
-
/>
|
|
177
|
-
)}
|
|
178
164
|
</div>
|
|
179
165
|
) : null;
|
|
180
166
|
}
|
|
181
167
|
|
|
182
168
|
const selectedClusterStyle = (selectedFeature) => {
|
|
183
|
-
function _clusterStyle(feature) {
|
|
169
|
+
function _clusterStyle(feature, selectedFeature) {
|
|
184
170
|
const size = feature.get('features').length;
|
|
185
171
|
let style = styleCache[size];
|
|
186
172
|
|
|
@@ -193,7 +179,7 @@ const selectedClusterStyle = (selectedFeature) => {
|
|
|
193
179
|
}),
|
|
194
180
|
fill: new ol.style.Fill({
|
|
195
181
|
// 309ebc blue 3 + green 3 mix
|
|
196
|
-
color: '#
|
|
182
|
+
color: '#006BB8', // #006BB8 #309ebc
|
|
197
183
|
}),
|
|
198
184
|
}),
|
|
199
185
|
text: new ol.style.Text({
|
|
@@ -207,18 +193,21 @@ const selectedClusterStyle = (selectedFeature) => {
|
|
|
207
193
|
}
|
|
208
194
|
|
|
209
195
|
if (size === 1) {
|
|
210
|
-
|
|
211
|
-
let
|
|
196
|
+
let color = feature.values_.features[0].values_['color'];
|
|
197
|
+
let width = feature.values_.features[0].values_['width'];
|
|
198
|
+
let radius = feature.values_.features[0].values_['radius'];
|
|
199
|
+
// console.log(color)
|
|
200
|
+
// let color = '#0083E0'; // #0083E0 #50B0A4
|
|
212
201
|
|
|
213
202
|
return new ol.style.Style({
|
|
214
203
|
image: new ol.style.Circle({
|
|
215
|
-
radius:
|
|
204
|
+
radius: radius,
|
|
216
205
|
fill: new ol.style.Fill({
|
|
217
206
|
color: '#fff',
|
|
218
207
|
}),
|
|
219
208
|
stroke: new ol.style.Stroke({
|
|
220
209
|
color: color,
|
|
221
|
-
width:
|
|
210
|
+
width: width,
|
|
222
211
|
}),
|
|
223
212
|
}),
|
|
224
213
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { isValidURL } from './utils';
|
|
2
|
+
import { isValidURL, truncateText } from './utils';
|
|
3
3
|
|
|
4
4
|
export default function FeatureDisplay({ feature }) {
|
|
5
5
|
return feature ? (
|
|
@@ -7,7 +7,7 @@ export default function FeatureDisplay({ feature }) {
|
|
|
7
7
|
<h3>
|
|
8
8
|
<strong>
|
|
9
9
|
<a target="_blank" rel="noopener noreferrer" href={feature.path}>
|
|
10
|
-
{feature.title}
|
|
10
|
+
{truncateText(feature.title)}
|
|
11
11
|
</a>
|
|
12
12
|
</strong>
|
|
13
13
|
</h3>
|
|
@@ -66,10 +66,10 @@ export default function FeatureDisplay({ feature }) {
|
|
|
66
66
|
''
|
|
67
67
|
)}
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
<
|
|
69
|
+
<div>
|
|
70
|
+
<span className="popup-title blue">Indicators</span>
|
|
71
71
|
<ul>
|
|
72
|
-
{feature.
|
|
72
|
+
{feature.indicators.map((item, index) => {
|
|
73
73
|
return (
|
|
74
74
|
<li key={index}>
|
|
75
75
|
<a
|
|
@@ -83,9 +83,9 @@ export default function FeatureDisplay({ feature }) {
|
|
|
83
83
|
);
|
|
84
84
|
})}
|
|
85
85
|
</ul>
|
|
86
|
-
</div>
|
|
86
|
+
</div>
|
|
87
87
|
{/* <div>
|
|
88
|
-
<h4>
|
|
88
|
+
<h4>Indicators</h4>
|
|
89
89
|
<ul>
|
|
90
90
|
{feature.sectors.map((item, index) => {
|
|
91
91
|
return <li key={index}>{item}</li>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { openlayers as ol } from '@eeacms/volto-openlayers-map';
|
|
3
3
|
import { useMapContext } from '@eeacms/volto-openlayers-map/api';
|
|
4
|
-
import {
|
|
4
|
+
import { zoomMapToFeatures } from './utils';
|
|
5
5
|
|
|
6
6
|
export const useStyles = () => {
|
|
7
7
|
const selected = React.useMemo(
|
|
@@ -35,18 +35,14 @@ export const useStyles = () => {
|
|
|
35
35
|
return { selected, selectStyle };
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
-
export default function FeatureInteraction({
|
|
39
|
-
onFeatureSelect,
|
|
40
|
-
hideFilters,
|
|
41
|
-
selectedCase,
|
|
42
|
-
}) {
|
|
38
|
+
export default function FeatureInteraction({ onFeatureSelect }) {
|
|
43
39
|
// console.log('featureinteraction', selectedCase);
|
|
44
40
|
const { map } = useMapContext();
|
|
45
41
|
const { selectStyle } = useStyles();
|
|
46
42
|
|
|
47
43
|
const select = new ol.interaction.Select({
|
|
48
44
|
condition: ol.condition.click,
|
|
49
|
-
style:
|
|
45
|
+
style: selectStyle,
|
|
50
46
|
});
|
|
51
47
|
|
|
52
48
|
React.useEffect(() => {
|
|
@@ -59,13 +55,12 @@ export default function FeatureInteraction({
|
|
|
59
55
|
const subfeatures = feature.values_.features;
|
|
60
56
|
if (subfeatures.length === 1) {
|
|
61
57
|
const selectedFeature = subfeatures[0].values_;
|
|
62
|
-
if (hideFilters) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
58
|
+
// if (hideFilters) {
|
|
59
|
+
// const url = window.location.origin + selectedFeature.path;
|
|
60
|
+
// window.location.href = url;
|
|
61
|
+
// }
|
|
67
62
|
onFeatureSelect(selectedFeature);
|
|
68
|
-
scrollToElement('ol-map-container');
|
|
63
|
+
// scrollToElement('ol-map-container');
|
|
69
64
|
// map.getView().animate({
|
|
70
65
|
// duration: 10,
|
|
71
66
|
// center: selectedFeature.geometry.flatCoordinates,
|
|
@@ -89,7 +84,7 @@ export default function FeatureInteraction({
|
|
|
89
84
|
|
|
90
85
|
return () => map.removeInteraction(select);
|
|
91
86
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
92
|
-
}, [map, selectStyle, onFeatureSelect
|
|
87
|
+
}, [map, selectStyle, onFeatureSelect]);
|
|
93
88
|
|
|
94
89
|
return null;
|
|
95
90
|
}
|
|
@@ -8,7 +8,7 @@ export default function InfoOverlay({
|
|
|
8
8
|
selectedFeature,
|
|
9
9
|
onFeatureSelect,
|
|
10
10
|
layerId,
|
|
11
|
-
hideFilters,
|
|
11
|
+
// hideFilters,
|
|
12
12
|
}) {
|
|
13
13
|
const { map } = useMapContext();
|
|
14
14
|
const [tooltip, setTooltipRef] = React.useState();
|
|
@@ -38,10 +38,7 @@ export default function InfoOverlay({
|
|
|
38
38
|
const features = target.getFeaturesAtPixel(pixel);
|
|
39
39
|
// const popupOverlay = overlay.element; // document.getElementById('popup-overlay');
|
|
40
40
|
|
|
41
|
-
if (
|
|
42
|
-
features.length &&
|
|
43
|
-
!hideFilters // && !isCluster(features)
|
|
44
|
-
) {
|
|
41
|
+
if (features.length) {
|
|
45
42
|
setShowTooltip(true);
|
|
46
43
|
} else {
|
|
47
44
|
// handle a click in an overlay popup
|
|
@@ -58,7 +55,7 @@ export default function InfoOverlay({
|
|
|
58
55
|
map.un('click', handler);
|
|
59
56
|
map.removeOverlay(overlay);
|
|
60
57
|
};
|
|
61
|
-
}, [map, tooltip, onFeatureSelect
|
|
58
|
+
}, [map, tooltip, onFeatureSelect]); //
|
|
62
59
|
|
|
63
60
|
const [isClient, setIsClient] = React.useState(false);
|
|
64
61
|
React.useEffect(() => setIsClient(true), []);
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { openlayers as ol } from '@eeacms/volto-openlayers-map';
|
|
2
2
|
|
|
3
|
+
export const truncateText = (str, max = 50) => {
|
|
4
|
+
if (str.length <= max) {
|
|
5
|
+
return str;
|
|
6
|
+
}
|
|
7
|
+
return str.substring(0, max) + '...';
|
|
8
|
+
};
|
|
9
|
+
|
|
3
10
|
export function isValidURL(string) {
|
|
4
11
|
try {
|
|
5
12
|
new URL(string);
|
|
@@ -40,6 +47,22 @@ export function zoomMapToFeatures(map, features, threshold = 500) {
|
|
|
40
47
|
|
|
41
48
|
export function getFeatures(cases) {
|
|
42
49
|
const Feature = ol.ol.Feature;
|
|
50
|
+
const colors = {
|
|
51
|
+
'Carbon-neutral and circular blue economy': '#004b7f',
|
|
52
|
+
'Digital twin of the ocean': '#004b7f',
|
|
53
|
+
'Prevent and eliminate pollution of waters': '#fdaf20',
|
|
54
|
+
'Protect and restore marine and freshwater ecosystems': '#007b6c',
|
|
55
|
+
'Public mobilisation and engagement': '#004b7f',
|
|
56
|
+
};
|
|
57
|
+
const width = {
|
|
58
|
+
'Demo site': 6,
|
|
59
|
+
'Associated region': 8,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const radius = {
|
|
63
|
+
'Demo site': 6,
|
|
64
|
+
'Associated region': 5,
|
|
65
|
+
};
|
|
43
66
|
|
|
44
67
|
return cases.map((c, index) => {
|
|
45
68
|
const {
|
|
@@ -65,7 +88,9 @@ export function getFeatures(cases) {
|
|
|
65
88
|
description: c.properties.description,
|
|
66
89
|
index: index,
|
|
67
90
|
path: c.properties.path,
|
|
68
|
-
color: c.properties.
|
|
91
|
+
color: colors[c.properties.objective] || '#B83230',
|
|
92
|
+
width: width[c.properties.type_is_region],
|
|
93
|
+
radius: radius[c.properties.type_is_region],
|
|
69
94
|
},
|
|
70
95
|
false,
|
|
71
96
|
);
|
|
@@ -73,53 +98,45 @@ export function getFeatures(cases) {
|
|
|
73
98
|
});
|
|
74
99
|
}
|
|
75
100
|
|
|
76
|
-
export function filterCases(cases, activeFilters,
|
|
101
|
+
export function filterCases(cases, activeFilters, indicatorOnly) {
|
|
77
102
|
const data = cases.filter((_case) => {
|
|
78
|
-
let flag_searchInput = false;
|
|
79
103
|
let flag_objective = false;
|
|
80
|
-
|
|
104
|
+
let flag_indicator = false;
|
|
81
105
|
let flag_project = false;
|
|
82
106
|
let flag_country = false;
|
|
83
|
-
let
|
|
84
|
-
? demoSitesIds.includes(_case.properties.url.split('/').pop())
|
|
85
|
-
: true;
|
|
107
|
+
let flag_indicatorOnly = false;
|
|
86
108
|
|
|
87
|
-
if (
|
|
88
|
-
|
|
109
|
+
if (indicatorOnly) {
|
|
110
|
+
let indicators = _case.properties.indicators?.map((item) => {
|
|
111
|
+
return item['title'].toString();
|
|
112
|
+
});
|
|
113
|
+
if (indicators?.includes(indicatorOnly)) flag_indicatorOnly = true;
|
|
89
114
|
} else {
|
|
90
|
-
|
|
91
|
-
flag_searchInput = true;
|
|
92
|
-
// } else if (
|
|
93
|
-
// _case.properties.description.toLowerCase().match(searchInput)
|
|
94
|
-
// ) {
|
|
95
|
-
// flag_searchInput = true;
|
|
96
|
-
}
|
|
115
|
+
flag_indicatorOnly = true;
|
|
97
116
|
}
|
|
98
117
|
|
|
99
118
|
// debugger;
|
|
100
119
|
if (!activeFilters.objective_filter.length) {
|
|
101
120
|
flag_objective = true;
|
|
102
121
|
} else {
|
|
103
|
-
let objective = _case.properties.objective
|
|
104
|
-
return item['id'].toString();
|
|
105
|
-
});
|
|
122
|
+
let objective = _case.properties.objective;
|
|
106
123
|
|
|
107
124
|
activeFilters.objective_filter.forEach((filter) => {
|
|
108
|
-
if (objective
|
|
125
|
+
if (objective === filter) flag_objective = true;
|
|
109
126
|
});
|
|
110
127
|
}
|
|
111
128
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
129
|
+
if (!activeFilters.indicator_filter.length) {
|
|
130
|
+
flag_indicator = true;
|
|
131
|
+
} else {
|
|
132
|
+
let indicators = _case.properties.indicators?.map((item) => {
|
|
133
|
+
return item['id'].toString();
|
|
134
|
+
});
|
|
118
135
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
136
|
+
activeFilters.indicator_filter.forEach((filter) => {
|
|
137
|
+
if (indicators?.includes(filter)) flag_indicator = true;
|
|
138
|
+
});
|
|
139
|
+
}
|
|
123
140
|
|
|
124
141
|
if (!activeFilters.project_filter.length) {
|
|
125
142
|
flag_project = true;
|
|
@@ -143,11 +160,11 @@ export function filterCases(cases, activeFilters, demoSitesIds, searchInput) {
|
|
|
143
160
|
});
|
|
144
161
|
}
|
|
145
162
|
|
|
146
|
-
return
|
|
163
|
+
return flag_indicatorOnly &&
|
|
147
164
|
flag_objective &&
|
|
165
|
+
flag_indicator &&
|
|
148
166
|
flag_country &&
|
|
149
|
-
flag_project
|
|
150
|
-
flag_searchInput
|
|
167
|
+
flag_project
|
|
151
168
|
? _case
|
|
152
169
|
: false;
|
|
153
170
|
});
|
|
@@ -155,7 +172,7 @@ export function filterCases(cases, activeFilters, demoSitesIds, searchInput) {
|
|
|
155
172
|
return data;
|
|
156
173
|
}
|
|
157
174
|
|
|
158
|
-
export function getFilters(cases) {
|
|
175
|
+
export function getFilters(cases, indicatorOnly) {
|
|
159
176
|
let _filters = {
|
|
160
177
|
objective_filter: {},
|
|
161
178
|
indicator_filter: {},
|
|
@@ -166,24 +183,52 @@ export function getFilters(cases) {
|
|
|
166
183
|
for (let key of Object.keys(cases)) {
|
|
167
184
|
const _case = cases[key];
|
|
168
185
|
// debugger;
|
|
169
|
-
// let nwrms_implemented = _case.properties.measures;
|
|
170
|
-
// nwrms_implemented.map((item) => {
|
|
171
|
-
// if (!_filters.nwrms_implemented.hasOwnProperty(item['id'])) {
|
|
172
|
-
// _filters.nwrms_implemented[item['id']] = item['title'];
|
|
173
|
-
// }
|
|
174
|
-
// return [];
|
|
175
|
-
// });
|
|
176
186
|
|
|
177
|
-
let
|
|
187
|
+
let indicators = _case.properties.indicators;
|
|
188
|
+
indicators.map((item) => {
|
|
189
|
+
if (
|
|
190
|
+
item['title'] &&
|
|
191
|
+
!_filters.indicator_filter.hasOwnProperty(item['id'])
|
|
192
|
+
) {
|
|
193
|
+
_filters.indicator_filter[item['id']] = item['title'];
|
|
194
|
+
}
|
|
195
|
+
return [];
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
let objective = _case.properties.objective;
|
|
199
|
+
if (objective && !_filters.objective_filter.hasOwnProperty(objective)) {
|
|
200
|
+
_filters.objective_filter[objective] = objective;
|
|
201
|
+
}
|
|
178
202
|
|
|
179
|
-
|
|
180
|
-
|
|
203
|
+
let project = _case.properties.project;
|
|
204
|
+
if (project && !_filters.project_filter.hasOwnProperty(project)) {
|
|
205
|
+
if (!indicatorOnly) {
|
|
206
|
+
_filters.project_filter[project] = project;
|
|
207
|
+
} else {
|
|
208
|
+
let indicators = _case.properties.indicators?.map((item) => {
|
|
209
|
+
return item['title'].toString();
|
|
210
|
+
});
|
|
211
|
+
if (indicators?.includes(indicatorOnly)) {
|
|
212
|
+
_filters.project_filter[project] = project;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
// _filters.project_filter[project] = project;
|
|
181
216
|
}
|
|
182
217
|
|
|
183
|
-
let countries = _case.properties.country;
|
|
218
|
+
let countries = _case.properties.country || [];
|
|
184
219
|
countries.map((item) => {
|
|
185
|
-
if (!_filters.country_filter.hasOwnProperty(item)) {
|
|
186
|
-
|
|
220
|
+
if (item && !_filters.country_filter.hasOwnProperty(item)) {
|
|
221
|
+
if (!indicatorOnly) {
|
|
222
|
+
_filters.country_filter[item] = item;
|
|
223
|
+
} else {
|
|
224
|
+
let indicators = _case.properties.indicators?.map((item) => {
|
|
225
|
+
return item['title'].toString();
|
|
226
|
+
});
|
|
227
|
+
if (indicators?.includes(indicatorOnly)) {
|
|
228
|
+
_filters.country_filter[item] = item;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
// _filters.country_filter[item] = item;
|
|
187
232
|
}
|
|
188
233
|
return [];
|
|
189
234
|
});
|