@eeacms/volto-marine-policy 2.0.6 → 2.0.7

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,17 @@ 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.7](https://github.com/eea/volto-marine-policy/compare/2.0.6...2.0.7) - 15 April 2025
8
+
9
+ #### :house: Internal changes
10
+
11
+ - style: Automated code fix [eea-jenkins - [`cb0de80`](https://github.com/eea/volto-marine-policy/commit/cb0de8004429b3dbeee35a1a35c098bec9ee5f4c)]
12
+ - style: Automated code fix [eea-jenkins - [`c91d18b`](https://github.com/eea/volto-marine-policy/commit/c91d18b6ee31c0a7406d41c69693f4cca87ffb2a)]
13
+
14
+ #### :hammer_and_wrench: Others
15
+
16
+ - pylint [laszlocseh - [`20a0b87`](https://github.com/eea/volto-marine-policy/commit/20a0b87ceda212c7cf9a6d2681e21dfe2546f881)]
17
+ - improvements to demo sites map viewer [laszlocseh - [`501420b`](https://github.com/eea/volto-marine-policy/commit/501420b5c8373f6bc79f31947a2275921ccd9dcf)]
7
18
  ### [2.0.6](https://github.com/eea/volto-marine-policy/compare/2.0.5...2.0.6) - 14 April 2025
8
19
 
9
20
  #### :house: Internal changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-marine-policy",
3
- "version": "2.0.6",
3
+ "version": "2.0.7",
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",
@@ -74,7 +74,7 @@ export default function DemoSitesExplorerView(props) {
74
74
  <Grid.Row>
75
75
  {cases.length ? (
76
76
  <Grid columns={12}>
77
- <Grid.Column mobile={12} tablet={12} computer={12}>
77
+ <Grid.Column mobile={10} tablet={10} computer={10}>
78
78
  <DemoSitesMap
79
79
  items={cases}
80
80
  activeItems={activeItems}
@@ -85,6 +85,23 @@ export default function DemoSitesExplorerView(props) {
85
85
  setMap={setMap}
86
86
  />
87
87
  </Grid.Column>
88
+ <Grid.Column mobile={2} tablet={2} computer={2}>
89
+ <div className="legend">
90
+ <div className="legend-row legend-subtitle">Legend</div>
91
+ <div className="legend-row">
92
+ <div className="circle">
93
+ <div className="dot-demosite"></div>
94
+ </div>
95
+ <div>Demo site</div>
96
+ </div>
97
+ <div className="legend-row">
98
+ <div className="circle">
99
+ <div className="dot-region"></div>
100
+ </div>
101
+ <div>Associated region</div>
102
+ </div>
103
+ </div>
104
+ </Grid.Column>
88
105
  </Grid>
89
106
  ) : null}
90
107
  </Grid.Row>
@@ -23,6 +23,21 @@ export function DemoSitesFilter(props) {
23
23
  map,
24
24
  } = props;
25
25
 
26
+ const customOrder = props?.customOrder || [];
27
+ const entries = Object.entries(filters?.[filterName] || {});
28
+ let sortedEntries = [];
29
+
30
+ if (customOrder.length > 0) {
31
+ sortedEntries = entries.sort(
32
+ (a, b) => customOrder.indexOf(a[0]) - customOrder.indexOf(b[0]),
33
+ );
34
+ // if(entries.length > 0 ) debugger;
35
+ } else {
36
+ sortedEntries = entries.sort((a, b) => a[1].localeCompare(b[1]));
37
+ }
38
+ const sortedData = Object.fromEntries(sortedEntries);
39
+ filters[filterName] = sortedData;
40
+
26
41
  const showInputs = (event) => {
27
42
  event.currentTarget.parentElement.classList.add('active');
28
43
  };
@@ -65,7 +80,7 @@ export function DemoSitesFilter(props) {
65
80
 
66
81
  <div className="filter-inputs">
67
82
  {Object.entries(filters?.[filterName] || {})
68
- .sort((item1, item2) => item1[1].localeCompare(item2[1]))
83
+ // .sort((item1, item2) => item1[1].localeCompare(item2[1]))
69
84
  .map(([value, label], index) => (
70
85
  <label
71
86
  htmlFor={label + index}
@@ -119,12 +134,19 @@ export function DemoSitesFilters(props) {
119
134
  <>
120
135
  {!hideFilters ? (
121
136
  <DemoSitesFilter
122
- filterTitle="Objective"
137
+ filterTitle="Objective/Enabler"
123
138
  filterName="objective_filter"
124
139
  filters={filters}
125
140
  activeFilters={activeFilters}
126
141
  setActiveFilters={setActiveFilters}
127
142
  map={map}
143
+ customOrder={[
144
+ 'Protect and restore marine and freshwater ecosystems',
145
+ 'Prevent and eliminate pollution of waters',
146
+ 'Carbon-neutral and circular blue economy',
147
+ 'Digital twin of the ocean',
148
+ 'Public mobilisation and engagement',
149
+ ]}
128
150
  />
129
151
  ) : (
130
152
  ''
@@ -54,7 +54,7 @@ export default function DemoSitesMap(props) {
54
54
 
55
55
  const [clusterSource] = React.useState(
56
56
  new ol.source.Cluster({
57
- distance: 19,
57
+ distance: 0,
58
58
  source: pointsSource,
59
59
  }),
60
60
  );
@@ -168,10 +168,10 @@ export default function DemoSitesMap(props) {
168
168
  const selectedClusterStyle = (selectedFeature) => {
169
169
  function _clusterStyle(feature, selectedFeature) {
170
170
  const size = feature.get('features').length;
171
- let style = styleCache[size];
171
+ let clusterStyle = styleCache[size];
172
172
 
173
- if (!style) {
174
- style = new ol.style.Style({
173
+ if (!clusterStyle) {
174
+ clusterStyle = new ol.style.Style({
175
175
  image: new ol.style.Circle({
176
176
  radius: 12 + Math.min(Math.floor(size / 3), 10),
177
177
  stroke: new ol.style.Stroke({
@@ -189,10 +189,10 @@ const selectedClusterStyle = (selectedFeature) => {
189
189
  }),
190
190
  }),
191
191
  });
192
- styleCache[size] = style;
192
+ styleCache[size] = clusterStyle;
193
193
  }
194
-
195
- if (size === 1) {
194
+ // set size === 1 to enable clusterization
195
+ if (size) {
196
196
  let color = feature.values_.features[0].values_['color'];
197
197
  let width = feature.values_.features[0].values_['width'];
198
198
  let radius = feature.values_.features[0].values_['radius'];
@@ -212,7 +212,7 @@ const selectedClusterStyle = (selectedFeature) => {
212
212
  }),
213
213
  });
214
214
  } else {
215
- return style;
215
+ return clusterStyle;
216
216
  }
217
217
  }
218
218
  return _clusterStyle;
@@ -39,13 +39,25 @@ export default function FeatureDisplay({ feature }) {
39
39
  {feature.project ? (
40
40
  <div>
41
41
  <span className="popup-title blue">Project: </span>
42
- <span>{feature.project}</span>
42
+ <span>
43
+ {isValidURL(feature.project_link) ? (
44
+ <a
45
+ href={feature.project_link}
46
+ target="_blank"
47
+ rel="noopener noreferrer"
48
+ >
49
+ {feature.project}
50
+ </a>
51
+ ) : (
52
+ <span>{feature.project}</span>
53
+ )}
54
+ </span>
43
55
  </div>
44
56
  ) : (
45
57
  ''
46
58
  )}
47
59
 
48
- {feature.project_link ? (
60
+ {/* {feature.project_link ? (
49
61
  <div>
50
62
  <span className="popup-title blue">Project link: </span>
51
63
  <span>
@@ -64,7 +76,7 @@ export default function FeatureDisplay({ feature }) {
64
76
  </div>
65
77
  ) : (
66
78
  ''
67
- )}
79
+ )} */}
68
80
 
69
81
  <div>
70
82
  <span className="popup-title blue">Indicators</span>
@@ -27,9 +27,13 @@ export default function InfoOverlay({
27
27
 
28
28
  const overlay = new ol.Overlay({
29
29
  element: document.getElementById('popup-overlay'),
30
- positioning: 'bottom-center',
31
- offset: [0, -10],
30
+ positioning: 'bottom-left',
31
+ offset: [0, 0],
32
32
  stopEvent: false,
33
+ // autoPan: true,
34
+ // autoPanAnimation: {
35
+ // duration: 250,
36
+ // },
33
37
  });
34
38
  map.addOverlay(overlay);
35
39
 
@@ -39,8 +43,12 @@ export default function InfoOverlay({
39
43
  // const popupOverlay = overlay.element; // document.getElementById('popup-overlay');
40
44
 
41
45
  if (features.length) {
46
+ const coordinate = evt.coordinate;
47
+ overlay.setPosition(coordinate);
42
48
  setShowTooltip(true);
43
49
  } else {
50
+ // const coordinate = evt.coordinate
51
+ // overlay.setPosition(coordinate);
44
52
  // handle a click in an overlay popup
45
53
  if (evt.originalEvent.target.tagName === 'A') return;
46
54
  setShowTooltip(false);
@@ -64,7 +72,7 @@ export default function InfoOverlay({
64
72
  <div
65
73
  id="popup-overlay"
66
74
  style={{
67
- position: 'absolute',
75
+ // position: 'absolute', // TODO POPUP
68
76
  zIndex: 1,
69
77
  visibility: showTooltip ? 'visible' : 'hidden',
70
78
  }}
@@ -16,9 +16,9 @@
16
16
 
17
17
  #csepopup {
18
18
  // width: 300px;
19
- width: 100%;
19
+ // width: 100%;
20
20
  // height: 100%;
21
- padding: 1em;
21
+ padding: 1em 1em 0 1em;
22
22
  // border: 1px solid black;
23
23
  // font-size: 14px;
24
24
  // line-height: initial;
@@ -37,7 +37,7 @@
37
37
  }
38
38
 
39
39
  div {
40
- margin-bottom: 16px;
40
+ margin-bottom: 1em;
41
41
  }
42
42
 
43
43
  ul {
@@ -75,27 +75,35 @@
75
75
  }
76
76
  }
77
77
 
78
+ .ol-viewport {
79
+ overflow: visible !important;
80
+ }
81
+
78
82
  .ol-overlaycontainer {
79
83
  // width: 370px;
80
84
  // height: 100%;
85
+ z-index: 10 !important;
81
86
 
82
87
  .ol-overlay-container {
83
88
  // position: relative !important;
84
- position: absolute !important;
85
- right: 30px;
86
- bottom: 30px;
87
- display: block !important;
89
+ // TODO POPUP
90
+ // position: absolute !important;
91
+ // right: 30px;
92
+ // bottom: 30px;
93
+ // display: block !important;
88
94
  // width: 100%;
89
95
  // height: 100%;
90
- background-color: #fefefe;
91
-
92
- #popup-overlay {
93
- position: relative !important;
94
- display: flex;
95
- width: 100%;
96
- height: 100%;
97
- align-items: center;
98
- }
96
+ background-color: #fafafa;
97
+ // border: 1px solid #004B7F;
98
+
99
+ // TODO POPUP
100
+ // #popup-overlay {
101
+ // position: relative !important;
102
+ // display: flex;
103
+ // width: 100%;
104
+ // height: 100%;
105
+ // align-items: center;
106
+ // }
99
107
  }
100
108
  }
101
109
 
@@ -132,7 +140,7 @@
132
140
 
133
141
  .ui.basic.button.facet-btn {
134
142
  position: relative !important;
135
- z-index: 99999;
143
+ z-index: 9;
136
144
  display: inline-block;
137
145
  overflow: hidden;
138
146
  padding: 0.5em 0em;
@@ -154,7 +162,7 @@
154
162
 
155
163
  span {
156
164
  position: relative !important;
157
- z-index: 99999;
165
+ z-index: 9;
158
166
  display: inline-block;
159
167
  overflow: hidden;
160
168
  padding: 0.5em 1em;
@@ -317,6 +325,10 @@
317
325
  }
318
326
  }
319
327
 
328
+ .active-filter-list {
329
+ width: 100%;
330
+ }
331
+
320
332
  .sui-search-box .search-input .terms-box .terms-box-left .search-icon img {
321
333
  fill: #004b7f !important;
322
334
  }
@@ -374,3 +386,56 @@
374
386
  background-color: rgba(0, 131, 224, 0.5);
375
387
  }
376
388
  }
389
+
390
+ .legend {
391
+ position: absolute;
392
+ bottom: 2em;
393
+ display: flex;
394
+ flex-direction: column;
395
+ align-items: flex-start;
396
+ gap: 0.5em;
397
+
398
+ .legend-row {
399
+ display: flex;
400
+ align-items: center;
401
+ gap: 0.5em;
402
+ }
403
+
404
+ .legend-subtitle {
405
+ font-size: 1.3em;
406
+ font-weight: 500;
407
+ }
408
+
409
+ .circle {
410
+ position: relative;
411
+ width: 22px;
412
+ min-width: 22px;
413
+ height: 22px;
414
+ /* dark green shade */
415
+ border-radius: 50%;
416
+ background-color: #007265;
417
+ gap: 0.5em;
418
+ }
419
+
420
+ .dot-demosite {
421
+ position: absolute;
422
+ top: 50%;
423
+ left: 50%;
424
+ width: 8px;
425
+ height: 8px;
426
+ border-radius: 50%;
427
+ background-color: white;
428
+ transform: translate(-50%, -50%);
429
+ }
430
+
431
+ .dot-region {
432
+ position: absolute;
433
+ top: 50%;
434
+ left: 50%;
435
+ width: 2px;
436
+ height: 2px;
437
+ border-radius: 50%;
438
+ background-color: white;
439
+ transform: translate(-50%, -50%);
440
+ }
441
+ }
@@ -48,11 +48,11 @@ export function zoomMapToFeatures(map, features, threshold = 500) {
48
48
  export function getFeatures(cases) {
49
49
  const Feature = ol.ol.Feature;
50
50
  const colors = {
51
- 'Carbon-neutral and circular blue economy': '#004b7f',
51
+ 'Carbon-neutral and circular blue economy': '#f9eb8a',
52
52
  'Digital twin of the ocean': '#004b7f',
53
53
  'Prevent and eliminate pollution of waters': '#fdaf20',
54
54
  'Protect and restore marine and freshwater ecosystems': '#007b6c',
55
- 'Public mobilisation and engagement': '#004b7f',
55
+ 'Public mobilisation and engagement': '#9e83b6',
56
56
  };
57
57
  const width = {
58
58
  'Demo site': 6,
@@ -130,7 +130,7 @@ export function filterCases(cases, activeFilters, indicatorOnly) {
130
130
  flag_indicator = true;
131
131
  } else {
132
132
  let indicators = _case.properties.indicators?.map((item) => {
133
- return item['id'].toString();
133
+ return '_' + item['id'].toString();
134
134
  });
135
135
 
136
136
  activeFilters.indicator_filter.forEach((filter) => {
@@ -188,9 +188,9 @@ export function getFilters(cases, indicatorOnly) {
188
188
  indicators.map((item) => {
189
189
  if (
190
190
  item['title'] &&
191
- !_filters.indicator_filter.hasOwnProperty(item['id'])
191
+ !_filters.indicator_filter.hasOwnProperty('_' + item['id'])
192
192
  ) {
193
- _filters.indicator_filter[item['id']] = item['title'];
193
+ _filters.indicator_filter['_' + item['id']] = item['title'];
194
194
  }
195
195
  return [];
196
196
  });