@eeacms/volto-cca-policy 0.3.107 → 0.3.109

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,20 @@ 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.3.109](https://github.com/eea/volto-cca-policy/compare/0.3.108...0.3.109) - 1 April 2026
8
+
9
+ #### :nail_care: Enhancements
10
+
11
+ - change: update gridBlock configuration - refs #302003 [kreafox - [`86e8002`](https://github.com/eea/volto-cca-policy/commit/86e80026e0f5bda7d0dd137aeeac0ebe2bef9063)]
12
+ - change: add info message on AdaptationOptionView - refs #296805 [kreafox - [`e7a8710`](https://github.com/eea/volto-cca-policy/commit/e7a8710d74b235a5254b938549dcf781343a7793)]
13
+ - refactor: move blocks configuration [kreafox - [`34f9415`](https://github.com/eea/volto-cca-policy/commit/34f94157d77524f57c2f7d2b7ab98d40f424c6a6)]
14
+
15
+ ### [0.3.108](https://github.com/eea/volto-cca-policy/compare/0.3.107...0.3.108) - 31 March 2026
16
+
17
+ #### :bug: Bug Fixes
18
+
19
+ - fix: active state in collection stats block, style improvements - refs #269021 [kreafox - [`408ec1c`](https://github.com/eea/volto-cca-policy/commit/408ec1cec816f626af0b14fe45fde3094ea9aafc)]
20
+
7
21
  ### [0.3.107](https://github.com/eea/volto-cca-policy/compare/0.3.106...0.3.107) - 30 March 2026
8
22
 
9
23
  #### :rocket: New Features
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-cca-policy",
3
- "version": "0.3.107",
3
+ "version": "0.3.109",
4
4
  "description": "@eeacms/volto-cca-policy: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: IDM2 A-Team",
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { useSelector, useDispatch } from 'react-redux';
3
+ import { useLocation } from 'react-router-dom';
3
4
  import { getQueryStats } from '@eeacms/volto-cca-policy/store';
4
5
  import { getBaseUrl as getBase } from '@eeacms/volto-cca-policy/utils';
5
6
  import { getBaseUrl } from '@plone/volto/helpers';
@@ -25,7 +26,8 @@ const useStats = (path, id, data) => {
25
26
 
26
27
  export const StatVoltoIcon = ({ name, value, source, showLabel = false }) => {
27
28
  const intl = useIntl();
28
- const label = intl.formatMessage({ id: name });
29
+ const label = intl.formatMessage({ id: name, defaultMessage: name });
30
+
29
31
  return (
30
32
  <div className="tab-icon" title={label}>
31
33
  <div className="tab-icon-wrapper">
@@ -41,6 +43,7 @@ export const StatVoltoIcon = ({ name, value, source, showLabel = false }) => {
41
43
  export const RemixIcon = ({ name, value, source, showLabel = false }) => {
42
44
  const intl = useIntl();
43
45
  const label = intl.formatMessage({ id: name, defaultMessage: name });
46
+
44
47
  return (
45
48
  <div className="tab-icon semantic-icon" title={label}>
46
49
  <div className="tab-icon-wrapper">
@@ -52,7 +55,7 @@ export const RemixIcon = ({ name, value, source, showLabel = false }) => {
52
55
  );
53
56
  };
54
57
 
55
- const makeSearchBlockQuery = ({ base, query, field, value }) => {
58
+ const makeSearchBlockQuery = ({ base, query = [], field, value }) => {
56
59
  const filtered = [
57
60
  ...query.filter(({ i }) => i !== field),
58
61
  {
@@ -61,8 +64,8 @@ const makeSearchBlockQuery = ({ base, query, field, value }) => {
61
64
  v: [value],
62
65
  },
63
66
  ];
64
- const params = qs.stringify({ query: JSON.stringify(filtered) });
65
67
 
68
+ const params = qs.stringify({ query: JSON.stringify(filtered) });
66
69
  return `${base}?${params}`;
67
70
  };
68
71
 
@@ -103,17 +106,48 @@ function remapItemTypeValue(val) {
103
106
  'Publication and report': 'Publication reference',
104
107
  'Video and podcast': 'Video',
105
108
  };
106
- if (val in list) {
107
- return list[val];
109
+
110
+ return list[val] || val;
111
+ }
112
+
113
+ function getActiveFilters(locationSearch) {
114
+ try {
115
+ const params = new URLSearchParams(locationSearch);
116
+ const queryParam = params.get('query');
117
+ if (!queryParam) return [];
118
+
119
+ const parsed = JSON.parse(queryParam);
120
+ return Array.isArray(parsed) ? parsed : [];
121
+ } catch (e) {
122
+ return [];
108
123
  }
109
- return val;
124
+ }
125
+
126
+ function isFilterActive(activeFilters, field, value) {
127
+ return activeFilters.some(
128
+ (f) =>
129
+ f?.i === field &&
130
+ Array.isArray(f?.v) &&
131
+ f.v.includes(value) &&
132
+ f?.o === 'plone.app.querystring.operation.selection.any',
133
+ );
110
134
  }
111
135
 
112
136
  export default function CollectionStatsView(props) {
113
137
  const { id, data = {}, pathname = props.path } = props;
114
- const field = data.aggregateField?.value;
138
+ const field =
139
+ typeof data.aggregateField === 'string'
140
+ ? data.aggregateField
141
+ : data.aggregateField?.value;
142
+
115
143
  const { queryParameterStyle = 'SearchBlock', query = {}, showLabel } = data;
116
144
  const base = getBase(props);
145
+ const location = useLocation();
146
+ const activeFilters = React.useMemo(
147
+ () => getActiveFilters(location.search),
148
+ [location.search],
149
+ );
150
+
117
151
  let stats = useStats(getBaseUrl(pathname), id, data);
118
152
  const intl = useIntl();
119
153
 
@@ -128,26 +162,37 @@ export default function CollectionStatsView(props) {
128
162
  const extraFilters = data?.extraFilters || [];
129
163
 
130
164
  return (
131
- (field && keys.length > 0 && (
165
+ (field && keys.length > 0 && IconComponent && (
132
166
  <div className="collection-stats">
133
167
  {keys
134
168
  .sort((a, b) => a.localeCompare(b))
135
169
  .map((k) => {
136
- let kV = remapItemTypeValue(k);
170
+ const kV = remapItemTypeValue(k);
171
+ const currentField = groupDefinition.searchFieldName || field;
172
+ const currentValue = intl.formatMessage({
173
+ id: kV,
174
+ defaultMessage: kV,
175
+ });
176
+
177
+ const href = urlHandler({
178
+ base,
179
+ query: query.query,
180
+ field: currentField,
181
+ value: currentValue,
182
+ extraFilters,
183
+ });
184
+
185
+ const active = isFilterActive(
186
+ activeFilters,
187
+ currentField,
188
+ currentValue,
189
+ );
190
+
137
191
  return (
138
192
  <UniversalLink
139
- className="tab-item-link"
193
+ className={`tab-item-link ${active ? 'active' : ''}`}
140
194
  key={k}
141
- href={urlHandler({
142
- base,
143
- query: query.query,
144
- field: groupDefinition.searchFieldName || field,
145
- value: intl.formatMessage({
146
- id: kV,
147
- defaultMessage: kV,
148
- }),
149
- extraFilters,
150
- })}
195
+ href={href}
151
196
  >
152
197
  <IconComponent
153
198
  name={k}
@@ -33,14 +33,23 @@ body.cca-main-homepage {
33
33
  display: inline-block;
34
34
  }
35
35
 
36
- .tab-item-link:hover {
37
- .count {
38
- background-color: @ccaGreenColor;
36
+ .tab-item-link {
37
+ &:hover,
38
+ &.active {
39
+ .count {
40
+ background-color: @ccaGreenColor;
41
+ }
42
+
43
+ .tab-icon,
44
+ .label {
45
+ color: @primaryColor;
46
+ }
39
47
  }
40
48
 
41
- .tab-icon,
42
- .label {
43
- color: @primaryColor;
49
+ &.active {
50
+ .label {
51
+ font-weight: 500;
52
+ }
44
53
  }
45
54
  }
46
55
 
@@ -1,4 +1,5 @@
1
1
  import { compose } from 'redux';
2
+ import { blockAvailableInMission } from '@eeacms/volto-cca-policy/utils';
2
3
 
3
4
  import installECDEIndicatorsBlock from './ECDEIndicators';
4
5
  import installCaseStudyExplorerBlock from './CaseStudyExplorer';
@@ -21,14 +22,46 @@ import installContentLinks from './ContentLinks';
21
22
  import installASTNavigation from './ASTNavigation';
22
23
  import installFlourishEmbedBlock from './FlourishEmbedBlock';
23
24
  import installDataConnectedEmbed from './DataConnectedEmbedBlock';
24
-
25
- // import installCountryMapHeatIndex from './CountryMapHeatIndex';
26
25
  import installCountryMapProfile from './CountryMapProfile';
27
26
 
28
27
  export default function installBlocks(config) {
29
28
  config.blocks.blocksConfig.title.restricted = false;
30
29
  config.blocks.blocksConfig.layoutSettings.restricted = false;
31
30
 
31
+ if (config.blocks.blocksConfig.maps) {
32
+ config.blocks.blocksConfig.maps.restricted = false;
33
+ }
34
+
35
+ if (config.blocks.blocksConfig.layoutSettings) {
36
+ config.blocks.blocksConfig.layoutSettings.blockHasOwnFocusManagement = false;
37
+ }
38
+
39
+ if (config.blocks.blocksConfig.video) {
40
+ config.blocks.blocksConfig.video.restricted = false;
41
+ }
42
+
43
+ config.blocks.blocksConfig.nextCloudVideo = {
44
+ ...config.blocks.blocksConfig.nextCloudVideo,
45
+ whiteList: [
46
+ 'https://cmshare.eea.europa.eu',
47
+ 'https://shareit.eea.europa.eu',
48
+ ],
49
+ };
50
+
51
+ if (config.blocks.blocksConfig.countryFlag) {
52
+ config.blocks.blocksConfig.countryFlag = {
53
+ ...config.blocks.blocksConfig.countryFlag,
54
+ restricted: ({ properties, block }) => {
55
+ return blockAvailableInMission(properties, block);
56
+ },
57
+ };
58
+ }
59
+
60
+ config.blocks.blocksConfig.gridBlock = {
61
+ ...config.blocks.blocksConfig.gridBlock,
62
+ maxLength: 6,
63
+ };
64
+
32
65
  // override the noResultsComponent to avoid the "No results" text
33
66
  config.blocks.blocksConfig['listing'].noResultsComponent = () => null;
34
67
 
@@ -55,7 +88,5 @@ export default function installBlocks(config) {
55
88
  installCountryMapProfile,
56
89
  installFlourishEmbedBlock,
57
90
  installDataConnectedEmbed,
58
- // installMKHMap,
59
- // installCountryMapHeatIndex,
60
91
  )(config);
61
92
  }
@@ -184,6 +184,17 @@ function AdaptationOptionView(props) {
184
184
 
185
185
  <Container>
186
186
  <PortalMessage content={content} />
187
+
188
+ <div className="styled-group info-section">
189
+ <p>
190
+ <span className="small-text">
191
+ This page is currently under construction, so it may look a bit
192
+ different than you're used to. We're in the process of preparing a
193
+ new layout to improve your experience. A fresh new look for the
194
+ adaptation options pages is coming soon.
195
+ </span>
196
+ </p>
197
+ </div>
187
198
  <Grid>
188
199
  <Grid.Row columns={12}>
189
200
  <Grid.Column
package/src/index.js CHANGED
@@ -11,7 +11,6 @@ import {
11
11
  MissionSignatoryProfileView,
12
12
  ImageWidget,
13
13
  } from '@eeacms/volto-cca-policy/components';
14
- import { blockAvailableInMission } from '@eeacms/volto-cca-policy/utils';
15
14
 
16
15
  import CcaEventView from './components/theme/Views/CcaEventView';
17
16
  import NewsItemView from './components/theme/Views/NewsItemView';
@@ -312,30 +311,6 @@ const applyConfig = (config) => {
312
311
  websiteTitle: 'Climate-ADAPT',
313
312
  };
314
313
 
315
- // Enable volto-embed
316
- if (config.blocks.blocksConfig.maps) {
317
- config.blocks.blocksConfig.maps.restricted = false;
318
- }
319
-
320
- if (config.blocks.blocksConfig.layoutSettings) {
321
- config.blocks.blocksConfig.layoutSettings.blockHasOwnFocusManagement = false;
322
- }
323
-
324
- // Enable video
325
- if (config.blocks.blocksConfig.video) {
326
- config.blocks.blocksConfig.video.restricted = false;
327
- }
328
-
329
- // Disable blocks on Mission
330
- if (config.blocks.blocksConfig.countryFlag) {
331
- config.blocks.blocksConfig.countryFlag = {
332
- ...config.blocks.blocksConfig.countryFlag,
333
- restricted: ({ properties, block }) => {
334
- return blockAvailableInMission(properties, block);
335
- },
336
- };
337
- }
338
-
339
314
  const { facetWidgets } = config.blocks.blocksConfig.search.extensions;
340
315
  const { rewriteOptions } = facetWidgets;
341
316
  const origin_website_blacklist = ['AdapteCCA', 'DRMKC'];
@@ -372,14 +347,6 @@ const applyConfig = (config) => {
372
347
  }
373
348
  }
374
349
 
375
- config.blocks.blocksConfig.nextCloudVideo = {
376
- ...config.blocks.blocksConfig.nextCloudVideo,
377
- whiteList: [
378
- 'https://cmshare.eea.europa.eu',
379
- 'https://shareit.eea.europa.eu',
380
- ],
381
- };
382
-
383
350
  config.blocks.groupBlocksOrder.push({ id: 'site', title: 'Site' });
384
351
 
385
352
  config.views.contentTypesViews = {
@@ -154,3 +154,22 @@
154
154
  }
155
155
  }
156
156
  }
157
+
158
+ #main .block.search {
159
+ .ui.accordion.filter-listing {
160
+ .filter-list-content {
161
+ padding: 0.5em 1em !important;
162
+ margin-top: 0.5em;
163
+ background: none;
164
+ }
165
+
166
+ .filter-list-group {
167
+ margin: 0;
168
+
169
+ .label {
170
+ color: inherit;
171
+ border-color: #eaeaea;
172
+ }
173
+ }
174
+ }
175
+ }
@@ -416,3 +416,18 @@ iframe {
416
416
  text-align: left;
417
417
  }
418
418
  }
419
+
420
+ .info-section {
421
+ padding: 0.7rem;
422
+ margin-top: 0 !important;
423
+ margin-bottom: 1.5em !important;
424
+ background-color: #f9f9f9;
425
+ box-shadow:
426
+ 0px 0px 0px 1px #d2d2d2 inset,
427
+ 0px 0px 0px 0px rgba(0, 0, 0, 0);
428
+
429
+ p,
430
+ p .small-text {
431
+ font-size: 15px !important;
432
+ }
433
+ }