@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.
@@ -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 { Icon } from '@plone/volto/components';
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
- if (config.blocks.blocksConfig.tabs_block.templates.accordion) {
120
- config.blocks.blocksConfig.tabs_block.templates.accordion.semanticIcon = {
121
- opened: 'ri-arrow-up-s-line',
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'];