@eeacms/volto-marine-policy 2.0.5 → 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,27 @@ 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)]
18
+ ### [2.0.6](https://github.com/eea/volto-marine-policy/compare/2.0.5...2.0.6) - 14 April 2025
19
+
20
+ #### :house: Internal changes
21
+
22
+ - style: Automated code fix [eea-jenkins - [`ae829bf`](https://github.com/eea/volto-marine-policy/commit/ae829bf49e357dc02128ff0dc4227e146ed06c0d)]
23
+
24
+ #### :hammer_and_wrench: Others
25
+
26
+ - fix eslint [laszlocseh - [`6e84248`](https://github.com/eea/volto-marine-policy/commit/6e8424833cbe25badb6bc4ba040048422878895f)]
27
+ - updates to demo sites map viewer [laszlocseh - [`19dc3da`](https://github.com/eea/volto-marine-policy/commit/19dc3dac8ac9ef8f91961d0ecf7878cf7b9660a4)]
7
28
  ### [2.0.5](https://github.com/eea/volto-marine-policy/compare/2.0.4...2.0.5) - 11 April 2025
8
29
 
9
30
  #### :house: Internal changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-marine-policy",
3
- "version": "2.0.5",
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",
@@ -14,11 +14,12 @@ export default function DemoSitesExplorerView(props) {
14
14
  const cases_url = config.settings.prefixPath
15
15
  ? '/@@demo-sites-map.arcgis.json'
16
16
  : '/marine/@@demo-sites-map.arcgis.json';
17
-
18
17
  let cases = useCases(addAppURL(cases_url));
19
- const { demoSitesIds } = props; // case studies from measure view
20
18
  const [selectedCase, onSelectedCase] = React.useState(null);
21
- const hideFilters = demoSitesIds ? true : false;
19
+
20
+ const { properties } = props;
21
+ const hideFilters = properties['@type'] === 'indicator_mo' ? true : false;
22
+ const indicatorOnly = hideFilters ? properties['title'] : null;
22
23
 
23
24
  const [activeFilters, setActiveFilters] = React.useState({
24
25
  objective_filter: [],
@@ -32,7 +33,7 @@ export default function DemoSitesExplorerView(props) {
32
33
  const [map, setMap] = React.useState();
33
34
 
34
35
  React.useEffect(() => {
35
- const _filters = getFilters(cases);
36
+ const _filters = getFilters(cases, indicatorOnly);
36
37
  setFilters(_filters);
37
38
  }, [
38
39
  cases,
@@ -41,41 +42,39 @@ export default function DemoSitesExplorerView(props) {
41
42
  activeFilters.project_filter,
42
43
  activeFilters.country_filter,
43
44
  activeItems.length,
45
+ indicatorOnly,
44
46
  ]);
45
47
 
46
48
  React.useEffect(() => {
47
- let activeItems = filterCases(cases, activeFilters, demoSitesIds);
49
+ let activeItems = filterCases(cases, activeFilters, indicatorOnly);
48
50
 
49
51
  setActiveItems(activeItems);
50
- }, [demoSitesIds, activeFilters, cases]);
52
+ }, [activeFilters, cases, indicatorOnly]);
51
53
 
52
54
  if (__SERVER__) return '';
53
55
 
54
56
  return (
55
57
  <div className="searchlib-block">
56
58
  <Grid.Row>
57
- {hideFilters ? null : (
58
- <ActiveFilters
59
- filters={filters}
60
- activeFilters={activeFilters}
61
- setActiveFilters={setActiveFilters}
62
- />
63
- )}
59
+ <ActiveFilters
60
+ filters={filters}
61
+ activeFilters={activeFilters}
62
+ setActiveFilters={setActiveFilters}
63
+ />
64
64
  </Grid.Row>
65
65
  <Grid.Row stretched={true} id="cse-filter">
66
- {hideFilters ? null : (
67
- <DemoSitesFilters
68
- filters={filters}
69
- activeFilters={activeFilters}
70
- setActiveFilters={setActiveFilters}
71
- map={map}
72
- />
73
- )}
66
+ <DemoSitesFilters
67
+ filters={filters}
68
+ activeFilters={activeFilters}
69
+ hideFilters={hideFilters}
70
+ setActiveFilters={setActiveFilters}
71
+ map={map}
72
+ />
74
73
  </Grid.Row>
75
74
  <Grid.Row>
76
75
  {cases.length ? (
77
76
  <Grid columns={12}>
78
- <Grid.Column mobile={12} tablet={12} computer={12}>
77
+ <Grid.Column mobile={10} tablet={10} computer={10}>
79
78
  <DemoSitesMap
80
79
  items={cases}
81
80
  activeItems={activeItems}
@@ -86,6 +85,23 @@ export default function DemoSitesExplorerView(props) {
86
85
  setMap={setMap}
87
86
  />
88
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>
89
105
  </Grid>
90
106
  ) : null}
91
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}
@@ -101,7 +116,7 @@ export function DemoSitesFilter(props) {
101
116
  }
102
117
 
103
118
  export function DemoSitesFilters(props) {
104
- const { filters, activeFilters, setActiveFilters, map } = props;
119
+ const { filters, activeFilters, hideFilters, setActiveFilters, map } = props;
105
120
 
106
121
  React.useEffect(() => {
107
122
  window.addEventListener('click', (event) => {
@@ -117,24 +132,37 @@ export function DemoSitesFilters(props) {
117
132
 
118
133
  return (
119
134
  <>
120
- <DemoSitesFilter
121
- filterTitle="Objective"
122
- filterName="objective_filter"
123
- filters={filters}
124
- activeFilters={activeFilters}
125
- setActiveFilters={setActiveFilters}
126
- map={map}
127
- />
128
-
129
- <DemoSitesFilter
130
- filterTitle="Indicator"
131
- filterName="indicator_filter"
132
- filters={filters}
133
- activeFilters={activeFilters}
134
- setActiveFilters={setActiveFilters}
135
- map={map}
136
- />
137
-
135
+ {!hideFilters ? (
136
+ <DemoSitesFilter
137
+ filterTitle="Objective/Enabler"
138
+ filterName="objective_filter"
139
+ filters={filters}
140
+ activeFilters={activeFilters}
141
+ setActiveFilters={setActiveFilters}
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
+ ]}
150
+ />
151
+ ) : (
152
+ ''
153
+ )}
154
+ {!hideFilters ? (
155
+ <DemoSitesFilter
156
+ filterTitle="Indicator"
157
+ filterName="indicator_filter"
158
+ filters={filters}
159
+ activeFilters={activeFilters}
160
+ setActiveFilters={setActiveFilters}
161
+ map={map}
162
+ />
163
+ ) : (
164
+ ''
165
+ )}
138
166
  <DemoSitesFilter
139
167
  filterTitle="Project"
140
168
  filterName="project_filter"
@@ -143,7 +171,6 @@ export function DemoSitesFilters(props) {
143
171
  setActiveFilters={setActiveFilters}
144
172
  map={map}
145
173
  />
146
-
147
174
  <DemoSitesFilter
148
175
  filterTitle="Country"
149
176
  filterName="country_filter"
@@ -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
  );
@@ -126,23 +126,21 @@ export default function DemoSitesMap(props) {
126
126
  >
127
127
  <Controls attribution={false} />
128
128
  <Layers>
129
- {hideFilters ? null : (
130
- <button
131
- className={cx(
132
- 'reset-map-button ui button secondary',
133
- String(resetMapButtonClass),
134
- )}
135
- onClick={() => {
136
- // scrollToElement('search-input');
137
- onSelectedCase(null);
138
- centerAndResetMapZoom(map);
139
- map.getInteractions().array_[9].getFeatures().clear();
140
- }}
141
- >
142
- <span className="result-info-title">Reset map</span>
143
- <i className="icon ri-map-2-line"></i>
144
- </button>
145
- )}
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>
146
144
  <InfoOverlay
147
145
  selectedFeature={selectedCase}
148
146
  onFeatureSelect={onSelectedCase}
@@ -151,8 +149,8 @@ export default function DemoSitesMap(props) {
151
149
  />
152
150
  <FeatureInteraction
153
151
  onFeatureSelect={onSelectedCase}
154
- hideFilters={hideFilters}
155
- selectedCase={selectedCase}
152
+ // hideFilters={hideFilters}
153
+ // selectedCase={selectedCase}
156
154
  />
157
155
  <Layer.Tile source={tileWMSSources[0]} zIndex={0} />
158
156
  <Layer.Vector
@@ -170,10 +168,10 @@ export default function DemoSitesMap(props) {
170
168
  const selectedClusterStyle = (selectedFeature) => {
171
169
  function _clusterStyle(feature, selectedFeature) {
172
170
  const size = feature.get('features').length;
173
- let style = styleCache[size];
171
+ let clusterStyle = styleCache[size];
174
172
 
175
- if (!style) {
176
- style = new ol.style.Style({
173
+ if (!clusterStyle) {
174
+ clusterStyle = new ol.style.Style({
177
175
  image: new ol.style.Circle({
178
176
  radius: 12 + Math.min(Math.floor(size / 3), 10),
179
177
  stroke: new ol.style.Stroke({
@@ -191,10 +189,10 @@ const selectedClusterStyle = (selectedFeature) => {
191
189
  }),
192
190
  }),
193
191
  });
194
- styleCache[size] = style;
192
+ styleCache[size] = clusterStyle;
195
193
  }
196
-
197
- if (size === 1) {
194
+ // set size === 1 to enable clusterization
195
+ if (size) {
198
196
  let color = feature.values_.features[0].values_['color'];
199
197
  let width = feature.values_.features[0].values_['width'];
200
198
  let radius = feature.values_.features[0].values_['radius'];
@@ -214,7 +212,7 @@ const selectedClusterStyle = (selectedFeature) => {
214
212
  }),
215
213
  });
216
214
  } else {
217
- return style;
215
+ return clusterStyle;
218
216
  }
219
217
  }
220
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,10 +76,10 @@ export default function FeatureDisplay({ feature }) {
64
76
  </div>
65
77
  ) : (
66
78
  ''
67
- )}
79
+ )} */}
68
80
 
69
81
  <div>
70
- <h4>Indicators</h4>
82
+ <span className="popup-title blue">Indicators</span>
71
83
  <ul>
72
84
  {feature.indicators.map((item, index) => {
73
85
  return (
@@ -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: hideFilters ? null : selectStyle,
45
+ style: selectStyle,
50
46
  });
51
47
 
52
48
  React.useEffect(() => {
@@ -59,11 +55,10 @@ 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
- const url = window.location.origin + selectedFeature.path;
64
- // window.open(url);
65
- window.location.href = url;
66
- }
58
+ // if (hideFilters) {
59
+ // const url = window.location.origin + selectedFeature.path;
60
+ // window.location.href = url;
61
+ // }
67
62
  onFeatureSelect(selectedFeature);
68
63
  // scrollToElement('ol-map-container');
69
64
  // map.getView().animate({
@@ -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, hideFilters]);
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();
@@ -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
 
@@ -38,12 +42,13 @@ export default function InfoOverlay({
38
42
  const features = target.getFeaturesAtPixel(pixel);
39
43
  // const popupOverlay = overlay.element; // document.getElementById('popup-overlay');
40
44
 
41
- if (
42
- features.length &&
43
- !hideFilters // && !isCluster(features)
44
- ) {
45
+ if (features.length) {
46
+ const coordinate = evt.coordinate;
47
+ overlay.setPosition(coordinate);
45
48
  setShowTooltip(true);
46
49
  } else {
50
+ // const coordinate = evt.coordinate
51
+ // overlay.setPosition(coordinate);
47
52
  // handle a click in an overlay popup
48
53
  if (evt.originalEvent.target.tagName === 'A') return;
49
54
  setShowTooltip(false);
@@ -58,7 +63,7 @@ export default function InfoOverlay({
58
63
  map.un('click', handler);
59
64
  map.removeOverlay(overlay);
60
65
  };
61
- }, [map, tooltip, onFeatureSelect, hideFilters]); //
66
+ }, [map, tooltip, onFeatureSelect]); //
62
67
 
63
68
  const [isClient, setIsClient] = React.useState(false);
64
69
  React.useEffect(() => setIsClient(true), []);
@@ -67,7 +72,7 @@ export default function InfoOverlay({
67
72
  <div
68
73
  id="popup-overlay"
69
74
  style={{
70
- position: 'absolute',
75
+ // position: 'absolute', // TODO POPUP
71
76
  zIndex: 1,
72
77
  visibility: showTooltip ? 'visible' : 'hidden',
73
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,
@@ -98,15 +98,22 @@ export function getFeatures(cases) {
98
98
  });
99
99
  }
100
100
 
101
- export function filterCases(cases, activeFilters, demoSitesIds) {
101
+ export function filterCases(cases, activeFilters, indicatorOnly) {
102
102
  const data = cases.filter((_case) => {
103
103
  let flag_objective = false;
104
104
  let flag_indicator = false;
105
105
  let flag_project = false;
106
106
  let flag_country = false;
107
- let flag_case = demoSitesIds
108
- ? demoSitesIds.includes(_case.properties.url.split('/').pop())
109
- : true;
107
+ let flag_indicatorOnly = false;
108
+
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;
114
+ } else {
115
+ flag_indicatorOnly = true;
116
+ }
110
117
 
111
118
  // debugger;
112
119
  if (!activeFilters.objective_filter.length) {
@@ -123,7 +130,7 @@ export function filterCases(cases, activeFilters, demoSitesIds) {
123
130
  flag_indicator = true;
124
131
  } else {
125
132
  let indicators = _case.properties.indicators?.map((item) => {
126
- return item['id'].toString();
133
+ return '_' + item['id'].toString();
127
134
  });
128
135
 
129
136
  activeFilters.indicator_filter.forEach((filter) => {
@@ -153,7 +160,7 @@ export function filterCases(cases, activeFilters, demoSitesIds) {
153
160
  });
154
161
  }
155
162
 
156
- return flag_case &&
163
+ return flag_indicatorOnly &&
157
164
  flag_objective &&
158
165
  flag_indicator &&
159
166
  flag_country &&
@@ -165,7 +172,7 @@ export function filterCases(cases, activeFilters, demoSitesIds) {
165
172
  return data;
166
173
  }
167
174
 
168
- export function getFilters(cases) {
175
+ export function getFilters(cases, indicatorOnly) {
169
176
  let _filters = {
170
177
  objective_filter: {},
171
178
  indicator_filter: {},
@@ -181,9 +188,9 @@ export function getFilters(cases) {
181
188
  indicators.map((item) => {
182
189
  if (
183
190
  item['title'] &&
184
- !_filters.indicator_filter.hasOwnProperty(item['id'])
191
+ !_filters.indicator_filter.hasOwnProperty('_' + item['id'])
185
192
  ) {
186
- _filters.indicator_filter[item['id']] = item['title'];
193
+ _filters.indicator_filter['_' + item['id']] = item['title'];
187
194
  }
188
195
  return [];
189
196
  });
@@ -195,13 +202,33 @@ export function getFilters(cases) {
195
202
 
196
203
  let project = _case.properties.project;
197
204
  if (project && !_filters.project_filter.hasOwnProperty(project)) {
198
- _filters.project_filter[project] = 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;
199
216
  }
200
217
 
201
218
  let countries = _case.properties.country || [];
202
219
  countries.map((item) => {
203
220
  if (item && !_filters.country_filter.hasOwnProperty(item)) {
204
- _filters.country_filter[item] = 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;
205
232
  }
206
233
  return [];
207
234
  });