@eeacms/volto-marine-policy 2.0.25 → 2.0.27

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 CHANGED
@@ -4,6 +4,24 @@ 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.27](https://github.com/eea/volto-marine-policy/compare/2.0.26...2.0.27) - 5 September 2025
8
+
9
+ #### :hammer_and_wrench: Others
10
+
11
+ - fix eslint [laszlocseh - [`3f90c17`](https://github.com/eea/volto-marine-policy/commit/3f90c17f976fdf48a2e967d2997487ba87a3535d)]
12
+ - Demo Sites Explorer filter Targets facet options by selected objective [laszlocseh - [`3b975ad`](https://github.com/eea/volto-marine-policy/commit/3b975ad4380196cfd71c8fd2919fc717f98528a5)]
13
+ ### [2.0.26](https://github.com/eea/volto-marine-policy/compare/2.0.25...2.0.26) - 29 August 2025
14
+
15
+ #### :rocket: Dependency updates
16
+
17
+ - Release @eeacms/volto-searchlib@2.1.10 [EEA Jenkins - [`17445e9`](https://github.com/eea/volto-marine-policy/commit/17445e91fa8ff3c66ebabdbc6f3e474f643f6d03)]
18
+
19
+ #### :hammer_and_wrench: Others
20
+
21
+ - Demo Sites Explorer show indicators link in popup [laszlocseh - [`5214931`](https://github.com/eea/volto-marine-policy/commit/52149317e361ce8bd9b4e0adc9c17ec61b35ecc1)]
22
+ - Fix map popup [narcis2005 - [`dd99fd7`](https://github.com/eea/volto-marine-policy/commit/dd99fd7b3ff6327730690b6a5da262905e626593)]
23
+ - lint ignore line [Claudia Ifrim - [`5de8369`](https://github.com/eea/volto-marine-policy/commit/5de8369f3470ef3bb592fc851a44c90489771f84)]
24
+ - ol fix [Claudia Ifrim - [`8eacd1f`](https://github.com/eea/volto-marine-policy/commit/8eacd1f3121e593d645eaaa0e1b22fc84fe73ced)]
7
25
  ### [2.0.25](https://github.com/eea/volto-marine-policy/compare/2.0.24...2.0.25) - 27 August 2025
8
26
 
9
27
  #### :hammer_and_wrench: Others
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-marine-policy",
3
- "version": "2.0.25",
3
+ "version": "2.0.27",
4
4
  "description": "@eeacms/volto-marine-policy: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: IDM2 A-Team",
@@ -40,7 +40,7 @@
40
40
  "@eeacms/volto-globalsearch": "2.1.2",
41
41
  "@eeacms/volto-metadata-block": "*",
42
42
  "@eeacms/volto-openlayers-map": "1.0.1",
43
- "@eeacms/volto-searchlib": "2.1.8",
43
+ "@eeacms/volto-searchlib": "2.1.10",
44
44
  "@eeacms/volto-tabs-block": "*",
45
45
  "@eeacms/volto-workflow-progress": "*",
46
46
  "@plone-collective/volto-authomatic": "2.0.1",
@@ -77,7 +77,7 @@ export default function DemoSitesExplorerView(props) {
77
77
  activeFilters={activeFilters}
78
78
  hideFilters={hideFilters}
79
79
  setActiveFilters={setActiveFilters}
80
- map={map}
80
+ highlightedIndex={highlightedIndex}
81
81
  />
82
82
  </Grid.Row>
83
83
  <Grid.Row>
@@ -1,6 +1,30 @@
1
1
  import React from 'react';
2
2
 
3
3
  import { clearFilters } from './utils';
4
+ import { objectivesCustomOrder } from './utils';
5
+
6
+ const objectivesTargets = {
7
+ 'Objective 1: Protect and restore marine and freshwater ecosystems and biodiversity':
8
+ [
9
+ 'Contribute to relevant marine nature restoration targets including degraded seabed habitats and coastal ecosystems',
10
+ "Protect at least 30% of the EU's seas and integrate ecological corridors, as part of a true Trans-European Nature Network",
11
+ "Strictly protect at least 10% of the EU's seas",
12
+ 'Restore at least 25,000 km of free/flowing rivers',
13
+ ],
14
+ 'Objective 2: Prevent and eliminate pollution of our oceans, seas and waters':
15
+ [
16
+ 'Reduce nutrient losses by 50%',
17
+ 'Reduce the use and risk of chemical pesticides by 50%',
18
+ 'Reduce plastic litter at sea by 50%',
19
+ 'Reduce by 30% microplastics released into the environment',
20
+ ],
21
+ 'Objective 3: Make the sustainable blue economy carbon-neutral and circular':
22
+ [
23
+ 'Achieve net zero maritime emissions',
24
+ 'Promote circular, low-carbon multi-purpose use of marine and water space',
25
+ 'Develop zero-carbon and low-impact aquaculture',
26
+ ],
27
+ };
4
28
 
5
29
  const normalizeSearchInput = (searchInput) => {
6
30
  let normInput = searchInput
@@ -13,6 +37,25 @@ const normalizeSearchInput = (searchInput) => {
13
37
  return '\\b' + normInput + '\\b';
14
38
  };
15
39
 
40
+ const filterTargetsByObjective = (filters, filterName, highlightedIndex) => {
41
+ if (filterName !== 'target_filter') return filters;
42
+ if (highlightedIndex < 0 || highlightedIndex > 2) return filters;
43
+
44
+ let selectedObjective = objectivesCustomOrder[highlightedIndex];
45
+ let allowedTargets = objectivesTargets[selectedObjective] || [];
46
+
47
+ // Filter the targets based on the allowed ones
48
+ if (filters['target_filter']) {
49
+ filters['target_filter'] = Object.fromEntries(
50
+ Object.entries(filters['target_filter']).filter(([key]) =>
51
+ allowedTargets.includes(key),
52
+ ),
53
+ );
54
+ }
55
+
56
+ return filters;
57
+ };
58
+
16
59
  export function DemoSitesFilter(props) {
17
60
  const {
18
61
  filterTitle,
@@ -20,11 +63,15 @@ export function DemoSitesFilter(props) {
20
63
  activeFilters,
21
64
  setActiveFilters,
22
65
  filterName,
23
- // map,
66
+ highlightedIndex,
24
67
  } = props;
25
68
 
26
69
  const customOrder = props?.customOrder || [];
27
- const entries = Object.entries(filters?.[filterName] || {});
70
+ const entries = Object.entries(
71
+ filterTargetsByObjective(filters, filterName, highlightedIndex)?.[
72
+ filterName
73
+ ] || {},
74
+ );
28
75
  let sortedEntries = [];
29
76
 
30
77
  if (customOrder.length > 0) {
@@ -112,7 +159,13 @@ export function DemoSitesFilter(props) {
112
159
  }
113
160
 
114
161
  export function DemoSitesFilters(props) {
115
- const { filters, activeFilters, hideFilters, setActiveFilters, map } = props;
162
+ const {
163
+ filters,
164
+ activeFilters,
165
+ hideFilters,
166
+ setActiveFilters,
167
+ highlightedIndex,
168
+ } = props;
116
169
 
117
170
  React.useEffect(() => {
118
171
  window.addEventListener('click', (event) => {
@@ -148,7 +201,7 @@ export function DemoSitesFilters(props) {
148
201
  filters={filters}
149
202
  activeFilters={activeFilters}
150
203
  setActiveFilters={setActiveFilters}
151
- map={map}
204
+ highlightedIndex={highlightedIndex}
152
205
  />
153
206
  ) : (
154
207
  ''
@@ -160,7 +213,7 @@ export function DemoSitesFilters(props) {
160
213
  filters={filters}
161
214
  activeFilters={activeFilters}
162
215
  setActiveFilters={setActiveFilters}
163
- map={map}
216
+ highlightedIndex={highlightedIndex}
164
217
  />
165
218
  ) : (
166
219
  ''
@@ -171,7 +224,7 @@ export function DemoSitesFilters(props) {
171
224
  filters={filters}
172
225
  activeFilters={activeFilters}
173
226
  setActiveFilters={setActiveFilters}
174
- map={map}
227
+ highlightedIndex={highlightedIndex}
175
228
  />
176
229
  <DemoSitesFilter
177
230
  filterTitle="Country"
@@ -179,7 +232,7 @@ export function DemoSitesFilters(props) {
179
232
  filters={filters}
180
233
  activeFilters={activeFilters}
181
234
  setActiveFilters={setActiveFilters}
182
- map={map}
235
+ highlightedIndex={highlightedIndex}
183
236
  />
184
237
  </>
185
238
  );
@@ -326,7 +379,7 @@ export function ActiveFilters(props) {
326
379
  {activeFilters.objective_filter.map((filterCode) => {
327
380
  const filterLabel = filters.objective_filter[filterCode];
328
381
  return (
329
- <div className="ui basic label filter-value">
382
+ <div key={filterCode} className="ui basic label filter-value">
330
383
  <span>{filterLabel}</span>
331
384
  <i
332
385
  tabIndex="0"
@@ -352,7 +405,7 @@ export function ActiveFilters(props) {
352
405
  {activeFilters.target_filter.map((filterCode) => {
353
406
  const filterLabel = filters.target_filter[filterCode];
354
407
  return (
355
- <div className="ui basic label filter-value">
408
+ <div key={filterCode} className="ui basic label filter-value">
356
409
  <span>{filterLabel}</span>
357
410
  <i
358
411
  tabIndex="0"
@@ -377,7 +430,7 @@ export function ActiveFilters(props) {
377
430
  {activeFilters.indicator_filter.map((filterCode) => {
378
431
  const filterLabel = filters.indicator_filter[filterCode];
379
432
  return (
380
- <div className="ui basic label filter-value">
433
+ <div key={filterCode} className="ui basic label filter-value">
381
434
  <span>{filterLabel}</span>
382
435
  <i
383
436
  tabIndex="0"
@@ -402,7 +455,7 @@ export function ActiveFilters(props) {
402
455
  {activeFilters.project_filter.map((filterCode) => {
403
456
  const filterLabel = filters.project_filter[filterCode];
404
457
  return (
405
- <div className="ui basic label filter-value">
458
+ <div key={filterCode} className="ui basic label filter-value">
406
459
  <span>{filterLabel}</span>
407
460
  <i
408
461
  tabIndex="0"
@@ -427,7 +480,7 @@ export function ActiveFilters(props) {
427
480
  {activeFilters.country_filter.map((filterCode) => {
428
481
  const filterLabel = filters.country_filter[filterCode];
429
482
  return (
430
- <div className="ui basic label filter-value">
483
+ <div key={filterCode} className="ui basic label filter-value">
431
484
  <span>{filterLabel}</span>
432
485
  <i
433
486
  tabIndex="0"
@@ -102,13 +102,13 @@ export default function FeatureDisplay({ feature }) {
102
102
  {feature.indicators.map((item, index) => {
103
103
  return (
104
104
  <li key={index}>
105
- <span
106
- // target="_blank"
107
- // rel="noopener noreferrer"
108
- // href={item['path']}
105
+ <a
106
+ target="_blank"
107
+ rel="noopener noreferrer"
108
+ href={item['path']}
109
109
  >
110
110
  {item['title']}
111
- </span>
111
+ </a>
112
112
  </li>
113
113
  );
114
114
  })}
@@ -4,18 +4,12 @@ import { withOpenLayers } from '@eeacms/volto-openlayers-map';
4
4
  import FeatureDisplay from './FeatureDisplay';
5
5
  import { usePrevious } from '@plone/volto/helpers/Utils/usePrevious';
6
6
 
7
- function InfoOverlay({
8
- selectedFeature,
9
- onFeatureSelect,
10
- layerId,
11
- // hideFilters,
12
- ol,
13
- }) {
7
+ function InfoOverlay({ selectedFeature, onFeatureSelect, layerId, ol }) {
14
8
  const { map } = useMapContext();
15
- const [tooltip, setTooltipRef] = React.useState();
16
- const [showTooltip, setShowTooltip] = React.useState();
17
-
9
+ const [tooltip, setTooltipRef] = React.useState(null);
10
+ const overlayRef = React.useRef();
18
11
  const prevLayerId = usePrevious(layerId);
12
+ const [showTooltip, setShowTooltip] = React.useState(false);
19
13
 
20
14
  React.useEffect(() => {
21
15
  if (prevLayerId && layerId !== prevLayerId) {
@@ -24,10 +18,10 @@ function InfoOverlay({
24
18
  }, [layerId, prevLayerId]);
25
19
 
26
20
  React.useEffect(() => {
27
- if (!(map && tooltip)) return;
21
+ if (!(map && tooltip && ol.Overlay)) return;
28
22
 
29
- const overlay = new ol.Overlay({
30
- element: document.getElementById('popup-overlay'),
23
+ overlayRef.current = new ol.Overlay({
24
+ element: tooltip,
31
25
  positioning: 'bottom-left',
32
26
  offset: [0, 0],
33
27
  stopEvent: false,
@@ -36,7 +30,7 @@ function InfoOverlay({
36
30
  // duration: 250,
37
31
  // },
38
32
  });
39
- map.addOverlay(overlay);
33
+ map.addOverlay(overlayRef.current);
40
34
 
41
35
  function handler(evt) {
42
36
  const { pixel, target } = evt;
@@ -45,15 +39,13 @@ function InfoOverlay({
45
39
 
46
40
  if (features.length) {
47
41
  const coordinate = evt.coordinate;
48
- overlay.setPosition(coordinate);
42
+ overlayRef.current.setPosition(coordinate);
49
43
  setShowTooltip(true);
50
44
  } else {
51
- // const coordinate = evt.coordinate
52
- // overlay.setPosition(coordinate);
53
45
  // handle a click in an overlay popup
54
46
  if (evt.originalEvent.target.tagName === 'A') return;
47
+ overlayRef.current.setPosition(undefined);
55
48
  setShowTooltip(false);
56
- // popupOverlay.style.display = 'none';
57
49
  onFeatureSelect(null);
58
50
  }
59
51
  }
@@ -62,9 +54,11 @@ function InfoOverlay({
62
54
 
63
55
  return () => {
64
56
  map.un('click', handler);
65
- map.removeOverlay(overlay);
57
+ if (overlayRef.current) {
58
+ map.removeOverlay(overlayRef.current);
59
+ }
66
60
  };
67
- }, [map, tooltip, onFeatureSelect, ol]); //
61
+ }, [map, tooltip, onFeatureSelect, ol.Overlay]);
68
62
 
69
63
  const [isClient, setIsClient] = React.useState(false);
70
64
  React.useEffect(() => setIsClient(true), []);
@@ -259,6 +259,7 @@ const ObjectivesChart = ({
259
259
  <ul>
260
260
  {Object.entries(objectives).map(([item, count], index) => (
261
261
  <li
262
+ key={item?.id || index}
262
263
  className={cx(
263
264
  index === highlightedIndex ? 'active' : '',
264
265
  customColors[index].replace('#', 'C'),
@@ -231,7 +231,7 @@
231
231
 
232
232
  .filter-input {
233
233
  display: flex;
234
- align-items: center;
234
+ align-items: baseline;
235
235
  justify-content: flex-start;
236
236
  cursor: pointer;
237
237
  font-size: 14px;
@@ -88,7 +88,7 @@ export function zoomMapToFeatures({ map, features, ol, threshold = 500 }) {
88
88
  }
89
89
 
90
90
  export function getFeatures({ cases, ol }) {
91
- const Feature = ol.Feature;
91
+ const Feature = ol.Feature; // eslint-disable-line no-unused-vars
92
92
  const colors = {
93
93
  'Objective 1: Protect and restore marine and freshwater ecosystems and biodiversity':
94
94
  '#007b6c',
@@ -113,7 +113,7 @@ export function getFeatures({ cases, ol }) {
113
113
  const {
114
114
  geometry: { coordinates },
115
115
  } = c;
116
- const point = new Feature(
116
+ const point = new ol.ol.Feature(
117
117
  new ol.geom.Point(ol.proj.fromLonLat(coordinates)),
118
118
  );
119
119
  point.setId(index);