@eeacms/volto-eea-website-theme 4.1.0 → 4.2.0
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 +15 -0
- package/package.json +1 -1
- package/src/actions/header-settings.js +9 -0
- package/src/actions/index.js +1 -1
- package/src/constants/ActionTypes.js +1 -1
- package/src/customizations/volto/components/manage/Blocks/Block/Order/Item.jsx +146 -0
- package/src/customizations/volto/components/theme/Header/Header.jsx +5 -2
- package/src/customizations/volto/server.jsx +0 -2
- package/src/helpers/headerSettingsExtender.js +20 -0
- package/src/index.js +7 -2
- package/src/reducers/index.js +1 -2
- package/src/actions/eea-settings.js +0 -9
- package/src/reducers/eea-settings.js +0 -33
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,21 @@ 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
|
+
### [4.2.0](https://github.com/eea/volto-eea-website-theme/compare/4.1.1...4.2.0) - 21 April 2026
|
|
8
|
+
|
|
9
|
+
#### :nail_care: Enhancements
|
|
10
|
+
|
|
11
|
+
- refactor: replace eea-settings controlpanel with header-settings via asyncPropsExtenders [Miu Razvan - [`f7d169b`](https://github.com/eea/volto-eea-website-theme/commit/f7d169b1bd12446cef74b78969cca1ddb19a7531)]
|
|
12
|
+
|
|
13
|
+
#### :hammer_and_wrench: Others
|
|
14
|
+
|
|
15
|
+
- Release 4.2.0 [Alin Voinea - [`8f7d6d0`](https://github.com/eea/volto-eea-website-theme/commit/8f7d6d0d0547dbe384c835375b56ccdb87c5dd44)]
|
|
16
|
+
### [4.1.1](https://github.com/eea/volto-eea-website-theme/compare/4.1.0...4.1.1) - 17 April 2026
|
|
17
|
+
|
|
18
|
+
#### :bug: Bug Fixes
|
|
19
|
+
|
|
20
|
+
- fix(order-sidebar): respect required and fixed block restrictions - refs #302095 [Alin Voinea - [`51557f2`](https://github.com/eea/volto-eea-website-theme/commit/51557f220fbe3992110e96862f4ab0ba987d42ed)]
|
|
21
|
+
|
|
7
22
|
### [4.1.0](https://github.com/eea/volto-eea-website-theme/compare/4.0.5...4.1.0) - 17 April 2026
|
|
8
23
|
|
|
9
24
|
#### :house: Internal changes
|
package/package.json
CHANGED
package/src/actions/index.js
CHANGED
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
export const SET_ISPRINT = 'SET_ISPRINT';
|
|
7
7
|
export const SET_PRINT_LOADING = 'SET_PRINT_LOADING';
|
|
8
8
|
export const GET_NAVIGATION_SETTINGS = 'GET_NAVIGATION_SETTINGS';
|
|
9
|
-
export const
|
|
9
|
+
export const GET_HEADER_SETTINGS = 'GET_HEADER_SETTINGS';
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
import classNames from 'classnames';
|
|
3
|
+
import { useDispatch, useSelector } from 'react-redux';
|
|
4
|
+
import includes from 'lodash/includes';
|
|
5
|
+
import isBoolean from 'lodash/isBoolean';
|
|
6
|
+
import cx from 'classnames';
|
|
7
|
+
import Icon from '@plone/volto/components/theme/Icon/Icon';
|
|
8
|
+
import { setUIState } from '@plone/volto/actions/form/form';
|
|
9
|
+
import config from '@plone/volto/registry';
|
|
10
|
+
|
|
11
|
+
import deleteSVG from '@plone/volto/icons/delete.svg';
|
|
12
|
+
import dragSVG from '@plone/volto/icons/drag.svg';
|
|
13
|
+
|
|
14
|
+
// TEMPORARY PATCH (Volto issue #6481):
|
|
15
|
+
// Remove this customization once the upstream fixes are released and adopted.
|
|
16
|
+
// Upstream PRs: https://github.com/plone/volto/pull/8124 and
|
|
17
|
+
// https://github.com/plone/volto/pull/8125
|
|
18
|
+
export const Item = forwardRef(
|
|
19
|
+
(
|
|
20
|
+
{
|
|
21
|
+
clone,
|
|
22
|
+
data,
|
|
23
|
+
depth,
|
|
24
|
+
disableSelection,
|
|
25
|
+
disableInteraction,
|
|
26
|
+
ghost,
|
|
27
|
+
id,
|
|
28
|
+
handleProps,
|
|
29
|
+
indentationWidth,
|
|
30
|
+
onRemove,
|
|
31
|
+
onSelectBlock,
|
|
32
|
+
parentId,
|
|
33
|
+
parentType,
|
|
34
|
+
style,
|
|
35
|
+
value,
|
|
36
|
+
wrapperRef,
|
|
37
|
+
errors,
|
|
38
|
+
...props
|
|
39
|
+
},
|
|
40
|
+
ref,
|
|
41
|
+
) => {
|
|
42
|
+
const selected = useSelector((state) => state.form.ui.selected);
|
|
43
|
+
const hovered = useSelector((state) => state.form.ui.hovered);
|
|
44
|
+
const multiSelected = useSelector((state) => state.form.ui.multiSelected);
|
|
45
|
+
const gridSelected = useSelector((state) => state.form.ui.gridSelected);
|
|
46
|
+
const dispatch = useDispatch();
|
|
47
|
+
|
|
48
|
+
const icon =
|
|
49
|
+
config.blocks.blocksConfig[data?.['@type']]?.icon ||
|
|
50
|
+
config.blocks.blocksConfig.title?.icon;
|
|
51
|
+
|
|
52
|
+
const required = isBoolean(data?.required)
|
|
53
|
+
? data.required
|
|
54
|
+
: includes(config.blocks.requiredBlocks, data?.['@type']);
|
|
55
|
+
const fixed = !!data?.fixed;
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<li
|
|
59
|
+
className={classNames(
|
|
60
|
+
'tree-item-wrapper',
|
|
61
|
+
clone && 'clone',
|
|
62
|
+
ghost && 'ghost',
|
|
63
|
+
disableSelection && 'disable-selection',
|
|
64
|
+
disableInteraction && 'disable-interaction',
|
|
65
|
+
)}
|
|
66
|
+
role="presentation"
|
|
67
|
+
onMouseOver={() => dispatch(setUIState({ hovered: id }))}
|
|
68
|
+
onFocus={() => dispatch(setUIState({ hovered: id }))}
|
|
69
|
+
onMouseLeave={() => dispatch(setUIState({ hovered: null }))}
|
|
70
|
+
onClick={(e) => {
|
|
71
|
+
if (depth === 0) {
|
|
72
|
+
const isMultipleSelection = e.shiftKey || e.ctrlKey || e.metaKey;
|
|
73
|
+
selected !== id &&
|
|
74
|
+
onSelectBlock(
|
|
75
|
+
id,
|
|
76
|
+
selected === id ? false : isMultipleSelection,
|
|
77
|
+
e,
|
|
78
|
+
);
|
|
79
|
+
} else {
|
|
80
|
+
dispatch(
|
|
81
|
+
setUIState({
|
|
82
|
+
selected: parentId,
|
|
83
|
+
multiSelected: [],
|
|
84
|
+
gridSelected: id,
|
|
85
|
+
}),
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
}}
|
|
89
|
+
ref={wrapperRef}
|
|
90
|
+
style={{
|
|
91
|
+
'--spacing': `${indentationWidth * depth}px`,
|
|
92
|
+
}}
|
|
93
|
+
{...props}
|
|
94
|
+
>
|
|
95
|
+
<div
|
|
96
|
+
className={classNames(
|
|
97
|
+
'tree-item',
|
|
98
|
+
(selected === id || gridSelected === id) && 'selected',
|
|
99
|
+
hovered === id && 'hovered',
|
|
100
|
+
includes(multiSelected, id) && 'multiSelected',
|
|
101
|
+
`depth-${depth}`,
|
|
102
|
+
)}
|
|
103
|
+
ref={ref}
|
|
104
|
+
style={style}
|
|
105
|
+
>
|
|
106
|
+
{!fixed && (
|
|
107
|
+
<button
|
|
108
|
+
ref={ref}
|
|
109
|
+
{...handleProps}
|
|
110
|
+
className={classNames('action', 'drag')}
|
|
111
|
+
tabIndex={0}
|
|
112
|
+
data-cypress="draggable-handle"
|
|
113
|
+
>
|
|
114
|
+
<Icon name={dragSVG} size="16px" />
|
|
115
|
+
</button>
|
|
116
|
+
)}
|
|
117
|
+
<span
|
|
118
|
+
className={cx('text', {
|
|
119
|
+
errored: errors && Object.keys(errors).length > 0,
|
|
120
|
+
})}
|
|
121
|
+
>
|
|
122
|
+
{icon && (
|
|
123
|
+
<Icon
|
|
124
|
+
name={icon}
|
|
125
|
+
size="20px"
|
|
126
|
+
style={{ verticalAlign: 'middle' }}
|
|
127
|
+
/>
|
|
128
|
+
)}{' '}
|
|
129
|
+
{data?.plaintext ||
|
|
130
|
+
config.blocks.blocksConfig[data?.['@type']]?.title ||
|
|
131
|
+
data?.title}
|
|
132
|
+
</span>
|
|
133
|
+
{!clone && onRemove && !required && (
|
|
134
|
+
<button
|
|
135
|
+
onClick={onRemove}
|
|
136
|
+
className={classNames('action', 'delete')}
|
|
137
|
+
tabIndex={0}
|
|
138
|
+
>
|
|
139
|
+
<Icon name={deleteSVG} size="18" />
|
|
140
|
+
</button>
|
|
141
|
+
)}
|
|
142
|
+
</div>
|
|
143
|
+
</li>
|
|
144
|
+
);
|
|
145
|
+
},
|
|
146
|
+
);
|
|
@@ -61,9 +61,12 @@ const EEAHeader = ({ pathname, token, items, history, subsite }) => {
|
|
|
61
61
|
const width = useSelector((state) => state.screen?.width);
|
|
62
62
|
const dispatch = useDispatch();
|
|
63
63
|
|
|
64
|
-
const
|
|
64
|
+
const headerSettings = useSelector(
|
|
65
|
+
(state) => state.reduxAsyncConnect?.headerSettings,
|
|
66
|
+
);
|
|
67
|
+
|
|
65
68
|
const headerSearchBox =
|
|
66
|
-
|
|
69
|
+
headerSettings?.searchBox || eea.headerSearchBox || [];
|
|
67
70
|
const previousToken = usePrevious(token);
|
|
68
71
|
const navigationSettings =
|
|
69
72
|
useSelector((state) => state.navigationSettings?.settings) ||
|
|
@@ -33,7 +33,6 @@ import {
|
|
|
33
33
|
import { changeLanguage } from '@plone/volto/actions/language/language';
|
|
34
34
|
|
|
35
35
|
import userSession from '@plone/volto/reducers/userSession/userSession';
|
|
36
|
-
import { getEEASettings } from '@eeacms/volto-eea-website-theme/actions';
|
|
37
36
|
|
|
38
37
|
import configureStore from '@plone/volto/store';
|
|
39
38
|
import ErrorPage from '@plone/volto/error';
|
|
@@ -264,7 +263,6 @@ server.get('/*', (req, res) => {
|
|
|
264
263
|
const location = parseUrl(url);
|
|
265
264
|
|
|
266
265
|
loadOnServer({ store, location, routes, api })
|
|
267
|
-
.then(() => Promise.all([store.dispatch(getEEASettings())]).catch(() => {}))
|
|
268
266
|
.then(() => {
|
|
269
267
|
const initialLang =
|
|
270
268
|
req.universalCookies.get('I18N_LANGUAGE') ||
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { getHeaderSettings } from '@eeacms/volto-eea-website-theme/actions';
|
|
2
|
+
|
|
3
|
+
// asyncPropsExtenders entry. Loads header settings during SSR so they're
|
|
4
|
+
// available to the Header component on the first render. Result lands in
|
|
5
|
+
// state.reduxAsyncConnect.headerSettings.
|
|
6
|
+
export const headerSettingsExtender = {
|
|
7
|
+
path: '/',
|
|
8
|
+
extend: (dispatchActions) => {
|
|
9
|
+
if (
|
|
10
|
+
dispatchActions.filter((a) => a.key === 'headerSettings').length === 0
|
|
11
|
+
) {
|
|
12
|
+
dispatchActions.push({
|
|
13
|
+
key: 'headerSettings',
|
|
14
|
+
promise: ({ store: { dispatch } }) =>
|
|
15
|
+
__SERVER__ && dispatch(getHeaderSettings()),
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return dispatchActions;
|
|
19
|
+
},
|
|
20
|
+
};
|
package/src/index.js
CHANGED
|
@@ -49,7 +49,8 @@ import okMiddleware from './middleware/ok';
|
|
|
49
49
|
import voltoCustomCSSMiddleware from './middleware/voltoCustom';
|
|
50
50
|
import { voltoCustomJsMiddleware } from './middleware/voltoCustom';
|
|
51
51
|
import installSlate from './slate';
|
|
52
|
-
import { print, navigationSettings
|
|
52
|
+
import { print, navigationSettings } from './reducers';
|
|
53
|
+
import { headerSettingsExtender } from './helpers/headerSettingsExtender';
|
|
53
54
|
|
|
54
55
|
import * as eea from './config';
|
|
55
56
|
|
|
@@ -676,9 +677,13 @@ const applyConfig = (config) => {
|
|
|
676
677
|
...(config.addonReducers || {}),
|
|
677
678
|
print,
|
|
678
679
|
navigationSettings,
|
|
679
|
-
eeaSettings,
|
|
680
680
|
};
|
|
681
681
|
|
|
682
|
+
config.settings.asyncPropsExtenders = [
|
|
683
|
+
...(config.settings.asyncPropsExtenders || []),
|
|
684
|
+
headerSettingsExtender,
|
|
685
|
+
];
|
|
686
|
+
|
|
682
687
|
// Mega menu object
|
|
683
688
|
if (!config.settings.menuItemsLayouts) {
|
|
684
689
|
config.settings.menuItemsLayouts = {};
|
package/src/reducers/index.js
CHANGED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { GET_EEA_SETTINGS } from '../constants/ActionTypes';
|
|
2
|
-
|
|
3
|
-
const initialState = {
|
|
4
|
-
error: null,
|
|
5
|
-
loaded: false,
|
|
6
|
-
loading: false,
|
|
7
|
-
data: {},
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export default function eeaSettings(state = initialState, action = {}) {
|
|
11
|
-
switch (action.type) {
|
|
12
|
-
case `${GET_EEA_SETTINGS}_PENDING`:
|
|
13
|
-
return { ...state, error: null, loaded: false, loading: true };
|
|
14
|
-
case `${GET_EEA_SETTINGS}_SUCCESS`:
|
|
15
|
-
return {
|
|
16
|
-
...state,
|
|
17
|
-
error: null,
|
|
18
|
-
loaded: true,
|
|
19
|
-
loading: false,
|
|
20
|
-
data: action.result || {},
|
|
21
|
-
};
|
|
22
|
-
case `${GET_EEA_SETTINGS}_FAIL`:
|
|
23
|
-
return {
|
|
24
|
-
...state,
|
|
25
|
-
error: action.error,
|
|
26
|
-
loaded: false,
|
|
27
|
-
loading: false,
|
|
28
|
-
data: {},
|
|
29
|
-
};
|
|
30
|
-
default:
|
|
31
|
-
return state;
|
|
32
|
-
}
|
|
33
|
-
}
|