@eeacms/volto-cca-policy 0.3.85 → 0.3.87

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.85](https://github.com/eea/volto-cca-policy/compare/1.0.0-alpha.1...0.3.85) - 14 October 2025
7
+ ### [0.3.87](https://github.com/eea/volto-cca-policy/compare/1.0.0-alpha.1...0.3.87) - 10 November 2025
8
8
 
9
9
  #### :rocket: Dependency updates
10
10
 
@@ -14,6 +14,10 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
14
14
 
15
15
  #### :bug: Bug Fixes
16
16
 
17
+ - fix(tests): increase code coverage [kreafox - [`66cd2b3`](https://github.com/eea/volto-cca-policy/commit/66cd2b39a9b7b026c171d99e2bf3b8a47b7cddd2)]
18
+ - fix(tests): update hyperlink text in PlanningTab [kreafox - [`05080e0`](https://github.com/eea/volto-cca-policy/commit/05080e0727730a5fe7c67d884ad6453eaf82081a)]
19
+ - fix(mission): adjust margins for nested lists and accordion padding [kreafox - [`1abf18f`](https://github.com/eea/volto-cca-policy/commit/1abf18fabe9efffa552ed2e6a8b57f9b1d59f7a6)]
20
+ - fix(mission): improve URL extraction logic - refs #291190 [kreafox - [`8e4c6e4`](https://github.com/eea/volto-cca-policy/commit/8e4c6e42dc35b4c940c39f9f25d587f66d0b242d)]
17
21
  - fix(mission): fix assessment risk numbering to match sorted order [kreafox - [`9ecea88`](https://github.com/eea/volto-cca-policy/commit/9ecea885394f1ae6ad63ffb03d8a10cd706caffb)]
18
22
  - fix: duplicated code - make ItemsSection reusable [kreafox - [`52e2625`](https://github.com/eea/volto-cca-policy/commit/52e2625914f699c194f75d561f97959ab6c21fbf)]
19
23
  - fix: add missing props for title block [kreafox - [`1d8efa0`](https://github.com/eea/volto-cca-policy/commit/1d8efa0136960261196e7585f89f4ff7db75ae17)]
@@ -21,6 +25,9 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
21
25
 
22
26
  #### :nail_care: Enhancements
23
27
 
28
+ - change(mission): update download fields for CSV export for mission funding search - refs #293691 [kreafox - [`7451c66`](https://github.com/eea/volto-cca-policy/commit/7451c6698a4160e580e39cb4b38a87cf38dd49d8)]
29
+ - change(mission): add third level for sectors and hazards - refs #291189 [kreafox - [`5cf352c`](https://github.com/eea/volto-cca-policy/commit/5cf352ce46284b3cbd106276b60a1d4fea89235d)]
30
+ - refactor(mission): simplify sector rendering logic in Action tab [kreafox - [`8413ccc`](https://github.com/eea/volto-cca-policy/commit/8413cccfd67e9a598f88474b8a034e7998063d23)]
24
31
  - change(mission): improve AccordionList [kreafox - [`cf1497f`](https://github.com/eea/volto-cca-policy/commit/cf1497ff50ff45cdb0bb8e995683969bb3e3c065)]
25
32
  - refactor(mission): remove unnecessary line breaks and simplify message rendering - refs #291190 [kreafox - [`430a123`](https://github.com/eea/volto-cca-policy/commit/430a12371b6e1c6a77ea65b6a434eda883568c64)]
26
33
  - refactor(mission): use ItemsSection in PlanningTab - refs #291190 [kreafox - [`9e96aaa`](https://github.com/eea/volto-cca-policy/commit/9e96aaac0686f6688b3406aca578b598882a9c29)]
@@ -40,6 +47,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
40
47
 
41
48
  #### :hammer_and_wrench: Others
42
49
 
50
+ - test: try to use specific version for plone-backend [kreafox - [`79c542e`](https://github.com/eea/volto-cca-policy/commit/79c542e8d55d2f1663b768c555880599634ae527)]
43
51
  - test(mission): add unit tests for NoDataReported and StatisticSection components [kreafox - [`36c6e36`](https://github.com/eea/volto-cca-policy/commit/36c6e36278124759240c896786f2ac0c20674730)]
44
52
  - test: resolve Jest errors in component tests [kreafox - [`6dbb735`](https://github.com/eea/volto-cca-policy/commit/6dbb73540e8301fcb42a4d52db7004f5a42db4d8)]
45
53
  - test: fix PlanningTab mock data to match component structure [kreafox - [`48e76e1`](https://github.com/eea/volto-cca-policy/commit/48e76e1e50e0c6d8a6a500fec3d1831419faeee9)]
@@ -129,8 +137,39 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
129
137
  - Add some loadable for components [Tiberiu Ichim - [`1793962`](https://github.com/eea/volto-cca-policy/commit/179396211c66a6a2465b2d1b6c0f2afc40fc7189)]
130
138
  - Refs #284961 - test [Tripon Eugen - [`c989f1f`](https://github.com/eea/volto-cca-policy/commit/c989f1f8638c0c5233c5c49f8673c9a2cdc7937e)]
131
139
  - Refs #284961 - add translations [Tripon Eugen - [`04ee988`](https://github.com/eea/volto-cca-policy/commit/04ee988c086d393b9b37ce1ea8d24f5e84f266aa)]
132
- ### [1.0.0-alpha.0](https://github.com/eea/volto-cca-policy/compare/0.3.84...1.0.0-alpha.0) - 15 July 2025
140
+ ### [1.0.0-alpha.0](https://github.com/eea/volto-cca-policy/compare/0.3.86...1.0.0-alpha.0) - 15 July 2025
133
141
 
142
+ ### [0.3.86](https://github.com/eea/volto-cca-policy/compare/0.3.85...0.3.86) - 31 October 2025
143
+
144
+ #### :bug: Bug Fixes
145
+
146
+ - fix(tests): increase code coverage [kreafox - [`66cd2b3`](https://github.com/eea/volto-cca-policy/commit/66cd2b39a9b7b026c171d99e2bf3b8a47b7cddd2)]
147
+ - fix(tests): update hyperlink text in PlanningTab [kreafox - [`05080e0`](https://github.com/eea/volto-cca-policy/commit/05080e0727730a5fe7c67d884ad6453eaf82081a)]
148
+ - fix(mission): adjust margins for nested lists and accordion padding [kreafox - [`1abf18f`](https://github.com/eea/volto-cca-policy/commit/1abf18fabe9efffa552ed2e6a8b57f9b1d59f7a6)]
149
+ - fix(mission): improve URL extraction logic - refs #291190 [kreafox - [`8e4c6e4`](https://github.com/eea/volto-cca-policy/commit/8e4c6e42dc35b4c940c39f9f25d587f66d0b242d)]
150
+
151
+ #### :nail_care: Enhancements
152
+
153
+ - change(mission): add third level for sectors and hazards - refs #291189 [kreafox - [`5cf352c`](https://github.com/eea/volto-cca-policy/commit/5cf352ce46284b3cbd106276b60a1d4fea89235d)]
154
+ - refactor(mission): simplify sector rendering logic in Action tab [kreafox - [`8413ccc`](https://github.com/eea/volto-cca-policy/commit/8413cccfd67e9a598f88474b8a034e7998063d23)]
155
+
156
+ #### :hammer_and_wrench: Others
157
+
158
+ - test: try to use specific version for plone-backend [kreafox - [`79c542e`](https://github.com/eea/volto-cca-policy/commit/79c542e8d55d2f1663b768c555880599634ae527)]
159
+ ### [0.3.85](https://github.com/eea/volto-cca-policy/compare/0.3.84...0.3.85) - 14 October 2025
160
+
161
+ #### :bug: Bug Fixes
162
+
163
+ - fix(mission): fix assessment risk numbering to match sorted order [kreafox - [`9ecea88`](https://github.com/eea/volto-cca-policy/commit/9ecea885394f1ae6ad63ffb03d8a10cd706caffb)]
164
+
165
+ #### :nail_care: Enhancements
166
+
167
+ - change(mission): improve AccordionList [kreafox - [`cf1497f`](https://github.com/eea/volto-cca-policy/commit/cf1497ff50ff45cdb0bb8e995683969bb3e3c065)]
168
+ - refactor(mission): remove unnecessary line breaks and simplify message rendering - refs #291190 [kreafox - [`430a123`](https://github.com/eea/volto-cca-policy/commit/430a12371b6e1c6a77ea65b6a434eda883568c64)]
169
+
170
+ #### :hammer_and_wrench: Others
171
+
172
+ - test(mission): add unit tests for NoDataReported and StatisticSection components [kreafox - [`36c6e36`](https://github.com/eea/volto-cca-policy/commit/36c6e36278124759240c896786f2ac0c20674730)]
134
173
  ### [0.3.84](https://github.com/eea/volto-cca-policy/compare/0.3.83...0.3.84) - 7 October 2025
135
174
 
136
175
  #### :bug: Bug Fixes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-cca-policy",
3
- "version": "0.3.85",
3
+ "version": "0.3.87",
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",
@@ -2,7 +2,12 @@ import '@testing-library/jest-dom';
2
2
  import { render, screen, fireEvent } from '@testing-library/react';
3
3
  import ImageGallery from './ImageGallery';
4
4
 
5
- jest.mock('react-slick', () => (props) => <div>React Slick Gallery</div>);
5
+ jest.mock('react-slick', () => {
6
+ const React = require('react');
7
+ return React.forwardRef((props, ref) => (
8
+ <div ref={ref}>React Slick Gallery</div>
9
+ ));
10
+ });
6
11
 
7
12
  const mockItems = [
8
13
  {
@@ -0,0 +1,70 @@
1
+ import '@testing-library/jest-dom';
2
+ import { render, screen } from '@testing-library/react';
3
+ import ItemsSection from './ItemsSection';
4
+ import defaultImage from '@eeacms/volto-cca-policy/../theme/assets/images/image-narrow.svg';
5
+
6
+ jest.mock('@eeacms/volto-cca-policy/utils', () => ({
7
+ normalizeImageFileName: (filename) => filename?.toLowerCase() || '',
8
+ }));
9
+
10
+ describe('ItemsSection', () => {
11
+ it('renders nothing when items is empty or undefined', () => {
12
+ const { container, rerender } = render(<ItemsSection items={[]} />);
13
+ expect(container.firstChild).toBeNull();
14
+
15
+ rerender(<ItemsSection />);
16
+ expect(container.firstChild).toBeNull();
17
+ });
18
+
19
+ it('renders default image when item has no icon', () => {
20
+ const mockItems = [{ Sector: 'Water' }];
21
+ render(<ItemsSection items={mockItems} field="Sector" iconPath="sector" />);
22
+
23
+ const image = screen.getByRole('img');
24
+ expect(image).toHaveAttribute('src', defaultImage);
25
+ expect(screen.getByText('Water')).toBeInTheDocument();
26
+ });
27
+
28
+ it('renders custom image when icon is provided', () => {
29
+ const mockItems = [{ Sector: 'Energy', Icon: 'Solar' }];
30
+ render(<ItemsSection items={mockItems} field="Sector" iconPath="sector" />);
31
+
32
+ const image = screen.getByRole('img');
33
+ expect(image).toHaveAttribute(
34
+ 'src',
35
+ '/en/mission/icons/signatory-reporting/sector/solar/@@images/image',
36
+ );
37
+ expect(screen.getByText('Energy')).toBeInTheDocument();
38
+ });
39
+
40
+ it('applies "column" class when more than 3 items exist', () => {
41
+ const mockItems = [
42
+ { Sector: 'Water' },
43
+ { Sector: 'Energy' },
44
+ { Sector: 'Agriculture' },
45
+ { Sector: 'Transport' },
46
+ ];
47
+
48
+ const { container } = render(
49
+ <ItemsSection items={mockItems} field="Sector" iconPath="sector" />,
50
+ );
51
+
52
+ const group = container.querySelector('.items-group');
53
+ expect(group).toHaveClass('column');
54
+ });
55
+
56
+ it('does not apply "column" class when 3 or fewer items', () => {
57
+ const mockItems = [
58
+ { Sector: 'Water' },
59
+ { Sector: 'Energy' },
60
+ { Sector: 'Agriculture' },
61
+ ];
62
+
63
+ const { container } = render(
64
+ <ItemsSection items={mockItems} field="Sector" iconPath="sector" />,
65
+ );
66
+
67
+ const group = container.querySelector('.items-group');
68
+ expect(group).not.toHaveClass('column');
69
+ });
70
+ });
@@ -1,4 +1,3 @@
1
- import { useLocation } from 'react-router-dom';
2
1
  import { Tab, Grid } 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';
@@ -8,15 +7,10 @@ import NoDataReported from '../NoDataReported';
8
7
  import ItemsSection from '../ItemsSection';
9
8
 
10
9
  const ActionTabContent = ({ action }) => {
11
- const location = useLocation();
12
10
  const hasHazards = action?.Climate_Hazards?.length > 0;
13
11
  const hasSectors = action?.Sectors?.length > 0;
14
12
  const hasBenefits = action?.Co_Benefits?.length > 0;
15
13
 
16
- const isSandbox = location.pathname.includes(
17
- '/mission/sandbox/eea-sandbox/signatory-reporting',
18
- );
19
-
20
14
  return (
21
15
  <>
22
16
  <Grid columns="12">
@@ -34,7 +28,8 @@ const ActionTabContent = ({ action }) => {
34
28
  {hasSectors && (
35
29
  <>
36
30
  <h5 className="small-label">{action.Sectors_Label}</h5>
37
- {isSandbox ? (
31
+
32
+ {action.Sectors.some((s) => s.Icon) ? (
38
33
  <ItemsSection
39
34
  items={action.Sectors}
40
35
  field="Sector"
@@ -110,18 +110,52 @@ const AssessmentTab = ({ result, general_text }) => {
110
110
 
111
111
  <br />
112
112
 
113
- {assessment_hazards_sectors.length > 0 && (
113
+ {assessment_hazards_sectors?.length > 0 && (
114
114
  <AccordionList
115
- accordions={assessment_hazards_sectors.map((category) => ({
116
- title: category.Hazard,
117
- content: (
118
- <ul>
119
- {category.Sectors.map((sector, idx) => (
120
- <li key={idx}>{sector}</li>
121
- ))}
122
- </ul>
123
- ),
124
- }))}
115
+ accordions={assessment_hazards_sectors.flatMap((item) => {
116
+ // Beta data (Category > Hazards > Sectors)
117
+ if (item.Category && Array.isArray(item.Hazards)) {
118
+ return [
119
+ {
120
+ title: item.Category,
121
+ content: (
122
+ <ul>
123
+ {item.Hazards.map((hazard, index) => (
124
+ <li key={index}>
125
+ <strong>{hazard.Hazard}</strong>
126
+ {Array.isArray(hazard.Sectors) &&
127
+ hazard.Sectors.length > 0 && (
128
+ <ul>
129
+ {hazard.Sectors.map((sector, sIndex) => (
130
+ <li key={sIndex}>{sector}</li>
131
+ ))}
132
+ </ul>
133
+ )}
134
+ </li>
135
+ ))}
136
+ </ul>
137
+ ),
138
+ },
139
+ ];
140
+ }
141
+
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
+ return [];
158
+ })}
125
159
  />
126
160
  )}
127
161
  </Tab.Pane>
@@ -6,6 +6,14 @@ jest.mock('@eeacms/volto-eea-design-system/ui', () => ({
6
6
  Callout: ({ children }) => <div>{children}</div>,
7
7
  }));
8
8
 
9
+ jest.mock('@eeacms/volto-cca-policy/helpers', () => ({
10
+ HTMLField: ({ value }) => <div>{value.data}</div>,
11
+ }));
12
+
13
+ jest.mock('../NoDataReported', () => ({ label }) => (
14
+ <div data-testid="no-data">{label}</div>
15
+ ));
16
+
9
17
  jest.mock('@eeacms/volto-cca-policy/utils', () => ({
10
18
  isEmpty: (arr) => !arr || arr.length === 0,
11
19
  formatTextToHTML: (text) => text,
@@ -38,13 +46,28 @@ const mockData = {
38
46
  Please_Explain: 'Explanation content here.',
39
47
  },
40
48
  ],
49
+ assessment_hazards_sectors: [
50
+ {
51
+ Category: 'Water Management',
52
+ Hazards: [
53
+ { Hazard: 'Flooding', Sectors: ['Agriculture', 'Health'] },
54
+ { Hazard: 'Drought', Sectors: ['Energy'] },
55
+ ],
56
+ },
57
+ {
58
+ Category: null,
59
+ Hazards: [
60
+ { Hazard: 'Storms', Sectors: ['Transport', 'Tourism'] },
61
+ { Hazard: 'Heatwaves', Sectors: ['Health'] },
62
+ ],
63
+ },
64
+ ],
41
65
  };
42
66
 
43
67
  describe('AssessmentTab', () => {
44
- it('renders core sections and nested tabs', () => {
68
+ it('renders all major sections correctly', () => {
45
69
  render(<AssessmentTab result={mockData} />);
46
70
 
47
- // General headings
48
71
  expect(screen.getByText('Assessment Title')).toBeInTheDocument();
49
72
  expect(screen.getByText('Assessment Subheading')).toBeInTheDocument();
50
73
  expect(
@@ -56,8 +79,54 @@ describe('AssessmentTab', () => {
56
79
  expect(screen.getByText('Hazards')).toBeInTheDocument();
57
80
  expect(screen.getByText('Hazards abstract text.')).toBeInTheDocument();
58
81
 
59
- // Items section
60
82
  expect(screen.getByText('Factor A')).toBeInTheDocument();
61
83
  expect(screen.getByText('Factor B')).toBeInTheDocument();
62
84
  });
85
+
86
+ it('renders assessment risks accordion with link and details', () => {
87
+ render(<AssessmentTab result={mockData} />);
88
+
89
+ expect(
90
+ screen.getByText('1. Risk Attachment Title - 2023'),
91
+ ).toBeInTheDocument();
92
+
93
+ expect(screen.getByText('Explore this risk')).toBeInTheDocument();
94
+ expect(screen.getByText('Details')).toBeInTheDocument();
95
+ expect(screen.getByText('Explanation content here.')).toBeInTheDocument();
96
+
97
+ const link = screen.getByRole('link', { name: 'Explore this risk' });
98
+ expect(link).toHaveAttribute('href', 'https://example.com');
99
+ });
100
+
101
+ it('renders beta-style hazards (Category > Hazard > Sector)', () => {
102
+ render(<AssessmentTab result={mockData} />);
103
+
104
+ expect(screen.getByText('Water Management')).toBeInTheDocument();
105
+ expect(screen.getByText('Flooding')).toBeInTheDocument();
106
+ expect(screen.getByText('Drought')).toBeInTheDocument();
107
+
108
+ expect(screen.getByText('Agriculture')).toBeInTheDocument();
109
+ expect(screen.getAllByText('Health').length).toBeGreaterThanOrEqual(1);
110
+ expect(screen.getByText('Energy')).toBeInTheDocument();
111
+ });
112
+
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
+ it('renders NoDataReported when no data available', () => {
124
+ render(
125
+ <AssessmentTab
126
+ result={{}}
127
+ general_text={{ No_Data_Reported_Label: 'No info' }}
128
+ />,
129
+ );
130
+ expect(screen.getByTestId('no-data')).toHaveTextContent('No info');
131
+ });
63
132
  });
@@ -159,27 +159,27 @@ const PlanningTab = ({ result, general_text }) => {
159
159
  </p>
160
160
  )}
161
161
 
162
- {action?.Name_Of_Plan_And_Hyperlink && (
163
- <p>
164
- {(() => {
165
- const { name, url } = extractPlanNameAndURL(
166
- action.Name_Of_Plan_And_Hyperlink,
167
- );
168
- return url ? (
169
- <a href={url} title={name} target="_blank" rel="noreferrer">
170
- <strong>
171
- {action.Further_Information_Link_Text}
172
- {name && ` [${name}]`}
173
- </strong>
162
+ {(() => {
163
+ const { url } = extractPlanNameAndURL(
164
+ action?.Name_Of_Plan_And_Hyperlink,
165
+ );
166
+
167
+ if (url && action?.Further_Information_Link_Text) {
168
+ return (
169
+ <p>
170
+ <a href={url} target="_blank" rel="noreferrer">
171
+ <strong>{action.Further_Information_Link_Text}</strong>
174
172
  </a>
175
- ) : null;
176
- })()}
177
- </p>
178
- )}
173
+ </p>
174
+ );
175
+ }
176
+
177
+ return null;
178
+ })()}
179
179
 
180
180
  {action?.Attachment && (
181
181
  <p>
182
- <a href={action.Attachment}>
182
+ <a href={action.Attachment} target="_blank" rel="noreferrer">
183
183
  <strong>{action.Explore_Plan_Link_Text}</strong>
184
184
  </a>
185
185
  </p>
@@ -105,7 +105,7 @@ describe('PlanningTab', () => {
105
105
  it('renders hyperlink with extracted name and URL', () => {
106
106
  const { getByText } = render(<PlanningTab result={mockResult} />);
107
107
 
108
- const link = getByText(/More Info \[Plan Example\]/);
108
+ const link = getByText('More Info');
109
109
  expect(link).toBeInTheDocument();
110
110
  expect(link.closest('a')).toHaveAttribute('href', 'https://plan-link.com');
111
111
  });
package/src/constants.js CHANGED
@@ -21,6 +21,73 @@ export const download_fields = [
21
21
  { field: 'cca_partner_contributors', name: 'Observatory impacts' },
22
22
  ];
23
23
 
24
+ export const download_mission_funding_fields = [
25
+ { field: 'about', name: 'About' },
26
+ { field: 'title', name: 'Title' },
27
+ { field: 'created', name: 'Creation Date' },
28
+ { field: 'issued', name: 'Issued Date' },
29
+ {
30
+ field: 'cca_objective_funding_programme',
31
+ name: 'Objective of the funding programme',
32
+ },
33
+ {
34
+ field: 'cca_funding_type',
35
+ name: 'Type of funding',
36
+ },
37
+ {
38
+ field: 'cca_funding_rate',
39
+ name: 'Funding rate (percentage of covered costs)',
40
+ },
41
+ {
42
+ field: 'cca_budget_range',
43
+ name: 'Expected budget range of proposals',
44
+ },
45
+ {
46
+ field: 'cca_is_blended',
47
+ name: 'Can the received funding be combined with other funding sources (blended)?',
48
+ },
49
+ {
50
+ field: 'cca_is_consortium_required',
51
+ name: 'Is a Consortium required to apply for the funding?',
52
+ },
53
+ {
54
+ field: 'cca_administering_authority',
55
+ name: 'Administering authority',
56
+ },
57
+ {
58
+ field: 'cca_publication_page',
59
+ name: 'Publication page',
60
+ },
61
+ {
62
+ field: 'cca_general_information',
63
+ name: 'General information',
64
+ },
65
+ {
66
+ field: 'cca_further_information',
67
+ name: 'Further information',
68
+ },
69
+ {
70
+ field: 'spatial',
71
+ name: 'Countries where the funding opportunity is offered',
72
+ },
73
+ {
74
+ field: 'cca_funding_region',
75
+ name: 'Region where the funding is offered',
76
+ },
77
+ {
78
+ field: 'cca_rast_steps',
79
+ name: 'RAST step(s) of relevance',
80
+ },
81
+ {
82
+ field: 'cca_eligible_entities',
83
+ name: 'Eligible to receive funding',
84
+ },
85
+ {
86
+ field: 'cca_adaptation_sectors',
87
+ name: 'Adaptation Sectors',
88
+ },
89
+ ];
90
+
24
91
  export const eea_languages = [
25
92
  { name: 'български', code: 'bg' },
26
93
  { name: 'Español', code: 'es' },
@@ -1,5 +1,6 @@
1
1
  import { mergeConfig } from '@eeacms/search';
2
2
  import { getClientProxyAddress } from '../utils';
3
+ import { download_mission_funding_fields } from '../../constants';
3
4
 
4
5
  import facets from './facets-funding';
5
6
 
@@ -29,6 +30,9 @@ export default function installMissionFundingSearch(config) {
29
30
  },
30
31
  };
31
32
 
33
+ config.searchui.missionFundingSearch.download_fields =
34
+ download_mission_funding_fields;
35
+
32
36
  const { missionFundingSearch } = config.searchui;
33
37
  missionFundingSearch.permanentFilters.push({
34
38
  bool: {
package/src/utils.js CHANGED
@@ -113,24 +113,29 @@ const trimTrailingChars = (str) => {
113
113
  export const extractPlanNameAndURL = (text) => {
114
114
  if (!text) return { name: '', url: '' };
115
115
 
116
- // Match URL inside parentheses
117
- const parenthesisMatch = text.match(/\((https?:\/\/[^\s)]+)\)/);
118
- // Match first direct URL not inside parentheses
119
- const directMatch = text.match(/https?:\/\/[^\s,;)]+/);
120
- const url = parenthesisMatch?.[1] || directMatch?.[0] || '';
116
+ // Match all URLs
117
+ const urls = text.match(/https?:\/\/[^\s,;)]+/g) || [];
121
118
 
122
119
  let name = text;
120
+ let url = '';
123
121
 
124
- if (url) {
125
- // Remove URL and any punctuation before it
126
- name = name.replace(`(${url})`, '').replace(url, '');
127
- name = trimTrailingChars(name).trim();
122
+ if (urls.length > 1) {
123
+ // Edge case like Rotterdam: use second URL as the actual link
124
+ name = text.split(urls[0])[0] || urls[0]; // name is before or equals first URL
125
+ url = urls[1];
126
+ } else {
127
+ const parenthesisMatch = text.match(/\((https?:\/\/[^\s)]+)\)/);
128
+ const directMatch = text.match(/https?:\/\/[^\s,;)]+/);
129
+ url = parenthesisMatch?.[1] || directMatch?.[0] || '';
130
+
131
+ if (url) {
132
+ name = text.replace(`(${url})`, '').replace(url, '');
133
+ }
128
134
  }
129
135
 
130
- return {
131
- name: name,
132
- url,
133
- };
136
+ name = trimTrailingChars(name).trim();
137
+
138
+ return { name, url };
134
139
  };
135
140
 
136
141
  export const isEmpty = (arr) => !Array.isArray(arr) || arr.length === 0;
@@ -112,6 +112,11 @@ body.subsite-mkh {
112
112
  margin: 2em 0;
113
113
  }
114
114
 
115
+ ul > li > ul {
116
+ margin-top: 0.3em;
117
+ margin-bottom: 1em;
118
+ }
119
+
115
120
  .sectors-introduction {
116
121
  margin-top: 3em;
117
122
  }
@@ -178,6 +183,12 @@ body.subsite-mkh {
178
183
  margin-bottom: 1em;
179
184
  }
180
185
 
186
+ .ui.accordion {
187
+ .content.active {
188
+ padding: 1rem 1rem !important;
189
+ }
190
+ }
191
+
181
192
  .tab-section-wrapper {
182
193
  padding: 1.5em;
183
194
  margin: 2em 0;