@eeacms/volto-cca-policy 0.3.91 → 0.3.93

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,7 +4,7 @@ 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.91](https://github.com/eea/volto-cca-policy/compare/1.0.0-alpha.1...0.3.91) - 2 December 2025
7
+ ### [0.3.93](https://github.com/eea/volto-cca-policy/compare/1.0.0-alpha.1...0.3.93) - 16 December 2025
8
8
 
9
9
  #### :rocket: Dependency updates
10
10
 
@@ -14,6 +14,8 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
14
14
 
15
15
  #### :bug: Bug Fixes
16
16
 
17
+ - fix: update comments [kreafox - [`1219fcc`](https://github.com/eea/volto-cca-policy/commit/1219fccab92e59428eccf6b05e600df5878dfe48)]
18
+ - fix: test [kreafox - [`9d687b6`](https://github.com/eea/volto-cca-policy/commit/9d687b68e7a461ad41c48258ba63651de8a0a2fb)]
17
19
  - fix: url instead of link in footer config - refs #293707 [kreafox - [`00e3489`](https://github.com/eea/volto-cca-policy/commit/00e3489e6855024ab8186e042d250b5529bea0e4)]
18
20
  - fix(tests): increase code coverage [kreafox - [`66cd2b3`](https://github.com/eea/volto-cca-policy/commit/66cd2b39a9b7b026c171d99e2bf3b8a47b7cddd2)]
19
21
  - fix(tests): update hyperlink text in PlanningTab [kreafox - [`05080e0`](https://github.com/eea/volto-cca-policy/commit/05080e0727730a5fe7c67d884ad6453eaf82081a)]
@@ -26,6 +28,10 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
26
28
 
27
29
  #### :nail_care: Enhancements
28
30
 
31
+ - change(mission): code cleanup [kreafox - [`dfa082b`](https://github.com/eea/volto-cca-policy/commit/dfa082b1dbb3480532a6787bf08f96b2af91e265)]
32
+ - change: code cleanup, add customization comments [kreafox - [`4418a01`](https://github.com/eea/volto-cca-policy/commit/4418a0157df75b4588956b15e1a0950bbd1f504c)]
33
+ - change: add 301/302 redirect handling [kreafox - [`1125c61`](https://github.com/eea/volto-cca-policy/commit/1125c61f8b963a1f49bb6f7672b68bed03e559f9)]
34
+ - change: update volto customizations [kreafox - [`a712c5d`](https://github.com/eea/volto-cca-policy/commit/a712c5da2f949262dc82b0526d3623c31a1ee105)]
29
35
  - change: update menu layout - refs #294274 [kreafox - [`984cbdf`](https://github.com/eea/volto-cca-policy/commit/984cbdfd8694f52416199a1bfef064fc22ad7ea9)]
30
36
  - change: cleanup, css fix [kreafox - [`cd1f97f`](https://github.com/eea/volto-cca-policy/commit/cd1f97f65b0549188ec336820c517e45ea728f47)]
31
37
  - change: remove website and contribution links from organisation cards, use semantic cards - refs #294273 [kreafox - [`7cffbca`](https://github.com/eea/volto-cca-policy/commit/7cffbca5cc2d422120b08fd683d5235f368256ce)]
@@ -43,6 +49,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
43
49
 
44
50
  #### :house: Internal changes
45
51
 
52
+ - style: add EEA green color as theme color - refs #295162 [kreafox - [`0073837`](https://github.com/eea/volto-cca-policy/commit/00738375afe1d0047b6ef2009a45d46fb37a8be6)]
46
53
  - style: improve organisation cards [kreafox - [`6ddd344`](https://github.com/eea/volto-cca-policy/commit/6ddd344ec2486355c15866e51fd33fc4e00c3ba9)]
47
54
  - style: Automated code fix [eea-jenkins - [`ef718da`](https://github.com/eea/volto-cca-policy/commit/ef718da674d72d1f3614593f7381fb422792eece)]
48
55
  - style: cleanup [kreafox - [`142f706`](https://github.com/eea/volto-cca-policy/commit/142f7069f84d1b8460cc6b133e0864f85ad6bc41)]
@@ -55,8 +62,11 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
55
62
 
56
63
  #### :hammer_and_wrench: Others
57
64
 
65
+ - resolve conflicts [Teodor - [`28f6d21`](https://github.com/eea/volto-cca-policy/commit/28f6d2127a1d2fa8c38d4a5d1f235916892774c8)]
66
+ - code cleanup [kreafox - [`5eb537f`](https://github.com/eea/volto-cca-policy/commit/5eb537f30bfc867e460fd46a145e0f7069b2c6f7)]
58
67
  - Refs #290863 - update message key [iugin - [`871b61c`](https://github.com/eea/volto-cca-policy/commit/871b61cea7070ff5ca6d303dcf5ecaf2fdd4e965)]
59
68
  - Refs #290863 - add translations [iugin - [`63dfc08`](https://github.com/eea/volto-cca-policy/commit/63dfc08243aa19dec5c92d800b22ed739f2f0f75)]
69
+ - code cleanup [Teodor - [`74dea17`](https://github.com/eea/volto-cca-policy/commit/74dea17652897c2f9e5524ea473e9250953ec614)]
60
70
  - test: try to use specific version for plone-backend [kreafox - [`79c542e`](https://github.com/eea/volto-cca-policy/commit/79c542e8d55d2f1663b768c555880599634ae527)]
61
71
  - test(mission): add unit tests for NoDataReported and StatisticSection components [kreafox - [`36c6e36`](https://github.com/eea/volto-cca-policy/commit/36c6e36278124759240c896786f2ac0c20674730)]
62
72
  - test: resolve Jest errors in component tests [kreafox - [`6dbb735`](https://github.com/eea/volto-cca-policy/commit/6dbb73540e8301fcb42a4d52db7004f5a42db4d8)]
@@ -147,8 +157,25 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
147
157
  - Add some loadable for components [Tiberiu Ichim - [`1793962`](https://github.com/eea/volto-cca-policy/commit/179396211c66a6a2465b2d1b6c0f2afc40fc7189)]
148
158
  - Refs #284961 - test [Tripon Eugen - [`c989f1f`](https://github.com/eea/volto-cca-policy/commit/c989f1f8638c0c5233c5c49f8673c9a2cdc7937e)]
149
159
  - Refs #284961 - add translations [Tripon Eugen - [`04ee988`](https://github.com/eea/volto-cca-policy/commit/04ee988c086d393b9b37ce1ea8d24f5e84f266aa)]
150
- ### [1.0.0-alpha.0](https://github.com/eea/volto-cca-policy/compare/0.3.90...1.0.0-alpha.0) - 15 July 2025
160
+ ### [1.0.0-alpha.0](https://github.com/eea/volto-cca-policy/compare/0.3.92...1.0.0-alpha.0) - 15 July 2025
151
161
 
162
+ ### [0.3.92](https://github.com/eea/volto-cca-policy/compare/0.3.91...0.3.92) - 8 December 2025
163
+
164
+ #### :nail_care: Enhancements
165
+
166
+ - change: code cleanup, add customization comments [kreafox - [`4418a01`](https://github.com/eea/volto-cca-policy/commit/4418a0157df75b4588956b15e1a0950bbd1f504c)]
167
+ - change: add 301/302 redirect handling [kreafox - [`1125c61`](https://github.com/eea/volto-cca-policy/commit/1125c61f8b963a1f49bb6f7672b68bed03e559f9)]
168
+ - change: update volto customizations [kreafox - [`a712c5d`](https://github.com/eea/volto-cca-policy/commit/a712c5da2f949262dc82b0526d3623c31a1ee105)]
169
+
170
+ #### :hammer_and_wrench: Others
171
+
172
+ - code cleanup [kreafox - [`5eb537f`](https://github.com/eea/volto-cca-policy/commit/5eb537f30bfc867e460fd46a145e0f7069b2c6f7)]
173
+ ### [0.3.91](https://github.com/eea/volto-cca-policy/compare/0.3.90...0.3.91) - 4 December 2025
174
+
175
+ #### :hammer_and_wrench: Others
176
+
177
+ - Refs #290863 - update message key [iugin - [`871b61c`](https://github.com/eea/volto-cca-policy/commit/871b61cea7070ff5ca6d303dcf5ecaf2fdd4e965)]
178
+ - Refs #290863 - add translations [iugin - [`63dfc08`](https://github.com/eea/volto-cca-policy/commit/63dfc08243aa19dec5c92d800b22ed739f2f0f75)]
152
179
  ### [0.3.90](https://github.com/eea/volto-cca-policy/compare/0.3.89...0.3.90) - 20 November 2025
153
180
 
154
181
  #### :nail_care: Enhancements
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-cca-policy",
3
- "version": "0.3.91",
3
+ "version": "0.3.93",
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,5 @@
1
1
  import React from 'react';
2
- import { Link, useLocation } from 'react-router-dom';
2
+ import { Link } from 'react-router-dom';
3
3
  import { Tab, Container, Divider, Button, Icon } from 'semantic-ui-react';
4
4
  import { formatTextToHTML } from '@eeacms/volto-cca-policy/utils';
5
5
  import { BannerTitle, HTMLField } from '@eeacms/volto-cca-policy/helpers';
@@ -18,14 +18,8 @@ const tabRenderers = {
18
18
  };
19
19
 
20
20
  const MissionSignatoryProfileView = ({ content }) => {
21
- const location = useLocation();
22
- const isSandbox = location.pathname.includes(
23
- '/mission/sandbox/eea-sandbox/signatory-reporting',
24
- );
25
21
  const signatoryData =
26
- content?.['@components']?.missionsignatoryprofile?.[
27
- isSandbox ? 'result_beta' : 'result'
28
- ] || {};
22
+ content?.['@components']?.missionsignatoryprofile?.result || {};
29
23
 
30
24
  const {
31
25
  governance = [{}],
@@ -113,7 +113,6 @@ const AssessmentTab = ({ result, general_text }) => {
113
113
  {assessment_hazards_sectors?.length > 0 && (
114
114
  <AccordionList
115
115
  accordions={assessment_hazards_sectors.flatMap((item) => {
116
- // Beta data (Category > Hazards > Sectors)
117
116
  if (item.Category && Array.isArray(item.Hazards)) {
118
117
  return [
119
118
  {
@@ -139,21 +138,6 @@ const AssessmentTab = ({ result, general_text }) => {
139
138
  ];
140
139
  }
141
140
 
142
- // Production data (Category=null but has Hazards array)
143
- if (item.Category === null && Array.isArray(item.Hazards)) {
144
- return item.Hazards.map((hazard) => ({
145
- title: hazard.Hazard,
146
- content: (
147
- <ul>
148
- {Array.isArray(hazard.Sectors) &&
149
- hazard.Sectors.map((sector, index) => (
150
- <li key={index}>{sector}</li>
151
- ))}
152
- </ul>
153
- ),
154
- }));
155
- }
156
-
157
141
  return [];
158
142
  })}
159
143
  />
@@ -98,28 +98,17 @@ describe('AssessmentTab', () => {
98
98
  expect(link).toHaveAttribute('href', 'https://example.com');
99
99
  });
100
100
 
101
- it('renders beta-style hazards (Category > Hazard > Sector)', () => {
101
+ it('renders hazards (Category > Hazard > Sector)', () => {
102
102
  render(<AssessmentTab result={mockData} />);
103
103
 
104
104
  expect(screen.getByText('Water Management')).toBeInTheDocument();
105
105
  expect(screen.getByText('Flooding')).toBeInTheDocument();
106
106
  expect(screen.getByText('Drought')).toBeInTheDocument();
107
-
108
107
  expect(screen.getByText('Agriculture')).toBeInTheDocument();
109
108
  expect(screen.getAllByText('Health').length).toBeGreaterThanOrEqual(1);
110
109
  expect(screen.getByText('Energy')).toBeInTheDocument();
111
110
  });
112
111
 
113
- it('renders production-style hazards (Hazard > Sectors)', () => {
114
- render(<AssessmentTab result={mockData} />);
115
-
116
- expect(screen.getByText('Storms')).toBeInTheDocument();
117
- expect(screen.getByText('Heatwaves')).toBeInTheDocument();
118
- expect(screen.getByText('Transport')).toBeInTheDocument();
119
- expect(screen.getByText('Tourism')).toBeInTheDocument();
120
- expect(screen.getAllByText('Health').length).toBeGreaterThanOrEqual(1);
121
- });
122
-
123
112
  it('renders NoDataReported when no data available', () => {
124
113
  render(
125
114
  <AssessmentTab
@@ -1 +1,9 @@
1
- Customized View.jsx to add the stripping of ++api++
1
+ # View Customizations
2
+
3
+ ## Changes
4
+
5
+ 1. **API URL stripping**: Removes `++api++` from URLs
6
+ 2. **Link redirect handling**: Supports 301/302 redirects for Link content types
7
+ - Checks `@components.redirect` from backend serializer
8
+ - Sets correct HTTP status code for SSR (301 vs 302)
9
+ - Backwards compatible with error-based redirects
@@ -18,6 +18,7 @@ import {
18
18
  Tags,
19
19
  Toolbar,
20
20
  } from '@plone/volto/components';
21
+ import { AlternateHrefLangs } from '@plone/volto/components/theme/AlternateHrefLangs/AlternateHrefLangs';
21
22
  import { listActions, getContent } from '@plone/volto/actions';
22
23
  import {
23
24
  BodyClass,
@@ -98,6 +99,8 @@ class View extends Component {
98
99
  * Error type
99
100
  */
100
101
  status: PropTypes.number,
102
+ code: PropTypes.number,
103
+ url: PropTypes.string,
101
104
  }),
102
105
  };
103
106
 
@@ -203,23 +206,33 @@ class View extends Component {
203
206
  */
204
207
  render() {
205
208
  const { views } = config;
206
- if (this.props.error && this.props.error.code === 301) {
207
- // const base = typeof window !== 'undefined' ? window.location.origin : '';
208
209
 
209
- const redirect = flattenToAppURL(this.props.error.url)
210
- .replaceAll('/++api++', '/')
210
+ // customization
211
+ const redirectData =
212
+ this.props.content?.['@components']?.redirect ||
213
+ ([301, 302].includes(this.props.error?.code) && {
214
+ url: this.props.error.url,
215
+ status: this.props.error.code,
216
+ });
217
+
218
+ if (redirectData) {
219
+ const redirect = flattenToAppURL(redirectData.url)
220
+ .replace('/++api++', '')
211
221
  .replaceAll('//', '/')
212
222
  .split('?')[0];
213
- const redirParams = {
214
- pathname: redirect,
215
- search: this.props.location.search,
216
- };
223
+ const targetUrl = `${redirect}${this.props.location.search}`;
224
+
225
+ if (this.props.staticContext) {
226
+ this.props.staticContext.error_code = redirectData.status || 302;
227
+ }
228
+
229
+ const shouldPush = redirectData.status === 302;
217
230
 
218
- // eslint-disable-next-line no-console
219
- console.log('Redirecting', redirParams);
231
+ return <Redirect to={targetUrl} push={shouldPush} />;
232
+ }
233
+ // end of customization
220
234
 
221
- return <Redirect to={redirParams} push={true} />;
222
- } else if (this.props.error && !this.props.connectionRefused) {
235
+ if (this.props.error && !this.props.connectionRefused) {
223
236
  let FoundView;
224
237
  if (this.props.error.status === undefined) {
225
238
  // For some reason, while development and if CORS is in place and the
@@ -247,6 +260,7 @@ class View extends Component {
247
260
  return (
248
261
  <div id="view">
249
262
  <ContentMetadataTags content={this.props.content} />
263
+ <AlternateHrefLangs content={this.props.content} />
250
264
  {/* Body class if displayName in component is set */}
251
265
  <BodyClass
252
266
  className={
@@ -50,10 +50,7 @@ export function addExpandersToPath(path, type, isAnonymous) {
50
50
  } = qs.parseUrl(path, { decode: false });
51
51
 
52
52
  const expandersFromConfig = apiExpanders
53
- .filter((expand) => {
54
- const res = matchPath(url, expand.match) && expand[type];
55
- return res;
56
- })
53
+ .filter((expand) => matchPath(url, expand.match) && expand[type])
57
54
  .map((expand) => expand[type]);
58
55
 
59
56
  const expandMerge = compact(
@@ -70,7 +67,15 @@ export function addExpandersToPath(path, type, isAnonymous) {
70
67
 
71
68
  const querystringFromConfig = apiExpanders
72
69
  .filter((expand) => matchPath(url, expand.match) && expand[type])
73
- .reduce((acc, expand) => ({ ...acc, ...expand?.['querystring'] }), {});
70
+ .reduce((acc, expand) => {
71
+ let querystring = expand?.['querystring'];
72
+ // The querystring accepts being a function to be able to take other
73
+ // config parameters
74
+ if (typeof querystring === 'function') {
75
+ querystring = querystring(config);
76
+ }
77
+ return { ...acc, ...querystring };
78
+ }, {});
74
79
 
75
80
  const queryMerge = { ...query, ...querystringFromConfig };
76
81
 
@@ -128,6 +133,13 @@ const apiMiddlewareFactory =
128
133
  const { settings } = config;
129
134
 
130
135
  const isAnonymous = !getState().userSession.token;
136
+ // const token = getState().userSession.token;
137
+ // let isAnonymous = true;
138
+ // if (token) {
139
+ // const tokenExpiration = jwtDecode(token).exp;
140
+ // const currentTime = new Date().getTime() / 1000;
141
+ // isAnonymous = !token || currentTime > tokenExpiration;
142
+ // }
131
143
 
132
144
  if (typeof action === 'function') {
133
145
  return action(dispatch, getState);
@@ -310,15 +322,23 @@ const apiMiddlewareFactory =
310
322
  }
311
323
 
312
324
  // Redirect
313
- else if (error?.code === 301) {
325
+ // customization
326
+ else if (error?.code === 301 || error?.code === 302) {
327
+ const redirectUrl =
328
+ error.response?.body?.url || error.response?.body?.location;
329
+
314
330
  next({
315
331
  ...rest,
316
- error,
332
+ error: {
333
+ ...error,
334
+ url: redirectUrl,
335
+ },
317
336
  statusCode: error.code,
318
337
  connectionRefused: false,
319
338
  type: SET_APIERROR,
320
339
  });
321
340
  }
341
+ // end of customization
322
342
 
323
343
  // Redirect
324
344
  else if (error?.code === 408) {
@@ -337,7 +357,7 @@ const apiMiddlewareFactory =
337
357
  ...rest,
338
358
  error,
339
359
  statusCode: error.response,
340
- message: error.response.body.message,
360
+ message: error.response?.body?.message,
341
361
  connectionRefused: false,
342
362
  type: SET_APIERROR,
343
363
  });
@@ -321,7 +321,11 @@ server.get('/*', (req, res) => {
321
321
  }
322
322
 
323
323
  if (context.url) {
324
- res.redirect(flattenToAppURL(context.url));
324
+ // customization
325
+ // Use error_code if set (for Link redirects with specific status)
326
+ const redirectStatus = context.error_code || 302;
327
+ res.redirect(redirectStatus, flattenToAppURL(context.url));
328
+ // end of customization
325
329
  } else if (context.error_code) {
326
330
  res.set({
327
331
  'Cache-Control': 'no-cache',
package/src/index.js CHANGED
@@ -570,6 +570,11 @@ const applyConfig = (config) => {
570
570
  config.widgets.vocabulary['plone.app.vocabularies.Users'] =
571
571
  SelectAutoCompleteWidget;
572
572
 
573
+ config.settings.themeColors = [
574
+ ...config.settings.themeColors,
575
+ { value: 'green', title: 'EEA Green' },
576
+ ];
577
+
573
578
  config.settings.matomoTrackerIdFn = (pathname) => {
574
579
  return pathname.split('/')[2] === 'mission'
575
580
  ? {
@@ -92,4 +92,82 @@
92
92
 
93
93
  .ui.items > .item > img + .content {
94
94
  padding-left: 1rem;
95
- }
95
+ }
96
+
97
+ /* Mobile responsive fixes for tabs block */
98
+ @media only screen and (max-width: 480px) {
99
+ .tabs-block .ui.vertical.menu .item .menu-item-text {
100
+ white-space: normal;
101
+ overflow-wrap: break-word;
102
+ word-break: keep-all;
103
+ font-size: 0.8rem;
104
+ line-height: 1.3;
105
+ }
106
+ }
107
+
108
+ @media only screen and (max-width: 380px) {
109
+ .tabs-block .ui.vertical.menu .item .asset-position .menu-item-text {
110
+ font-size: 0.7rem;
111
+ }
112
+ }
113
+
114
+ @media only screen and (max-width: 345px) {
115
+ .tabs-block .ui.vertical.menu .item .asset-position .menu-item-text {
116
+ font-size: 0.65rem;
117
+ }
118
+ }
119
+
120
+ /* Hero */
121
+ .color-bg-green {
122
+ background-color: @green;
123
+ }
124
+
125
+ /* Divider */
126
+ .ui.divider.green,
127
+ .ui.divider.green:not(.vertical):not(.horizontal) {
128
+ border-top-color: @green;
129
+ color: @green;
130
+ }
131
+
132
+ /* Accordion */
133
+ .ui.accordion.green > .active.title,
134
+ .ui.accordion.green.inverted > .title,
135
+ .ui.accordion.green > .filter,
136
+ .ui.accordion.secondary.green > .active.title,
137
+ .ui.accordion.secondary.green.inverted > .title,
138
+ .ui.accordion.secondary.green > .filter {
139
+ --bg-color: @green;
140
+ }
141
+
142
+ .ui.accordion.green > .active.title,
143
+ .ui.accordion.green.inverted > .title,
144
+ .ui.accordion.green.inverted > .icon,
145
+ .ui.accordion.green > .filter {
146
+ --text-color-hover: white;
147
+ --text-color: white;
148
+ }
149
+
150
+ /* Listing cards */
151
+ .ui.card.green {
152
+ box-shadow: none !important;
153
+ border: none;
154
+ }
155
+
156
+ .ui.card.green {
157
+ --card-text-color: @green;
158
+ --card-background-color: white;
159
+ }
160
+
161
+ .card.green.inverted,
162
+ .cardsVisualization .ui.card.green {
163
+ --card-background-color: white;
164
+ --card-text-color: @green !important;
165
+ }
166
+
167
+ .cardsVisualization {
168
+ .ui.cards {
169
+ .ui.card.green::before {
170
+ background-color: @green;
171
+ }
172
+ }
173
+ }