@eeacms/volto-eea-website-theme 0.6.3 → 0.6.6

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,9 +4,34 @@ All notable changes to this project will be documented in this file. Dates are d
4
4
 
5
5
  Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
6
 
7
+ #### [0.6.6](https://github.com/eea/volto-eea-website-theme/compare/0.6.5...0.6.6)
8
+
9
+ - condition config of accordion only if found to avoid error [`21b9cd7`](https://github.com/eea/volto-eea-website-theme/commit/21b9cd7006aed894e0eac5aa4a4b370233b334ab)
10
+ - Add customization for volto-tabs-block [`71878f4`](https://github.com/eea/volto-eea-website-theme/commit/71878f49e9e34f9fbab66c6b805dd9ff6e353b29)
11
+ - change(footer): update footer implementation to use subfooter section #33 [`e4cb3c0`](https://github.com/eea/volto-eea-website-theme/commit/e4cb3c042414ba5811924b40c532738da978fdbd)
12
+ - change(footer): update footer implementation to use latest changes to the subfooter component [`efa23fe`](https://github.com/eea/volto-eea-website-theme/commit/efa23fecee0786c3d9a254c8115b3f28a8be5302)
13
+
14
+ #### [0.6.5](https://github.com/eea/volto-eea-website-theme/compare/0.6.4...0.6.5)
15
+
16
+ > 3 June 2022
17
+
18
+ - fix(tags): Replace customizations of volto-widgets-view with config r… [`#32`](https://github.com/eea/volto-eea-website-theme/pull/32)
19
+ - fix(tags): Replace customizations of volto-widgets-view with config registry [`8f8c6fc`](https://github.com/eea/volto-eea-website-theme/commit/8f8c6fcdc6d48a56fbb35db781432390a703a215)
20
+
21
+ #### [0.6.4](https://github.com/eea/volto-eea-website-theme/compare/0.6.3...0.6.4)
22
+
23
+ > 2 June 2022
24
+
25
+ - Release [`#31`](https://github.com/eea/volto-eea-website-theme/pull/31)
26
+ - Fix: missing translations [`53b0f20`](https://github.com/eea/volto-eea-website-theme/commit/53b0f20daf01f48d81d6b79f9f7a5bcd166b0d2d)
27
+ - Customize Toolbar.jsx - volto 16.0.0-alpha.7 [`b26182f`](https://github.com/eea/volto-eea-website-theme/commit/b26182f9ac7369497f3602fb5842248f7b7da7c5)
28
+
7
29
  #### [0.6.3](https://github.com/eea/volto-eea-website-theme/compare/0.6.2...0.6.3)
8
30
 
9
- - Relase 0.6.3 [`ea16b39`](https://github.com/eea/volto-eea-website-theme/commit/ea16b39873096e16005f360746f4ef92220bc3fd)
31
+ > 2 June 2022
32
+
33
+ - Relase 0.6.3 [`#30`](https://github.com/eea/volto-eea-website-theme/pull/30)
34
+ - Release [`#29`](https://github.com/eea/volto-eea-website-theme/pull/29)
10
35
  - Remove unused languages [`fd988a6`](https://github.com/eea/volto-eea-website-theme/commit/fd988a6f172ad85dd5533e258e0be36e07693717)
11
36
 
12
37
  #### [0.6.2](https://github.com/eea/volto-eea-website-theme/compare/0.6.1...0.6.2)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-eea-website-theme",
3
- "version": "0.6.3",
3
+ "version": "0.6.6",
4
4
  "description": "@eeacms/volto-eea-website-theme: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: IDM2 A-Team",
package/src/config.js CHANGED
@@ -8,60 +8,151 @@ import ccaLogo from '@eeacms/volto-eea-design-system/../theme/themes/eea/assets/
8
8
  import copernicusLogo from '@eeacms/volto-eea-design-system/../theme/themes/eea/assets/logo/copernicus.svg';
9
9
  import industryLogo from '@eeacms/volto-eea-design-system/../theme/themes/eea/assets/logo/industry.svg';
10
10
  import marineLogo from '@eeacms/volto-eea-design-system/../theme/themes/eea/assets/logo/marine.svg';
11
+ import eionetLogo from '@eeacms/volto-eea-design-system/../theme/themes/eea/assets/logo/eionet.svg';
12
+ import eeaLogo from '@eeacms/volto-eea-design-system/../theme/themes/eea/assets/logo/eea.svg';
11
13
 
12
14
  // TODO: to be consolidated with headerLinks
13
- export const partnerWebsites = [
14
- {
15
- link: 'https://biodiversity.europa.eu/',
16
- src: biseLogo,
17
- alt: 'Biodiversity',
18
- },
19
- {
20
- link: 'https://climate-energy.eea.europa.eu/',
21
- src: energyLogo,
22
- alt: 'Climate and energy in the EU',
23
- },
24
- {
25
- link: 'https://insitu.copernicus.eu/',
26
- src: insituLogo,
27
- alt: 'Copernicus in situ',
28
- },
29
- {
30
- link: 'https://ipchem.jrc.ec.europa.eu/RDSIdiscovery/ipchem/index.html',
31
- src: ipchemLogo,
32
- alt: 'Information platform for chemical monitoring',
33
- },
34
- {
35
- link: 'https://water.europa.eu/freshwater',
36
- src: freshwaterLogo,
37
- alt: 'WISE freshwater',
38
- },
39
- {
40
- link: 'https://forest.eea.europa.eu/',
41
- src: fiseLogo,
42
- alt: 'Forest information system for europe',
43
- },
44
- {
45
- link: 'https://climate-adapt.eea.europa.eu/',
46
- src: ccaLogo,
47
- alt: 'Climate adapt',
48
- },
49
- {
50
- link: 'https://land.copernicus.eu/',
51
- src: copernicusLogo,
52
- alt: 'Copernicus land monitoring service',
53
- },
54
- {
55
- link: 'https://industry.eea.europa.eu/',
56
- src: industryLogo,
57
- alt: 'European industrial emissions portal',
58
- },
59
- {
60
- link: 'https://water.europa.eu/marine',
61
- src: marineLogo,
62
- alt: 'WISE marine',
63
- },
64
- ];
15
+ // Footer.jsx config options
16
+ export const footerOpts = {
17
+ header: 'EEA information systems',
18
+ logosHeader: 'Managed by',
19
+ contactHeader: 'Contact Us',
20
+ actions: [
21
+ {
22
+ title: 'Login',
23
+ link: '/login',
24
+ },
25
+ {
26
+ link: '/sitemap',
27
+ title: 'Sitemap',
28
+ },
29
+ {
30
+ link: '/privacy',
31
+ title: 'Privacy',
32
+ },
33
+ {
34
+ link: '/copyright',
35
+ title: 'Copyright',
36
+ copy: true,
37
+ },
38
+ ],
39
+ sites: [
40
+ {
41
+ link: 'https://biodiversity.europa.eu/',
42
+ src: biseLogo,
43
+ alt: 'Biodiversity',
44
+ },
45
+ {
46
+ link: 'https://climate-energy.eea.europa.eu/',
47
+ src: energyLogo,
48
+ alt: 'Climate and energy in the EU',
49
+ },
50
+ {
51
+ link: 'https://insitu.copernicus.eu/',
52
+ src: insituLogo,
53
+ alt: 'Copernicus in situ',
54
+ },
55
+ {
56
+ link: 'https://ipchem.jrc.ec.europa.eu/RDSIdiscovery/ipchem/index.html',
57
+ src: ipchemLogo,
58
+ alt: 'Information platform for chemical monitoring',
59
+ },
60
+ {
61
+ link: 'https://water.europa.eu/freshwater',
62
+ src: freshwaterLogo,
63
+ alt: 'WISE freshwater',
64
+ },
65
+ {
66
+ link: 'https://forest.eea.europa.eu/',
67
+ src: fiseLogo,
68
+ alt: 'Forest information system for europe',
69
+ },
70
+ {
71
+ link: 'https://climate-adapt.eea.europa.eu/',
72
+ src: ccaLogo,
73
+ alt: 'Climate adapt',
74
+ },
75
+ {
76
+ link: 'https://land.copernicus.eu/',
77
+ src: copernicusLogo,
78
+ alt: 'Copernicus land monitoring service',
79
+ },
80
+ {
81
+ link: 'https://industry.eea.europa.eu/',
82
+ src: industryLogo,
83
+ alt: 'European industrial emissions portal',
84
+ },
85
+ {
86
+ link: 'https://water.europa.eu/marine',
87
+ src: marineLogo,
88
+ alt: 'WISE marine',
89
+ },
90
+ ],
91
+ managedBy: [
92
+ {
93
+ link: 'https://www.eea.europa.eu/',
94
+ src: eeaLogo,
95
+ alt: 'EEA Logo',
96
+ className: 'site logo',
97
+ columnSize: {
98
+ mobile: 12,
99
+ tablet: 12,
100
+ computer: 5,
101
+ },
102
+ },
103
+ {
104
+ link: 'https://www.eionet.europa.eu/',
105
+ src: eionetLogo,
106
+ alt: 'EIONET Logo',
107
+ className: 'eionet logo',
108
+ columnSize: {
109
+ mobile: 12,
110
+ tablet: 12,
111
+ computer: 6,
112
+ },
113
+ },
114
+ ],
115
+ social: [
116
+ {
117
+ name: 'twitter',
118
+ icon: 'ri-twitter-fill',
119
+ link: 'https://twitter.com/euenvironment',
120
+ },
121
+ {
122
+ name: 'facebook',
123
+ icon: 'ri-facebook-box-fill',
124
+ link: 'https://www.facebook.com/European.Environment.Agency',
125
+ },
126
+ {
127
+ name: 'linkedin',
128
+ icon: 'ri-linkedin-fill',
129
+ link: 'https://www.linkedin.com/company/european-environment-agency',
130
+ },
131
+ {
132
+ name: 'youtube',
133
+ icon: 'ri-youtube-fill',
134
+ link: 'https://www.youtube.com/user/EEAvideos',
135
+ },
136
+ {
137
+ name: 'rss',
138
+ icon: 'ri-rss-fill',
139
+ link: '/subscription/news-feeds',
140
+ },
141
+ ],
142
+ contacts: [
143
+ {
144
+ icon: 'comment outline',
145
+ text: 'Ask your question',
146
+ link: '/contact-us',
147
+ },
148
+ {
149
+ icon: 'envelope outline',
150
+ text: 'Sign up to our newsletter',
151
+ link: '/newsletter',
152
+ },
153
+ ],
154
+ address: 'Kongens Nytorv 6 1050 Copenhagen K (+45) 33 36 71 00',
155
+ };
65
156
 
66
157
  export const globalHeaderPartnerLinks = {
67
158
  title: 'Environmental information systems',
@@ -101,64 +192,6 @@ export const globalHeaderPartnerLinks = {
101
192
  ],
102
193
  };
103
194
 
104
- export const globalActions = [
105
- {
106
- link: '/login',
107
- title: 'CMS Login',
108
- },
109
- {
110
- link: '/sitemap',
111
- title: 'Sitemap',
112
- },
113
- {
114
- link: '/privacy',
115
- title: 'Privacy',
116
- },
117
- {
118
- link: '/copyright',
119
- title: 'Copyright',
120
- copy: true,
121
- },
122
- ];
123
-
124
- export const socialActions = [
125
- {
126
- name: 'twitter',
127
- link: 'https://twitter.com/euenvironment',
128
- },
129
- {
130
- name: 'facebook',
131
- link: 'https://www.facebook.com/European.Environment.Agency',
132
- },
133
- {
134
- name: 'linkedin',
135
- link: 'https://www.linkedin.com/company/european-environment-agency',
136
- },
137
- {
138
- name: 'youtube',
139
- link: 'https://www.youtube.com/user/EEAvideos',
140
- },
141
- {
142
- name: 'rss',
143
- link: '/subscription/news-feeds',
144
- },
145
- ];
146
-
147
- export const footerActions = [
148
- {
149
- icon: 'comment outline',
150
- text: 'Ask your question',
151
- link: '/contact-us',
152
- },
153
- {
154
- icon: 'envelope outline',
155
- text: 'Sign up to our newsletter',
156
- link: '/newsletter',
157
- },
158
- ];
159
-
160
- export const address = 'Kongens Nytorv 6 1050 Copenhagen K (+45) 33 36 71 00';
161
-
162
195
  export const languages = [
163
196
  { name: 'Български', code: 'bg' },
164
197
  { name: 'čeština', code: 'cs' },
@@ -0,0 +1,589 @@
1
+ /**
2
+ * Toolbar component.
3
+ * @module components/manage/Toolbar/Toolbar
4
+ */
5
+
6
+ import React, { Component } from 'react';
7
+ import { defineMessages, injectIntl } from 'react-intl';
8
+ import PropTypes from 'prop-types';
9
+ import { Link } from 'react-router-dom';
10
+ import jwtDecode from 'jwt-decode';
11
+ import { connect } from 'react-redux';
12
+ import { compose } from 'redux';
13
+ import { doesNodeContainClick } from 'semantic-ui-react/dist/commonjs/lib';
14
+ import { withCookies } from 'react-cookie';
15
+ import { filter, find } from 'lodash';
16
+ import cx from 'classnames';
17
+ import config from '@plone/volto/registry';
18
+
19
+ import More from '@plone/volto/components/manage/Toolbar/More';
20
+ import PersonalTools from '@plone/volto/components/manage/Toolbar/PersonalTools';
21
+ import Types from '@plone/volto/components/manage/Toolbar/Types';
22
+ import PersonalInformation from '@plone/volto/components/manage/Preferences/PersonalInformation';
23
+ import PersonalPreferences from '@plone/volto/components/manage/Preferences/PersonalPreferences';
24
+ import StandardWrapper from '@plone/volto/components/manage/Toolbar/StandardWrapper';
25
+ import {
26
+ getTypes,
27
+ listActions,
28
+ setExpandedToolbar,
29
+ unlockContent,
30
+ } from '@plone/volto/actions';
31
+ import { Icon } from '@plone/volto/components';
32
+ import { BodyClass, getBaseUrl, getCookieOptions } from '@plone/volto/helpers';
33
+ import { Pluggable } from '@plone/volto/components/manage/Pluggable';
34
+
35
+ import penSVG from '@plone/volto/icons/pen.svg';
36
+ import unlockSVG from '@plone/volto/icons/unlock.svg';
37
+ import folderSVG from '@plone/volto/icons/folder.svg';
38
+ import addSVG from '@plone/volto/icons/add-document.svg';
39
+ import moreSVG from '@plone/volto/icons/more.svg';
40
+ import userSVG from '@plone/volto/icons/user.svg';
41
+ import clearSVG from '@plone/volto/icons/clear.svg';
42
+
43
+ const messages = defineMessages({
44
+ edit: {
45
+ id: 'Edit',
46
+ defaultMessage: 'Edit',
47
+ },
48
+ contents: {
49
+ id: 'Contents',
50
+ defaultMessage: 'Contents',
51
+ },
52
+ add: {
53
+ id: 'Add',
54
+ defaultMessage: 'Add',
55
+ },
56
+ more: {
57
+ id: 'More',
58
+ defaultMessage: 'More',
59
+ },
60
+ personalTools: {
61
+ id: 'Personal tools',
62
+ defaultMessage: 'Personal tools',
63
+ },
64
+ shrinkToolbar: {
65
+ id: 'Shrink toolbar',
66
+ defaultMessage: 'Shrink toolbar',
67
+ },
68
+ personalInformation: {
69
+ id: 'Personal Information',
70
+ defaultMessage: 'Personal Information',
71
+ },
72
+ personalPreferences: {
73
+ id: 'Personal Preferences',
74
+ defaultMessage: 'Personal Preferences',
75
+ },
76
+ collection: {
77
+ id: 'Collection',
78
+ defaultMessage: 'Collection',
79
+ },
80
+ file: {
81
+ id: 'File',
82
+ defaultMessage: 'File',
83
+ },
84
+ link: {
85
+ id: 'Link',
86
+ defaultMessage: 'Link',
87
+ },
88
+ newsItem: {
89
+ id: 'News Item',
90
+ defaultMessage: 'News Item',
91
+ },
92
+ page: {
93
+ id: 'Page',
94
+ defaultMessage: 'Page',
95
+ },
96
+ back: {
97
+ id: 'Back',
98
+ defaultMessage: 'Back',
99
+ },
100
+ unlock: {
101
+ id: 'Unlock',
102
+ defaultMessage: 'Unlock',
103
+ },
104
+ });
105
+
106
+ const toolbarComponents = {
107
+ personalTools: { component: PersonalTools, wrapper: null },
108
+ more: { component: More, wrapper: null },
109
+ types: { component: Types, wrapper: null, contentAsProps: true },
110
+ profile: {
111
+ component: PersonalInformation,
112
+ wrapper: StandardWrapper,
113
+ wrapperTitle: messages.personalInformation,
114
+ hideToolbarBody: true,
115
+ },
116
+ preferences: {
117
+ component: PersonalPreferences,
118
+ wrapper: StandardWrapper,
119
+ wrapperTitle: messages.personalPreferences,
120
+ hideToolbarBody: true,
121
+ },
122
+ };
123
+
124
+ /**
125
+ * Toolbar container class.
126
+ * @class Toolbar
127
+ * @extends Component
128
+ */
129
+ class Toolbar extends Component {
130
+ /**
131
+ * Property types.
132
+ * @property {Object} propTypes Property types.
133
+ * @static
134
+ */
135
+ static propTypes = {
136
+ actions: PropTypes.shape({
137
+ object: PropTypes.arrayOf(PropTypes.object),
138
+ object_buttons: PropTypes.arrayOf(PropTypes.object),
139
+ user: PropTypes.arrayOf(PropTypes.object),
140
+ }),
141
+ token: PropTypes.string,
142
+ userId: PropTypes.string,
143
+ pathname: PropTypes.string.isRequired,
144
+ content: PropTypes.shape({
145
+ '@type': PropTypes.string,
146
+ is_folderish: PropTypes.bool,
147
+ review_state: PropTypes.string,
148
+ }),
149
+ getTypes: PropTypes.func.isRequired,
150
+ types: PropTypes.arrayOf(
151
+ PropTypes.shape({
152
+ '@id': PropTypes.string,
153
+ addable: PropTypes.bool,
154
+ title: PropTypes.string,
155
+ }),
156
+ ),
157
+ listActions: PropTypes.func.isRequired,
158
+ unlockContent: PropTypes.func,
159
+ unlockRequest: PropTypes.objectOf(PropTypes.any),
160
+ inner: PropTypes.element.isRequired,
161
+ hideDefaultViewButtons: PropTypes.bool,
162
+ };
163
+
164
+ /**
165
+ * Default properties.
166
+ * @property {Object} defaultProps Default properties.
167
+ * @static
168
+ */
169
+ static defaultProps = {
170
+ actions: null,
171
+ token: null,
172
+ userId: null,
173
+ content: null,
174
+ hideDefaultViewButtons: false,
175
+ types: [],
176
+ };
177
+
178
+ toolbarWindow = React.createRef();
179
+
180
+ constructor(props) {
181
+ super(props);
182
+ const { cookies } = props;
183
+ this.state = {
184
+ expanded: cookies.get('toolbar_expanded') !== 'false',
185
+ showMenu: false,
186
+ menuStyle: {},
187
+ menuComponents: [],
188
+ loadedComponents: [],
189
+ hideToolbarBody: false,
190
+ };
191
+ }
192
+
193
+ /**
194
+ * Component will mount
195
+ * @method componentDidMount
196
+ * @returns {undefined}
197
+ */
198
+ componentDidMount() {
199
+ this.props.listActions(getBaseUrl(this.props.pathname));
200
+ this.props.getTypes(getBaseUrl(this.props.pathname));
201
+ this.props.setExpandedToolbar(this.state.expanded);
202
+ document.addEventListener('mousedown', this.handleClickOutside, false);
203
+ }
204
+
205
+ /**
206
+ * Component will receive props
207
+ * @method componentWillReceiveProps
208
+ * @param {Object} nextProps Next properties
209
+ * @returns {undefined}
210
+ */
211
+ UNSAFE_componentWillReceiveProps(nextProps) {
212
+ if (nextProps.pathname !== this.props.pathname) {
213
+ this.props.listActions(getBaseUrl(nextProps.pathname));
214
+ this.props.getTypes(getBaseUrl(nextProps.pathname));
215
+ }
216
+
217
+ // Unlock
218
+ if (this.props.unlockRequest.loading && nextProps.unlockRequest.loaded) {
219
+ this.props.listActions(getBaseUrl(nextProps.pathname));
220
+ }
221
+ }
222
+
223
+ /**
224
+ * Component will receive props
225
+ * @method componentWillUnmount
226
+ * @returns {undefined}
227
+ */
228
+ componentWillUnmount() {
229
+ document.removeEventListener('mousedown', this.handleClickOutside, false);
230
+ }
231
+
232
+ handleShrink = () => {
233
+ const { cookies } = this.props;
234
+ cookies.set('toolbar_expanded', !this.state.expanded, getCookieOptions());
235
+ this.setState(
236
+ (state) => ({ expanded: !state.expanded }),
237
+ () => this.props.setExpandedToolbar(this.state.expanded),
238
+ );
239
+ };
240
+
241
+ closeMenu = () =>
242
+ this.setState(() => ({ showMenu: false, loadedComponents: [] }));
243
+
244
+ loadComponent = (type) => {
245
+ const { loadedComponents } = this.state;
246
+ if (!this.state.loadedComponents.includes(type)) {
247
+ this.setState({
248
+ loadedComponents: [...loadedComponents, type],
249
+ hideToolbarBody: toolbarComponents[type].hideToolbarBody || false,
250
+ });
251
+ }
252
+ };
253
+
254
+ unloadComponent = () => {
255
+ this.setState((state) => ({
256
+ loadedComponents: state.loadedComponents.slice(0, -1),
257
+ hideToolbarBody:
258
+ toolbarComponents[
259
+ state.loadedComponents[state.loadedComponents.length - 2]
260
+ ].hideToolbarBody || false,
261
+ }));
262
+ };
263
+
264
+ toggleMenu = (e, selector) => {
265
+ if (this.state.showMenu) {
266
+ this.closeMenu();
267
+ return;
268
+ }
269
+ // PersonalTools always shows at bottom
270
+ if (selector === 'personalTools') {
271
+ this.setState((state) => ({
272
+ showMenu: !state.showMenu,
273
+ menuStyle: { bottom: 0 },
274
+ }));
275
+ } else {
276
+ this.setState((state) => ({
277
+ showMenu: !state.showMenu,
278
+ menuStyle: { top: 0 },
279
+ }));
280
+ }
281
+ this.loadComponent(selector);
282
+ };
283
+
284
+ handleClickOutside = (e) => {
285
+ if (this.pusher && doesNodeContainClick(this.pusher, e)) return;
286
+ this.closeMenu();
287
+ };
288
+
289
+ unlock = (e) => {
290
+ this.props.unlockContent(getBaseUrl(this.props.pathname), true);
291
+ };
292
+
293
+ /**
294
+ * Render method.
295
+ * @method render
296
+ * @returns {string} Markup for the component.
297
+ */
298
+ render() {
299
+ const path = getBaseUrl(this.props.pathname);
300
+ const lock = this.props.content?.lock;
301
+ const unlockAction =
302
+ lock?.locked && lock?.stealable && lock?.creator !== this.props.userId;
303
+ const editAction =
304
+ !unlockAction && find(this.props.actions.object, { id: 'edit' });
305
+ const folderContentsAction = find(this.props.actions.object, {
306
+ id: 'folderContents',
307
+ });
308
+ const { expanded } = this.state;
309
+
310
+ return (
311
+ this.props.token && (
312
+ <>
313
+ <BodyClass
314
+ className={expanded ? 'has-toolbar' : 'has-toolbar-collapsed'}
315
+ />
316
+ <div
317
+ style={this.state.menuStyle}
318
+ className={
319
+ this.state.showMenu ? 'toolbar-content show' : 'toolbar-content'
320
+ }
321
+ ref={this.toolbarWindow}
322
+ >
323
+ {this.state.showMenu && (
324
+ // This sets the scroll locker in the body tag in mobile
325
+ <BodyClass className="has-toolbar-menu-open" />
326
+ )}
327
+ <div
328
+ className="pusher-puller"
329
+ ref={(node) => (this.pusher = node)}
330
+ style={{
331
+ transform: this.toolbarWindow.current
332
+ ? `translateX(-${
333
+ (this.state.loadedComponents.length - 1) *
334
+ this.toolbarWindow.current.getBoundingClientRect().width
335
+ }px)`
336
+ : null,
337
+ }}
338
+ >
339
+ {this.state.loadedComponents.map((component, index) =>
340
+ (() => {
341
+ const ToolbarComponent =
342
+ toolbarComponents[component].component;
343
+ const WrapperComponent = toolbarComponents[component].wrapper;
344
+ const haveActions =
345
+ toolbarComponents[component].hideToolbarBody;
346
+ const title =
347
+ toolbarComponents[component].wrapperTitle &&
348
+ this.props.intl.formatMessage(
349
+ toolbarComponents[component].wrapperTitle,
350
+ );
351
+ if (WrapperComponent) {
352
+ return (
353
+ <WrapperComponent
354
+ componentName={component}
355
+ componentTitle={title}
356
+ pathname={this.props.pathname}
357
+ loadComponent={this.loadComponent}
358
+ unloadComponent={this.unloadComponent}
359
+ componentIndex={index}
360
+ theToolbar={this.toolbarWindow}
361
+ key={`personalToolsComponent-${index}`}
362
+ closeMenu={this.closeMenu}
363
+ hasActions={haveActions}
364
+ >
365
+ <ToolbarComponent
366
+ pathname={this.props.pathname}
367
+ loadComponent={this.loadComponent}
368
+ unloadComponent={this.unloadComponent}
369
+ componentIndex={index}
370
+ theToolbar={this.toolbarWindow}
371
+ closeMenu={this.closeMenu}
372
+ isToolbarEmbedded
373
+ />
374
+ </WrapperComponent>
375
+ );
376
+ } else {
377
+ return (
378
+ <ToolbarComponent
379
+ pathname={this.props.pathname}
380
+ loadComponent={this.loadComponent}
381
+ unloadComponent={this.unloadComponent}
382
+ componentIndex={index}
383
+ theToolbar={this.toolbarWindow}
384
+ key={`personalToolsComponent-${index}`}
385
+ closeMenu={this.closeMenu}
386
+ content={
387
+ toolbarComponents[component].contentAsProps
388
+ ? this.props.content
389
+ : null
390
+ }
391
+ />
392
+ );
393
+ }
394
+ })(),
395
+ )}
396
+ </div>
397
+ </div>
398
+ <div className={this.state.expanded ? 'toolbar expanded' : 'toolbar'}>
399
+ <div className="toolbar-body">
400
+ <div className="toolbar-actions">
401
+ {this.props.hideDefaultViewButtons && this.props.inner && (
402
+ <>{this.props.inner}</>
403
+ )}
404
+ {!this.props.hideDefaultViewButtons && (
405
+ <>
406
+ {unlockAction && (
407
+ <button
408
+ aria-label={this.props.intl.formatMessage(
409
+ messages.unlock,
410
+ )}
411
+ className="unlock"
412
+ onClick={(e) => this.unlock(e)}
413
+ tabIndex={0}
414
+ >
415
+ <Icon
416
+ name={unlockSVG}
417
+ size="30px"
418
+ className="unlock"
419
+ title={this.props.intl.formatMessage(messages.unlock)}
420
+ />
421
+ </button>
422
+ )}
423
+
424
+ {editAction && (
425
+ <Link
426
+ aria-label={this.props.intl.formatMessage(
427
+ messages.edit,
428
+ )}
429
+ className="edit"
430
+ to={`${path}/edit`}
431
+ >
432
+ <Icon
433
+ name={penSVG}
434
+ size="30px"
435
+ className="circled"
436
+ title={this.props.intl.formatMessage(messages.edit)}
437
+ />
438
+ </Link>
439
+ )}
440
+ {this.props.content &&
441
+ this.props.content.is_folderish &&
442
+ folderContentsAction &&
443
+ !this.props.pathname.endsWith('/contents') && (
444
+ <Link
445
+ aria-label={this.props.intl.formatMessage(
446
+ messages.contents,
447
+ )}
448
+ to={`${path}/contents`}
449
+ >
450
+ <Icon
451
+ name={folderSVG}
452
+ size="30px"
453
+ title={this.props.intl.formatMessage(
454
+ messages.contents,
455
+ )}
456
+ />
457
+ </Link>
458
+ )}
459
+ {this.props.content &&
460
+ this.props.content.is_folderish &&
461
+ folderContentsAction &&
462
+ this.props.pathname.endsWith('/contents') && (
463
+ <Link
464
+ to={`${path}`}
465
+ aria-label={this.props.intl.formatMessage(
466
+ messages.back,
467
+ )}
468
+ >
469
+ <Icon
470
+ name={clearSVG}
471
+ className="contents circled"
472
+ size="30px"
473
+ title={this.props.intl.formatMessage(messages.back)}
474
+ />
475
+ </Link>
476
+ )}
477
+ {this.props.content &&
478
+ ((this.props.content.is_folderish &&
479
+ this.props.types.length > 0) ||
480
+ (config.settings.isMultilingual &&
481
+ this.props.content['@components']?.translations)) && (
482
+ <button
483
+ className="add"
484
+ aria-label={this.props.intl.formatMessage(
485
+ messages.add,
486
+ )}
487
+ onClick={(e) => this.toggleMenu(e, 'types')}
488
+ tabIndex={0}
489
+ id="toolbar-add"
490
+ >
491
+ <Icon
492
+ name={addSVG}
493
+ size="30px"
494
+ title={this.props.intl.formatMessage(messages.add)}
495
+ />
496
+ </button>
497
+ )}
498
+ <div className="toolbar-button-spacer" />
499
+ <button
500
+ className="more"
501
+ aria-label={this.props.intl.formatMessage(messages.more)}
502
+ onClick={(e) => this.toggleMenu(e, 'more')}
503
+ tabIndex={0}
504
+ id="toolbar-more"
505
+ >
506
+ <Icon
507
+ className="mobile hidden"
508
+ name={moreSVG}
509
+ size="30px"
510
+ title={this.props.intl.formatMessage(messages.more)}
511
+ />
512
+ {this.state.showMenu ? (
513
+ <Icon
514
+ className="mobile only"
515
+ name={clearSVG}
516
+ size="30px"
517
+ />
518
+ ) : (
519
+ <Icon
520
+ className="mobile only"
521
+ name={moreSVG}
522
+ size="30px"
523
+ />
524
+ )}
525
+ </button>
526
+ </>
527
+ )}
528
+ </div>
529
+ <div className="toolbar-bottom">
530
+ <Pluggable name="main.toolbar.bottom" />
531
+ {!this.props.hideDefaultViewButtons && (
532
+ <button
533
+ className="user"
534
+ aria-label={this.props.intl.formatMessage(
535
+ messages.personalTools,
536
+ )}
537
+ onClick={(e) => this.toggleMenu(e, 'personalTools')}
538
+ tabIndex={0}
539
+ id="toolbar-personal"
540
+ >
541
+ <Icon
542
+ name={userSVG}
543
+ size="30px"
544
+ title={this.props.intl.formatMessage(
545
+ messages.personalTools,
546
+ )}
547
+ />
548
+ </button>
549
+ )}
550
+ </div>
551
+ </div>
552
+ <div className="toolbar-handler">
553
+ <button
554
+ aria-label={this.props.intl.formatMessage(
555
+ messages.shrinkToolbar,
556
+ )}
557
+ className={cx({
558
+ [this.props.content?.review_state]: this.props.content
559
+ ?.review_state,
560
+ })}
561
+ onClick={this.handleShrink}
562
+ />
563
+ </div>
564
+ </div>
565
+ <div className="pusher" />
566
+ </>
567
+ )
568
+ );
569
+ }
570
+ }
571
+
572
+ export default compose(
573
+ injectIntl,
574
+ withCookies,
575
+ connect(
576
+ (state, props) => ({
577
+ actions: state.actions.actions,
578
+ token: state.userSession.token,
579
+ userId: state.userSession.token
580
+ ? jwtDecode(state.userSession.token).sub
581
+ : '',
582
+ content: state.content.data,
583
+ pathname: props.pathname,
584
+ types: filter(state.types.types, 'addable'),
585
+ unlockRequest: state.content.unlock,
586
+ }),
587
+ { getTypes, listActions, setExpandedToolbar, unlockContent },
588
+ ),
589
+ )(Toolbar);
@@ -5,68 +5,15 @@
5
5
 
6
6
  import React from 'react';
7
7
  import EEAFooter from '@eeacms/volto-eea-design-system/ui/Footer/Footer';
8
- import { Grid, Image } from 'semantic-ui-react';
9
- import { Link } from 'react-router-dom';
10
-
11
- import EIONETLogo from '@eeacms/volto-eea-design-system/../theme/themes/eea/assets/logo/EIONETLogo.png';
12
- import EEALogo from '@eeacms/volto-eea-design-system/../theme/themes/eea/assets/logo/EEA-Logo-white.svg';
13
-
14
8
  import config from '@plone/volto/registry';
15
9
 
16
10
  const Footer = (props) => {
17
11
  const { eea } = config.settings;
18
-
19
12
  return (
20
13
  <EEAFooter>
21
- <EEAFooter.Header>The EEA also contributes to</EEAFooter.Header>
22
- <EEAFooter.Sites sites={config.settings.eea.partnerWebsites} />
23
-
24
- <EEAFooter.SubFooter>
25
- <div className="subfooter">
26
- <Grid>
27
- <Grid.Column mobile={6} tablet={7} computer={8}>
28
- <div className="item">
29
- <div className="site logo">
30
- <Link to="/">
31
- <Image src={EEALogo} alt="EEA Logo"></Image>
32
- </Link>
33
- <p className="description">An agency of the European Union</p>
34
- </div>
35
-
36
- <div className="eionet logo">
37
- <a href="https://www.eionet.europa.eu/">
38
- <Image src={EIONETLogo} alt="EIONET Logo"></Image>
39
- </a>
40
- <p className="description">
41
- European Environment
42
- <br />
43
- Information and
44
- <br />
45
- Observation Network
46
- </p>
47
- </div>
48
- </div>
49
- </Grid.Column>
50
- <Grid.Column mobile={6} tablet={5} computer={4}>
51
- <div className="item">
52
- <EEAFooter.Contact
53
- contacts={eea.footerActions}
54
- header="Contact Us"
55
- address={eea.address}
56
- />
57
- <EEAFooter.Social social={eea.socialActions} />
58
- </div>
59
- </Grid.Column>
60
- </Grid>
61
- <Grid>
62
- <Grid.Row>
63
- <Grid.Column>
64
- <EEAFooter.Actions actions={eea.globalActions} />
65
- </Grid.Column>
66
- </Grid.Row>
67
- </Grid>
68
- </div>
69
- </EEAFooter.SubFooter>
14
+ <EEAFooter.Header>{eea.footerOpts.header}</EEAFooter.Header>
15
+ <EEAFooter.Sites sites={eea.footerOpts.sites} />
16
+ <EEAFooter.SubFooter {...eea.footerOpts} />
70
17
  </EEAFooter>
71
18
  );
72
19
  };
package/src/index.js CHANGED
@@ -3,6 +3,7 @@ import InpageNavigation from '@eeacms/volto-eea-design-system/ui/InpageNavigatio
3
3
  import installCustomTitle from '@eeacms/volto-eea-website-theme/components/manage/Blocks/Title';
4
4
  import CustomCSS from '@eeacms/volto-eea-website-theme/components/theme/CustomCSS/CustomCSS';
5
5
  import DraftBackground from '@eeacms/volto-eea-website-theme/components/theme/DraftBackground/DraftBackground';
6
+ import { TokenWidget } from '@eeacms/volto-eea-website-theme/components/theme/Widgets/TokenWidget';
6
7
 
7
8
  const applyConfig = (config) => {
8
9
  config.settings.eea = {
@@ -15,10 +16,26 @@ const applyConfig = (config) => {
15
16
  config.blocks.blocksConfig.accordion.semanticIcon = 'ri-arrow-down-s-line';
16
17
  }
17
18
 
19
+ // Apply tabs block customization
20
+ if (config.blocks.blocksConfig.tabs_block) {
21
+ if (config.blocks.blocksConfig.tabs_block.templates.accordion) {
22
+ config.blocks.blocksConfig.tabs_block.templates.accordion.semanticIcon = {
23
+ opened: 'ri-arrow-up-s-line',
24
+ closed: 'ri-arrow-down-s-line',
25
+ };
26
+ }
27
+ }
28
+
18
29
  // Description block custom CSS
19
30
  config.blocks.blocksConfig.description.className =
20
31
  'documentDescription eea callout';
21
32
 
33
+ // Custom TokenWidget
34
+ if (config.widgets.views) {
35
+ config.widgets.views.id.subjects = TokenWidget;
36
+ config.widgets.views.widget.tags = TokenWidget;
37
+ }
38
+
22
39
  // apply inPage navigation
23
40
  config.settings.appExtras = [
24
41
  ...(config.settings.appExtras || []),