@eeacms/volto-cca-policy 0.3.24 → 0.3.26
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 +40 -0
- package/package.json +1 -1
- package/src/components/manage/Blocks/MissionSignatoriesProfile/AccordionList.test.jsx +33 -0
- package/src/components/manage/Blocks/MissionSignatoriesProfile/MissionSignatoriesProfileView.js +19 -6
- package/src/components/manage/Blocks/MissionSignatoriesProfile/MissionSignatoriesProfileView.test.jsx +89 -25
- package/src/components/manage/Blocks/MissionSignatoriesProfile/TabSections/AssessmentTab.jsx +20 -1
- package/src/components/manage/Blocks/MissionSignatoriesProfile/TabSections/GovernanceTab.jsx +8 -64
- package/src/components/manage/Blocks/MissionSignatoriesProfile/TabSections/GovernanceTab.test.jsx +20 -0
- package/src/components/manage/Blocks/MissionSignatoriesProfile/TabSections/PlanningTab.jsx +182 -108
- package/src/components/manage/Blocks/MissionSignatoriesProfile/TabSections/PlanningTab.test.jsx +110 -0
- package/src/components/manage/Blocks/MissionSignatoriesProfile/style.less +21 -5
- package/src/constants.js +51 -0
- package/src/index.js +3 -29
- package/src/search/cca/config.js +4 -23
- package/src/search/common.js +39 -36
- package/src/search/health_observatory/config-health.js +2 -2
- package/src/search/vocabulary.js +7 -3
- package/src/utils.js +35 -5
- package/src/components/manage/Blocks/MissionSignatoriesProfile/ItemsSection.jsx +0 -54
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,46 @@ 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.26](https://github.com/eea/volto-cca-policy/compare/0.3.25...0.3.26) - 15 April 2025
|
|
8
|
+
|
|
9
|
+
#### :rocket: New Features
|
|
10
|
+
|
|
11
|
+
- feat: add extractFirstURL to parse first URL from text; update formatTextToHTML - refs #285361 [kreafox - [`a348454`](https://github.com/eea/volto-cca-policy/commit/a348454d52a06c4cbd668a7ffeaebed74d4a6788)]
|
|
12
|
+
|
|
13
|
+
#### :nail_care: Enhancements
|
|
14
|
+
|
|
15
|
+
- change: better link handler, update planning section, update tests - refs #285361 [kreafox - [`547fbb7`](https://github.com/eea/volto-cca-policy/commit/547fbb7ac308c274b94ff961b4abbae629adf93e)]
|
|
16
|
+
- change: update Governance section - refs #285296 [kreafox - [`0a9b924`](https://github.com/eea/volto-cca-policy/commit/0a9b92433239cf8d288885e561d6ecdd1beac6b5)]
|
|
17
|
+
|
|
18
|
+
#### :house: Internal changes
|
|
19
|
+
|
|
20
|
+
- style: Automated code fix [eea-jenkins - [`7396574`](https://github.com/eea/volto-cca-policy/commit/7396574df65205350cedb1e105927cb9d01ce3ae)]
|
|
21
|
+
- style: Automated code fix [eea-jenkins - [`2f6ca50`](https://github.com/eea/volto-cca-policy/commit/2f6ca50ad766066511659ac8dd85a3daceeca1d8)]
|
|
22
|
+
|
|
23
|
+
### [0.3.25](https://github.com/eea/volto-cca-policy/compare/0.3.24...0.3.25) - 14 April 2025
|
|
24
|
+
|
|
25
|
+
#### :bug: Bug Fixes
|
|
26
|
+
|
|
27
|
+
- fix: code cleanup [kreafox - [`6608927`](https://github.com/eea/volto-cca-policy/commit/660892792e10ef6f38c66d8f2d6b7f2993973bdf)]
|
|
28
|
+
|
|
29
|
+
#### :nail_care: Enhancements
|
|
30
|
+
|
|
31
|
+
- change: update planning section, add more tests - refs #285361 [kreafox - [`1d148c8`](https://github.com/eea/volto-cca-policy/commit/1d148c87f0f523effdf7399d7f8a1ddc4620e03e)]
|
|
32
|
+
- change: update planning section - refs #285361 [kreafox - [`50de23f`](https://github.com/eea/volto-cca-policy/commit/50de23f8e75053602b7d0bc1441ae1c59fe0944d)]
|
|
33
|
+
|
|
34
|
+
#### :house: Internal changes
|
|
35
|
+
|
|
36
|
+
- style: Automated code fix [eea-jenkins - [`e4f700e`](https://github.com/eea/volto-cca-policy/commit/e4f700ea7bcb425ae168308d47729ec59b15b2c4)]
|
|
37
|
+
|
|
38
|
+
#### :hammer_and_wrench: Others
|
|
39
|
+
|
|
40
|
+
- Remove console log [Tiberiu Ichim - [`a5ae067`](https://github.com/eea/volto-cca-policy/commit/a5ae06713b54cb1f5fce475827db0a8cd678ecf0)]
|
|
41
|
+
- More langs [Tiberiu Ichim - [`e17b887`](https://github.com/eea/volto-cca-policy/commit/e17b8870eb9e0cdadcab3eca126119287fd2bac2)]
|
|
42
|
+
- test: increase code coverage [kreafox - [`7aeb818`](https://github.com/eea/volto-cca-policy/commit/7aeb818b31fcf2c5225f0b4a6d0294664313b8aa)]
|
|
43
|
+
- increase code coverage [kreafox - [`f82df41`](https://github.com/eea/volto-cca-policy/commit/f82df41ed61fbd901fc5013d966f745c2a97f315)]
|
|
44
|
+
- fix tests [kreafox - [`cf4d267`](https://github.com/eea/volto-cca-policy/commit/cf4d2677c523609b0387f6d8142cb1ad58f0353e)]
|
|
45
|
+
- fix tests [kreafox - [`2151ffc`](https://github.com/eea/volto-cca-policy/commit/2151ffc3d27ff41bd7e72c6c0f373274925e11e8)]
|
|
46
|
+
- fix tests [kreafox - [`3971083`](https://github.com/eea/volto-cca-policy/commit/3971083f85a79d6f99d15b622ca8140a67b1a665)]
|
|
7
47
|
### [0.3.24](https://github.com/eea/volto-cca-policy/compare/0.3.23...0.3.24) - 11 April 2025
|
|
8
48
|
|
|
9
49
|
#### :rocket: Dependency updates
|
package/package.json
CHANGED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import '@testing-library/jest-dom';
|
|
3
|
+
import { render, fireEvent } from '@testing-library/react';
|
|
4
|
+
import AccordionList from './AccordionList';
|
|
5
|
+
|
|
6
|
+
describe('AccordionList', () => {
|
|
7
|
+
const mockAccordions = [
|
|
8
|
+
{ title: 'Section 1', content: 'Content for section 1' },
|
|
9
|
+
{ title: 'Section 2', content: 'Content for section 2' },
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
it('renders all accordion titles', () => {
|
|
13
|
+
const { getByText } = render(<AccordionList accordions={mockAccordions} />);
|
|
14
|
+
expect(getByText('Section 1')).toBeInTheDocument();
|
|
15
|
+
expect(getByText('Section 2')).toBeInTheDocument();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('toggles accordion content on title click', () => {
|
|
19
|
+
const { getByText, container } = render(
|
|
20
|
+
<AccordionList accordions={mockAccordions} />,
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
const contentDiv = container.querySelector('.content');
|
|
24
|
+
|
|
25
|
+
expect(contentDiv).not.toHaveClass('active');
|
|
26
|
+
|
|
27
|
+
fireEvent.click(getByText('Section 1'));
|
|
28
|
+
expect(contentDiv).toHaveClass('active');
|
|
29
|
+
|
|
30
|
+
fireEvent.click(getByText('Section 1'));
|
|
31
|
+
expect(contentDiv).not.toHaveClass('active');
|
|
32
|
+
});
|
|
33
|
+
});
|
package/src/components/manage/Blocks/MissionSignatoriesProfile/MissionSignatoriesProfileView.js
CHANGED
|
@@ -11,7 +11,9 @@ import './style.less';
|
|
|
11
11
|
|
|
12
12
|
const MissionSignatoriesProfileView = (props) => {
|
|
13
13
|
const { data } = props;
|
|
14
|
-
const result = data?._v_results
|
|
14
|
+
const result = data?._v_results || {};
|
|
15
|
+
const governance = result?.governance?.[0] || {};
|
|
16
|
+
|
|
15
17
|
// const dataJson = JSON.parse(result?.Cooperation_Experience);
|
|
16
18
|
const [activeIndex, setActiveIndex] = React.useState(0);
|
|
17
19
|
|
|
@@ -23,7 +25,9 @@ const MissionSignatoriesProfileView = (props) => {
|
|
|
23
25
|
'DescribeDetailCooperationEnhance'
|
|
24
26
|
]
|
|
25
27
|
} */}
|
|
26
|
-
<
|
|
28
|
+
<h2>{result?.planning_titles?.[0].Signatory}</h2>
|
|
29
|
+
|
|
30
|
+
<br />
|
|
27
31
|
|
|
28
32
|
<Tab
|
|
29
33
|
menu={{
|
|
@@ -42,19 +46,28 @@ const MissionSignatoriesProfileView = (props) => {
|
|
|
42
46
|
},
|
|
43
47
|
{
|
|
44
48
|
menuItem: 'Governance',
|
|
45
|
-
render: () => <GovernanceTab result={
|
|
49
|
+
render: () => <GovernanceTab result={governance} />,
|
|
46
50
|
},
|
|
47
51
|
{
|
|
48
52
|
menuItem: 'Assessment',
|
|
49
|
-
render: () => <AssessmentTab
|
|
53
|
+
render: () => <AssessmentTab />,
|
|
50
54
|
},
|
|
51
55
|
{
|
|
52
56
|
menuItem: 'Planning',
|
|
53
|
-
render: () =>
|
|
57
|
+
render: () => (
|
|
58
|
+
<PlanningTab
|
|
59
|
+
result={{
|
|
60
|
+
planning_goals: result?.planning_goals,
|
|
61
|
+
planning_titles: result?.planning_titles,
|
|
62
|
+
planning_climate_action: result?.planning_climate_action,
|
|
63
|
+
planning_climate_sectors: result?.planning_climate_sectors,
|
|
64
|
+
}}
|
|
65
|
+
/>
|
|
66
|
+
),
|
|
54
67
|
},
|
|
55
68
|
{
|
|
56
69
|
menuItem: 'Action Pages',
|
|
57
|
-
render: () => <ActionPagesTab
|
|
70
|
+
render: () => <ActionPagesTab />,
|
|
58
71
|
},
|
|
59
72
|
]}
|
|
60
73
|
/>
|
|
@@ -1,43 +1,107 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import '@testing-library/jest-dom/extend-expect';
|
|
3
|
-
import { render, fireEvent } from '@testing-library/react';
|
|
3
|
+
import { render, fireEvent, waitFor } from '@testing-library/react';
|
|
4
4
|
import MissionSignatoriesProfileView from './MissionSignatoriesProfileView';
|
|
5
5
|
|
|
6
|
+
// Mock components for tabs
|
|
7
|
+
jest.mock('./TabSections/IntroductionTab', () => () => (
|
|
8
|
+
<div>Introduction Content</div>
|
|
9
|
+
));
|
|
10
|
+
jest.mock('./TabSections/GovernanceTab', () => () => (
|
|
11
|
+
<div>Governance Content</div>
|
|
12
|
+
));
|
|
13
|
+
jest.mock('./TabSections/AssessmentTab', () => () => (
|
|
14
|
+
<div>Assessment Content</div>
|
|
15
|
+
));
|
|
16
|
+
jest.mock('./TabSections/PlanningTab', () => () => <div>Planning Content</div>);
|
|
17
|
+
jest.mock('./TabSections/ActionPagesTab', () => () => (
|
|
18
|
+
<div>Action Pages Content</div>
|
|
19
|
+
));
|
|
20
|
+
|
|
6
21
|
describe('MissionSignatoriesProfileView', () => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
};
|
|
22
|
+
const data = {
|
|
23
|
+
_v_results: {
|
|
24
|
+
planning_titles: [{ Signatory: 'Test Signatory Title' }],
|
|
25
|
+
planning_goals: [],
|
|
26
|
+
planning_climate_action: [],
|
|
27
|
+
planning_climate_sectors: [],
|
|
28
|
+
governance: [{}],
|
|
29
|
+
},
|
|
30
|
+
};
|
|
17
31
|
|
|
32
|
+
it('should render the component with data and tabs', () => {
|
|
18
33
|
const { getByText } = render(<MissionSignatoriesProfileView data={data} />);
|
|
19
34
|
|
|
20
|
-
expect(getByText('Test Signatory')).toBeInTheDocument();
|
|
21
35
|
expect(getByText('Governance')).toBeInTheDocument();
|
|
22
36
|
expect(getByText('Assessment')).toBeInTheDocument();
|
|
23
37
|
expect(getByText('Planning')).toBeInTheDocument();
|
|
24
38
|
expect(getByText('Action Pages')).toBeInTheDocument();
|
|
39
|
+
expect(getByText('Introduction')).toBeInTheDocument();
|
|
25
40
|
});
|
|
26
41
|
|
|
27
|
-
it('should render
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
};
|
|
42
|
+
it('should render Signatory title', () => {
|
|
43
|
+
const { getByText } = render(<MissionSignatoriesProfileView data={data} />);
|
|
44
|
+
expect(getByText('Test Signatory Title')).toBeInTheDocument();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('should handle missing planning_titles gracefully', () => {
|
|
48
|
+
const data = { _v_results: { governance: [{}] } };
|
|
49
|
+
const { container } = render(<MissionSignatoriesProfileView data={data} />);
|
|
50
|
+
expect(container).toBeInTheDocument();
|
|
51
|
+
});
|
|
35
52
|
|
|
53
|
+
it('should handle empty _v_results object gracefully', () => {
|
|
54
|
+
const { getByText } = render(
|
|
55
|
+
<MissionSignatoriesProfileView data={{ _v_results: {} }} />,
|
|
56
|
+
);
|
|
57
|
+
expect(getByText('Introduction')).toBeInTheDocument();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('should handle completely missing data prop', () => {
|
|
61
|
+
const { getByText } = render(<MissionSignatoriesProfileView data={{}} />);
|
|
62
|
+
expect(getByText('Planning')).toBeInTheDocument();
|
|
63
|
+
expect(getByText('Introduction')).toBeInTheDocument();
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('should render all tab labels', () => {
|
|
67
|
+
const { getByText } = render(<MissionSignatoriesProfileView data={{}} />);
|
|
68
|
+
[
|
|
69
|
+
'Introduction',
|
|
70
|
+
'Governance',
|
|
71
|
+
'Assessment',
|
|
72
|
+
'Planning',
|
|
73
|
+
'Action Pages',
|
|
74
|
+
].forEach((label) => {
|
|
75
|
+
expect(getByText(label)).toBeInTheDocument();
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('should switch between tabs and display correct content', async () => {
|
|
36
80
|
const { getByText } = render(<MissionSignatoriesProfileView data={data} />);
|
|
37
|
-
|
|
38
|
-
fireEvent.click(
|
|
39
|
-
|
|
40
|
-
getByText('
|
|
41
|
-
)
|
|
81
|
+
|
|
82
|
+
fireEvent.click(getByText('Governance'));
|
|
83
|
+
await waitFor(() =>
|
|
84
|
+
expect(getByText('Governance Content')).toBeInTheDocument(),
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
fireEvent.click(getByText('Introduction'));
|
|
88
|
+
await waitFor(() =>
|
|
89
|
+
expect(getByText('Introduction Content')).toBeInTheDocument(),
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
fireEvent.click(getByText('Assessment'));
|
|
93
|
+
await waitFor(() =>
|
|
94
|
+
expect(getByText('Assessment Content')).toBeInTheDocument(),
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
fireEvent.click(getByText('Planning'));
|
|
98
|
+
await waitFor(() =>
|
|
99
|
+
expect(getByText('Planning Content')).toBeInTheDocument(),
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
fireEvent.click(getByText('Action Pages'));
|
|
103
|
+
await waitFor(() =>
|
|
104
|
+
expect(getByText('Action Pages Content')).toBeInTheDocument(),
|
|
105
|
+
);
|
|
42
106
|
});
|
|
43
107
|
});
|
package/src/components/manage/Blocks/MissionSignatoriesProfile/TabSections/AssessmentTab.jsx
CHANGED
|
@@ -10,10 +10,29 @@ import {
|
|
|
10
10
|
} from 'semantic-ui-react';
|
|
11
11
|
import { Callout } from '@eeacms/volto-eea-design-system/ui';
|
|
12
12
|
import AccordionList from './../AccordionList';
|
|
13
|
-
import ItemsSection from './../ItemsSection';
|
|
14
13
|
|
|
15
14
|
import image from '@eeacms/volto-cca-policy/../theme//assets/images/image-narrow.svg';
|
|
16
15
|
|
|
16
|
+
const ItemsSection = ({ items }) => {
|
|
17
|
+
return (
|
|
18
|
+
<ItemGroup className="items-group">
|
|
19
|
+
<Item>
|
|
20
|
+
<Image size="small" src={image} />
|
|
21
|
+
<ItemContent verticalAlign="middle">
|
|
22
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit
|
|
23
|
+
</ItemContent>
|
|
24
|
+
</Item>
|
|
25
|
+
|
|
26
|
+
<Item>
|
|
27
|
+
<Image size="small" src={image} />
|
|
28
|
+
<ItemContent verticalAlign="middle">
|
|
29
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit
|
|
30
|
+
</ItemContent>
|
|
31
|
+
</Item>
|
|
32
|
+
</ItemGroup>
|
|
33
|
+
);
|
|
34
|
+
};
|
|
35
|
+
|
|
17
36
|
const AssessmentTab = () => {
|
|
18
37
|
const [activeIndex, setActiveIndex] = React.useState(0);
|
|
19
38
|
return (
|
package/src/components/manage/Blocks/MissionSignatoriesProfile/TabSections/GovernanceTab.jsx
CHANGED
|
@@ -4,85 +4,29 @@ import { Callout } from '@eeacms/volto-eea-design-system/ui';
|
|
|
4
4
|
import { HTMLField } from '@eeacms/volto-cca-policy/helpers';
|
|
5
5
|
import { formatTextToHTML } from '@eeacms/volto-cca-policy/utils';
|
|
6
6
|
import AccordionList from './../AccordionList';
|
|
7
|
-
import StatisticsSection from './../StatisticsSection';
|
|
8
7
|
|
|
9
8
|
const GovernanceTab = ({ result }) => {
|
|
10
|
-
const
|
|
11
|
-
{
|
|
12
|
-
value: '460km',
|
|
13
|
-
label: 'Duis non quam et nisi tincidunt',
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
value: '51-60%',
|
|
17
|
-
label: 'Vestibulum ante ipsum primis',
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
value: '2.431.213',
|
|
21
|
-
label: 'Aliquam erat volutpat',
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
value: '2023',
|
|
25
|
-
label: 'Etiam accumsan urna a mauris',
|
|
26
|
-
},
|
|
27
|
-
];
|
|
9
|
+
const { Introduction, Describe_Title, Describe, Provide_Title, Provide } =
|
|
10
|
+
result || {};
|
|
28
11
|
|
|
29
12
|
return (
|
|
30
13
|
<Tab.Pane>
|
|
31
14
|
<h2>Governance</h2>
|
|
32
15
|
<Callout>
|
|
33
|
-
<p>
|
|
34
|
-
Sed at risus vel nulla consequat fermentum. Donec et orci mauris.
|
|
35
|
-
Nullam tempor velit id mi luctus, a scelerisque libero accumsan. In
|
|
36
|
-
hac habitasse platea dictumst. Cras ac nunc nec massa tristique
|
|
37
|
-
fringilla.
|
|
38
|
-
</p>
|
|
16
|
+
<p>{Introduction}</p>
|
|
39
17
|
</Callout>
|
|
40
18
|
|
|
41
|
-
<
|
|
19
|
+
<h3>{Describe_Title}</h3>
|
|
42
20
|
|
|
43
|
-
<
|
|
44
|
-
<AccordionList
|
|
45
|
-
accordions={[
|
|
46
|
-
{
|
|
47
|
-
title: 'Vestibulum ante ipsum primis',
|
|
48
|
-
content: 'No additional details provided.',
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
title: 'Etiam accumsan urna a mauris',
|
|
52
|
-
content: 'No additional details provided.',
|
|
53
|
-
},
|
|
54
|
-
]}
|
|
55
|
-
/>
|
|
21
|
+
<HTMLField value={{ data: formatTextToHTML(Describe) }} />
|
|
56
22
|
|
|
57
|
-
<
|
|
58
|
-
|
|
59
|
-
<HTMLField value={{ data: formatTextToHTML(result?.Describe) }} />
|
|
23
|
+
<br />
|
|
60
24
|
|
|
61
25
|
<AccordionList
|
|
62
26
|
accordions={[
|
|
63
27
|
{
|
|
64
|
-
title:
|
|
65
|
-
content: (
|
|
66
|
-
<HTMLField value={{ data: formatTextToHTML(result?.Provide) }} />
|
|
67
|
-
),
|
|
68
|
-
},
|
|
69
|
-
]}
|
|
70
|
-
/>
|
|
71
|
-
|
|
72
|
-
<h3>
|
|
73
|
-
{result?.Signatory} engages with other levels of government regarding
|
|
74
|
-
their:
|
|
75
|
-
</h3>
|
|
76
|
-
|
|
77
|
-
<AccordionList
|
|
78
|
-
accordions={[
|
|
79
|
-
{
|
|
80
|
-
title: 'Vestibulum ante ipsum primis',
|
|
81
|
-
content: 'No additional details provided.',
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
title: 'Etiam accumsan urna a mauris',
|
|
85
|
-
content: 'No additional details provided.',
|
|
28
|
+
title: <>{Provide_Title}</>,
|
|
29
|
+
content: <HTMLField value={{ data: formatTextToHTML(Provide) }} />,
|
|
86
30
|
},
|
|
87
31
|
]}
|
|
88
32
|
/>
|
package/src/components/manage/Blocks/MissionSignatoriesProfile/TabSections/GovernanceTab.test.jsx
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render } from '@testing-library/react';
|
|
3
|
+
import '@testing-library/jest-dom';
|
|
4
|
+
import GovernanceTab from './GovernanceTab';
|
|
5
|
+
|
|
6
|
+
describe('GovernanceTab', () => {
|
|
7
|
+
const mockResult = {
|
|
8
|
+
Describe_Title: 'Opportunities and benefits of climate action',
|
|
9
|
+
Provide_Title: 'Further details and evidence',
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
it('renders the governance tab correctly', () => {
|
|
13
|
+
const { getByText } = render(<GovernanceTab result={mockResult} />);
|
|
14
|
+
|
|
15
|
+
expect(
|
|
16
|
+
getByText('Opportunities and benefits of climate action'),
|
|
17
|
+
).toBeInTheDocument();
|
|
18
|
+
expect(getByText('Further details and evidence')).toBeInTheDocument();
|
|
19
|
+
});
|
|
20
|
+
});
|
|
@@ -1,117 +1,191 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Tab,
|
|
4
|
+
Message,
|
|
5
|
+
Segment,
|
|
6
|
+
Grid,
|
|
7
|
+
Item,
|
|
8
|
+
ItemGroup,
|
|
9
|
+
ItemContent,
|
|
10
|
+
Image,
|
|
11
|
+
} from 'semantic-ui-react';
|
|
3
12
|
import { Callout } from '@eeacms/volto-eea-design-system/ui';
|
|
13
|
+
import { HTMLField } from '@eeacms/volto-cca-policy/helpers';
|
|
14
|
+
import {
|
|
15
|
+
formatTextToHTML,
|
|
16
|
+
extractPlanNameAndURL,
|
|
17
|
+
} from '@eeacms/volto-cca-policy/utils';
|
|
4
18
|
import AccordionList from './../AccordionList';
|
|
5
|
-
import
|
|
19
|
+
import image from '@eeacms/volto-cca-policy/../theme/assets/images/image-narrow.svg';
|
|
20
|
+
|
|
21
|
+
const ItemsSection = ({ items }) => {
|
|
22
|
+
if (!items?.length) return null;
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<ItemGroup className="items-group">
|
|
26
|
+
{items.map((sector, index) => (
|
|
27
|
+
<Item key={index}>
|
|
28
|
+
<Image size="small" src={image} />
|
|
29
|
+
<ItemContent verticalAlign="middle">{sector}</ItemContent>
|
|
30
|
+
</Item>
|
|
31
|
+
))}
|
|
32
|
+
</ItemGroup>
|
|
33
|
+
);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const PlanningGoalContent = ({ goal }) => {
|
|
37
|
+
const hasHazards = goal?.Climate_Hazards?.length > 0;
|
|
38
|
+
const hasComments = !!goal?.Comments;
|
|
39
|
+
const hasDescription = !!goal?.Description;
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<div>
|
|
43
|
+
<Grid columns="12">
|
|
44
|
+
{hasHazards && (
|
|
45
|
+
<Grid.Column mobile={12} tablet={12} computer={6}>
|
|
46
|
+
<h5>{goal.Climate_Hazards_Addressed_Label}</h5>
|
|
47
|
+
<ul>
|
|
48
|
+
{goal.Climate_Hazards.map((hazard, index) => (
|
|
49
|
+
<li key={index}>{hazard}</li>
|
|
50
|
+
))}
|
|
51
|
+
</ul>
|
|
52
|
+
</Grid.Column>
|
|
53
|
+
)}
|
|
54
|
+
<Grid.Column mobile={12} tablet={12} computer={hasHazards ? 6 : 12}>
|
|
55
|
+
{hasComments && (
|
|
56
|
+
<>
|
|
57
|
+
<h5 className="small-label">{goal.Comments_Label}</h5>
|
|
58
|
+
<Segment>
|
|
59
|
+
<HTMLField value={{ data: formatTextToHTML(goal.Comments) }} />
|
|
60
|
+
</Segment>
|
|
61
|
+
</>
|
|
62
|
+
)}
|
|
63
|
+
{hasDescription && (
|
|
64
|
+
<>
|
|
65
|
+
<h5 className="small-label">{goal.Description_Label}</h5>
|
|
66
|
+
<Segment>
|
|
67
|
+
<HTMLField
|
|
68
|
+
value={{ data: formatTextToHTML(goal.Description) }}
|
|
69
|
+
/>
|
|
70
|
+
</Segment>
|
|
71
|
+
</>
|
|
72
|
+
)}
|
|
73
|
+
</Grid.Column>
|
|
74
|
+
</Grid>
|
|
75
|
+
</div>
|
|
76
|
+
);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const PlanningTab = ({ result }) => {
|
|
80
|
+
const {
|
|
81
|
+
planning_goals = [],
|
|
82
|
+
planning_titles = [],
|
|
83
|
+
planning_climate_action = [],
|
|
84
|
+
} = result || {};
|
|
85
|
+
|
|
86
|
+
const titleData = planning_titles?.[0];
|
|
87
|
+
const goalData = planning_goals?.[0];
|
|
88
|
+
|
|
89
|
+
const sortedGoals = [...planning_goals].sort((a, b) => {
|
|
90
|
+
const aNum = parseInt(a.Adaptation_Goal_Id.replace(/\D/g, ''), 10);
|
|
91
|
+
const bNum = parseInt(b.Adaptation_Goal_Id.replace(/\D/g, ''), 10);
|
|
92
|
+
return aNum - bNum;
|
|
93
|
+
});
|
|
6
94
|
|
|
7
|
-
const PlanningTab = () => {
|
|
8
95
|
return (
|
|
9
96
|
<Tab.Pane>
|
|
10
|
-
<h2>
|
|
11
|
-
|
|
12
|
-
<
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
{
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
<p>
|
|
103
|
-
<a href="/">
|
|
104
|
-
<strong>Nunc euismod bibendum augue</strong>
|
|
105
|
-
</a>
|
|
106
|
-
</p>
|
|
107
|
-
|
|
108
|
-
<p>
|
|
109
|
-
<a href="/">
|
|
110
|
-
<strong>
|
|
111
|
-
Donec in laoreet leo. Quisque suscipit ligula eu turpis dignissim
|
|
112
|
-
</strong>
|
|
113
|
-
</a>
|
|
114
|
-
</p>
|
|
97
|
+
{titleData?.Title && <h2>{titleData.Title}</h2>}
|
|
98
|
+
{titleData?.Abstract_Line && (
|
|
99
|
+
<Callout>
|
|
100
|
+
<p>{titleData.Abstract_Line}</p>
|
|
101
|
+
</Callout>
|
|
102
|
+
)}
|
|
103
|
+
|
|
104
|
+
{sortedGoals.map((goal, index) => {
|
|
105
|
+
return (
|
|
106
|
+
<div key={index} className="section-wrapper">
|
|
107
|
+
<span className="goal-title-label">{goal?.Title_Label}</span>
|
|
108
|
+
|
|
109
|
+
<HTMLField value={{ data: formatTextToHTML(goal?.Title) }} />
|
|
110
|
+
|
|
111
|
+
<AccordionList
|
|
112
|
+
variation="tertiary"
|
|
113
|
+
accordions={[
|
|
114
|
+
{
|
|
115
|
+
title: goal?.More_Details_Label || 'More details',
|
|
116
|
+
content: <PlanningGoalContent goal={goal} />,
|
|
117
|
+
},
|
|
118
|
+
]}
|
|
119
|
+
/>
|
|
120
|
+
</div>
|
|
121
|
+
);
|
|
122
|
+
})}
|
|
123
|
+
|
|
124
|
+
{goalData?.Climate_Action_Title && (
|
|
125
|
+
<h2>{goalData.Climate_Action_Title}</h2>
|
|
126
|
+
)}
|
|
127
|
+
|
|
128
|
+
{goalData?.Climate_Action_Abstract && (
|
|
129
|
+
<Callout>
|
|
130
|
+
<p>{goalData.Climate_Action_Abstract}</p>
|
|
131
|
+
</Callout>
|
|
132
|
+
)}
|
|
133
|
+
|
|
134
|
+
{planning_climate_action.map((action, index) => {
|
|
135
|
+
return (
|
|
136
|
+
<React.Fragment key={index}>
|
|
137
|
+
<br />
|
|
138
|
+
{action?.Sectors_Introduction && (
|
|
139
|
+
<Message>
|
|
140
|
+
<p>{action.Sectors_Introduction}</p>
|
|
141
|
+
</Message>
|
|
142
|
+
)}
|
|
143
|
+
|
|
144
|
+
<ItemsSection items={action?.Sectors} />
|
|
145
|
+
{action?.Description && <p>{action.Description}</p>}
|
|
146
|
+
|
|
147
|
+
{(action?.Approval_Year || action?.End_Year) && (
|
|
148
|
+
<p>
|
|
149
|
+
{action?.Year_Of_Approval_Label}{' '}
|
|
150
|
+
<strong className="date">{action.Approval_Year}</strong>{' '}
|
|
151
|
+
{action?.End_Year_Of_Plan_Label}{' '}
|
|
152
|
+
<strong className="date">{action.End_Year}</strong>
|
|
153
|
+
</p>
|
|
154
|
+
)}
|
|
155
|
+
|
|
156
|
+
{action?.Name_Of_Plan_And_Hyperlink && (
|
|
157
|
+
<p>
|
|
158
|
+
{(() => {
|
|
159
|
+
const { name, url } = extractPlanNameAndURL(
|
|
160
|
+
action.Name_Of_Plan_And_Hyperlink,
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
return url ? (
|
|
164
|
+
<a href={url} title={name} target="_blank" rel="noreferrer">
|
|
165
|
+
<strong>
|
|
166
|
+
{action.Further_Information_Link_Text}
|
|
167
|
+
{name && ` [${name}]`}
|
|
168
|
+
</strong>
|
|
169
|
+
</a>
|
|
170
|
+
) : (
|
|
171
|
+
<strong>
|
|
172
|
+
{action.Further_Information_Link_Text}
|
|
173
|
+
{name && ` [${name}]`}
|
|
174
|
+
</strong>
|
|
175
|
+
);
|
|
176
|
+
})()}
|
|
177
|
+
</p>
|
|
178
|
+
)}
|
|
179
|
+
{action?.Attachment && (
|
|
180
|
+
<p>
|
|
181
|
+
<a href={action.Attachment}>
|
|
182
|
+
<strong>{action.Explore_Plan_Link_Text}</strong>
|
|
183
|
+
</a>
|
|
184
|
+
</p>
|
|
185
|
+
)}
|
|
186
|
+
</React.Fragment>
|
|
187
|
+
);
|
|
188
|
+
})}
|
|
115
189
|
</Tab.Pane>
|
|
116
190
|
);
|
|
117
191
|
};
|
package/src/components/manage/Blocks/MissionSignatoriesProfile/TabSections/PlanningTab.test.jsx
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render } from '@testing-library/react';
|
|
3
|
+
import '@testing-library/jest-dom';
|
|
4
|
+
import PlanningTab from './PlanningTab';
|
|
5
|
+
|
|
6
|
+
jest.mock('@eeacms/volto-cca-policy/helpers', () => ({
|
|
7
|
+
HTMLField: ({ value }) => (
|
|
8
|
+
<div dangerouslySetInnerHTML={{ __html: value.data }} />
|
|
9
|
+
),
|
|
10
|
+
}));
|
|
11
|
+
|
|
12
|
+
jest.mock('@eeacms/volto-cca-policy/utils', () => ({
|
|
13
|
+
formatTextToHTML: (text) => text,
|
|
14
|
+
extractPlanNameAndURL: (str) => ({
|
|
15
|
+
name: 'Plan Example',
|
|
16
|
+
url: 'https://plan-link.com',
|
|
17
|
+
}),
|
|
18
|
+
}));
|
|
19
|
+
|
|
20
|
+
describe('PlanningTab', () => {
|
|
21
|
+
const mockResult = {
|
|
22
|
+
planning_titles: [
|
|
23
|
+
{ Title: 'Planning Title', Abstract_Line: 'Abstract info' },
|
|
24
|
+
],
|
|
25
|
+
planning_goals: [
|
|
26
|
+
{
|
|
27
|
+
Adaptation_Goal_Id: 'AG-001',
|
|
28
|
+
Title: 'Goal Title 1',
|
|
29
|
+
Title_Label: 'Goal 1 Label',
|
|
30
|
+
More_Details_Label: 'Details',
|
|
31
|
+
Climate_Hazards: ['Heat', 'Flood'],
|
|
32
|
+
Climate_Hazards_Addressed_Label: 'Hazards',
|
|
33
|
+
Comments_Label: 'Comments',
|
|
34
|
+
Comments: 'Some comments',
|
|
35
|
+
Description_Label: 'Description',
|
|
36
|
+
Description: 'Detailed description',
|
|
37
|
+
Climate_Action_Title: 'Action Title',
|
|
38
|
+
Climate_Action_Abstract: 'Action abstract',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
Adaptation_Goal_Id: 'AG-002',
|
|
42
|
+
Title: 'Goal Title 2',
|
|
43
|
+
Title_Label: 'Goal 2 Label',
|
|
44
|
+
More_Details_Label: 'Details',
|
|
45
|
+
Climate_Hazards: ['Drought', 'Storm'],
|
|
46
|
+
Climate_Hazards_Addressed_Label: 'Hazards',
|
|
47
|
+
Comments_Label: 'Comments',
|
|
48
|
+
Comments: 'Other comments',
|
|
49
|
+
Description_Label: 'Description',
|
|
50
|
+
Description: 'Another detailed description',
|
|
51
|
+
Climate_Action_Title: 'Action Title',
|
|
52
|
+
Climate_Action_Abstract: 'Another action abstract',
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
planning_climate_action: [
|
|
56
|
+
{
|
|
57
|
+
Sectors_Introduction: 'Intro to sectors',
|
|
58
|
+
Description: 'Sector description',
|
|
59
|
+
Year_Of_Approval_Label: 'Approval Year:',
|
|
60
|
+
Approval_Year: '2023',
|
|
61
|
+
End_Year_Of_Plan_Label: 'End Year:',
|
|
62
|
+
End_Year: '2030',
|
|
63
|
+
Name_Of_Plan_And_Hyperlink: 'http://example.com; https://plan-link.com',
|
|
64
|
+
Further_Information_Link_Text: 'More Info',
|
|
65
|
+
Attachment: 'http://attachment.com',
|
|
66
|
+
Explore_Plan_Link_Text: 'Explore Plan',
|
|
67
|
+
Sectors: ['Agriculture'],
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
it('renders planning tab with basic data', () => {
|
|
73
|
+
const { getByText } = render(<PlanningTab result={mockResult} />);
|
|
74
|
+
|
|
75
|
+
expect(getByText('Planning Title')).toBeInTheDocument();
|
|
76
|
+
expect(getByText('Abstract info')).toBeInTheDocument();
|
|
77
|
+
|
|
78
|
+
expect(getByText('Goal Title 1')).toBeInTheDocument();
|
|
79
|
+
expect(getByText('Goal Title 2')).toBeInTheDocument();
|
|
80
|
+
|
|
81
|
+
expect(getByText('Action Title')).toBeInTheDocument();
|
|
82
|
+
expect(getByText('Intro to sectors')).toBeInTheDocument();
|
|
83
|
+
expect(getByText('Sector description')).toBeInTheDocument();
|
|
84
|
+
|
|
85
|
+
expect(getByText(/Approval Year:/)).toBeInTheDocument();
|
|
86
|
+
expect(getByText(/2023/)).toBeInTheDocument();
|
|
87
|
+
expect(getByText(/End Year:/)).toBeInTheDocument();
|
|
88
|
+
expect(getByText(/2030/)).toBeInTheDocument();
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('renders ItemsSection if there are sectors', () => {
|
|
92
|
+
const { getByText } = render(<PlanningTab result={mockResult} />);
|
|
93
|
+
|
|
94
|
+
expect(getByText(/Agriculture/)).toBeInTheDocument();
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('renders image in ItemsSection', () => {
|
|
98
|
+
const { container } = render(<PlanningTab result={mockResult} />);
|
|
99
|
+
const images = container.querySelectorAll('img');
|
|
100
|
+
expect(images.length).toBeGreaterThan(0);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('renders hyperlink with extracted name and URL', () => {
|
|
104
|
+
const { getByText } = render(<PlanningTab result={mockResult} />);
|
|
105
|
+
|
|
106
|
+
const link = getByText(/More Info \[Plan Example\]/);
|
|
107
|
+
expect(link).toBeInTheDocument();
|
|
108
|
+
expect(link.closest('a')).toHaveAttribute('href', 'https://plan-link.com');
|
|
109
|
+
});
|
|
110
|
+
});
|
|
@@ -8,6 +8,10 @@
|
|
|
8
8
|
margin: 2em 0;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
.column > .ui.segment {
|
|
12
|
+
background-color: #fff !important;
|
|
13
|
+
}
|
|
14
|
+
|
|
11
15
|
.section-wrapper-info {
|
|
12
16
|
display: flex;
|
|
13
17
|
justify-content: space-between;
|
|
@@ -20,12 +24,24 @@
|
|
|
20
24
|
}
|
|
21
25
|
|
|
22
26
|
.section-wrapper {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
margin: 1em 0;
|
|
28
|
+
|
|
29
|
+
.goal-title-label {
|
|
30
|
+
display: inline-block;
|
|
31
|
+
padding: 0.3em 0.5em;
|
|
32
|
+
margin: 1em 0;
|
|
33
|
+
background-color: #dbe7f4;
|
|
34
|
+
font-size: 14px;
|
|
35
|
+
font-weight: bold;
|
|
36
|
+
text-transform: uppercase;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.ui.accordion {
|
|
40
|
+
margin-top: 1em;
|
|
41
|
+
}
|
|
26
42
|
|
|
27
|
-
.
|
|
28
|
-
|
|
43
|
+
.small-label {
|
|
44
|
+
font-size: 1em;
|
|
29
45
|
}
|
|
30
46
|
}
|
|
31
47
|
|
package/src/constants.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export const download_fields = [
|
|
2
|
+
// { field: 'cca_uid', name: 'UID' },
|
|
3
|
+
{ field: 'about', name: 'About' },
|
|
4
|
+
{ field: 'title', name: 'Title' },
|
|
5
|
+
{ field: 'created', name: 'Creation Date' },
|
|
6
|
+
{ field: 'issued', name: 'Publication Date' },
|
|
7
|
+
{ field: 'creators', name: 'Creator' },
|
|
8
|
+
{ field: 'objectProvides', name: 'Content type' },
|
|
9
|
+
{ field: 'cca_keywords', name: 'Keywords' },
|
|
10
|
+
{ field: 'cca_adaptation_sectors', name: 'Sectors' },
|
|
11
|
+
{ field: 'cca_climate_impacts', name: 'Climate impact' },
|
|
12
|
+
{ field: 'transnational_regions', name: 'Transnational regions' },
|
|
13
|
+
{ field: 'cca_adaptation_elements', name: 'Adaptation Approaches' },
|
|
14
|
+
{ field: 'cca_funding_programme', name: 'Funding programme' },
|
|
15
|
+
{ field: 'cca_key_type_measure', name: 'Key type measure' },
|
|
16
|
+
{ field: 'cca_geographic_countries', name: 'Countries' },
|
|
17
|
+
{ field: 'cca_origin_websites', name: 'Origin website' },
|
|
18
|
+
{ field: 'cca_health_impacts', name: 'Health impacts' },
|
|
19
|
+
{ field: 'cca_partner_contributors', name: 'Observatory impacts' },
|
|
20
|
+
// { field: 'fulltext', name: 'Description' },
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
export const eea_languages = [
|
|
24
|
+
{ name: 'English', code: 'en' },
|
|
25
|
+
{ name: 'български', code: 'bg' },
|
|
26
|
+
{ name: 'Español', code: 'es' },
|
|
27
|
+
// { name: 'Čeština', code: 'cs' },
|
|
28
|
+
{ name: 'Dansk', code: 'da' },
|
|
29
|
+
{ name: 'Deutsch', code: 'de' },
|
|
30
|
+
// { name: 'Eesti keel', code: 'et' },
|
|
31
|
+
{ name: 'Ελληνικά', code: 'el' },
|
|
32
|
+
{ name: 'Français', code: 'fr' },
|
|
33
|
+
// { name: 'Gaeilge', code: 'ga' },
|
|
34
|
+
{ name: 'Hrvatski', code: 'hr' },
|
|
35
|
+
{ name: 'Italiano', code: 'it' },
|
|
36
|
+
// { name: 'Latviešu valoda', code: 'lv' },
|
|
37
|
+
// { name: 'Lietuvių kalba', code: 'lt' },
|
|
38
|
+
// { name: 'Magyar', code: 'hu' },
|
|
39
|
+
// { name: 'Malti', code: 'mt' },
|
|
40
|
+
// { name: 'Nederlands', code: 'nl' },
|
|
41
|
+
{ name: 'Polski', code: 'pl' },
|
|
42
|
+
{ name: 'Português', code: 'pt' },
|
|
43
|
+
{ name: 'Română', code: 'ro' },
|
|
44
|
+
// { name: 'Slovenčina', code: 'sk' },
|
|
45
|
+
// { name: 'Slovenščina', code: 'sl' },
|
|
46
|
+
{ name: 'Suomi', code: 'fi' },
|
|
47
|
+
{ name: 'Svenska', code: 'sv' },
|
|
48
|
+
{ name: 'Íslenska', code: 'is' },
|
|
49
|
+
{ name: 'Nynorsk', code: 'nn' },
|
|
50
|
+
// { name: 'Türkçe', code: 'tr' },
|
|
51
|
+
];
|
package/src/index.js
CHANGED
|
@@ -42,6 +42,8 @@ import eeaWhiteLogo from '@eeacms/volto-eea-design-system/../theme/themes/eea/as
|
|
|
42
42
|
import './slate-styles.less';
|
|
43
43
|
import BrokenLinks from './components/theme/Views/BrokenLinks';
|
|
44
44
|
|
|
45
|
+
import { eea_languages } from './constants';
|
|
46
|
+
|
|
45
47
|
const getEnv = () => (typeof window !== 'undefined' ? window.env : process.env);
|
|
46
48
|
|
|
47
49
|
const pathToNegRegex = (p) => `(?!(${p}))`;
|
|
@@ -140,35 +142,7 @@ const applyConfig = (config) => {
|
|
|
140
142
|
// EEA customizations
|
|
141
143
|
config.settings.eea = {
|
|
142
144
|
...(config.settings.eea || {}),
|
|
143
|
-
languages:
|
|
144
|
-
{ name: 'English', code: 'en' },
|
|
145
|
-
// { name: 'български', code: 'bg' },
|
|
146
|
-
{ name: 'Español', code: 'es' },
|
|
147
|
-
// { name: 'Čeština', code: 'cs' },
|
|
148
|
-
{ name: 'Dansk', code: 'da' },
|
|
149
|
-
{ name: 'Deutsch', code: 'de' },
|
|
150
|
-
// { name: 'Eesti keel', code: 'et' },
|
|
151
|
-
{ name: 'Ελληνικά', code: 'el' },
|
|
152
|
-
{ name: 'Français', code: 'fr' },
|
|
153
|
-
// { name: 'Gaeilge', code: 'ga' },
|
|
154
|
-
{ name: 'Hrvatski', code: 'hr' },
|
|
155
|
-
{ name: 'Italiano', code: 'it' },
|
|
156
|
-
// { name: 'Latviešu valoda', code: 'lv' },
|
|
157
|
-
// { name: 'Lietuvių kalba', code: 'lt' },
|
|
158
|
-
// { name: 'Magyar', code: 'hu' },
|
|
159
|
-
// { name: 'Malti', code: 'mt' },
|
|
160
|
-
// { name: 'Nederlands', code: 'nl' },
|
|
161
|
-
{ name: 'Polski', code: 'pl' },
|
|
162
|
-
{ name: 'Português', code: 'pt' },
|
|
163
|
-
// { name: 'Română', code: 'ro' },
|
|
164
|
-
// { name: 'Slovenčina', code: 'sk' },
|
|
165
|
-
// { name: 'Slovenščina', code: 'sl' },
|
|
166
|
-
{ name: 'Suomi', code: 'fi' },
|
|
167
|
-
{ name: 'Svenska', code: 'sv' },
|
|
168
|
-
{ name: 'Íslenska', code: 'is' },
|
|
169
|
-
{ name: 'Nynorsk', code: 'nn' },
|
|
170
|
-
// { name: 'Türkçe', code: 'tr' },
|
|
171
|
-
],
|
|
145
|
+
languages: eea_languages,
|
|
172
146
|
headerOpts: {
|
|
173
147
|
...(config.settings.eea?.headerOpts || {}),
|
|
174
148
|
logo: ccaLogo,
|
package/src/search/cca/config.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { mergeConfig } from '@eeacms/search';
|
|
2
2
|
import { getClientProxyAddress } from '../utils';
|
|
3
|
-
import
|
|
3
|
+
import { vocab } from '../vocabulary';
|
|
4
4
|
|
|
5
5
|
import facets from './facets';
|
|
6
6
|
import views from './views';
|
|
7
|
+
import { download_fields } from '../../constants';
|
|
7
8
|
|
|
8
9
|
const ccaConfig = {
|
|
9
10
|
title: 'ClimateAdapt Main',
|
|
@@ -76,30 +77,10 @@ export default function installMainSearch(config) {
|
|
|
76
77
|
index_name: 'data_searchui',
|
|
77
78
|
host: process.env.RAZZLE_ES_PROXY_ADDR || 'http://localhost:3000',
|
|
78
79
|
runtime_mappings: cca_build_runtime_mappings,
|
|
79
|
-
|
|
80
|
+
vocab,
|
|
80
81
|
};
|
|
81
82
|
|
|
82
|
-
config.searchui.ccaSearch.download_fields =
|
|
83
|
-
// { field: 'cca_uid', name: 'UID' },
|
|
84
|
-
{ field: 'about', name: 'About' },
|
|
85
|
-
{ field: 'title', name: 'Title' },
|
|
86
|
-
{ field: 'created', name: 'Creation Date' },
|
|
87
|
-
{ field: 'issued', name: 'Publication Date' },
|
|
88
|
-
{ field: 'creators', name: 'Creator' },
|
|
89
|
-
{ field: 'objectProvides', name: 'Content type' },
|
|
90
|
-
{ field: 'cca_keywords', name: 'Keywords' },
|
|
91
|
-
{ field: 'cca_adaptation_sectors', name: 'Sectors' },
|
|
92
|
-
{ field: 'cca_climate_impacts', name: 'Climate impact' },
|
|
93
|
-
{ field: 'transnational_regions', name: 'Transnational regions' },
|
|
94
|
-
{ field: 'cca_adaptation_elements', name: 'Adaptation Approaches' },
|
|
95
|
-
{ field: 'cca_funding_programme', name: 'Funding programme' },
|
|
96
|
-
{ field: 'cca_key_type_measure', name: 'Key type measure' },
|
|
97
|
-
{ field: 'cca_geographic_countries', name: 'Countries' },
|
|
98
|
-
{ field: 'cca_origin_websites', name: 'Origin website' },
|
|
99
|
-
{ field: 'cca_health_impacts', name: 'Health impacts' },
|
|
100
|
-
{ field: 'cca_partner_contributors', name: 'Observatory impacts' },
|
|
101
|
-
// { field: 'fulltext', name: 'Description' },
|
|
102
|
-
];
|
|
83
|
+
config.searchui.ccaSearch.download_fields = download_fields;
|
|
103
84
|
|
|
104
85
|
const { ccaSearch } = config.searchui;
|
|
105
86
|
|
package/src/search/common.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { eea_languages } from '@eeacms/volto-cca-policy/constants';
|
|
1
2
|
import { booleanFacet } from '@eeacms/search';
|
|
2
3
|
import { getTodayWithTime } from './utils';
|
|
3
4
|
|
|
@@ -192,42 +193,44 @@ export const language = {
|
|
|
192
193
|
type: 'any',
|
|
193
194
|
};
|
|
194
195
|
},
|
|
195
|
-
facetValues:
|
|
196
|
-
'de',
|
|
197
|
-
'en',
|
|
198
|
-
'es',
|
|
199
|
-
'fr',
|
|
200
|
-
'it',
|
|
201
|
-
'pl',
|
|
202
|
-
// 'ar',
|
|
203
|
-
// 'bg',
|
|
204
|
-
// 'bs',
|
|
205
|
-
// 'cs',
|
|
206
|
-
// 'da',
|
|
207
|
-
// 'el',
|
|
208
|
-
// 'et',
|
|
209
|
-
// 'fi',
|
|
210
|
-
// 'ga',
|
|
211
|
-
// 'hr',
|
|
212
|
-
// 'hu',
|
|
213
|
-
// 'is',
|
|
214
|
-
// 'lt',
|
|
215
|
-
// 'lv',
|
|
216
|
-
// 'mk',
|
|
217
|
-
// 'mt',
|
|
218
|
-
// 'nl',
|
|
219
|
-
// 'no',
|
|
220
|
-
// 'pt',
|
|
221
|
-
// 'ro',
|
|
222
|
-
// 'ru',
|
|
223
|
-
// 'sh',
|
|
224
|
-
// 'sk',
|
|
225
|
-
// 'sl',
|
|
226
|
-
// 'sq',
|
|
227
|
-
// 'sr',
|
|
228
|
-
// 'sv',
|
|
229
|
-
// 'tr',
|
|
230
|
-
],
|
|
196
|
+
facetValues: eea_languages.map(({ code }) => code),
|
|
231
197
|
sortOn: 'custom',
|
|
232
198
|
sortOnCustomLabel: 'Alphabetical',
|
|
233
199
|
};
|
|
200
|
+
|
|
201
|
+
// [
|
|
202
|
+
// 'de',
|
|
203
|
+
// 'en',
|
|
204
|
+
// 'es',
|
|
205
|
+
// 'fr',
|
|
206
|
+
// 'it',
|
|
207
|
+
// 'pl',
|
|
208
|
+
// // 'ar',
|
|
209
|
+
// // 'bg',
|
|
210
|
+
// // 'bs',
|
|
211
|
+
// // 'cs',
|
|
212
|
+
// // 'da',
|
|
213
|
+
// // 'el',
|
|
214
|
+
// // 'et',
|
|
215
|
+
// // 'fi',
|
|
216
|
+
// // 'ga',
|
|
217
|
+
// // 'hr',
|
|
218
|
+
// // 'hu',
|
|
219
|
+
// // 'is',
|
|
220
|
+
// // 'lt',
|
|
221
|
+
// // 'lv',
|
|
222
|
+
// // 'mk',
|
|
223
|
+
// // 'mt',
|
|
224
|
+
// // 'nl',
|
|
225
|
+
// // 'no',
|
|
226
|
+
// // 'pt',
|
|
227
|
+
// // 'ro',
|
|
228
|
+
// // 'ru',
|
|
229
|
+
// // 'sh',
|
|
230
|
+
// // 'sk',
|
|
231
|
+
// // 'sl',
|
|
232
|
+
// // 'sq',
|
|
233
|
+
// // 'sr',
|
|
234
|
+
// // 'sv',
|
|
235
|
+
// // 'tr',
|
|
236
|
+
// ]
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { mergeConfig } from '@eeacms/search';
|
|
2
2
|
import { build_runtime_mappings } from '@eeacms/volto-globalsearch/utils';
|
|
3
3
|
import { getClientProxyAddress } from './../utils';
|
|
4
|
-
import
|
|
4
|
+
import { vocab } from './../vocabulary';
|
|
5
5
|
|
|
6
6
|
import facets from './facets-health';
|
|
7
7
|
import views from './views-health';
|
|
@@ -90,7 +90,7 @@ export default function installMainSearch(config) {
|
|
|
90
90
|
elastic_index: '_es/globalsearch',
|
|
91
91
|
index_name: 'data_searchui',
|
|
92
92
|
host: process.env.RAZZLE_ES_PROXY_ADDR || 'http://localhost:3000',
|
|
93
|
-
|
|
93
|
+
vocab,
|
|
94
94
|
runtime_mappings: build_runtime_mappings(clusters),
|
|
95
95
|
};
|
|
96
96
|
|
package/src/search/vocabulary.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { eea_languages } from '@eeacms/volto-cca-policy/constants';
|
|
2
|
+
|
|
3
|
+
export const vocab = {
|
|
2
4
|
cluster_name: {
|
|
3
5
|
cca: 'Climate-ADAPT',
|
|
4
6
|
},
|
|
@@ -19,6 +21,8 @@ const vocab = {
|
|
|
19
21
|
'Publication reference': 'Publications and reports',
|
|
20
22
|
Video: 'Videos and podcasts',
|
|
21
23
|
},
|
|
24
|
+
language: Object.assign(
|
|
25
|
+
{},
|
|
26
|
+
...eea_languages.map(({ name, code }) => ({ [code]: name })),
|
|
27
|
+
),
|
|
22
28
|
};
|
|
23
|
-
|
|
24
|
-
export default { vocab };
|
package/src/utils.js
CHANGED
|
@@ -81,11 +81,41 @@ export const filterBlocks = (content, blockTypes = []) => {
|
|
|
81
81
|
export const formatTextToHTML = (text) => {
|
|
82
82
|
if (!text) return '';
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
84
|
+
let formattedText = text
|
|
85
|
+
.replace(/\\\\/g, '\\') // unescape backslashes
|
|
86
|
+
.replace(/\\'/g, "'") // unescape single quotes
|
|
87
|
+
.replace(/\\"/g, '"') // unescape double quotes
|
|
88
|
+
.replace(/\\t\\n/g, '') // handle \t\n
|
|
89
|
+
.replace(/\\n\\n/g, '</p><p>') // double line break = paragraph
|
|
90
|
+
.replace(/\\no\s*/g, '<br />• ') // list-like "o " to bullet point
|
|
91
|
+
.replace(/\\n/g, '<br />'); // single line break
|
|
89
92
|
|
|
90
93
|
return `<p>${formattedText}</p>`;
|
|
91
94
|
};
|
|
95
|
+
|
|
96
|
+
export const extractPlanNameAndURL = (text) => {
|
|
97
|
+
if (!text) return { name: '', url: '' };
|
|
98
|
+
|
|
99
|
+
// Match URL inside parentheses
|
|
100
|
+
const parenthesisMatch = text.match(/\((https?:\/\/[^\s)]+)\)/);
|
|
101
|
+
// Match first direct URL not inside parentheses
|
|
102
|
+
const directMatch = text.match(/https?:\/\/[^\s,;)]+/);
|
|
103
|
+
const url = parenthesisMatch?.[1] || directMatch?.[0] || '';
|
|
104
|
+
|
|
105
|
+
let name = text;
|
|
106
|
+
|
|
107
|
+
if (url) {
|
|
108
|
+
// Remove URL and any punctuation before it
|
|
109
|
+
name = name
|
|
110
|
+
.replace(`(${url})`, '')
|
|
111
|
+
.replace(url, '')
|
|
112
|
+
.replace(/[-–;,:\s]+$/, '')
|
|
113
|
+
.replace(/[-–;,:\s]+$/, '')
|
|
114
|
+
.trim();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
name: name,
|
|
119
|
+
url,
|
|
120
|
+
};
|
|
121
|
+
};
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Item, ItemGroup, ItemContent, Image } from 'semantic-ui-react';
|
|
3
|
-
|
|
4
|
-
import image from '@eeacms/volto-cca-policy/../theme//assets/images/image-narrow.svg';
|
|
5
|
-
|
|
6
|
-
const ItemsSection = ({ items }) => {
|
|
7
|
-
return (
|
|
8
|
-
<ItemGroup className="items-group">
|
|
9
|
-
<Item>
|
|
10
|
-
<Image size="small" src={image} />
|
|
11
|
-
<ItemContent verticalAlign="middle">
|
|
12
|
-
Lorem ipsum dolor sit amet, consectetur adipiscing elit
|
|
13
|
-
</ItemContent>
|
|
14
|
-
</Item>
|
|
15
|
-
|
|
16
|
-
<Item>
|
|
17
|
-
<Image size="small" src={image} />
|
|
18
|
-
<ItemContent verticalAlign="middle">
|
|
19
|
-
Lorem ipsum dolor sit amet, consectetur adipiscing elit
|
|
20
|
-
</ItemContent>
|
|
21
|
-
</Item>
|
|
22
|
-
|
|
23
|
-
<Item>
|
|
24
|
-
<Image size="small" src={image} />
|
|
25
|
-
<ItemContent verticalAlign="middle">
|
|
26
|
-
Lorem ipsum dolor sit amet, consectetur adipiscing elit
|
|
27
|
-
</ItemContent>
|
|
28
|
-
</Item>
|
|
29
|
-
|
|
30
|
-
<Item>
|
|
31
|
-
<Image size="small" src={image} />
|
|
32
|
-
<ItemContent verticalAlign="middle">
|
|
33
|
-
Lorem ipsum dolor sit amet, consectetur adipiscing elit
|
|
34
|
-
</ItemContent>
|
|
35
|
-
</Item>
|
|
36
|
-
|
|
37
|
-
<Item>
|
|
38
|
-
<Image size="small" src={image} />
|
|
39
|
-
<ItemContent verticalAlign="middle">
|
|
40
|
-
Lorem ipsum dolor sit amet, consectetur adipiscing elit
|
|
41
|
-
</ItemContent>
|
|
42
|
-
</Item>
|
|
43
|
-
|
|
44
|
-
<Item>
|
|
45
|
-
<Image size="small" src={image} />
|
|
46
|
-
<ItemContent verticalAlign="middle">
|
|
47
|
-
Lorem ipsum dolor sit amet, consectetur adipiscing elit
|
|
48
|
-
</ItemContent>
|
|
49
|
-
</Item>
|
|
50
|
-
</ItemGroup>
|
|
51
|
-
);
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
export default ItemsSection;
|