@eeacms/volto-cca-policy 0.3.40 → 0.3.42

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,34 @@ 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.42](https://github.com/eea/volto-cca-policy/compare/0.3.41...0.3.42) - 15 May 2025
8
+
9
+ #### :rocket: Dependency updates
10
+
11
+ - Release @eeacms/volto-globalsearch@2.1.2 [EEA Jenkins - [`e8281dd`](https://github.com/eea/volto-cca-policy/commit/e8281dd309f4c2734d137946554d1ff50d3e5c97)]
12
+
13
+ #### :bug: Bug Fixes
14
+
15
+ - fix: production crash by using safe Statistic subcomponent access [kreafox - [`af7b1d7`](https://github.com/eea/volto-cca-policy/commit/af7b1d745b0080e0a01325b35b860dc537510689)]
16
+
17
+ ### [0.3.41](https://github.com/eea/volto-cca-policy/compare/0.3.40...0.3.41) - 14 May 2025
18
+
19
+ #### :rocket: Dependency updates
20
+
21
+ - Release @eeacms/volto-globalsearch@2.1.1 [EEA Jenkins - [`95087df`](https://github.com/eea/volto-cca-policy/commit/95087dfc874dfac0186dbaad184666ab9b8649df)]
22
+
23
+ #### :bug: Bug Fixes
24
+
25
+ - fix(mission): fix signatory profile actions order - refs #286863 [kreafox - [`48de556`](https://github.com/eea/volto-cca-policy/commit/48de556432efa9c88676f6b938e451d18cce9582)]
26
+ - fix: update test [kreafox - [`951460d`](https://github.com/eea/volto-cca-policy/commit/951460d723278de41e9749e432aff1891497d4fa)]
27
+ - fix: update test [kreafox - [`4608fc9`](https://github.com/eea/volto-cca-policy/commit/4608fc90c2f68c8625a4ad00d8dca5c79c78551c)]
28
+
29
+ #### :nail_care: Enhancements
30
+
31
+ - change(mission): move signatory profile CSS to theme folder [kreafox - [`be3744f`](https://github.com/eea/volto-cca-policy/commit/be3744ff175412dbca210a25ac6d1ac686ff4d83)]
32
+ - change(mission): add statitic for Governance section - refs #285296 [kreafox - [`67774d2`](https://github.com/eea/volto-cca-policy/commit/67774d24334b213dc9e870403df9cd15d005219d)]
33
+ - change: adjust tab labels order from backend response - refs #287273 [kreafox - [`6fc277d`](https://github.com/eea/volto-cca-policy/commit/6fc277d8479198d2307de9c092d460a6676a8a51)]
34
+
7
35
  ### [0.3.40](https://github.com/eea/volto-cca-policy/compare/0.3.39...0.3.40) - 13 May 2025
8
36
 
9
37
  #### :bug: Bug Fixes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-cca-policy",
3
- "version": "0.3.40",
3
+ "version": "0.3.42",
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",
@@ -32,7 +32,7 @@
32
32
  "@eeacms/volto-eea-design-system": "<=1.36.3",
33
33
  "@eeacms/volto-eea-website-theme": "^1.35.0",
34
34
  "@eeacms/volto-embed": "^9.1.1",
35
- "@eeacms/volto-globalsearch": "2.1.0",
35
+ "@eeacms/volto-globalsearch": "2.1.2",
36
36
  "@eeacms/volto-hero-block": "^7.1.0",
37
37
  "@eeacms/volto-openlayers-map": "*",
38
38
  "@eeacms/volto-searchlib": "2.0.16",
@@ -6,7 +6,12 @@ import AssessmentTab from './TabSections/AssessmentTab';
6
6
  import PlanningTab from './TabSections/PlanningTab';
7
7
  import ActionPagesTab from './TabSections/ActionPagesTab';
8
8
 
9
- import './style.less';
9
+ const tabRenderers = {
10
+ Governance_Label: (data) => <GovernanceTab result={data} />,
11
+ Assessment_Label: (data) => <AssessmentTab result={data} />,
12
+ Planning_Label: (data) => <PlanningTab result={data} />,
13
+ Action_Label: (data) => <ActionPagesTab result={data} />,
14
+ };
10
15
 
11
16
  const MissionSignatoryProfileView = (props) => {
12
17
  const { content } = props || {};
@@ -19,12 +24,27 @@ const MissionSignatoryProfileView = (props) => {
19
24
  const assessment = result?.assessment || {};
20
25
  const action = result?.action || {};
21
26
  const footer_text = result?.footer_text || {};
22
- const tab_labels = result?.tab_labels || {};
23
- const { Governance_Label, Assessment_Label, Planning_Label, Action_Label } =
24
- tab_labels || {};
27
+ const tab_labels = result?.tab_labels || [];
25
28
 
26
29
  const [activeIndex, setActiveIndex] = React.useState(0);
27
30
 
31
+ const panes = tab_labels
32
+ .filter(({ key }) => key !== 'Language')
33
+ .map(({ key, value }) => {
34
+ const renderTab = tabRenderers[key];
35
+ const dataMap = {
36
+ Governance_Label: governance,
37
+ Assessment_Label: assessment,
38
+ Planning_Label: planning,
39
+ Action_Label: action,
40
+ };
41
+
42
+ return {
43
+ menuItem: value,
44
+ render: () => (renderTab ? renderTab(dataMap[key]) : null),
45
+ };
46
+ });
47
+
28
48
  return (
29
49
  <Container>
30
50
  <BannerTitle
@@ -39,7 +59,7 @@ const MissionSignatoryProfileView = (props) => {
39
59
  hideShareButton: false,
40
60
  }}
41
61
  />
42
- <div className="signatories-profile">
62
+ <div className="signatory-profile">
43
63
  <br />
44
64
 
45
65
  <Tab
@@ -52,24 +72,7 @@ const MissionSignatoryProfileView = (props) => {
52
72
  grid={{ paneWidth: 9, tabWidth: 3, stackable: true }}
53
73
  activeIndex={activeIndex}
54
74
  onTabChange={(e, { activeIndex }) => setActiveIndex(activeIndex)}
55
- panes={[
56
- {
57
- menuItem: Governance_Label || 'Governance',
58
- render: () => <GovernanceTab result={governance} />,
59
- },
60
- {
61
- menuItem: Assessment_Label || 'Assessment',
62
- render: () => <AssessmentTab result={assessment} />,
63
- },
64
- {
65
- menuItem: Planning_Label || 'Planning',
66
- render: () => <PlanningTab result={planning} />,
67
- },
68
- {
69
- menuItem: Action_Label || 'Action',
70
- render: () => <ActionPagesTab result={action} />,
71
- },
72
- ]}
75
+ panes={panes}
73
76
  />
74
77
 
75
78
  {footer_text.Disclaimer && (
@@ -17,27 +17,42 @@ jest.mock('@eeacms/volto-cca-policy/helpers', () => ({
17
17
  }));
18
18
 
19
19
  describe('MissionSignatoryProfileView', () => {
20
- const data = {
21
- _v_results: {
22
- planning: {
23
- planning_titles: [{}],
20
+ const content = {
21
+ '@components': {
22
+ missionsignatoryprofile: {
23
+ result: {
24
+ governance: [{}],
25
+ assessment: {},
26
+ planning: {},
27
+ action: {},
28
+ footer_text: {
29
+ Disclaimer_Title: 'Disclaimer Title',
30
+ Disclaimer: 'This is a disclaimer.',
31
+ },
32
+ tab_labels: [
33
+ { key: 'Governance_Label', value: 'Governance' },
34
+ { key: 'Assessment_Label', value: 'Assessment' },
35
+ { key: 'Planning_Label', value: 'Planning & Target' },
36
+ { key: 'Action_Label', value: 'Action' },
37
+ { key: 'Language', value: 'en' }, // will be filtered out
38
+ ],
39
+ },
24
40
  },
25
- governance: [{}],
26
41
  },
27
42
  };
28
43
 
29
44
  it('renders tab labels and default content', () => {
30
- render(<MissionSignatoryProfileView data={data} />);
45
+ render(<MissionSignatoryProfileView content={content} />);
31
46
 
32
47
  // Tab labels
33
48
  expect(screen.getByText('Governance')).toBeInTheDocument();
34
49
  expect(screen.getByText('Assessment')).toBeInTheDocument();
35
- expect(screen.getByText('Planning')).toBeInTheDocument();
50
+ expect(screen.getByText('Planning & Target')).toBeInTheDocument();
36
51
  expect(screen.getByText('Action')).toBeInTheDocument();
37
52
  });
38
53
 
39
54
  it('switches tabs and renders corresponding content', () => {
40
- render(<MissionSignatoryProfileView data={data} />);
55
+ render(<MissionSignatoryProfileView content={content} />);
41
56
 
42
57
  fireEvent.click(screen.getByText('Governance'));
43
58
  expect(screen.getByText('Mocked Governance')).toBeInTheDocument();
@@ -45,10 +60,16 @@ describe('MissionSignatoryProfileView', () => {
45
60
  fireEvent.click(screen.getByText('Assessment'));
46
61
  expect(screen.getByText('Mocked Assessment')).toBeInTheDocument();
47
62
 
48
- fireEvent.click(screen.getByText('Planning'));
63
+ fireEvent.click(screen.getByText('Planning & Target'));
49
64
  expect(screen.getByText('Mocked Planning')).toBeInTheDocument();
50
65
 
51
66
  fireEvent.click(screen.getByText('Action'));
52
67
  expect(screen.getByText('Mocked Action')).toBeInTheDocument();
53
68
  });
69
+
70
+ it('renders footer disclaimer text if present', () => {
71
+ render(<MissionSignatoryProfileView content={content} />);
72
+ expect(screen.getByText('Disclaimer Title')).toBeInTheDocument();
73
+ expect(screen.getByText('This is a disclaimer.')).toBeInTheDocument();
74
+ });
54
75
  });
@@ -0,0 +1,16 @@
1
+ import { Statistic } from 'semantic-ui-react';
2
+
3
+ const StatisticSection = ({ statistic }) => {
4
+ return (
5
+ <Statistic.Group widths="two" size="small">
6
+ {statistic.map((stat, index) => (
7
+ <Statistic key={index}>
8
+ <Statistic.Value>{stat.value}</Statistic.Value>
9
+ <Statistic.Label>{stat.label}</Statistic.Label>
10
+ </Statistic>
11
+ ))}
12
+ </Statistic.Group>
13
+ );
14
+ };
15
+
16
+ export default StatisticSection;
@@ -65,11 +65,7 @@ const ActionPagesTab = ({ result }) => {
65
65
  const { Title, Abstract, Abstract_Line } = result.action_text?.[0] || [];
66
66
  const actions = result.actions || [];
67
67
 
68
- const sortedActions = [...actions].sort((a, b) => {
69
- const aNum = parseInt(a.Action_Id.replace(/\D/g, ''), 10);
70
- const bNum = parseInt(b.Action_Id.replace(/\D/g, ''), 10);
71
- return aNum - bNum;
72
- });
68
+ const sortedActions = [...actions].sort((a, b) => a.Order - b.Order);
73
69
 
74
70
  return (
75
71
  <Tab.Pane>
@@ -85,7 +81,7 @@ const ActionPagesTab = ({ result }) => {
85
81
  return (
86
82
  <div key={index} className="section-wrapper">
87
83
  <h5 className="section-title">
88
- <span className="section-number">{action.Action_Id}. </span>
84
+ <span className="section-number">{action.Order}. </span>
89
85
  <HTMLField value={{ data: formatTextToHTML(action?.Action) }} />
90
86
  </h5>
91
87
 
@@ -1,4 +1,3 @@
1
- import React from 'react';
2
1
  import { Tab, Image, Segment, Item } from 'semantic-ui-react';
3
2
  import { Callout } from '@eeacms/volto-eea-design-system/ui';
4
3
  import { HTMLField } from '@eeacms/volto-cca-policy/helpers';
@@ -1,9 +1,9 @@
1
- import React from 'react';
2
1
  import { Tab } from 'semantic-ui-react';
3
2
  import { Callout } from '@eeacms/volto-eea-design-system/ui';
4
3
  import { HTMLField } from '@eeacms/volto-cca-policy/helpers';
5
4
  import { formatTextToHTML } from '@eeacms/volto-cca-policy/utils';
6
5
  import AccordionList from '../AccordionList';
6
+ import StatisticSection from '../StatisticSection';
7
7
 
8
8
  const GovernanceTab = ({ result }) => {
9
9
  const {
@@ -13,14 +13,43 @@ const GovernanceTab = ({ result }) => {
13
13
  Describe,
14
14
  Provide_Title,
15
15
  Provide,
16
+ Statistic_Area,
17
+ Statistic_Area_Label,
18
+ Statistic_Jurisdiction_Range,
19
+ Statistic_Jurisdiction_Range_Label,
20
+ Statistic_Population_Size,
21
+ Statistic_Population_Size_Label,
22
+ Statistic_Population_Year,
23
+ Statistic_Population_Year_Label,
16
24
  } = result;
17
25
 
26
+ const statisticData = [
27
+ {
28
+ value: Statistic_Area,
29
+ label: Statistic_Area_Label,
30
+ },
31
+ {
32
+ value: Statistic_Jurisdiction_Range,
33
+ label: Statistic_Jurisdiction_Range_Label,
34
+ },
35
+ {
36
+ value: Statistic_Population_Size,
37
+ label: Statistic_Population_Size_Label,
38
+ },
39
+ {
40
+ value: Statistic_Population_Year,
41
+ label: Statistic_Population_Year_Label,
42
+ },
43
+ ].filter((stat) => stat.value && stat.label);
44
+
18
45
  return (
19
46
  <Tab.Pane>
20
47
  {Title && <h2>{Title}</h2>}
21
48
 
22
49
  {Introduction && <Callout>{Introduction}</Callout>}
23
50
 
51
+ <StatisticSection statistic={statisticData} />
52
+
24
53
  {Describe_Title && <h3>{Describe_Title}</h3>}
25
54
 
26
55
  {Describe && <HTMLField value={{ data: formatTextToHTML(Describe) }} />}
@@ -116,6 +116,103 @@ body.subsite-mkh {
116
116
  #mega-menu .ui.accordion .content {
117
117
  background: @subsiteBackgroundGradient;
118
118
  }
119
+
120
+ /* Mission signatory profile */
121
+ .signatory-profile {
122
+ .ui.items.items-group {
123
+ margin: 2em 0 !important;
124
+ }
125
+
126
+ .column > .ui.segment {
127
+ background-color: #fff !important;
128
+ }
129
+
130
+ .section-wrapper-info {
131
+ display: flex;
132
+ justify-content: space-between;
133
+ font-size: 14px;
134
+
135
+ .date {
136
+ position: relative;
137
+ top: 5px;
138
+ }
139
+ }
140
+
141
+ .description > p {
142
+ margin-bottom: 1em;
143
+ }
144
+
145
+ .tab-section-wrapper {
146
+ padding: 1.5em;
147
+ margin: 2em 0;
148
+ background-color: #f9f9f9;
149
+
150
+ &.assessment {
151
+ .ui.accordion {
152
+ margin-top: 1em;
153
+
154
+ .content.active {
155
+ padding: 1rem 1rem !important;
156
+ background-color: @white;
157
+ }
158
+
159
+ .ui.segment.border {
160
+ border: 1px solid #e6e7e8;
161
+ }
162
+ }
163
+ }
164
+ }
165
+
166
+ .section-wrapper {
167
+ padding: 1em;
168
+ margin: 1em 0;
169
+ background-color: #f9f9f9;
170
+
171
+ .section-title {
172
+ display: flex;
173
+ align-items: baseline;
174
+ gap: 0.5em;
175
+ }
176
+
177
+ .ui.accordion {
178
+ margin-top: 1em;
179
+
180
+ .content.active {
181
+ padding-bottom: 1rem !important;
182
+ }
183
+ }
184
+
185
+ .small-label {
186
+ font-size: 1em;
187
+ }
188
+ }
189
+
190
+ .section-number {
191
+ color: @pineGreen;
192
+ }
193
+
194
+ strong.date {
195
+ margin-right: 0.5em;
196
+ }
197
+
198
+ .items-group {
199
+ display: block !important;
200
+ column-count: 2;
201
+
202
+ .item {
203
+ padding: 0.5em 0 !important;
204
+ break-inside: avoid-column;
205
+
206
+ .content {
207
+ padding-left: 0.5rem !important;
208
+ }
209
+ }
210
+ }
211
+
212
+ .footer-text {
213
+ margin-top: 3em;
214
+ }
215
+ }
119
216
  }
120
217
 
121
218
  /* Latest news updates, Latest events */
@@ -1,23 +0,0 @@
1
- import React from 'react';
2
-
3
- import {
4
- Statistic,
5
- StatisticValue,
6
- StatisticLabel,
7
- StatisticGroup,
8
- } from 'semantic-ui-react';
9
-
10
- const StatisticsSection = ({ statistics }) => {
11
- return (
12
- <StatisticGroup widths="two" size="small">
13
- {statistics.map((stat, index) => (
14
- <Statistic key={index}>
15
- <StatisticValue>{stat.value}</StatisticValue>
16
- <StatisticLabel>{stat.label}</StatisticLabel>
17
- </Statistic>
18
- ))}
19
- </StatisticGroup>
20
- );
21
- };
22
-
23
- export default StatisticsSection;
@@ -1,100 +0,0 @@
1
- @type: 'extra';
2
- @element: 'custom';
3
-
4
- @import (multiple, reference, optional) '../../theme.config';
5
-
6
- .signatories-profile {
7
- .ui.items.items-group {
8
- margin: 2em 0 !important;
9
- }
10
-
11
- .column > .ui.segment {
12
- background-color: #fff !important;
13
- }
14
-
15
- .section-wrapper-info {
16
- display: flex;
17
- justify-content: space-between;
18
- font-size: 14px;
19
-
20
- .date {
21
- position: relative;
22
- top: 5px;
23
- }
24
- }
25
-
26
- .description > p {
27
- margin-bottom: 1em;
28
- }
29
-
30
- .tab-section-wrapper {
31
- padding: 1.5em;
32
- margin: 2em 0;
33
- background-color: #f9f9f9;
34
-
35
- &.assessment {
36
- .ui.accordion {
37
- margin-top: 1em;
38
-
39
- .content.active {
40
- padding: 1rem 1rem !important;
41
- background-color: @white;
42
- }
43
-
44
- .ui.segment.border {
45
- border: 1px solid #e6e7e8;
46
- }
47
- }
48
- }
49
- }
50
-
51
- .section-wrapper {
52
- padding: 1em;
53
- margin: 1em 0;
54
- background-color: #f9f9f9;
55
-
56
- .section-title {
57
- display: flex;
58
- align-items: baseline;
59
- gap: 0.5em;
60
- }
61
-
62
- .ui.accordion {
63
- margin-top: 1em;
64
-
65
- .content.active {
66
- padding-bottom: 1rem !important;
67
- }
68
- }
69
-
70
- .small-label {
71
- font-size: 1em;
72
- }
73
- }
74
-
75
- .section-number {
76
- color: @pineGreen;
77
- }
78
-
79
- strong.date {
80
- margin-right: 0.5em;
81
- }
82
-
83
- .items-group {
84
- display: block !important;
85
- column-count: 2;
86
-
87
- .item {
88
- padding: 0.5em 0 !important;
89
- break-inside: avoid-column;
90
-
91
- .content {
92
- padding-left: 0.5rem !important;
93
- }
94
- }
95
- }
96
-
97
- .footer-text {
98
- margin-top: 3em;
99
- }
100
- }