@eeacms/volto-cca-policy 0.1.14 → 0.1.16
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 +32 -0
- package/README.md +1 -0
- package/package.json +1 -1
- package/src/components/theme/Views/C3SIndicatorView.jsx +139 -20
- package/src/customizations/@eeacms/volto-eea-design-system/ui/Footer/Contact.jsx +36 -0
- package/src/customizations/volto/components/theme/Header/Header.jsx +73 -5
- package/src/customizations/volto/components/theme/Header/HeaderMain.jsx +190 -0
- package/src/customizations/volto/components/theme/Header/HeaderMenuPopUp.js +373 -0
- package/src/index.js +29 -13
- package/theme/globals/site.overrides +18 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,38 @@ 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.1.16](https://github.com/eea/volto-cca-policy/compare/0.1.15...0.1.16) - 29 March 2023
|
|
8
|
+
|
|
9
|
+
#### :hammer_and_wrench: Others
|
|
10
|
+
|
|
11
|
+
- Add whitelist for volto-nextcloud-video-block. [GhitaB - [`bb4e972`](https://github.com/eea/volto-cca-policy/commit/bb4e972fa4cdabc28f85bd902defce3906234a51)]
|
|
12
|
+
- Add whitelist for volto-nextcloud-video-block. [GhitaB - [`577f659`](https://github.com/eea/volto-cca-policy/commit/577f65936809f6fcb9fa6a6bacc14f7b335f9707)]
|
|
13
|
+
- Use UniversalLink for footer links [kreafox - [`efd34a4`](https://github.com/eea/volto-cca-policy/commit/efd34a4451b205ff5f3da022c781f425bd2f9572)]
|
|
14
|
+
- Make it footer contact link to work with mailto [kreafox - [`e8938dc`](https://github.com/eea/volto-cca-policy/commit/e8938dc94aa5d47998ecf505084c3ae170ed59c3)]
|
|
15
|
+
- Remove context navigation for RAST [kreafox - [`f85c972`](https://github.com/eea/volto-cca-policy/commit/f85c97259af58ff10b49b882eaec089cb8464f65)]
|
|
16
|
+
- Make footer description bold [kreafox - [`2e4184e`](https://github.com/eea/volto-cca-policy/commit/2e4184e3f8d811cdc6cd7d7732d6f8115463183f)]
|
|
17
|
+
- Add header override for search [kreafox - [`280489e`](https://github.com/eea/volto-cca-policy/commit/280489e6075ea31a2db4a595f681c68c0fa82b7d)]
|
|
18
|
+
- Set number of columns for grid block [kreafox - [`b0ef1d0`](https://github.com/eea/volto-cca-policy/commit/b0ef1d0f19e293f0a9805f913b4040c8fddb1a9c)]
|
|
19
|
+
- Refs #160116 - C3SIndicatorView: add disclaimer info. [GhitaB - [`765ed01`](https://github.com/eea/volto-cca-policy/commit/765ed013d38b56091c5e384ea1facaf31e3aa531)]
|
|
20
|
+
- Undo initialBlocks [kreafox - [`2c17118`](https://github.com/eea/volto-cca-policy/commit/2c17118e07e784bb57ce2564f1108d8183ec5b78)]
|
|
21
|
+
- CSS fix [kreafox - [`f77f74e`](https://github.com/eea/volto-cca-policy/commit/f77f74e01ba2458311411537e1477636bffc140f)]
|
|
22
|
+
- Add headerSearchBox to Header [kreafox - [`b873129`](https://github.com/eea/volto-cca-policy/commit/b873129483f32ff9ab8d1ae0f2406be75e3f7afd)]
|
|
23
|
+
- Add organisationName and websiteTitle to config [kreafox - [`ff41a58`](https://github.com/eea/volto-cca-policy/commit/ff41a588b4a8b0a8ff0d1f67310becbd7cbb6c1c)]
|
|
24
|
+
- Set initialBlocks [kreafox - [`d1741f6`](https://github.com/eea/volto-cca-policy/commit/d1741f6a0c3e68c6172a19c51c53c221b351bb5d)]
|
|
25
|
+
- Refs #160116 - C3SIndicatorView: iframe no border. [GhitaB - [`055d287`](https://github.com/eea/volto-cca-policy/commit/055d2872b0e33def79a6d5446d229b9febad813e)]
|
|
26
|
+
- Refs #160116 - C3SIndicatorView: right buttons (.btn-right). [GhitaB - [`dcf7359`](https://github.com/eea/volto-cca-policy/commit/dcf73596a53e5e0621bd2a3809598afd6233718f)]
|
|
27
|
+
- Refs #160116 - C3SIndicatorView: custom align for titles vs buttons. [GhitaB - [`02bdbca`](https://github.com/eea/volto-cca-policy/commit/02bdbcab131c3fa5b359d4de3749c70e26dd8285)]
|
|
28
|
+
- Refs #160116 - C3SIndicatorView: update url params when showDetails changes. [GhitaB - [`c7ad9d1`](https://github.com/eea/volto-cca-policy/commit/c7ad9d140f265aff75c5963d126ef4eff92b57f7)]
|
|
29
|
+
- Refs #160116 - C3SIndicatorView: add title for details/overview. [GhitaB - [`53fd12d`](https://github.com/eea/volto-cca-policy/commit/53fd12d42a77c9792bd677fb2d53dcd74d9c87a6)]
|
|
30
|
+
- Refs #160116 - C3SIndicatorView: set Details mode if #details in url. [GhitaB - [`017b9cd`](https://github.com/eea/volto-cca-policy/commit/017b9cd433aedbf0166c259126be8d4ae59b835a)]
|
|
31
|
+
- Refs #160116 - C3SIndicatorView: toggle Details vs Overview mode. [GhitaB - [`1c3f7af`](https://github.com/eea/volto-cca-policy/commit/1c3f7afd7f45e61c849e053337af69448b51363a)]
|
|
32
|
+
- Refs #160116 - C3SIndicatorView: add overview iframe. [GhitaB - [`4ed4ed6`](https://github.com/eea/volto-cca-policy/commit/4ed4ed66bc8bf71a019c89070361f257fa81afc2)]
|
|
33
|
+
- Refs #160116 - C3SIndicatorView: details iframe - use real data. [GhitaB - [`8fa2a7d`](https://github.com/eea/volto-cca-policy/commit/8fa2a7d3b6fa991959136e457299c16ad7d64a14)]
|
|
34
|
+
- Refs #160116 - C3SIndicatorView: clean code. [GhitaB - [`a5b165e`](https://github.com/eea/volto-cca-policy/commit/a5b165e8386f519dbba23c18a555d8a7bcc6cd5d)]
|
|
35
|
+
- WIP [Tiberiu Ichim - [`892c285`](https://github.com/eea/volto-cca-policy/commit/892c285a618b1daf92a7c0e8878a09671377ef65)]
|
|
36
|
+
- Refs #160116 - C3SIndicatorView: WIP iframe. [GhitaB - [`97a42aa`](https://github.com/eea/volto-cca-policy/commit/97a42aa9eaa565a4b8c08427b4d0a62f28bf5a87)]
|
|
37
|
+
### [0.1.15](https://github.com/eea/volto-cca-policy/compare/0.1.14...0.1.15) - 27 March 2023
|
|
38
|
+
|
|
7
39
|
### [0.1.14](https://github.com/eea/volto-cca-policy/compare/0.1.13...0.1.14) - 24 March 2023
|
|
8
40
|
|
|
9
41
|
#### :hammer_and_wrench: Others
|
package/README.md
CHANGED
package/package.json
CHANGED
|
@@ -1,30 +1,125 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
// ContentMetadata,
|
|
5
|
-
// LinksList,
|
|
6
|
-
// PublishedModifiedInfo,
|
|
7
|
-
// ShareInfo,
|
|
8
|
-
} from '@eeacms/volto-cca-policy/helpers';
|
|
1
|
+
import React, { useState, useEffect } from 'react';
|
|
2
|
+
import spinner from '@eeacms/volto-cca-policy/../theme//assets/images/spinner.svg';
|
|
3
|
+
import { HTMLField } from '@eeacms/volto-cca-policy/helpers';
|
|
9
4
|
import { Grid } from 'semantic-ui-react';
|
|
10
|
-
// import { Fragment } from 'react';
|
|
11
5
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
if (!__SERVER__) {
|
|
7
|
+
window.cds_toolbox = {
|
|
8
|
+
cds_public_path: 'https://cds.climate.copernicus.eu/toolbox/',
|
|
15
9
|
};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const createIframe = (div_id, details_url, details_params, spinner_url) => {
|
|
13
|
+
return `
|
|
14
|
+
<iframe width="100%" height="800px" srcdoc="<html><head>
|
|
15
|
+
<title>CDS integration test</title>
|
|
16
|
+
<meta charset='utf-8' />
|
|
17
|
+
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
|
|
18
|
+
<script>
|
|
19
|
+
window.cds_toolbox = { cds_public_path: 'https://cds.climate.copernicus.eu/toolbox/' };
|
|
20
|
+
</script>
|
|
21
|
+
<script type='text/javascript' src='https://cds.climate.copernicus.eu/toolbox/toolbox-latest.js'></script>
|
|
22
|
+
</head>
|
|
23
|
+
<body>
|
|
24
|
+
<div class='t-ct'>
|
|
25
|
+
<div id='${div_id}'>
|
|
26
|
+
<div class='pre-app-loading'>
|
|
27
|
+
<img src='${spinner_url}' alt='Loading'>
|
|
28
|
+
<div>
|
|
29
|
+
...loading configuration...
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
<script type='text/javascript'>
|
|
35
|
+
document.addEventListener('DOMContentLoaded',
|
|
36
|
+
function () {
|
|
37
|
+
window.cds_toolbox.runApp(
|
|
38
|
+
'${div_id}',
|
|
39
|
+
'${details_url}',
|
|
40
|
+
${details_params}
|
|
41
|
+
);
|
|
42
|
+
}, false);
|
|
43
|
+
</script>
|
|
44
|
+
</body></html>"
|
|
45
|
+
/>`;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const Details = (props) => {
|
|
49
|
+
const { content } = props;
|
|
50
|
+
const c3s_details_url = content.details_app_toolbox_url;
|
|
51
|
+
const c3s_details_params = JSON.stringify(
|
|
52
|
+
content.details_app_parameters,
|
|
53
|
+
).replace(/"/g, "'"); // we avoid double quotes in iframe text
|
|
54
|
+
const [spinnerUrl, setSpinnerUrl] = useState(null);
|
|
55
|
+
|
|
56
|
+
React.useEffect(() => {
|
|
57
|
+
setSpinnerUrl(spinner);
|
|
58
|
+
}, []);
|
|
16
59
|
|
|
17
60
|
return (
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
61
|
+
<div
|
|
62
|
+
className="iframe-container"
|
|
63
|
+
dangerouslySetInnerHTML={{
|
|
64
|
+
__html: createIframe(
|
|
65
|
+
'toolbox-app-details',
|
|
66
|
+
c3s_details_url,
|
|
67
|
+
c3s_details_params,
|
|
68
|
+
spinnerUrl,
|
|
69
|
+
),
|
|
70
|
+
}}
|
|
71
|
+
/>
|
|
72
|
+
);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const Overview = (props) => {
|
|
76
|
+
const { content } = props;
|
|
77
|
+
const c3s_overview_url = content.overview_app_toolbox_url;
|
|
78
|
+
const c3s_overview_params = JSON.stringify(
|
|
79
|
+
content.overview_app_parameters,
|
|
80
|
+
).replace(/"/g, "'"); // we avoid double quotes in iframe text
|
|
81
|
+
const [spinnerUrl, setSpinnerUrl] = useState(null);
|
|
82
|
+
|
|
83
|
+
React.useEffect(() => {
|
|
84
|
+
setSpinnerUrl(spinner);
|
|
85
|
+
}, []);
|
|
86
|
+
|
|
87
|
+
return (
|
|
88
|
+
<div
|
|
89
|
+
className="iframe-container"
|
|
90
|
+
dangerouslySetInnerHTML={{
|
|
91
|
+
__html: createIframe(
|
|
92
|
+
'toolbox-app-overview',
|
|
93
|
+
c3s_overview_url,
|
|
94
|
+
c3s_overview_params,
|
|
95
|
+
spinnerUrl,
|
|
96
|
+
),
|
|
97
|
+
}}
|
|
98
|
+
/>
|
|
23
99
|
);
|
|
24
100
|
};
|
|
25
101
|
|
|
26
102
|
function C3SIndicatorView(props) {
|
|
27
103
|
const { content } = props;
|
|
104
|
+
const [showDetails, setShowDetails] = useState(false);
|
|
105
|
+
|
|
106
|
+
const toggleIframe = () => {
|
|
107
|
+
setShowDetails(!showDetails);
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
useEffect(() => {
|
|
111
|
+
if (window.location.hash === '#details') {
|
|
112
|
+
setShowDetails(true);
|
|
113
|
+
}
|
|
114
|
+
}, []);
|
|
115
|
+
|
|
116
|
+
useEffect(() => {
|
|
117
|
+
if (showDetails) {
|
|
118
|
+
window.history.pushState({}, '', '#details');
|
|
119
|
+
} else {
|
|
120
|
+
window.history.pushState({}, '', window.location.pathname);
|
|
121
|
+
}
|
|
122
|
+
}, [showDetails]);
|
|
28
123
|
|
|
29
124
|
return (
|
|
30
125
|
<div className="c3sindicator-view">
|
|
@@ -37,15 +132,39 @@ function C3SIndicatorView(props) {
|
|
|
37
132
|
computer={12}
|
|
38
133
|
className="col-full"
|
|
39
134
|
>
|
|
40
|
-
<
|
|
41
|
-
|
|
135
|
+
<a
|
|
136
|
+
href="/knowledge/european-climate-data-explorer/"
|
|
137
|
+
className="btn-right"
|
|
138
|
+
>
|
|
42
139
|
<button className="ui button primary">ECDE homepage</button>
|
|
43
140
|
</a>
|
|
141
|
+
<h1>{content.title}</h1>
|
|
44
142
|
<HTMLField
|
|
45
143
|
value={content.long_description}
|
|
46
144
|
className="long_description"
|
|
47
145
|
/>
|
|
48
|
-
<
|
|
146
|
+
<a href="#details" className="btn-right">
|
|
147
|
+
<button className="ui button primary" onClick={toggleIframe}>
|
|
148
|
+
{showDetails ? 'Go back' : 'Explore in detail'}
|
|
149
|
+
</button>
|
|
150
|
+
</a>
|
|
151
|
+
<h2>
|
|
152
|
+
{content.indicator_title} {showDetails && ' - Explore index'}
|
|
153
|
+
</h2>
|
|
154
|
+
{!__SERVER__ && !showDetails && <Overview {...props} />}
|
|
155
|
+
{!__SERVER__ && showDetails && <Details {...props} />}
|
|
156
|
+
|
|
157
|
+
<p>
|
|
158
|
+
Content in the European Climate Data Explorer pages is delivered
|
|
159
|
+
by the{' '}
|
|
160
|
+
<a href="https://climate.copernicus.eu/">
|
|
161
|
+
Copernicus Climate Change Service (C3S)
|
|
162
|
+
</a>{' '}
|
|
163
|
+
implemented by ECMWF.{' '}
|
|
164
|
+
<a href="/knowledge/european-climate-data-explorer/disclaimer">
|
|
165
|
+
Disclaimer
|
|
166
|
+
</a>
|
|
167
|
+
</p>
|
|
49
168
|
</Grid.Column>
|
|
50
169
|
</div>
|
|
51
170
|
</Grid>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { UniversalLink } from '@plone/volto/components';
|
|
4
|
+
|
|
5
|
+
const Contact = ({ children, contacts }) =>
|
|
6
|
+
children?.length ? (
|
|
7
|
+
children
|
|
8
|
+
) : (
|
|
9
|
+
<div className="contact-block">
|
|
10
|
+
{contacts?.map((contact, index) => {
|
|
11
|
+
return (
|
|
12
|
+
<div className="contact" key={index}>
|
|
13
|
+
<UniversalLink href={contact.link} className="bold">
|
|
14
|
+
{contact.text}
|
|
15
|
+
</UniversalLink>
|
|
16
|
+
{contact.children && (
|
|
17
|
+
<div className="subcontact">
|
|
18
|
+
{contact.children.map((child, index) => (
|
|
19
|
+
<UniversalLink href={child.link} key={index}>
|
|
20
|
+
{child.text}
|
|
21
|
+
</UniversalLink>
|
|
22
|
+
))}
|
|
23
|
+
</div>
|
|
24
|
+
)}
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
27
|
+
})}
|
|
28
|
+
</div>
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
Contact.propTypes = {
|
|
32
|
+
contacts: PropTypes.array,
|
|
33
|
+
header: PropTypes.string,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export default Contact;
|
|
@@ -4,9 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import React from 'react';
|
|
7
|
-
import { Dropdown, Image } from 'semantic-ui-react';
|
|
7
|
+
import { Dropdown, Image } from 'semantic-ui-react'; // Container, Menu, Grid
|
|
8
8
|
import { connect, useDispatch, useSelector } from 'react-redux';
|
|
9
|
-
|
|
10
9
|
import { withRouter } from 'react-router-dom';
|
|
11
10
|
import { UniversalLink } from '@plone/volto/components';
|
|
12
11
|
import {
|
|
@@ -24,9 +23,10 @@ import eeaFlag from '@eeacms/volto-eea-design-system/../theme/themes/eea/assets/
|
|
|
24
23
|
import config from '@plone/volto/registry';
|
|
25
24
|
import { compose } from 'recompose';
|
|
26
25
|
import { BodyClass } from '@plone/volto/helpers';
|
|
27
|
-
|
|
28
26
|
import cx from 'classnames';
|
|
29
27
|
|
|
28
|
+
import HeaderMain from './HeaderMain';
|
|
29
|
+
|
|
30
30
|
function removeTrailingSlash(path) {
|
|
31
31
|
return path.replace(/\/+$/, '');
|
|
32
32
|
}
|
|
@@ -59,6 +59,7 @@ const EEAHeader = ({ pathname, token, items, history, subsite }) => {
|
|
|
59
59
|
|
|
60
60
|
const { eea } = config.settings;
|
|
61
61
|
const headerOpts = eea.headerOpts || {};
|
|
62
|
+
// const headerSearchBox = eea.headerSearchBox || [];
|
|
62
63
|
const { logo, logoWhite } = headerOpts || {};
|
|
63
64
|
const width = useSelector((state) => state.screen?.width);
|
|
64
65
|
const dispatch = useDispatch();
|
|
@@ -198,8 +199,9 @@ const EEAHeader = ({ pathname, token, items, history, subsite }) => {
|
|
|
198
199
|
</Header.TopDropdownMenu>
|
|
199
200
|
)}
|
|
200
201
|
</Header.TopHeader>
|
|
201
|
-
<Header.Main
|
|
202
|
+
{/* <Header.Main
|
|
202
203
|
pathname={pathname}
|
|
204
|
+
headerSearchBox={headerSearchBox}
|
|
203
205
|
inverted={isHomePageInverse ? true : false}
|
|
204
206
|
transparency={isHomePageInverse ? true : false}
|
|
205
207
|
logo={
|
|
@@ -262,7 +264,73 @@ const EEAHeader = ({ pathname, token, items, history, subsite }) => {
|
|
|
262
264
|
{props?.iconPosition === 'right' && props?.children}
|
|
263
265
|
</UniversalLink>
|
|
264
266
|
)}
|
|
265
|
-
></Header.Main>
|
|
267
|
+
></Header.Main> */}
|
|
268
|
+
|
|
269
|
+
<HeaderMain
|
|
270
|
+
inverted={isHomePageInverse ? true : false}
|
|
271
|
+
transparency={isHomePageInverse ? true : false}
|
|
272
|
+
pathname={pathname}
|
|
273
|
+
logo={
|
|
274
|
+
<div {...(isSubsite ? { className: 'logo-wrapper' } : {})}>
|
|
275
|
+
{!!subsite && subsite.title ? (
|
|
276
|
+
<>
|
|
277
|
+
{subsite.subsite_logo ? (
|
|
278
|
+
<Logo
|
|
279
|
+
src={subsite.subsite_logo?.scales.preview.download}
|
|
280
|
+
title={subsite.title}
|
|
281
|
+
alt={subsite.title}
|
|
282
|
+
url={flattenToAppURL(subsite['@id'])}
|
|
283
|
+
/>
|
|
284
|
+
) : (
|
|
285
|
+
subsite.title
|
|
286
|
+
)}
|
|
287
|
+
<div className="subsite-logo">
|
|
288
|
+
<Logo
|
|
289
|
+
src={isHomePageInverse ? logoWhite : logo}
|
|
290
|
+
title={eea.websiteTitle}
|
|
291
|
+
alt={eea.organisationName}
|
|
292
|
+
url={eea.logoTargetUrl}
|
|
293
|
+
/>
|
|
294
|
+
</div>
|
|
295
|
+
</>
|
|
296
|
+
) : (
|
|
297
|
+
<Logo
|
|
298
|
+
src={isHomePageInverse ? logoWhite : logo}
|
|
299
|
+
title={eea.websiteTitle}
|
|
300
|
+
alt={eea.organisationName}
|
|
301
|
+
url={eea.logoTargetUrl}
|
|
302
|
+
/>
|
|
303
|
+
)}
|
|
304
|
+
</div>
|
|
305
|
+
}
|
|
306
|
+
menuItems={items}
|
|
307
|
+
renderGlobalMenuItem={(item, { onClick }) => (
|
|
308
|
+
<a
|
|
309
|
+
href={item.url || '/'}
|
|
310
|
+
title={item.title}
|
|
311
|
+
onClick={(e) => {
|
|
312
|
+
e.preventDefault();
|
|
313
|
+
onClick(e, item);
|
|
314
|
+
}}
|
|
315
|
+
>
|
|
316
|
+
{item.title}
|
|
317
|
+
</a>
|
|
318
|
+
)}
|
|
319
|
+
renderMenuItem={(item, options, props) => (
|
|
320
|
+
<UniversalLink
|
|
321
|
+
href={item.url || '/'}
|
|
322
|
+
title={item.title}
|
|
323
|
+
{...(options || {})}
|
|
324
|
+
className={cx(options?.className, {
|
|
325
|
+
active: item.url === router_pathname,
|
|
326
|
+
})}
|
|
327
|
+
>
|
|
328
|
+
{props?.iconPosition !== 'right' && props?.children}
|
|
329
|
+
<span>{item.title}</span>
|
|
330
|
+
{props?.iconPosition === 'right' && props?.children}
|
|
331
|
+
</UniversalLink>
|
|
332
|
+
)}
|
|
333
|
+
/>
|
|
266
334
|
</Header>
|
|
267
335
|
);
|
|
268
336
|
};
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Header component.
|
|
3
|
+
* @module components/theme/Header/Header
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import React from 'react'; // , { Component }
|
|
7
|
+
import { useHistory } from 'react-router-dom';
|
|
8
|
+
import { Link } from 'react-router-dom';
|
|
9
|
+
|
|
10
|
+
import { Container, Image, Menu, Grid } from 'semantic-ui-react';
|
|
11
|
+
|
|
12
|
+
import closeIcon from '@eeacms/volto-eea-design-system/../theme/themes/eea/assets/images/Header/close-line.svg';
|
|
13
|
+
import searchIcon from '@eeacms/volto-eea-design-system/../theme/themes/eea/assets/images/Header/search-line.svg';
|
|
14
|
+
import burgerIcon from '@eeacms/volto-eea-design-system/../theme/themes/eea/assets/images/Header/menu-line.svg';
|
|
15
|
+
|
|
16
|
+
import HeaderMenuPopUp from './HeaderMenuPopUp';
|
|
17
|
+
|
|
18
|
+
const HeaderMain = ({
|
|
19
|
+
logo,
|
|
20
|
+
menuItems,
|
|
21
|
+
renderMenuItem,
|
|
22
|
+
renderGlobalMenuItem,
|
|
23
|
+
pathname,
|
|
24
|
+
transparency,
|
|
25
|
+
inverted,
|
|
26
|
+
}) => {
|
|
27
|
+
const history = useHistory();
|
|
28
|
+
const [activeItem, setActiveItem] = React.useState(pathname);
|
|
29
|
+
const [menuIsActive, setMenuIsActive] = React.useState(false);
|
|
30
|
+
const [burger, setBurger] = React.useState('');
|
|
31
|
+
|
|
32
|
+
React.useEffect(() => {
|
|
33
|
+
setMenuIsActive(false);
|
|
34
|
+
|
|
35
|
+
setBurger('');
|
|
36
|
+
// remove active menu when we have no pathname which means we hit logo to go home
|
|
37
|
+
if (!pathname) {
|
|
38
|
+
setActiveItem('');
|
|
39
|
+
}
|
|
40
|
+
}, [pathname]);
|
|
41
|
+
|
|
42
|
+
const mobileBurgerOnClick = () => {
|
|
43
|
+
if (burger === '') {
|
|
44
|
+
setBurger('open');
|
|
45
|
+
setMenuIsActive(true);
|
|
46
|
+
} else {
|
|
47
|
+
setBurger('');
|
|
48
|
+
setMenuIsActive(false);
|
|
49
|
+
setActiveItem('');
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const menuOnClickOutside = () => {
|
|
54
|
+
// restore active element if nothing was selected from the menu dropdown
|
|
55
|
+
if (pathname !== activeItem) {
|
|
56
|
+
setActiveItem(pathname);
|
|
57
|
+
}
|
|
58
|
+
// close mobile navigation when clicking outside if we have value for nav
|
|
59
|
+
if (burger) {
|
|
60
|
+
setBurger('');
|
|
61
|
+
}
|
|
62
|
+
// always close the menu
|
|
63
|
+
setMenuIsActive(false);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const menuOnClick = (e, item) => {
|
|
67
|
+
setActiveItem(item['@id'] || item.url);
|
|
68
|
+
if (item.items.length) {
|
|
69
|
+
setMenuIsActive(true);
|
|
70
|
+
} else {
|
|
71
|
+
history.push(item.url);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// Listens for escape keydown event
|
|
76
|
+
React.useEffect(() => {
|
|
77
|
+
const escKeyPressed = (e) => {
|
|
78
|
+
if (e.key === 'Escape') {
|
|
79
|
+
// menuOnClickOutside();
|
|
80
|
+
// restore active element if nothing was selected from the menu dropdown
|
|
81
|
+
if (pathname !== activeItem) {
|
|
82
|
+
setActiveItem(pathname);
|
|
83
|
+
}
|
|
84
|
+
// close mobile navigation when clicking outside if we have value for nav
|
|
85
|
+
if (burger) {
|
|
86
|
+
setBurger('');
|
|
87
|
+
}
|
|
88
|
+
// always close the menu & search
|
|
89
|
+
setMenuIsActive(false);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
document.addEventListener('keydown', escKeyPressed);
|
|
94
|
+
|
|
95
|
+
return () => {
|
|
96
|
+
document.removeEventListener('keydown', escKeyPressed);
|
|
97
|
+
};
|
|
98
|
+
}, [activeItem, burger, pathname]);
|
|
99
|
+
|
|
100
|
+
const node = React.useRef();
|
|
101
|
+
const mobileMenuBurgerRef = React.useRef();
|
|
102
|
+
const desktopMenuRef = React.useRef();
|
|
103
|
+
|
|
104
|
+
return (
|
|
105
|
+
<div
|
|
106
|
+
className={`main bar ${transparency ? 'transparency' : ''}`}
|
|
107
|
+
ref={node}
|
|
108
|
+
>
|
|
109
|
+
<Container>
|
|
110
|
+
<Grid>
|
|
111
|
+
<Grid.Column mobile={8} tablet={8} computer={4}>
|
|
112
|
+
{logo}
|
|
113
|
+
</Grid.Column>
|
|
114
|
+
<Grid.Column mobile={4} tablet={4} computer={8}>
|
|
115
|
+
<div className={inverted ? 'main-menu inverted' : 'main-menu'}>
|
|
116
|
+
{menuItems && (
|
|
117
|
+
<div
|
|
118
|
+
className="ui text eea-main-menu tablet or lower hidden menu"
|
|
119
|
+
ref={desktopMenuRef}
|
|
120
|
+
id={'navigation'}
|
|
121
|
+
>
|
|
122
|
+
{menuItems.map((item) => (
|
|
123
|
+
<Menu.Item
|
|
124
|
+
name={item['@id'] || item.url}
|
|
125
|
+
key={item['@id'] || item.url}
|
|
126
|
+
active={
|
|
127
|
+
activeItem.indexOf(item['@id']) !== -1 ||
|
|
128
|
+
activeItem.indexOf(item.url) !== -1
|
|
129
|
+
}
|
|
130
|
+
>
|
|
131
|
+
{renderGlobalMenuItem(item, {
|
|
132
|
+
onClick: menuOnClick,
|
|
133
|
+
})}
|
|
134
|
+
</Menu.Item>
|
|
135
|
+
))}
|
|
136
|
+
</div>
|
|
137
|
+
)}
|
|
138
|
+
|
|
139
|
+
<Link to="/en/mission/knowledge-and-data/search-the-database">
|
|
140
|
+
<button
|
|
141
|
+
className="search-action"
|
|
142
|
+
tabIndex="0"
|
|
143
|
+
aria-pressed="false"
|
|
144
|
+
aria-haspopup="true"
|
|
145
|
+
>
|
|
146
|
+
<Image src={searchIcon} alt="search button open/close" />
|
|
147
|
+
</button>
|
|
148
|
+
</Link>
|
|
149
|
+
|
|
150
|
+
<BurgerAction
|
|
151
|
+
className={`mobile ${burger}`}
|
|
152
|
+
onClick={mobileBurgerOnClick}
|
|
153
|
+
ref={mobileMenuBurgerRef}
|
|
154
|
+
>
|
|
155
|
+
<Image
|
|
156
|
+
src={burger === 'open' ? `${closeIcon}` : `${burgerIcon}`}
|
|
157
|
+
alt="menu icon open/close"
|
|
158
|
+
/>
|
|
159
|
+
</BurgerAction>
|
|
160
|
+
</div>
|
|
161
|
+
</Grid.Column>
|
|
162
|
+
</Grid>
|
|
163
|
+
</Container>
|
|
164
|
+
<HeaderMenuPopUp
|
|
165
|
+
renderMenuItem={renderMenuItem}
|
|
166
|
+
activeItem={activeItem}
|
|
167
|
+
menuItems={menuItems}
|
|
168
|
+
pathName={pathname}
|
|
169
|
+
onClose={menuOnClickOutside}
|
|
170
|
+
triggerRefs={[mobileMenuBurgerRef, desktopMenuRef]}
|
|
171
|
+
visible={menuIsActive}
|
|
172
|
+
/>
|
|
173
|
+
</div>
|
|
174
|
+
);
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
const BurgerAction = React.forwardRef((props, ref) => (
|
|
178
|
+
<button
|
|
179
|
+
ref={ref}
|
|
180
|
+
className={`burger-action ${props.className}`}
|
|
181
|
+
tabIndex="0"
|
|
182
|
+
aria-pressed="false"
|
|
183
|
+
aria-haspopup="true"
|
|
184
|
+
onClick={props.onClick}
|
|
185
|
+
>
|
|
186
|
+
{props.children}
|
|
187
|
+
</button>
|
|
188
|
+
));
|
|
189
|
+
|
|
190
|
+
export default HeaderMain;
|
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Transition } from 'semantic-ui-react';
|
|
3
|
+
import { Container, Grid, List, Icon, Accordion } from 'semantic-ui-react';
|
|
4
|
+
|
|
5
|
+
import { cloneDeep } from 'lodash';
|
|
6
|
+
|
|
7
|
+
import { useClickOutside } from '@eeacms/volto-eea-design-system/helpers';
|
|
8
|
+
|
|
9
|
+
const createColumns = (item, length, renderMenuItem) => {
|
|
10
|
+
let subArrays = [];
|
|
11
|
+
let size = length;
|
|
12
|
+
for (let i = 0; i < item.items.length; i += size) {
|
|
13
|
+
subArrays.push(item.items.slice(i, i + size));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const column = subArrays.map((subArray, index) => (
|
|
17
|
+
<Grid.Column key={index}>
|
|
18
|
+
<List>
|
|
19
|
+
{subArray.map((arrayItem, idx) => (
|
|
20
|
+
<React.Fragment key={idx}>
|
|
21
|
+
{renderMenuItem(arrayItem, {
|
|
22
|
+
className: 'item',
|
|
23
|
+
role: 'listitem',
|
|
24
|
+
key: idx,
|
|
25
|
+
})}
|
|
26
|
+
</React.Fragment>
|
|
27
|
+
))}
|
|
28
|
+
</List>
|
|
29
|
+
</Grid.Column>
|
|
30
|
+
));
|
|
31
|
+
|
|
32
|
+
return column;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const ItemGrid = ({ item, columns, length, renderMenuItem }) => (
|
|
36
|
+
<>
|
|
37
|
+
{renderMenuItem(item, { className: 'sub-title' })}
|
|
38
|
+
{item.items.length ? (
|
|
39
|
+
<Grid columns={columns}>
|
|
40
|
+
{createColumns(item, length, renderMenuItem)}
|
|
41
|
+
</Grid>
|
|
42
|
+
) : null}
|
|
43
|
+
</>
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const Item = ({ item, icon = false, iconName, renderMenuItem }) => (
|
|
47
|
+
<>
|
|
48
|
+
{renderMenuItem(item, { className: 'sub-title' })}
|
|
49
|
+
<List className="menu-list">
|
|
50
|
+
{item.items.map((listItem, index) => (
|
|
51
|
+
<React.Fragment key={index}>
|
|
52
|
+
{renderMenuItem(
|
|
53
|
+
listItem,
|
|
54
|
+
{
|
|
55
|
+
className: 'item',
|
|
56
|
+
key: index,
|
|
57
|
+
role: 'listitem',
|
|
58
|
+
},
|
|
59
|
+
{ children: icon && <Icon className={iconName} /> },
|
|
60
|
+
)}
|
|
61
|
+
</React.Fragment>
|
|
62
|
+
))}
|
|
63
|
+
</List>
|
|
64
|
+
</>
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
const Topics = ({ menuItem, renderMenuItem }) => (
|
|
68
|
+
<Grid>
|
|
69
|
+
{menuItem.items.map((section, index) => (
|
|
70
|
+
<React.Fragment key={index}>
|
|
71
|
+
{section.title === 'At a glance' ? (
|
|
72
|
+
<Grid.Column width={3} id="at-a-glance">
|
|
73
|
+
<Item item={section} key={index} renderMenuItem={renderMenuItem} />
|
|
74
|
+
</Grid.Column>
|
|
75
|
+
) : (
|
|
76
|
+
<Grid.Column width={9} key={index} id="topics-right-column">
|
|
77
|
+
<ItemGrid
|
|
78
|
+
item={section}
|
|
79
|
+
columns={4}
|
|
80
|
+
length={10}
|
|
81
|
+
key={index}
|
|
82
|
+
renderMenuItem={renderMenuItem}
|
|
83
|
+
/>
|
|
84
|
+
</Grid.Column>
|
|
85
|
+
)}
|
|
86
|
+
</React.Fragment>
|
|
87
|
+
))}
|
|
88
|
+
</Grid>
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
const Countries = ({ menuItem, renderMenuItem }) => (
|
|
92
|
+
<Grid>
|
|
93
|
+
<Grid.Column width={8}>
|
|
94
|
+
{menuItem.items.map((section, index) => (
|
|
95
|
+
<React.Fragment key={index}>
|
|
96
|
+
{section.title === 'EEA member countries' && (
|
|
97
|
+
<ItemGrid
|
|
98
|
+
item={section}
|
|
99
|
+
columns={5}
|
|
100
|
+
length={7}
|
|
101
|
+
renderMenuItem={renderMenuItem}
|
|
102
|
+
/>
|
|
103
|
+
)}
|
|
104
|
+
</React.Fragment>
|
|
105
|
+
))}
|
|
106
|
+
</Grid.Column>
|
|
107
|
+
<Grid.Column width={4}>
|
|
108
|
+
<Grid columns={1} className="nested-grid">
|
|
109
|
+
{menuItem.items.map((section, index) => (
|
|
110
|
+
<React.Fragment key={index}>
|
|
111
|
+
{section.title !== 'EEA member countries' && (
|
|
112
|
+
<Grid.Column>
|
|
113
|
+
<ItemGrid
|
|
114
|
+
item={section}
|
|
115
|
+
columns={2}
|
|
116
|
+
length={3}
|
|
117
|
+
renderMenuItem={renderMenuItem}
|
|
118
|
+
/>
|
|
119
|
+
</Grid.Column>
|
|
120
|
+
)}
|
|
121
|
+
</React.Fragment>
|
|
122
|
+
))}
|
|
123
|
+
</Grid>
|
|
124
|
+
</Grid.Column>
|
|
125
|
+
</Grid>
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
const StandardMegaMenuGrid = ({ menuItem, renderMenuItem }) => (
|
|
129
|
+
<Grid columns={4}>
|
|
130
|
+
{menuItem.items.map((section, index) => (
|
|
131
|
+
<Grid.Column key={index}>
|
|
132
|
+
<Item item={section} renderMenuItem={renderMenuItem} />
|
|
133
|
+
</Grid.Column>
|
|
134
|
+
))}
|
|
135
|
+
</Grid>
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
const FirstLevelContent = ({ element, renderMenuItem, pathName }) => {
|
|
139
|
+
const topics = element.title === 'Topics' ? true : false;
|
|
140
|
+
let defaultIndex = -1;
|
|
141
|
+
|
|
142
|
+
return (
|
|
143
|
+
<>
|
|
144
|
+
{!topics ? (
|
|
145
|
+
<React.Fragment>
|
|
146
|
+
{element.items.map((item, index) => {
|
|
147
|
+
let firstLevelPanels = [];
|
|
148
|
+
if (!item.items.length) {
|
|
149
|
+
return (
|
|
150
|
+
<React.Fragment key={index}>
|
|
151
|
+
{renderMenuItem(item, { className: 'item sub-title' })}
|
|
152
|
+
</React.Fragment>
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
let x = {};
|
|
156
|
+
x.key = item['@id'] || item['url'];
|
|
157
|
+
if (pathName.indexOf(item.url) !== -1) {
|
|
158
|
+
defaultIndex = index;
|
|
159
|
+
}
|
|
160
|
+
x.title = (
|
|
161
|
+
<Accordion.Title key={`title=${index}`} as="button">
|
|
162
|
+
{item.title}
|
|
163
|
+
<Icon className="ri-arrow-down-s-line" size="small" />
|
|
164
|
+
</Accordion.Title>
|
|
165
|
+
);
|
|
166
|
+
let overflow_item = cloneDeep(item);
|
|
167
|
+
overflow_item.title = 'See all';
|
|
168
|
+
x.content = (
|
|
169
|
+
<Accordion.Content>
|
|
170
|
+
{renderMenuItem(overflow_item, {
|
|
171
|
+
className: 'item title-item',
|
|
172
|
+
})}
|
|
173
|
+
<SecondLevelContent
|
|
174
|
+
element={item}
|
|
175
|
+
renderMenuItem={renderMenuItem}
|
|
176
|
+
/>
|
|
177
|
+
</Accordion.Content>
|
|
178
|
+
);
|
|
179
|
+
firstLevelPanels.push(x);
|
|
180
|
+
return (
|
|
181
|
+
<Accordion.Accordion
|
|
182
|
+
panels={firstLevelPanels}
|
|
183
|
+
key={index}
|
|
184
|
+
defaultActiveIndex={defaultIndex === index ? 0 : -1}
|
|
185
|
+
/>
|
|
186
|
+
);
|
|
187
|
+
})}
|
|
188
|
+
</React.Fragment>
|
|
189
|
+
) : (
|
|
190
|
+
<SecondLevelContent
|
|
191
|
+
element={element}
|
|
192
|
+
topics={true}
|
|
193
|
+
renderMenuItem={renderMenuItem}
|
|
194
|
+
/>
|
|
195
|
+
)}
|
|
196
|
+
</>
|
|
197
|
+
);
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
const SecondLevelContent = ({ element, topics = false, renderMenuItem }) => {
|
|
201
|
+
let content;
|
|
202
|
+
if (topics) {
|
|
203
|
+
const atAGlance = element.items.find(
|
|
204
|
+
(element) => element.title === 'At a glance',
|
|
205
|
+
);
|
|
206
|
+
const inDepth = element.items.find(
|
|
207
|
+
(element) => element.url.indexOf('in-depth') !== -1,
|
|
208
|
+
);
|
|
209
|
+
content = (
|
|
210
|
+
<List>
|
|
211
|
+
{atAGlance &&
|
|
212
|
+
atAGlance.items.map((item, index) => (
|
|
213
|
+
<React.Fragment key={index}>
|
|
214
|
+
{renderMenuItem(item, {
|
|
215
|
+
key: index,
|
|
216
|
+
role: 'listitem',
|
|
217
|
+
className: 'item',
|
|
218
|
+
})}
|
|
219
|
+
</React.Fragment>
|
|
220
|
+
))}
|
|
221
|
+
{inDepth && (
|
|
222
|
+
<React.Fragment key={inDepth.url}>
|
|
223
|
+
{renderMenuItem(inDepth, {
|
|
224
|
+
key: inDepth.url,
|
|
225
|
+
role: 'listitem',
|
|
226
|
+
className: 'item',
|
|
227
|
+
})}
|
|
228
|
+
</React.Fragment>
|
|
229
|
+
)}
|
|
230
|
+
</List>
|
|
231
|
+
);
|
|
232
|
+
} else {
|
|
233
|
+
content = (
|
|
234
|
+
<List>
|
|
235
|
+
{element.items.map((item, index) => (
|
|
236
|
+
<React.Fragment key={index}>
|
|
237
|
+
{renderMenuItem(item, {
|
|
238
|
+
key: index,
|
|
239
|
+
role: 'listitem',
|
|
240
|
+
className: 'item',
|
|
241
|
+
})}
|
|
242
|
+
</React.Fragment>
|
|
243
|
+
))}
|
|
244
|
+
</List>
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return <>{content}</>;
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
const NestedAccordion = ({ menuItems, renderMenuItem, pathName }) => {
|
|
252
|
+
let defaultIndex = -1;
|
|
253
|
+
const rootPanels = [];
|
|
254
|
+
menuItems.forEach((element, index) => {
|
|
255
|
+
let x = {};
|
|
256
|
+
x.key = index;
|
|
257
|
+
|
|
258
|
+
if (pathName.indexOf(element.url) !== -1) {
|
|
259
|
+
defaultIndex = index;
|
|
260
|
+
}
|
|
261
|
+
x.title = (
|
|
262
|
+
<Accordion.Title key={`title-${index}`} index={index} as="button">
|
|
263
|
+
{element.title}
|
|
264
|
+
<Icon className="ri-arrow-down-s-line" size="small" />
|
|
265
|
+
</Accordion.Title>
|
|
266
|
+
);
|
|
267
|
+
let overview = cloneDeep(element);
|
|
268
|
+
x.content = (
|
|
269
|
+
<Accordion.Content key={index}>
|
|
270
|
+
<div className="mega-menu-title">
|
|
271
|
+
{/* Inverted right labeled button as a category title - Mobile */}
|
|
272
|
+
{renderMenuItem(
|
|
273
|
+
overview,
|
|
274
|
+
{ className: 'ui button inverted icon right labeled' },
|
|
275
|
+
{
|
|
276
|
+
iconPosition: 'right',
|
|
277
|
+
children: (
|
|
278
|
+
<>
|
|
279
|
+
{/* Add word overview to titles */}
|
|
280
|
+
<span> overview</span>
|
|
281
|
+
<Icon className={'arrow right icon'} alt={'Title icon'} />
|
|
282
|
+
</>
|
|
283
|
+
),
|
|
284
|
+
},
|
|
285
|
+
)}
|
|
286
|
+
</div>
|
|
287
|
+
<FirstLevelContent
|
|
288
|
+
element={element}
|
|
289
|
+
renderMenuItem={renderMenuItem}
|
|
290
|
+
pathName={pathName}
|
|
291
|
+
/>
|
|
292
|
+
</Accordion.Content>
|
|
293
|
+
);
|
|
294
|
+
rootPanels.push(x);
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
return <Accordion defaultActiveIndex={defaultIndex} panels={rootPanels} />;
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
function HeaderMenuPopUp({
|
|
301
|
+
menuItems,
|
|
302
|
+
renderMenuItem,
|
|
303
|
+
pathName,
|
|
304
|
+
onClose,
|
|
305
|
+
triggerRefs,
|
|
306
|
+
activeItem,
|
|
307
|
+
visible,
|
|
308
|
+
}) {
|
|
309
|
+
const nodeRef = React.useRef();
|
|
310
|
+
useClickOutside({ targetRefs: [nodeRef, ...triggerRefs], callback: onClose });
|
|
311
|
+
|
|
312
|
+
const menuItem = menuItems.find(
|
|
313
|
+
(current) => current.url === activeItem || current['@id'] === activeItem,
|
|
314
|
+
);
|
|
315
|
+
|
|
316
|
+
return (
|
|
317
|
+
<Transition visible={visible} animation="slide down" duration={300}>
|
|
318
|
+
<div id="mega-menu" ref={nodeRef}>
|
|
319
|
+
<Container>
|
|
320
|
+
{menuItem && (
|
|
321
|
+
<div className="menu-content tablet hidden mobile hidden">
|
|
322
|
+
{/* Inverted right labeled button as a category title,
|
|
323
|
+
for topics the button goes inside the grid */}
|
|
324
|
+
{menuItem.title && (
|
|
325
|
+
<div className="mega-menu-title">
|
|
326
|
+
{renderMenuItem(
|
|
327
|
+
menuItem,
|
|
328
|
+
{ className: 'ui button inverted icon right labeled' },
|
|
329
|
+
{
|
|
330
|
+
iconPosition: 'right',
|
|
331
|
+
children: (
|
|
332
|
+
<>
|
|
333
|
+
{/* Add word overview to titles */}
|
|
334
|
+
<span> overview</span>
|
|
335
|
+
<Icon
|
|
336
|
+
className={'arrow right icon'}
|
|
337
|
+
alt={'Title icon'}
|
|
338
|
+
/>
|
|
339
|
+
</>
|
|
340
|
+
),
|
|
341
|
+
},
|
|
342
|
+
)}
|
|
343
|
+
</div>
|
|
344
|
+
)}
|
|
345
|
+
{menuItem.title === 'Topics' ? (
|
|
346
|
+
<Topics menuItem={menuItem} renderMenuItem={renderMenuItem} />
|
|
347
|
+
) : menuItem.title === 'Countries' ? (
|
|
348
|
+
<Countries
|
|
349
|
+
menuItem={menuItem}
|
|
350
|
+
renderMenuItem={renderMenuItem}
|
|
351
|
+
/>
|
|
352
|
+
) : (
|
|
353
|
+
<StandardMegaMenuGrid
|
|
354
|
+
menuItem={menuItem}
|
|
355
|
+
renderMenuItem={renderMenuItem}
|
|
356
|
+
/>
|
|
357
|
+
)}
|
|
358
|
+
</div>
|
|
359
|
+
)}
|
|
360
|
+
<div className="tablet only mobile only">
|
|
361
|
+
<NestedAccordion
|
|
362
|
+
menuItems={menuItems}
|
|
363
|
+
renderMenuItem={renderMenuItem}
|
|
364
|
+
pathName={pathName}
|
|
365
|
+
/>
|
|
366
|
+
</div>
|
|
367
|
+
</Container>
|
|
368
|
+
</div>
|
|
369
|
+
</Transition>
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
export default HeaderMenuPopUp;
|
package/src/index.js
CHANGED
|
@@ -96,13 +96,8 @@ const applyConfig = (config) => {
|
|
|
96
96
|
{
|
|
97
97
|
icon: 'comment outline',
|
|
98
98
|
text: 'Contact',
|
|
99
|
-
link: '
|
|
99
|
+
link: 'climate.adapt@eea.europa.eu',
|
|
100
100
|
},
|
|
101
|
-
// {
|
|
102
|
-
// icon: 'envelope outline',
|
|
103
|
-
// text: 'Sign up to our newsletter',
|
|
104
|
-
// link: '/newsletter',
|
|
105
|
-
// },
|
|
106
101
|
],
|
|
107
102
|
},
|
|
108
103
|
headerSearchBox: [
|
|
@@ -114,8 +109,16 @@ const applyConfig = (config) => {
|
|
|
114
109
|
// 'Looking for more information? Try searching the full EEA website content',
|
|
115
110
|
// buttonTitle: 'Go to full site search',
|
|
116
111
|
},
|
|
112
|
+
// {
|
|
113
|
+
// path: '/en/mission',
|
|
114
|
+
// placeholder: 'Search...',
|
|
115
|
+
// description: 'Looking for more information?',
|
|
116
|
+
// buttonTitle: 'Go to advanced search',
|
|
117
|
+
// },
|
|
117
118
|
],
|
|
118
119
|
logoTargetUrl: '/en',
|
|
120
|
+
organisationName: 'Climate-ADAPT',
|
|
121
|
+
websiteTitle: 'Climate-ADAPT',
|
|
119
122
|
};
|
|
120
123
|
|
|
121
124
|
// Enable volto-embed
|
|
@@ -128,6 +131,19 @@ const applyConfig = (config) => {
|
|
|
128
131
|
config.blocks.blocksConfig.video.restricted = false;
|
|
129
132
|
}
|
|
130
133
|
|
|
134
|
+
config.blocks.blocksConfig.__grid = {
|
|
135
|
+
...config.blocks.blocksConfig.__grid,
|
|
136
|
+
maxNumberOfColumns: 5,
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
config.blocks.blocksConfig.nextCloudVideo = {
|
|
140
|
+
...config.blocks.blocksConfig.nextCloudVideo,
|
|
141
|
+
whiteList: [
|
|
142
|
+
'https://cmshare.eea.europa.eu',
|
|
143
|
+
'https://shareit.eea.europa.eu',
|
|
144
|
+
],
|
|
145
|
+
};
|
|
146
|
+
|
|
131
147
|
//console.log(config);
|
|
132
148
|
config.views.contentTypesViews = {
|
|
133
149
|
...config.views.contentTypesViews,
|
|
@@ -145,13 +161,13 @@ const applyConfig = (config) => {
|
|
|
145
161
|
};
|
|
146
162
|
|
|
147
163
|
config.settings.contextNavigationLocations = [
|
|
148
|
-
{
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
},
|
|
164
|
+
// {
|
|
165
|
+
// title: 'Regional Adaptation Support Tool',
|
|
166
|
+
// columns: 4,
|
|
167
|
+
// topLevel: 2,
|
|
168
|
+
// bottomLevel: 0,
|
|
169
|
+
// rootPath: '/mission/knowledge-and-data/regional-adaptation-support-tool',
|
|
170
|
+
// },
|
|
155
171
|
{
|
|
156
172
|
title: 'UrbanAST',
|
|
157
173
|
topLevel: 3,
|
|
@@ -46,7 +46,19 @@ div.video-view {
|
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
// C3S Indicator view styles
|
|
50
|
+
div.c3sindicator-view {
|
|
51
|
+
iframe {
|
|
52
|
+
border: none;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
49
56
|
// General styles
|
|
57
|
+
.btn-right {
|
|
58
|
+
margin: calc(2rem - 0.1em) 0em 1rem;
|
|
59
|
+
float: right;
|
|
60
|
+
}
|
|
61
|
+
|
|
50
62
|
div.share-info {
|
|
51
63
|
margin-top: 1em;
|
|
52
64
|
text-align: right;
|
|
@@ -76,6 +88,10 @@ div.content-metadata {
|
|
|
76
88
|
|
|
77
89
|
// Mission subsites
|
|
78
90
|
body.subsite-mkh {
|
|
91
|
+
.top.bar .ui.container {
|
|
92
|
+
z-index: 3;
|
|
93
|
+
}
|
|
94
|
+
|
|
79
95
|
&.subsite-root {
|
|
80
96
|
.segment.content-area {
|
|
81
97
|
padding-top: 0;
|
|
@@ -99,6 +115,7 @@ body.subsite-mkh {
|
|
|
99
115
|
|
|
100
116
|
p {
|
|
101
117
|
font-size: 1.125rem;
|
|
118
|
+
font-weight: 600;
|
|
102
119
|
}
|
|
103
120
|
}
|
|
104
121
|
|
|
@@ -134,7 +151,7 @@ body.subsite-mkh {
|
|
|
134
151
|
}
|
|
135
152
|
|
|
136
153
|
.eea.header .subsite-logo {
|
|
137
|
-
z-index:
|
|
154
|
+
z-index: 1;
|
|
138
155
|
height: 100%;
|
|
139
156
|
|
|
140
157
|
.logo {
|