@eeacms/volto-eea-website-theme 1.22.0 → 1.23.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 +29 -1
- package/DEVELOP.md +6 -7
- package/README.md +20 -20
- package/RELEASE.md +14 -14
- package/jest-addon.config.js +3 -0
- package/package.json +3 -3
- package/src/config.js +27 -15
- package/src/customizations/@plone/volto-slate/editor/extensions/normalizeExternalData.js +9 -0
- package/src/customizations/volto/components/manage/Blocks/Image/Edit.test.jsx +312 -0
- package/src/customizations/volto/components/manage/Form/Form.test.jsx +1124 -0
- package/src/customizations/volto/components/manage/Widgets/ObjectBrowserWidget.test.jsx +193 -0
- package/src/customizations/volto/components/theme/Comments/Comments.test.jsx +407 -0
- package/src/customizations/volto/components/theme/Header/Header.test.jsx +326 -0
- package/src/index.js +90 -15
- package/src/index.test.js +343 -0
- package/src/customizations/@eeacms/volto-tabs-block/components/templates/default/schema.js +0 -109
- package/src/customizations/@eeacms/volto-tabs-block/components/templates/horizontal-responsive/schema.js +0 -109
@@ -0,0 +1,326 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import renderer from 'react-test-renderer';
|
3
|
+
import { render, fireEvent } from '@testing-library/react';
|
4
|
+
import configureStore from 'redux-mock-store';
|
5
|
+
import { Router } from 'react-router-dom';
|
6
|
+
import { createMemoryHistory } from 'history';
|
7
|
+
import { Provider } from 'react-intl-redux';
|
8
|
+
import config from '@plone/volto/registry';
|
9
|
+
|
10
|
+
import Header from './Header';
|
11
|
+
|
12
|
+
const mockStore = configureStore();
|
13
|
+
let history = createMemoryHistory();
|
14
|
+
|
15
|
+
describe('Header', () => {
|
16
|
+
it('renders a header component', () => {
|
17
|
+
const store = mockStore({
|
18
|
+
userSession: { token: null },
|
19
|
+
intl: {
|
20
|
+
locale: 'en',
|
21
|
+
messages: {},
|
22
|
+
},
|
23
|
+
navigation: {
|
24
|
+
items: ['en'],
|
25
|
+
},
|
26
|
+
content: {
|
27
|
+
data: {
|
28
|
+
layout: 'homepage_inverse_view',
|
29
|
+
},
|
30
|
+
},
|
31
|
+
router: {
|
32
|
+
location: {
|
33
|
+
pathname: '/home/',
|
34
|
+
},
|
35
|
+
},
|
36
|
+
});
|
37
|
+
|
38
|
+
config.settings = {
|
39
|
+
...config.settings,
|
40
|
+
eea: {
|
41
|
+
headerOpts: undefined,
|
42
|
+
},
|
43
|
+
};
|
44
|
+
|
45
|
+
const component = renderer.create(
|
46
|
+
<Provider store={store}>
|
47
|
+
<Router history={history}>
|
48
|
+
<Header pathname="/home" />
|
49
|
+
</Router>
|
50
|
+
</Provider>,
|
51
|
+
);
|
52
|
+
const json = component.toJSON();
|
53
|
+
expect(json).toMatchSnapshot();
|
54
|
+
});
|
55
|
+
|
56
|
+
it('renders a header component', () => {
|
57
|
+
const store = mockStore({
|
58
|
+
userSession: { token: null },
|
59
|
+
intl: {
|
60
|
+
locale: 'en',
|
61
|
+
messages: {},
|
62
|
+
},
|
63
|
+
navigation: {
|
64
|
+
items: ['en'],
|
65
|
+
},
|
66
|
+
content: {
|
67
|
+
data: {
|
68
|
+
layout: 'homepage_inverse_view',
|
69
|
+
},
|
70
|
+
},
|
71
|
+
router: {
|
72
|
+
location: {
|
73
|
+
pathname: '/home/',
|
74
|
+
},
|
75
|
+
},
|
76
|
+
});
|
77
|
+
|
78
|
+
config.settings = {
|
79
|
+
...config.settings,
|
80
|
+
eea: {
|
81
|
+
headerOpts: {},
|
82
|
+
},
|
83
|
+
};
|
84
|
+
|
85
|
+
const component = renderer.create(
|
86
|
+
<Provider store={store}>
|
87
|
+
<Router history={history}>
|
88
|
+
<Header pathname="/blog" />
|
89
|
+
</Router>
|
90
|
+
</Provider>,
|
91
|
+
);
|
92
|
+
const json = component.toJSON();
|
93
|
+
expect(json).toMatchSnapshot();
|
94
|
+
});
|
95
|
+
|
96
|
+
it('renders a header component', () => {
|
97
|
+
const store = mockStore({
|
98
|
+
userSession: { token: null },
|
99
|
+
intl: {
|
100
|
+
locale: undefined,
|
101
|
+
messages: {},
|
102
|
+
},
|
103
|
+
navigation: {
|
104
|
+
items: ['en'],
|
105
|
+
},
|
106
|
+
content: {
|
107
|
+
data: {
|
108
|
+
layout: 'homepage_view',
|
109
|
+
'@components': {
|
110
|
+
translations: {
|
111
|
+
items: [{ language: 'en' }, { language: 'ro' }],
|
112
|
+
},
|
113
|
+
},
|
114
|
+
},
|
115
|
+
},
|
116
|
+
router: {
|
117
|
+
location: {
|
118
|
+
pathname: '/home/',
|
119
|
+
},
|
120
|
+
},
|
121
|
+
});
|
122
|
+
|
123
|
+
config.settings = {
|
124
|
+
...config.settings,
|
125
|
+
eea: {
|
126
|
+
headerOpts: {
|
127
|
+
partnerLinks: {
|
128
|
+
links: [{ href: '/link1', title: 'link 1' }],
|
129
|
+
},
|
130
|
+
},
|
131
|
+
defaultLanguage: 'en',
|
132
|
+
languages: [{ code: 'en' }, { code: 'ro' }],
|
133
|
+
},
|
134
|
+
isMultilingual: true,
|
135
|
+
supportedLanguages: ['en', 'ro'],
|
136
|
+
hasLanguageDropdown: true,
|
137
|
+
};
|
138
|
+
|
139
|
+
const { container, rerender } = render(
|
140
|
+
<Provider store={store}>
|
141
|
+
<Router history={history}>
|
142
|
+
<Header pathname="/blog" />
|
143
|
+
</Router>
|
144
|
+
</Provider>,
|
145
|
+
);
|
146
|
+
|
147
|
+
fireEvent.click(container.querySelector('.content'));
|
148
|
+
fireEvent.keyDown(container.querySelector('.content'), { keyCode: 37 });
|
149
|
+
fireEvent.keyDown(container.querySelector('.content a'), { keyCode: 37 });
|
150
|
+
fireEvent.keyDown(container.querySelector('a[href="/link1"]'), {
|
151
|
+
keyCode: 37,
|
152
|
+
});
|
153
|
+
fireEvent.click(container.querySelector('.country-code'));
|
154
|
+
|
155
|
+
// expect(getByText('da')).toBeInTheDocument();
|
156
|
+
|
157
|
+
rerender(
|
158
|
+
<Provider store={{ ...store, userSession: { token: '1234' } }}>
|
159
|
+
<Router history={history}>
|
160
|
+
<Header pathname="/blog" />
|
161
|
+
</Router>
|
162
|
+
</Provider>,
|
163
|
+
);
|
164
|
+
});
|
165
|
+
|
166
|
+
it('renders a header component', () => {
|
167
|
+
const store = mockStore({
|
168
|
+
userSession: { token: null },
|
169
|
+
intl: {
|
170
|
+
locale: undefined,
|
171
|
+
messages: {},
|
172
|
+
},
|
173
|
+
navigation: {
|
174
|
+
items: ['en'],
|
175
|
+
},
|
176
|
+
content: {
|
177
|
+
data: {
|
178
|
+
layout: 'homepage_view',
|
179
|
+
'@components': {
|
180
|
+
subsite: {
|
181
|
+
'@type': 'Subsite',
|
182
|
+
title: 'Home Page',
|
183
|
+
subsite_logo: {
|
184
|
+
scales: {
|
185
|
+
mini: {
|
186
|
+
download:
|
187
|
+
'http://localhost:8080/Plone/subsite_logo/@@images/image/mini',
|
188
|
+
},
|
189
|
+
},
|
190
|
+
},
|
191
|
+
},
|
192
|
+
translations: {
|
193
|
+
items: [{ language: 'ro' }],
|
194
|
+
},
|
195
|
+
},
|
196
|
+
},
|
197
|
+
},
|
198
|
+
router: {
|
199
|
+
location: {
|
200
|
+
pathname: '/home/',
|
201
|
+
},
|
202
|
+
},
|
203
|
+
});
|
204
|
+
|
205
|
+
config.settings = {
|
206
|
+
...config.settings,
|
207
|
+
eea: {
|
208
|
+
headerOpts: {
|
209
|
+
partnerLinks: {
|
210
|
+
links: [{ href: '/link1', title: 'link 1' }],
|
211
|
+
},
|
212
|
+
},
|
213
|
+
defaultLanguage: 'en',
|
214
|
+
languages: [{ code: 'en' }, { code: 'ro' }],
|
215
|
+
},
|
216
|
+
isMultilingual: true,
|
217
|
+
supportedLanguages: ['en', 'ro'],
|
218
|
+
hasLanguageDropdown: true,
|
219
|
+
};
|
220
|
+
|
221
|
+
const { container, rerender } = render(
|
222
|
+
<Provider store={store}>
|
223
|
+
<Router history={history}>
|
224
|
+
<Header pathname="/blog" />
|
225
|
+
</Router>
|
226
|
+
</Provider>,
|
227
|
+
);
|
228
|
+
|
229
|
+
fireEvent.click(container.querySelector('.content'));
|
230
|
+
fireEvent.keyDown(container.querySelector('.content'), { keyCode: 37 });
|
231
|
+
fireEvent.keyDown(container.querySelector('.content a'), { keyCode: 37 });
|
232
|
+
fireEvent.keyDown(container.querySelector('a[href="/link1"]'), {
|
233
|
+
keyCode: 37,
|
234
|
+
});
|
235
|
+
fireEvent.click(container.querySelector('.country-code'));
|
236
|
+
|
237
|
+
// expect(getByText('da')).toBeInTheDocument();
|
238
|
+
|
239
|
+
rerender(
|
240
|
+
<Provider store={{ ...store, userSession: { token: '1234' } }}>
|
241
|
+
<Router history={history}>
|
242
|
+
<Header pathname="/blog" />
|
243
|
+
</Router>
|
244
|
+
</Provider>,
|
245
|
+
);
|
246
|
+
});
|
247
|
+
|
248
|
+
it('renders a header component', () => {
|
249
|
+
const store = mockStore({
|
250
|
+
userSession: { token: null },
|
251
|
+
intl: {
|
252
|
+
locale: undefined,
|
253
|
+
messages: {},
|
254
|
+
},
|
255
|
+
navigation: {
|
256
|
+
items: [
|
257
|
+
{ url: '/test1', title: 'test 1', nav_title: 'Test 1', items: [] },
|
258
|
+
{ url: undefined, title: 'test 2', items: [] },
|
259
|
+
],
|
260
|
+
},
|
261
|
+
content: {
|
262
|
+
data: {
|
263
|
+
layout: 'homepage_view',
|
264
|
+
'@components': {
|
265
|
+
subsite: {
|
266
|
+
'@type': 'Subsite',
|
267
|
+
title: 'Home Page',
|
268
|
+
subsite_logo: undefined,
|
269
|
+
},
|
270
|
+
translations: {
|
271
|
+
items: [{ language: 'ro' }],
|
272
|
+
},
|
273
|
+
},
|
274
|
+
},
|
275
|
+
},
|
276
|
+
router: {
|
277
|
+
location: {
|
278
|
+
pathname: '/home/',
|
279
|
+
},
|
280
|
+
},
|
281
|
+
});
|
282
|
+
|
283
|
+
config.settings = {
|
284
|
+
...config.settings,
|
285
|
+
eea: {
|
286
|
+
headerOpts: {
|
287
|
+
partnerLinks: {
|
288
|
+
links: [{ href: '/link1', title: 'link 1' }],
|
289
|
+
},
|
290
|
+
},
|
291
|
+
defaultLanguage: 'en',
|
292
|
+
languages: [{ code: 'en' }, { code: 'ro' }],
|
293
|
+
},
|
294
|
+
isMultilingual: true,
|
295
|
+
supportedLanguages: ['en', 'ro'],
|
296
|
+
hasLanguageDropdown: true,
|
297
|
+
};
|
298
|
+
|
299
|
+
const { container, rerender } = render(
|
300
|
+
<Provider store={store}>
|
301
|
+
<Router history={history}>
|
302
|
+
<Header pathname="/blog" />
|
303
|
+
</Router>
|
304
|
+
</Provider>,
|
305
|
+
);
|
306
|
+
|
307
|
+
fireEvent.click(container.querySelector('.content'));
|
308
|
+
fireEvent.keyDown(container.querySelector('.content'), { keyCode: 37 });
|
309
|
+
fireEvent.keyDown(container.querySelector('.content a'), { keyCode: 37 });
|
310
|
+
fireEvent.keyDown(container.querySelector('a[href="/link1"]'), {
|
311
|
+
keyCode: 37,
|
312
|
+
});
|
313
|
+
fireEvent.click(container.querySelector('.country-code'));
|
314
|
+
fireEvent.click(container.querySelector('a[href="/test1"]'));
|
315
|
+
|
316
|
+
// expect(getByText('da')).toBeInTheDocument();
|
317
|
+
|
318
|
+
rerender(
|
319
|
+
<Provider store={{ ...store, userSession: { token: '1234' } }}>
|
320
|
+
<Router history={history}>
|
321
|
+
<Header pathname="/blog" />
|
322
|
+
</Router>
|
323
|
+
</Provider>,
|
324
|
+
);
|
325
|
+
});
|
326
|
+
});
|
package/src/index.js
CHANGED
@@ -1,26 +1,26 @@
|
|
1
|
-
import
|
2
|
-
import { getBlocks } from '@plone/volto/helpers';
|
1
|
+
import InpageNavigation from '@eeacms/volto-eea-design-system/ui/InpageNavigation/InpageNavigation';
|
3
2
|
import CustomCSS from '@eeacms/volto-eea-website-theme/components/theme/CustomCSS/CustomCSS';
|
4
3
|
import DraftBackground from '@eeacms/volto-eea-website-theme/components/theme/DraftBackground/DraftBackground';
|
5
4
|
import HomePageInverseView from '@eeacms/volto-eea-website-theme/components/theme/Homepage/HomePageInverseView';
|
6
5
|
import HomePageView from '@eeacms/volto-eea-website-theme/components/theme/Homepage/HomePageView';
|
7
|
-
import InpageNavigation from '@eeacms/volto-eea-design-system/ui/InpageNavigation/InpageNavigation';
|
8
6
|
import NotFound from '@eeacms/volto-eea-website-theme/components/theme/NotFound/NotFound';
|
9
|
-
import { TopicsWidget } from '@eeacms/volto-eea-website-theme/components/theme/Widgets/TopicsWidget';
|
10
7
|
import { TokenWidget } from '@eeacms/volto-eea-website-theme/components/theme/Widgets/TokenWidget';
|
8
|
+
import { TopicsWidget } from '@eeacms/volto-eea-website-theme/components/theme/Widgets/TopicsWidget';
|
9
|
+
import { Icon } from '@plone/volto/components';
|
10
|
+
import { getBlocks } from '@plone/volto/helpers';
|
11
11
|
|
12
|
-
import { addStylingFieldsetSchemaEnhancer } from '@eeacms/volto-eea-website-theme/helpers/schema-utils';
|
13
|
-
import installCustomTitle from '@eeacms/volto-eea-website-theme/components/manage/Blocks/Title';
|
14
12
|
import installLayoutSettingsBlock from '@eeacms/volto-eea-website-theme/components/manage/Blocks/LayoutSettings';
|
13
|
+
import installCustomTitle from '@eeacms/volto-eea-website-theme/components/manage/Blocks/Title';
|
14
|
+
import { addStylingFieldsetSchemaEnhancer } from '@eeacms/volto-eea-website-theme/helpers/schema-utils';
|
15
15
|
|
16
|
+
import FlexGroup from '@eeacms/volto-eea-website-theme/components/manage/Blocks/GroupBlockTemplate/FlexGroup/FlexGroup';
|
16
17
|
import BaseTag from './components/theme/BaseTag';
|
17
18
|
import SubsiteClass from './components/theme/SubsiteClass';
|
18
|
-
import FlexGroup from '@eeacms/volto-eea-website-theme/components/manage/Blocks/GroupBlockTemplate/FlexGroup/FlexGroup';
|
19
19
|
import contentBoxSVG from './icons/content-box.svg';
|
20
20
|
|
21
|
-
import installSlate from './slate';
|
22
21
|
import okMiddleware from './middleware/ok';
|
23
22
|
import voltoCustomMiddleware from './middleware/voltoCustom';
|
23
|
+
import installSlate from './slate';
|
24
24
|
|
25
25
|
import * as eea from './config';
|
26
26
|
|
@@ -30,6 +30,84 @@ const restrictedBlocks = [
|
|
30
30
|
'teaser',
|
31
31
|
];
|
32
32
|
|
33
|
+
/**
|
34
|
+
* Customizes the variations of a tabs block by modifying their schema and semantic icons.
|
35
|
+
*
|
36
|
+
* @param {Array} tabs_block_variations - An array of variations for the tabs block.
|
37
|
+
* @param {Object} config - The Volto configuration object.
|
38
|
+
*/
|
39
|
+
function tabVariationCustomization(tabs_block_variations, config) {
|
40
|
+
if (!tabs_block_variations) return;
|
41
|
+
const defaultVariation = tabs_block_variations.find(
|
42
|
+
({ id }) => id === 'default',
|
43
|
+
);
|
44
|
+
const accordionVariation = tabs_block_variations.find(
|
45
|
+
({ id }) => id === 'accordion',
|
46
|
+
);
|
47
|
+
const horizontalVariation = tabs_block_variations.find(
|
48
|
+
({ id }) => id === 'horizontal-responsive',
|
49
|
+
);
|
50
|
+
|
51
|
+
if (accordionVariation) {
|
52
|
+
accordionVariation.semanticIcon = {
|
53
|
+
opened: 'ri-arrow-up-s-line',
|
54
|
+
closed: 'ri-arrow-down-s-line',
|
55
|
+
};
|
56
|
+
}
|
57
|
+
|
58
|
+
const oldSchemaEnhancer =
|
59
|
+
config.blocks.blocksConfig.tabs_block.schemaEnhancer;
|
60
|
+
config.blocks.blocksConfig.tabs_block.schemaEnhancer = (props) => {
|
61
|
+
const schema = (oldSchemaEnhancer ? oldSchemaEnhancer(props) : props)
|
62
|
+
.schema;
|
63
|
+
const oldSchemaExtender = schema.properties.data.schemaExtender;
|
64
|
+
schema.properties.data.schemaExtender = (schema, child) => {
|
65
|
+
const innerSchema = oldSchemaExtender
|
66
|
+
? oldSchemaExtender(schema, child)
|
67
|
+
: schema;
|
68
|
+
innerSchema.properties.icon.description = (
|
69
|
+
<>
|
70
|
+
Ex. ri-home-line. See{' '}
|
71
|
+
<a
|
72
|
+
target="_blank"
|
73
|
+
rel="noopener noreferrer"
|
74
|
+
href="https://remixicon.com/"
|
75
|
+
>
|
76
|
+
Remix Icon set
|
77
|
+
</a>
|
78
|
+
</>
|
79
|
+
);
|
80
|
+
return innerSchema;
|
81
|
+
};
|
82
|
+
return schema;
|
83
|
+
};
|
84
|
+
const oldDefaultSchemaEnhancer = defaultVariation.schemaEnhancer;
|
85
|
+
defaultVariation.schemaEnhancer = (props) => {
|
86
|
+
const newSchema = oldDefaultSchemaEnhancer(props);
|
87
|
+
const menuFieldset = newSchema.fieldsets.find(({ id }) => id === 'menu');
|
88
|
+
menuFieldset.fields = [
|
89
|
+
'menuAlign',
|
90
|
+
'menuPosition',
|
91
|
+
'menuColor',
|
92
|
+
'menuInverted',
|
93
|
+
];
|
94
|
+
return newSchema;
|
95
|
+
};
|
96
|
+
|
97
|
+
const oldHorizontalSchemaEnhancer = horizontalVariation.schemaEnhancer;
|
98
|
+
horizontalVariation.schemaEnhancer = (props) => {
|
99
|
+
const newSchema = oldHorizontalSchemaEnhancer(props);
|
100
|
+
const menuFieldset = newSchema.fieldsets.find(({ id }) => id === 'menu');
|
101
|
+
menuFieldset.fields = [
|
102
|
+
'menuAlign',
|
103
|
+
'menuPosition',
|
104
|
+
'menuColor',
|
105
|
+
'menuInverted',
|
106
|
+
];
|
107
|
+
return newSchema;
|
108
|
+
};
|
109
|
+
}
|
110
|
+
|
33
111
|
const applyConfig = (config) => {
|
34
112
|
// EEA specific settings
|
35
113
|
config.settings.eea = {
|
@@ -116,12 +194,9 @@ const applyConfig = (config) => {
|
|
116
194
|
|
117
195
|
// Apply tabs block customization
|
118
196
|
if (config.blocks.blocksConfig.tabs_block) {
|
119
|
-
|
120
|
-
config.blocks.blocksConfig.tabs_block.
|
121
|
-
|
122
|
-
closed: 'ri-arrow-down-s-line',
|
123
|
-
};
|
124
|
-
}
|
197
|
+
const tabs_block_variations =
|
198
|
+
config.blocks.blocksConfig.tabs_block.variations;
|
199
|
+
tabVariationCustomization(tabs_block_variations, config);
|
125
200
|
}
|
126
201
|
//Group block flex variation
|
127
202
|
if (config.blocks.blocksConfig.group) {
|
@@ -154,8 +229,8 @@ const applyConfig = (config) => {
|
|
154
229
|
if (config.blocks.blocksConfig.columnsBlock) {
|
155
230
|
config.blocks.blocksConfig.columnsBlock.available_colors = eea.colors;
|
156
231
|
config.blocks.blocksConfig.columnsBlock.tocEntries = (
|
157
|
-
block = {},
|
158
232
|
tocData,
|
233
|
+
block = {},
|
159
234
|
) => {
|
160
235
|
// integration with volto-block-toc
|
161
236
|
const headlines = tocData.levels || ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
|