@eeacms/volto-cca-policy 0.3.39 → 0.3.40

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,29 @@ 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.40](https://github.com/eea/volto-cca-policy/compare/0.3.39...0.3.40) - 13 May 2025
8
+
9
+ #### :bug: Bug Fixes
10
+
11
+ - fix: tests [kreafox - [`1852df4`](https://github.com/eea/volto-cca-policy/commit/1852df43cde6f0f173fcd28d79a0576407d9b313)]
12
+ - fix: class -> className [kreafox - [`56124bc`](https://github.com/eea/volto-cca-policy/commit/56124bc768fafcd59fc280d5ed9f8a6840969691)]
13
+ - fix: tests [kreafox - [`4f95457`](https://github.com/eea/volto-cca-policy/commit/4f954579aed4ed94e796be0de712ab1fc025d96a)]
14
+
15
+ #### :nail_care: Enhancements
16
+
17
+ - change: update Assessment section to render html tags [kreafox - [`011d752`](https://github.com/eea/volto-cca-policy/commit/011d752a949ca08ece75bed5aed46103216875ba)]
18
+ - change: update mission signatory profile templates - refs #286863, #286151 [kreafox - [`fde31e1`](https://github.com/eea/volto-cca-policy/commit/fde31e1ccb694a6109a49155010edf3fba34e512)]
19
+ - change(view): add footer text - refs #287671 [kreafox - [`864a247`](https://github.com/eea/volto-cca-policy/commit/864a247e754117b56a42608779ea60b0da8b71e2)]
20
+
21
+ #### :house: Internal changes
22
+
23
+ - style: Automated code fix [eea-jenkins - [`b301fff`](https://github.com/eea/volto-cca-policy/commit/b301fff27818a9317be2b6c4a992ddd9d1672663)]
24
+ - style: Automated code fix [eea-jenkins - [`3aa5289`](https://github.com/eea/volto-cca-policy/commit/3aa52897989a36dae14a0f0c00f4addd233eef18)]
25
+
26
+ #### :hammer_and_wrench: Others
27
+
28
+ - Refs #287520 - eslint [Tripon Eugen - [`fe3883e`](https://github.com/eea/volto-cca-policy/commit/fe3883ede70439de7f42cc817f9471996ad98696)]
29
+ - Refs #287520 - test resposition [Tripon Eugen - [`3114d1b`](https://github.com/eea/volto-cca-policy/commit/3114d1b8bb2d1017c590b1405f83cddeda5f5d35)]
7
30
  ### [0.3.39](https://github.com/eea/volto-cca-policy/compare/0.3.38...0.3.39) - 9 May 2025
8
31
 
9
32
  #### :nail_care: Enhancements
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-cca-policy",
3
- "version": "0.3.39",
3
+ "version": "0.3.40",
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",
@@ -47,25 +47,38 @@ export function filterCases(cases, activeFilters) {
47
47
  impacts: false,
48
48
  };
49
49
 
50
- activeFilters.sectors.forEach((filter) => {
51
- if (_case.properties.sectors.includes(',' + filter + ','))
52
- flag.sectors = true;
53
- });
54
-
55
- activeFilters.elements.forEach((filter) => {
56
- if (_case.properties.elements.includes(',' + filter + ','))
57
- flag.elements = true;
58
- });
59
-
60
- activeFilters.impacts.forEach((filter) => {
61
- if (_case.properties.impacts.includes(',' + filter + ','))
62
- flag.impacts = true;
63
- });
64
-
65
- activeFilters.measures.forEach((filter) => {
66
- if (_case.properties.ktms.includes(',' + filter + ','))
67
- flag.measures = true;
68
- });
50
+ // activeFilters.sectors.forEach((filter) => {
51
+ // if (_case.properties.sectors.includes(',' + filter + ','))
52
+ // flag.sectors = true;
53
+ // });
54
+ flag.sectors = activeFilters.sectors.every((sub) =>
55
+ _case.properties.sectors.includes(sub),
56
+ );
57
+
58
+ // ADAPTATION APPROACHES
59
+ // activeFilters.elements.forEach((filter) => {
60
+ // if (_case.properties.elements.includes(',' + filter + ','))
61
+ // flag.elements = true;
62
+ // });
63
+ flag.elements = activeFilters.elements.every((sub) =>
64
+ _case.properties.elements.includes(sub),
65
+ );
66
+
67
+ // activeFilters.impacts.forEach((filter) => {
68
+ // if (_case.properties.impacts.includes(',' + filter + ','))
69
+ // flag.impacts = true;
70
+ // });
71
+ flag.impacts = activeFilters.impacts.every((sub) =>
72
+ _case.properties.impacts.includes(sub),
73
+ );
74
+
75
+ // activeFilters.measures.forEach((filter) => {
76
+ // if (_case.properties.ktms.includes(',' + filter + ','))
77
+ // flag.measures = true;
78
+ // });
79
+ flag.measures = activeFilters.measures.every((sub) =>
80
+ _case.properties.ktms.includes(sub),
81
+ );
69
82
 
70
83
  return (activeFilters.sectors.length ? flag.sectors : true) &&
71
84
  (activeFilters.elements.length ? flag.elements : true) &&
@@ -35,7 +35,7 @@ export default function View(props) {
35
35
  return (
36
36
  <>
37
37
  {isNonEN && (
38
- <Message class="eea callout">
38
+ <Message className="eea callout">
39
39
  <FormattedMessage
40
40
  id="officiallyInEnglish"
41
41
  defaultMessage="Officially reported governmental information is only available in English"
@@ -43,7 +43,7 @@ export default function View(props) {
43
43
  </Message>
44
44
  )}
45
45
  {dataJson.message_top ? (
46
- <div class="eea callout">{dataJson.message_top}</div>
46
+ <div className="eea callout">{dataJson.message_top}</div>
47
47
  ) : null}
48
48
  {dataJson.top_accordeon ? (
49
49
  <div className="top-accordion">
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { Tab, Container } from 'semantic-ui-react';
2
+ import { Tab, Container, Divider } from 'semantic-ui-react';
3
3
  import { BannerTitle } from '@eeacms/volto-cca-policy/helpers';
4
4
  import GovernanceTab from './TabSections/GovernanceTab';
5
5
  import AssessmentTab from './TabSections/AssessmentTab';
@@ -14,10 +14,11 @@ const MissionSignatoryProfileView = (props) => {
14
14
  props?.content?.['@components']?.missionsignatoryprofile || {};
15
15
 
16
16
  const result = dataJson?.result || {};
17
- const governance = result?.governance?.[0] || [];
17
+ const governance = result?.governance?.[0] || {};
18
18
  const planning = result?.planning || {};
19
19
  const assessment = result?.assessment || {};
20
20
  const action = result?.action || {};
21
+ const footer_text = result?.footer_text || {};
21
22
  const tab_labels = result?.tab_labels || {};
22
23
  const { Governance_Label, Assessment_Label, Planning_Label, Action_Label } =
23
24
  tab_labels || {};
@@ -70,6 +71,14 @@ const MissionSignatoryProfileView = (props) => {
70
71
  },
71
72
  ]}
72
73
  />
74
+
75
+ {footer_text.Disclaimer && (
76
+ <div className="footer-text">
77
+ <Divider />
78
+ <strong>{footer_text.Disclaimer_Title}</strong>
79
+ <p>{footer_text.Disclaimer}</p>
80
+ </div>
81
+ )}
73
82
  </div>
74
83
  </Container>
75
84
  );
@@ -1,12 +1,14 @@
1
- import React from 'react';
2
1
  import { Tab, Grid } from 'semantic-ui-react';
3
2
  import { Callout } from '@eeacms/volto-eea-design-system/ui';
3
+ import { HTMLField } from '@eeacms/volto-cca-policy/helpers';
4
+ import { formatTextToHTML } from '@eeacms/volto-cca-policy/utils';
4
5
  import AccordionList from '../AccordionList';
5
6
 
6
7
  const ActionsTabContent = ({ action }) => {
7
8
  const hasHazards = action?.Climate_Hazards?.length > 0;
8
- const hasSectors = !!action?.Sectors;
9
- const hasBenefits = !!action?.Co_Benefits;
9
+ const hasSectors = action?.Sectors.length > 0;
10
+ const hasBenefits = action?.Co_Benefits.length > 0;
11
+
10
12
  return (
11
13
  <>
12
14
  <Grid columns="12">
@@ -72,21 +74,23 @@ const ActionPagesTab = ({ result }) => {
72
74
  return (
73
75
  <Tab.Pane>
74
76
  {Title && <h2>{Title}</h2>}
75
- {Abstract && <p>{Abstract}</p>}
76
- {Abstract_Line && <Callout>{Abstract_Line}</Callout>}
77
-
78
- <br />
77
+ {Abstract && <HTMLField value={{ data: formatTextToHTML(Abstract) }} />}
78
+ {Abstract_Line && (
79
+ <Callout>
80
+ <HTMLField value={{ data: formatTextToHTML(Abstract_Line) }} />
81
+ </Callout>
82
+ )}
79
83
 
80
84
  {sortedActions.map((action, index) => {
81
85
  return (
82
86
  <div key={index} className="section-wrapper">
83
87
  <h5 className="section-title">
84
- <span className="section-number">{action.Order}. </span>
85
- <span>{action?.Action}</span>
88
+ <span className="section-number">{action.Action_Id}. </span>
89
+ <HTMLField value={{ data: formatTextToHTML(action?.Action) }} />
86
90
  </h5>
87
91
 
88
92
  <AccordionList
89
- variation="tertiary"
93
+ variation="secondary"
90
94
  accordions={[
91
95
  {
92
96
  title: action?.More_Details_Label || 'More details',
@@ -61,7 +61,7 @@ describe('ActionPagesTab', () => {
61
61
  };
62
62
 
63
63
  it('renders action tab content correctly', () => {
64
- const { getByText, getAllByText } = render(
64
+ const { getByText, container } = render(
65
65
  <ActionPagesTab result={mockResult} />,
66
66
  );
67
67
 
@@ -71,9 +71,7 @@ describe('ActionPagesTab', () => {
71
71
  ).toBeInTheDocument();
72
72
  expect(getByText('Summary line here.')).toBeInTheDocument();
73
73
 
74
- const sections = getAllByText(/^\d+\./).map((el) =>
75
- el.closest('.section-wrapper'),
76
- );
74
+ const sections = container.querySelectorAll('.section-wrapper');
77
75
 
78
76
  // First action
79
77
  const firstAction = within(sections[0]);
@@ -1,6 +1,8 @@
1
1
  import React from 'react';
2
2
  import { Tab, Image, Segment, Item } from 'semantic-ui-react';
3
3
  import { Callout } from '@eeacms/volto-eea-design-system/ui';
4
+ import { HTMLField } from '@eeacms/volto-cca-policy/helpers';
5
+ import { formatTextToHTML } from '@eeacms/volto-cca-policy/utils';
4
6
  import AccordionList from '../AccordionList';
5
7
 
6
8
  import image from '@eeacms/volto-cca-policy/../theme//assets/images/image-narrow.svg';
@@ -38,7 +40,7 @@ const AssessmentAccordionContent = ({ result }) => {
38
40
 
39
41
  <h5>{result.Further_Details_Label}</h5>
40
42
  <Segment className="border">
41
- <p>{result.Please_Explain}</p>
43
+ <HTMLField value={{ data: formatTextToHTML(result.Please_Explain) }} />
42
44
  </Segment>
43
45
  </>
44
46
  );
@@ -63,9 +65,13 @@ const AssessmentTab = ({ result }) => {
63
65
  return (
64
66
  <Tab.Pane>
65
67
  {Title && <h2>{Title}</h2>}
66
- {Subheading && <Callout>{Subheading}</Callout>}
68
+ {Subheading && (
69
+ <Callout>
70
+ <HTMLField value={{ data: formatTextToHTML(Subheading) }} />
71
+ </Callout>
72
+ )}
67
73
 
68
- {Abstract && <p>{Abstract}</p>}
74
+ {Abstract && <HTMLField value={{ data: formatTextToHTML(Abstract) }} />}
69
75
 
70
76
  <div className="tab-section-wrapper assessment">
71
77
  {Cra_Title && <h3>{Cra_Title}</h3>}
@@ -99,7 +105,9 @@ const AssessmentTab = ({ result }) => {
99
105
 
100
106
  {Hazards_Title && <h3>{Hazards_Title}</h3>}
101
107
 
102
- {Hazards_Abstract && <p>{Hazards_Abstract}</p>}
108
+ {Hazards_Abstract && (
109
+ <HTMLField value={{ data: formatTextToHTML(Hazards_Abstract) }} />
110
+ )}
103
111
 
104
112
  <br />
105
113
 
@@ -88,17 +88,25 @@ const PlanningTab = ({ result }) => {
88
88
  return (
89
89
  <Tab.Pane>
90
90
  {titleData?.Title && <h2>{titleData.Title}</h2>}
91
- {titleData?.Abstract_Line && <Callout>{titleData.Abstract_Line}</Callout>}
91
+ {titleData?.Abstract_Line && (
92
+ <Callout>
93
+ <HTMLField
94
+ value={{ data: formatTextToHTML(titleData?.Abstract_Line) }}
95
+ />
96
+ </Callout>
97
+ )}
92
98
 
93
99
  {sortedGoals.map((goal, index) => {
94
100
  return (
95
101
  <div key={index} className="section-wrapper">
96
- <span className="goal-title-label">{goal?.Title_Label}</span>
102
+ <h5 className="section-title">
103
+ <span className="section-number">{goal?.Title_Label} </span>
97
104
 
98
- <HTMLField value={{ data: formatTextToHTML(goal?.Title) }} />
105
+ <HTMLField value={{ data: formatTextToHTML(goal?.Title) }} />
106
+ </h5>
99
107
 
100
108
  <AccordionList
101
- variation="tertiary"
109
+ variation="secondary"
102
110
  accordions={[
103
111
  {
104
112
  title: goal?.More_Details_Label || 'More details',
@@ -115,7 +123,11 @@ const PlanningTab = ({ result }) => {
115
123
  )}
116
124
 
117
125
  {goalData?.Climate_Action_Abstract && (
118
- <Callout>{goalData.Climate_Action_Abstract}</Callout>
126
+ <Callout>
127
+ <HTMLField
128
+ value={{ data: formatTextToHTML(goalData.Climate_Action_Abstract) }}
129
+ />
130
+ </Callout>
119
131
  )}
120
132
 
121
133
  {planning_climate_action.map((action, index) => {
@@ -124,12 +136,22 @@ const PlanningTab = ({ result }) => {
124
136
  <br />
125
137
  {action?.Sectors_Introduction && (
126
138
  <Message>
127
- <p>{action.Sectors_Introduction}</p>
139
+ <HTMLField
140
+ value={{
141
+ data: formatTextToHTML(action.Sectors_Introduction),
142
+ }}
143
+ />
128
144
  </Message>
129
145
  )}
130
146
 
131
147
  <ItemsSection items={action?.Sectors} />
132
- {action?.Description && <p>{action.Description}</p>}
148
+
149
+ {action?.Description && (
150
+ <HTMLField
151
+ className="description"
152
+ value={{ data: formatTextToHTML(action.Description) }}
153
+ />
154
+ )}
133
155
 
134
156
  {(action?.Approval_Year || action?.End_Year) && (
135
157
  <p>
@@ -23,6 +23,10 @@
23
23
  }
24
24
  }
25
25
 
26
+ .description > p {
27
+ margin-bottom: 1em;
28
+ }
29
+
26
30
  .tab-section-wrapper {
27
31
  padding: 1.5em;
28
32
  margin: 2em 0;
@@ -45,20 +49,22 @@
45
49
  }
46
50
 
47
51
  .section-wrapper {
52
+ padding: 1em;
48
53
  margin: 1em 0;
54
+ background-color: #f9f9f9;
49
55
 
50
- .goal-title-label {
51
- display: inline-block;
52
- padding: 0.3em 0.5em;
53
- margin: 1em 0;
54
- background-color: #dbe7f4;
55
- font-size: 14px;
56
- font-weight: bold;
57
- text-transform: uppercase;
56
+ .section-title {
57
+ display: flex;
58
+ align-items: baseline;
59
+ gap: 0.5em;
58
60
  }
59
61
 
60
62
  .ui.accordion {
61
63
  margin-top: 1em;
64
+
65
+ .content.active {
66
+ padding-bottom: 1rem !important;
67
+ }
62
68
  }
63
69
 
64
70
  .small-label {
@@ -66,6 +72,10 @@
66
72
  }
67
73
  }
68
74
 
75
+ .section-number {
76
+ color: @pineGreen;
77
+ }
78
+
69
79
  strong.date {
70
80
  margin-right: 0.5em;
71
81
  }
@@ -83,4 +93,8 @@
83
93
  }
84
94
  }
85
95
  }
96
+
97
+ .footer-text {
98
+ margin-top: 3em;
99
+ }
86
100
  }
@@ -9,13 +9,13 @@ import {
9
9
  } from '@eeacms/volto-cca-policy/helpers';
10
10
  import {
11
11
  Container,
12
- Segment,
12
+ // Segment,
13
13
  Divider,
14
14
  Grid,
15
15
  ListItem,
16
16
  List,
17
17
  } from 'semantic-ui-react';
18
- import { UniversalLink } from '@plone/volto/components';
18
+ // import { UniversalLink } from '@plone/volto/components';
19
19
  import {
20
20
  ShareInfoButton,
21
21
  PortalMessage,
@@ -253,9 +253,12 @@ function AdaptationOptionView(props) {
253
253
  computer={4}
254
254
  className="col-right"
255
255
  >
256
- <ContentMetadata {...props} />
256
+ <ContentMetadata
257
+ {...props}
258
+ related_case_studies={related_case_studies}
259
+ />
257
260
 
258
- {related_case_studies?.length > 0 && (
261
+ {/* {related_case_studies?.length > 0 && (
259
262
  <Segment>
260
263
  <h5>
261
264
  <FormattedMessage
@@ -273,7 +276,7 @@ function AdaptationOptionView(props) {
273
276
  ))}
274
277
  </ul>
275
278
  </Segment>
276
- )}
279
+ )} */}
277
280
  </Grid.Column>
278
281
  </div>
279
282
  </Grid>
@@ -1,8 +1,7 @@
1
- import React from 'react';
2
1
  import { MemoryRouter } from 'react-router-dom';
3
2
  import configureStore from 'redux-mock-store';
4
3
  import '@testing-library/jest-dom/extend-expect';
5
- import { render } from '@testing-library/react';
4
+ import { render, waitFor } from '@testing-library/react';
6
5
  import { Provider } from 'react-intl-redux';
7
6
  import { BrokenLinksComponent } from './BrokenLinks';
8
7
 
@@ -17,7 +16,18 @@ describe('BrokenLinksComponent', () => {
17
16
  messages: {},
18
17
  },
19
18
  });
19
+
20
+ global.fetch = jest.fn(() =>
21
+ Promise.resolve({
22
+ json: () =>
23
+ Promise.resolve({
24
+ broken_links: {},
25
+ }),
26
+ }),
27
+ );
28
+
20
29
  const reactTable = await import('@tanstack/react-table');
30
+
21
31
  const { container } = render(
22
32
  <Provider store={store}>
23
33
  <MemoryRouter>
@@ -25,6 +35,9 @@ describe('BrokenLinksComponent', () => {
25
35
  </MemoryRouter>
26
36
  </Provider>,
27
37
  );
28
- expect(container).toBeTruthy();
38
+
39
+ await waitFor(() => {
40
+ expect(container).toBeTruthy();
41
+ });
29
42
  });
30
43
  });
@@ -13,6 +13,7 @@ import {
13
13
  PUBLICATION_REPORT,
14
14
  } from '@eeacms/volto-cca-policy/helpers/Constants';
15
15
  import { MetadataItemList } from '@eeacms/volto-cca-policy/helpers';
16
+ import { UniversalLink } from '@plone/volto/components';
16
17
 
17
18
  const messages = defineMessages({
18
19
  default_info_tooltip: {
@@ -342,6 +343,11 @@ function ContentMetadata(props) {
342
343
  key_type_measures,
343
344
  funding_programme,
344
345
  } = content;
346
+ // const related_case_studies = props.hasAttribute('related_case_studies')
347
+ // ? props['related_case_studies']
348
+ // : [];
349
+ const related_case_studies = props['related_case_studies'];
350
+
345
351
  const type = content['@type'];
346
352
  const hasGeoChars = geochars !== null || spatial_layer.length > 0;
347
353
 
@@ -364,6 +370,26 @@ function ContentMetadata(props) {
364
370
  portaltype={type}
365
371
  />
366
372
 
373
+ {related_case_studies?.length > 0 && (
374
+ <>
375
+ <h5>
376
+ <FormattedMessage
377
+ id="Case studies related to this option:"
378
+ defaultMessage="Case studies related to this option:"
379
+ />
380
+ </h5>
381
+ <ul className="related-case-studies">
382
+ {related_case_studies.map((item, index) => (
383
+ <li key={index}>
384
+ <UniversalLink key={index} href={item.url}>
385
+ {item.title}
386
+ </UniversalLink>
387
+ </li>
388
+ ))}
389
+ </ul>
390
+ </>
391
+ )}
392
+
367
393
  {keywords && keywords?.length > 0 && (
368
394
  <>
369
395
  <h5>