@eeacms/volto-eea-website-theme 2.0.1 → 2.1.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 +6 -22
- package/package.json +1 -1
- package/src/components/theme/CustomCSS/CustomCSS.jsx +4 -4
- package/src/components/theme/Widgets/TopicsWidget.test.jsx +7 -2
- package/src/customizations/@plone/volto-slate/editor/SlateEditor.jsx +11 -8
- package/src/customizations/volto/components/manage/Blocks/Image/Edit.jsx +7 -2
- package/src/customizations/volto/components/manage/Blocks/Image/View.jsx +3 -2
- package/src/customizations/volto/components/manage/Blocks/Image/schema.js +2 -0
- package/src/customizations/volto/components/theme/Header/Header.jsx +12 -69
- package/src/customizations/volto/components/theme/Header/Header.test.jsx +48 -59
- package/src/customizations/volto/components/theme/Header/LanguageSwitcher.jsx +71 -0
- package/src/customizations/volto/components/theme/Image/Image.jsx +119 -0
- package/src/customizations/volto/components/theme/Image/README.md +3 -0
- package/src/index.js +12 -0
package/CHANGELOG.md
CHANGED
@@ -4,11 +4,14 @@ 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
|
-
### [2.0
|
7
|
+
### [2.1.0](https://github.com/eea/volto-eea-website-theme/compare/2.0.2...2.1.0) - 23 May 2024
|
8
8
|
|
9
|
-
#### :
|
9
|
+
#### :hammer_and_wrench: Others
|
10
|
+
|
11
|
+
- bump package version [David Ichim - [`3c0c2eb`](https://github.com/eea/volto-eea-website-theme/commit/3c0c2eb3a863e85451c68f6d56b3e704de260618)]
|
12
|
+
### [2.0.2](https://github.com/eea/volto-eea-website-theme/compare/2.0.1...2.0.2) - 20 May 2024
|
10
13
|
|
11
|
-
|
14
|
+
### [2.0.1](https://github.com/eea/volto-eea-website-theme/compare/2.0.0...2.0.1) - 15 May 2024
|
12
15
|
|
13
16
|
#### :hammer_and_wrench: Others
|
14
17
|
|
@@ -64,7 +67,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
64
67
|
|
65
68
|
#### :hammer_and_wrench: Others
|
66
69
|
|
67
|
-
- Add Sonarqube tag using insitu-frontend addons list [EEA Jenkins - [`adc6730`](https://github.com/eea/volto-eea-website-theme/commit/adc6730e21a37afb865b842182624401de6a29f5)]
|
68
70
|
### [1.33.1](https://github.com/eea/volto-eea-website-theme/compare/1.33.0...1.33.1) - 4 April 2024
|
69
71
|
|
70
72
|
#### :bug: Bug Fixes
|
@@ -198,8 +200,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
198
200
|
|
199
201
|
- bump version [Razvan - [`721e939`](https://github.com/eea/volto-eea-website-theme/commit/721e939d12e324b459ebfa78a2e656ee7142a3d6)]
|
200
202
|
- merge master into this branch [Razvan - [`586c8f9`](https://github.com/eea/volto-eea-website-theme/commit/586c8f910bac55a043bd8dda60e9444bd2ae1663)]
|
201
|
-
- Add Sonarqube tag using freshwater-frontend addons list [EEA Jenkins - [`fd90044`](https://github.com/eea/volto-eea-website-theme/commit/fd9004442a9d1d465f7601ecdefe3e23c61e6a9c)]
|
202
|
-
- Add Sonarqube tag using insitu-frontend addons list [EEA Jenkins - [`4bc3dd3`](https://github.com/eea/volto-eea-website-theme/commit/4bc3dd3ae412a66befd04b5b80fab3716c929240)]
|
203
203
|
- test: Update jest,Jenkinsfile,lint to volto-addons-template PR30 [valentinab25 - [`c4dbd28`](https://github.com/eea/volto-eea-website-theme/commit/c4dbd289358205bc2d849aab7edb11ccf3b89cee)]
|
204
204
|
- fix tests [Razvan - [`042330b`](https://github.com/eea/volto-eea-website-theme/commit/042330bc97d32ffe7ba769b4f2453f71cffed706)]
|
205
205
|
- remove RemoveSchema logic [Razvan - [`08d10f8`](https://github.com/eea/volto-eea-website-theme/commit/08d10f8bf6f75478260e4e4c66d7316ba87b907a)]
|
@@ -294,11 +294,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
294
294
|
- test: Add real image to cypress test [Alin Voinea - [`4ff591a`](https://github.com/eea/volto-eea-website-theme/commit/4ff591ae3318c9588b4e2114582c0fa6cfdf31ae)]
|
295
295
|
- test: Add cypress tests for Image block styling position and align [Alin Voinea - [`7341ef7`](https://github.com/eea/volto-eea-website-theme/commit/7341ef7b92714fc0cc3ab0c31c39033e7b3e19e7)]
|
296
296
|
- Revert "change(tests): commented out rss test since title block config is missing" [Alin Voinea - [`fb61191`](https://github.com/eea/volto-eea-website-theme/commit/fb611918d6ca380b89b594f283dcf9f685a4b294)]
|
297
|
-
- test: [JENKINS] Use java17 for sonarqube scanner [valentinab25 - [`6a3be30`](https://github.com/eea/volto-eea-website-theme/commit/6a3be3092589411af7808a235f76de5222fd3868)]
|
298
|
-
- test: [JENKINS] Run cypress in started frontend container [valentinab25 - [`c3978f2`](https://github.com/eea/volto-eea-website-theme/commit/c3978f23375ef066e9fd6f6c2e34ba6c1c058f69)]
|
299
|
-
- test: [JENKINS] Add cpu limit on cypress docker [valentinab25 - [`f672779`](https://github.com/eea/volto-eea-website-theme/commit/f672779e845bec9240ccc901e9f53ec80c5a1819)]
|
300
|
-
- test: [JENKINS] Increase shm-size to cypress docker [valentinab25 - [`ae5d8e3`](https://github.com/eea/volto-eea-website-theme/commit/ae5d8e3f4e04dc2808d47ce2ee886e1b23b528da)]
|
301
|
-
- test: [JENKINS] Improve cypress time [valentinab25 - [`170ff0c`](https://github.com/eea/volto-eea-website-theme/commit/170ff0c8e3b30e69479bdf1117e811fea94f1027)]
|
302
297
|
### [1.23.0](https://github.com/eea/volto-eea-website-theme/compare/1.22.1...1.23.0) - 2 November 2023
|
303
298
|
|
304
299
|
#### :rocket: New Features
|
@@ -311,7 +306,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
311
306
|
|
312
307
|
#### :house: Internal changes
|
313
308
|
|
314
|
-
- chore: [JENKINS] Refactor automated testing [valentinab25 - [`f28fce3`](https://github.com/eea/volto-eea-website-theme/commit/f28fce3d1eb815f95fb9aa40de42b10b7e8e30c5)]
|
315
309
|
- chore: husky, lint-staged use fixed versions [valentinab25 - [`6d15088`](https://github.com/eea/volto-eea-website-theme/commit/6d150886c5aeb2ca0b569270486e60f7cc274e2c)]
|
316
310
|
- chore:volto 16 in tests, update docs, fix stylelint overrides [valentinab25 - [`20c0323`](https://github.com/eea/volto-eea-website-theme/commit/20c032380b33c0077c869a05136f93e2fb68e5d4)]
|
317
311
|
|
@@ -497,7 +491,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
497
491
|
|
498
492
|
#### :house: Internal changes
|
499
493
|
|
500
|
-
- chore: [JENKINS] Deprecate circularity website [valentinab25 - [`370dcbf`](https://github.com/eea/volto-eea-website-theme/commit/370dcbfbf1a8135ce7b1b3b271b004552a631837)]
|
501
494
|
|
502
495
|
#### :hammer_and_wrench: Others
|
503
496
|
|
@@ -653,7 +646,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
653
646
|
|
654
647
|
#### :hammer_and_wrench: Others
|
655
648
|
|
656
|
-
- Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`6c5e2f8`](https://github.com/eea/volto-eea-website-theme/commit/6c5e2f80456e2061d9e9c15fd0a0b91b9ac70568)]
|
657
649
|
### [1.9.1](https://github.com/eea/volto-eea-website-theme/compare/1.9.0...1.9.1) - 28 February 2023
|
658
650
|
|
659
651
|
#### :bug: Bug Fixes
|
@@ -800,7 +792,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
800
792
|
|
801
793
|
- For some reasons types is a string [Alin Voinea - [`3769a09`](https://github.com/eea/volto-eea-website-theme/commit/3769a0981181d5b633f3498daebbe96be8b4b833)]
|
802
794
|
- Fix(redirect): o.filter - refs #157627 [Alin Voinea - [`deb23da`](https://github.com/eea/volto-eea-website-theme/commit/deb23da846444cc96539697fd798429ae0abe89e)]
|
803
|
-
- Add Sonarqube tag using advisory-board-frontend addons list [EEA Jenkins - [`f1fffc5`](https://github.com/eea/volto-eea-website-theme/commit/f1fffc5db96725440863d545580b4e76cce4b796)]
|
804
795
|
### [1.5.0](https://github.com/eea/volto-eea-website-theme/compare/1.4.2...1.5.0) - 9 January 2023
|
805
796
|
|
806
797
|
#### :hammer_and_wrench: Others
|
@@ -834,7 +825,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
834
825
|
|
835
826
|
- Release 1.4.0 [Alin Voinea - [`bd42a0d`](https://github.com/eea/volto-eea-website-theme/commit/bd42a0d26e928cac5d99933194755da3db06b341)]
|
836
827
|
- bump version to use as volto-eea-design-system [David Ichim - [`f4be047`](https://github.com/eea/volto-eea-website-theme/commit/f4be047328b46399b03b612d378b18aaf82e7dc1)]
|
837
|
-
- Add Sonarqube tag using advisory-board-frontend addons list [EEA Jenkins - [`9b7cfef`](https://github.com/eea/volto-eea-website-theme/commit/9b7cfefb4d34fc1c948015e491feb370f9795bd8)]
|
838
828
|
- test(Jenkins): Run tests and cypress with latest canary @plone/volto [Alin Voinea - [`df252a9`](https://github.com/eea/volto-eea-website-theme/commit/df252a9bfed0bb86cadf53c59dd1603b1e2cd822)]
|
839
829
|
### [1.3.2](https://github.com/eea/volto-eea-website-theme/compare/1.3.1...1.3.2) - 16 December 2022
|
840
830
|
|
@@ -844,7 +834,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
844
834
|
|
845
835
|
#### :hammer_and_wrench: Others
|
846
836
|
|
847
|
-
- Add Sonarqube tag using cca-frontend addons list [EEA Jenkins - [`a43c658`](https://github.com/eea/volto-eea-website-theme/commit/a43c658a7920c8df95e763b9a637f38ce77eba2c)]
|
848
837
|
- Better razzle.config [Tiberiu Ichim - [`81dbf48`](https://github.com/eea/volto-eea-website-theme/commit/81dbf48815fb27facb4f82c9b764540fdf188b2e)]
|
849
838
|
- Better razzle.config [Tiberiu Ichim - [`7bc9da2`](https://github.com/eea/volto-eea-website-theme/commit/7bc9da2cd837ab62a95cd29979cdd9b0055b7d67)]
|
850
839
|
### [1.3.1](https://github.com/eea/volto-eea-website-theme/compare/1.3.0...1.3.1) - 28 November 2022
|
@@ -855,7 +844,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
855
844
|
|
856
845
|
#### :hammer_and_wrench: Others
|
857
846
|
|
858
|
-
- yarn 3 [Alin Voinea - [`ea7a709`](https://github.com/eea/volto-eea-website-theme/commit/ea7a7094945312776e9b6f44e371178603e92139)]
|
859
847
|
### [1.3.0](https://github.com/eea/volto-eea-website-theme/compare/1.2.0...1.3.0) - 22 November 2022
|
860
848
|
|
861
849
|
#### :rocket: New Features
|
@@ -896,7 +884,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
896
884
|
- Add subsite class to body [Tiberiu Ichim - [`74d700f`](https://github.com/eea/volto-eea-website-theme/commit/74d700fbfd6249a8604762a7e4e49cce857db0f3)]
|
897
885
|
- Add subsite info to header [Tiberiu Ichim - [`47daf8b`](https://github.com/eea/volto-eea-website-theme/commit/47daf8bb6374a1222040626b19d4154df7ba1b83)]
|
898
886
|
- fix eslint [Miu Razvan - [`eb8d0a7`](https://github.com/eea/volto-eea-website-theme/commit/eb8d0a790bc70c0aae256c6ff35f63c4885f338e)]
|
899
|
-
- Add Sonarqube tag using circularity-frontend addons list [EEA Jenkins - [`cc578a4`](https://github.com/eea/volto-eea-website-theme/commit/cc578a413b205a8e61e091fab3a88f94cedefc89)]
|
900
887
|
### [1.1.0](https://github.com/eea/volto-eea-website-theme/compare/1.0.0...1.1.0) - 28 October 2022
|
901
888
|
|
902
889
|
#### :nail_care: Enhancements
|
@@ -944,7 +931,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
944
931
|
|
945
932
|
#### :hammer_and_wrench: Others
|
946
933
|
|
947
|
-
- Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`33b56ac`](https://github.com/eea/volto-eea-website-theme/commit/33b56acb13fbaf0c5b79e8fc6e13c4b699c79c90)]
|
948
934
|
### [0.7.3](https://github.com/eea/volto-eea-website-theme/compare/0.7.2...0.7.3) - 22 September 2022
|
949
935
|
|
950
936
|
#### :hammer_and_wrench: Others
|
@@ -1212,7 +1198,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
1212
1198
|
- Header refactor, add custom logo #5 [ichim-david - [`4950235`](https://github.com/eea/volto-eea-website-theme/commit/49502358105437cfeac3b144e6d301cb59aa2346)]
|
1213
1199
|
- Update footer.config with new publication card component [ichim-david - [`2e38e9a`](https://github.com/eea/volto-eea-website-theme/commit/2e38e9a417f835009d60c80d4eb4b30229f55e45)]
|
1214
1200
|
- feature(breadcrumbs): implement eea-design-system breadcrumb as Volto component #32 #7 [ichim-david - [`181af41`](https://github.com/eea/volto-eea-website-theme/commit/181af4125ce2b9ddac56dab4723cb11c26633221)]
|
1215
|
-
- Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`da8ceb6`](https://github.com/eea/volto-eea-website-theme/commit/da8ceb68ea68bfbc9504e48ccd4d68277f11ab9a)]
|
1216
1201
|
- use breadcrumbs from eea-design-system [nileshgulia1 - [`db2f9e9`](https://github.com/eea/volto-eea-website-theme/commit/db2f9e9a4327420a3cce9a9903cd88549b129eab)]
|
1217
1202
|
- Update theme.config [ichim-david - [`8eca4f4`](https://github.com/eea/volto-eea-website-theme/commit/8eca4f40397a4aeca6d39029c92db78968d37064)]
|
1218
1203
|
- Added keyContent component to theme.config [ichim-david - [`d86f202`](https://github.com/eea/volto-eea-website-theme/commit/d86f202d0274d839487a88b51cae9a0e899beb23)]
|
@@ -1254,5 +1239,4 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
1254
1239
|
|
1255
1240
|
#### :hammer_and_wrench: Others
|
1256
1241
|
|
1257
|
-
- yarn bootstrap [Alin Voinea - [`6995e9e`](https://github.com/eea/volto-eea-website-theme/commit/6995e9e091f21fdbbdffa8a44fc0e2c626f6d46a)]
|
1258
1242
|
- Initial commit [Alin Voinea - [`6a9c03a`](https://github.com/eea/volto-eea-website-theme/commit/6a9c03a7cebe71ca87e82cf58c42904063e9d8d3)]
|
package/package.json
CHANGED
@@ -2,11 +2,11 @@ import React from 'react';
|
|
2
2
|
import config from '@plone/volto/registry';
|
3
3
|
|
4
4
|
const CustomCSS = (props) => {
|
5
|
+
const href = `${config.settings.apiPath}/voltoCustom.css`;
|
5
6
|
return (
|
6
|
-
|
7
|
-
rel={
|
8
|
-
|
9
|
-
/>
|
7
|
+
<>
|
8
|
+
<link rel="stylesheet" href={href} />
|
9
|
+
</>
|
10
10
|
);
|
11
11
|
};
|
12
12
|
export default CustomCSS;
|
@@ -18,12 +18,17 @@ describe('TopicsWidget Component', () => {
|
|
18
18
|
},
|
19
19
|
});
|
20
20
|
|
21
|
+
const tags = [
|
22
|
+
{ title: 'Environment', token: '1' },
|
23
|
+
{ title: 'Climate', token: '2' },
|
24
|
+
];
|
25
|
+
|
21
26
|
const { container } = render(
|
22
27
|
<Provider store={store}>
|
23
28
|
<Router history={history}>
|
24
29
|
<TopicsWidget
|
25
|
-
value={
|
26
|
-
children={
|
30
|
+
value={tags}
|
31
|
+
children={(tagTitle) => <span>{tagTitle}</span>}
|
27
32
|
className={'test'}
|
28
33
|
/>
|
29
34
|
</Router>
|
@@ -87,10 +87,10 @@ class SlateEditor extends Component {
|
|
87
87
|
const uid = uuid(); // used to namespace the editor's plugins
|
88
88
|
|
89
89
|
this.slateSettings = props.slateSettings || config.settings.slate;
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
90
|
+
this.initialValue =
|
91
|
+
this.props.value && this.props.value.length > 0
|
92
|
+
? cloneDeep(this.props.value)
|
93
|
+
: this.slateSettings.defaultValue();
|
94
94
|
|
95
95
|
this.state = {
|
96
96
|
editor: this.createEditor(uid),
|
@@ -182,8 +182,11 @@ class SlateEditor extends Component {
|
|
182
182
|
this.props.value &&
|
183
183
|
!isEqual(this.props.value, this.state.internalValue)
|
184
184
|
) {
|
185
|
-
const newValue = cloneDeep(this.props.value);
|
186
185
|
const { editor } = this.state;
|
186
|
+
const newValue =
|
187
|
+
this.props.value && this.props.value.length > 0
|
188
|
+
? cloneDeep(this.props.value)
|
189
|
+
: this.slateSettings.defaultValue();
|
187
190
|
|
188
191
|
resetNodes(editor, { nodes: newValue });
|
189
192
|
|
@@ -209,7 +212,6 @@ class SlateEditor extends Component {
|
|
209
212
|
|
210
213
|
if (!prevProps.selected && this.props.selected) {
|
211
214
|
// if the SlateEditor becomes selected from unselected
|
212
|
-
|
213
215
|
if (window.getSelection().type === 'None') {
|
214
216
|
// TODO: why is this condition checked?
|
215
217
|
Transforms.select(
|
@@ -217,7 +219,6 @@ class SlateEditor extends Component {
|
|
217
219
|
Editor.range(this.state.editor, Editor.start(this.state.editor, [])),
|
218
220
|
);
|
219
221
|
}
|
220
|
-
|
221
222
|
ReactEditor.focus(this.state.editor);
|
222
223
|
}
|
223
224
|
|
@@ -331,7 +332,9 @@ class SlateEditor extends Component {
|
|
331
332
|
this.props.onBlur && this.props.onBlur();
|
332
333
|
return null;
|
333
334
|
}}
|
334
|
-
onClick={
|
335
|
+
onClick={(e) => {
|
336
|
+
return this.props.onClick && this.props.onClick(e);
|
337
|
+
}}
|
335
338
|
onSelect={(e) => {
|
336
339
|
if (!selected && this.props.onFocus) {
|
337
340
|
// we can't overwrite the onFocus of Editable, as the onFocus
|
@@ -313,6 +313,7 @@ class Edit extends Component {
|
|
313
313
|
'@id': data.url,
|
314
314
|
image_field: data.image_field,
|
315
315
|
image_scales: data.image_scales,
|
316
|
+
data: data,
|
316
317
|
}
|
317
318
|
: undefined
|
318
319
|
}
|
@@ -323,7 +324,9 @@ class Edit extends Component {
|
|
323
324
|
? // Backwards compat in the case that the block is storing the full server URL
|
324
325
|
(() => {
|
325
326
|
if (data.size === 'l')
|
326
|
-
return `${flattenToAppURL(
|
327
|
+
return `${flattenToAppURL(
|
328
|
+
data.url,
|
329
|
+
)}/@@images/image/large`;
|
327
330
|
if (data.size === 'm')
|
328
331
|
return `${flattenToAppURL(
|
329
332
|
data.url,
|
@@ -332,7 +335,9 @@ class Edit extends Component {
|
|
332
335
|
return `${flattenToAppURL(
|
333
336
|
data.url,
|
334
337
|
)}/@@images/image/mini`;
|
335
|
-
return `${flattenToAppURL(
|
338
|
+
return `${flattenToAppURL(
|
339
|
+
data.url,
|
340
|
+
)}/@@images/image/large`;
|
336
341
|
})()
|
337
342
|
: data.url
|
338
343
|
}
|
@@ -76,6 +76,7 @@ export const View = (props) => {
|
|
76
76
|
'@id': data.url,
|
77
77
|
image_field: data.image_field,
|
78
78
|
image_scales: data.image_scales,
|
79
|
+
data: data,
|
79
80
|
}
|
80
81
|
: undefined
|
81
82
|
}
|
@@ -88,7 +89,7 @@ export const View = (props) => {
|
|
88
89
|
if (data.size === 'l')
|
89
90
|
return `${flattenToAppURL(
|
90
91
|
data.url,
|
91
|
-
)}/@@images/image`;
|
92
|
+
)}/@@images/image/large`;
|
92
93
|
if (data.size === 'm')
|
93
94
|
return `${flattenToAppURL(
|
94
95
|
data.url,
|
@@ -99,7 +100,7 @@ export const View = (props) => {
|
|
99
100
|
)}/@@images/image/mini`;
|
100
101
|
return `${flattenToAppURL(
|
101
102
|
data.url,
|
102
|
-
)}/@@images/image`;
|
103
|
+
)}/@@images/image/large`;
|
103
104
|
})()
|
104
105
|
: data.url
|
105
106
|
}
|
@@ -95,10 +95,12 @@ export function ImageSchema({ formData, intl }) {
|
|
95
95
|
align: {
|
96
96
|
title: intl.formatMessage(messages.Align),
|
97
97
|
widget: 'align',
|
98
|
+
default: 'center',
|
98
99
|
},
|
99
100
|
size: {
|
100
101
|
title: intl.formatMessage(messages.size),
|
101
102
|
widget: 'image_size',
|
103
|
+
default: 'l',
|
102
104
|
},
|
103
105
|
href: {
|
104
106
|
title: intl.formatMessage(messages.LinkTo),
|
@@ -9,16 +9,10 @@ import { connect, useDispatch, useSelector } from 'react-redux';
|
|
9
9
|
|
10
10
|
import { withRouter } from 'react-router-dom';
|
11
11
|
import { UniversalLink } from '@plone/volto/components';
|
12
|
-
import {
|
13
|
-
getBaseUrl,
|
14
|
-
hasApiExpander,
|
15
|
-
flattenToAppURL,
|
16
|
-
} from '@plone/volto/helpers';
|
12
|
+
import { getBaseUrl, hasApiExpander } from '@plone/volto/helpers';
|
17
13
|
import { getNavigation } from '@plone/volto/actions';
|
18
14
|
import { Header, Logo } from '@eeacms/volto-eea-design-system/ui';
|
19
15
|
import { usePrevious } from '@eeacms/volto-eea-design-system/helpers';
|
20
|
-
import { find } from 'lodash';
|
21
|
-
import globeIcon from '@eeacms/volto-eea-design-system/../theme/themes/eea/assets/images/Header/global-line.svg';
|
22
16
|
import eeaFlag from '@eeacms/volto-eea-design-system/../theme/themes/eea/assets/images/Header/eea.png';
|
23
17
|
|
24
18
|
import config from '@plone/volto/registry';
|
@@ -26,6 +20,9 @@ import { compose } from 'recompose';
|
|
26
20
|
import { BodyClass } from '@plone/volto/helpers';
|
27
21
|
|
28
22
|
import cx from 'classnames';
|
23
|
+
import loadable from '@loadable/component';
|
24
|
+
|
25
|
+
const LazyLanguageSwitcher = loadable(() => import('./LanguageSwitcher'));
|
29
26
|
|
30
27
|
function removeTrailingSlash(path) {
|
31
28
|
return path.replace(/\/+$/, '');
|
@@ -35,11 +32,6 @@ function removeTrailingSlash(path) {
|
|
35
32
|
* EEA Specific Header component.
|
36
33
|
*/
|
37
34
|
const EEAHeader = ({ pathname, token, items, history, subsite }) => {
|
38
|
-
const currentLang = useSelector((state) => state.intl.locale);
|
39
|
-
const translations = useSelector(
|
40
|
-
(state) => state.content.data?.['@components']?.translations?.items,
|
41
|
-
);
|
42
|
-
|
43
35
|
const router_pathname = useSelector((state) => {
|
44
36
|
return removeTrailingSlash(state.router?.location?.pathname) || '';
|
45
37
|
});
|
@@ -61,31 +53,25 @@ const EEAHeader = ({ pathname, token, items, history, subsite }) => {
|
|
61
53
|
const { eea } = config.settings;
|
62
54
|
const headerOpts = eea.headerOpts || {};
|
63
55
|
const headerSearchBox = eea.headerSearchBox || [];
|
64
|
-
const { logo, logoWhite } = headerOpts
|
56
|
+
const { logo, logoWhite } = headerOpts;
|
65
57
|
const width = useSelector((state) => state.screen?.width);
|
66
58
|
const dispatch = useDispatch();
|
67
59
|
const previousToken = usePrevious(token);
|
68
|
-
const [language, setLanguage] = React.useState(
|
69
|
-
currentLang || eea.defaultLanguage,
|
70
|
-
);
|
71
60
|
|
72
61
|
React.useEffect(() => {
|
73
|
-
const { settings } = config;
|
74
62
|
const base_url = getBaseUrl(pathname);
|
63
|
+
const { settings } = config;
|
64
|
+
|
65
|
+
// Check if navigation data needs to be fetched based on the API expander availability
|
75
66
|
if (!hasApiExpander('navigation', base_url)) {
|
76
67
|
dispatch(getNavigation(base_url, settings.navDepth));
|
77
68
|
}
|
78
|
-
}, [pathname, dispatch]);
|
79
69
|
|
80
|
-
|
70
|
+
// Additional check for token changes
|
81
71
|
if (token !== previousToken) {
|
82
|
-
|
83
|
-
const base = getBaseUrl(pathname);
|
84
|
-
if (!hasApiExpander('navigation', base)) {
|
85
|
-
dispatch(getNavigation(base, settings.navDepth));
|
86
|
-
}
|
72
|
+
dispatch(getNavigation(base_url, settings.navDepth));
|
87
73
|
}
|
88
|
-
}, [token, dispatch,
|
74
|
+
}, [pathname, token, dispatch, previousToken]);
|
89
75
|
|
90
76
|
return (
|
91
77
|
<Header menuItems={items}>
|
@@ -155,50 +141,7 @@ const EEAHeader = ({ pathname, token, items, history, subsite }) => {
|
|
155
141
|
{config.settings.isMultilingual &&
|
156
142
|
config.settings.supportedLanguages.length > 1 &&
|
157
143
|
config.settings.hasLanguageDropdown && (
|
158
|
-
<
|
159
|
-
id="language-switcher"
|
160
|
-
className="item"
|
161
|
-
text={`${language.toUpperCase()}`}
|
162
|
-
mobileText={`${language.toUpperCase()}`}
|
163
|
-
icon={
|
164
|
-
<Image
|
165
|
-
src={globeIcon}
|
166
|
-
alt="language dropdown globe icon"
|
167
|
-
></Image>
|
168
|
-
}
|
169
|
-
viewportWidth={width}
|
170
|
-
>
|
171
|
-
<ul
|
172
|
-
className="wrapper language-list"
|
173
|
-
role="listbox"
|
174
|
-
aria-label="language switcher"
|
175
|
-
>
|
176
|
-
{eea.languages.map((item, index) => (
|
177
|
-
<Dropdown.Item
|
178
|
-
as="li"
|
179
|
-
key={index}
|
180
|
-
text={
|
181
|
-
<span>
|
182
|
-
{item.name}
|
183
|
-
<span className="country-code">
|
184
|
-
{item.code.toUpperCase()}
|
185
|
-
</span>
|
186
|
-
</span>
|
187
|
-
}
|
188
|
-
onClick={() => {
|
189
|
-
const translation = find(translations, {
|
190
|
-
language: item.code,
|
191
|
-
});
|
192
|
-
const to = translation
|
193
|
-
? flattenToAppURL(translation['@id'])
|
194
|
-
: `/${item.code}`;
|
195
|
-
setLanguage(item.code);
|
196
|
-
history.push(to);
|
197
|
-
}}
|
198
|
-
></Dropdown.Item>
|
199
|
-
))}
|
200
|
-
</ul>
|
201
|
-
</Header.TopDropdownMenu>
|
144
|
+
<LazyLanguageSwitcher width={width} history={history} />
|
202
145
|
)}
|
203
146
|
</Header.TopHeader>
|
204
147
|
<Header.Main
|
@@ -1,19 +1,33 @@
|
|
1
1
|
import React from 'react';
|
2
|
-
import
|
3
|
-
import
|
2
|
+
import { render, fireEvent, getByText } from '@testing-library/react';
|
3
|
+
import '@testing-library/jest-dom/extend-expect';
|
4
4
|
import configureStore from 'redux-mock-store';
|
5
5
|
import { Router } from 'react-router-dom';
|
6
6
|
import { createMemoryHistory } from 'history';
|
7
7
|
import { Provider } from 'react-intl-redux';
|
8
8
|
import config from '@plone/volto/registry';
|
9
|
-
|
9
|
+
import { waitFor } from '@testing-library/react';
|
10
10
|
import Header from './Header';
|
11
11
|
|
12
12
|
const mockStore = configureStore();
|
13
13
|
let history = createMemoryHistory();
|
14
14
|
|
15
|
+
const item = {
|
16
|
+
'@id': 'en',
|
17
|
+
description: 'Description of item',
|
18
|
+
items: [],
|
19
|
+
review_state: 'published',
|
20
|
+
title: 'Test english article',
|
21
|
+
};
|
22
|
+
|
23
|
+
jest.mock('@plone/volto/helpers/Loadable/Loadable');
|
24
|
+
beforeAll(
|
25
|
+
async () =>
|
26
|
+
await require('@plone/volto/helpers/Loadable/Loadable').__setLoadables(),
|
27
|
+
);
|
28
|
+
|
15
29
|
describe('Header', () => {
|
16
|
-
it('renders a header component', () => {
|
30
|
+
it('renders a header component with homepage_inverse_view layout', () => {
|
17
31
|
const store = mockStore({
|
18
32
|
userSession: { token: null },
|
19
33
|
intl: {
|
@@ -21,7 +35,7 @@ describe('Header', () => {
|
|
21
35
|
messages: {},
|
22
36
|
},
|
23
37
|
navigation: {
|
24
|
-
items: [
|
38
|
+
items: [item],
|
25
39
|
},
|
26
40
|
content: {
|
27
41
|
data: {
|
@@ -38,22 +52,23 @@ describe('Header', () => {
|
|
38
52
|
config.settings = {
|
39
53
|
...config.settings,
|
40
54
|
eea: {
|
55
|
+
...config.settings.eea,
|
41
56
|
headerOpts: undefined,
|
57
|
+
logoTargetUrl: '/',
|
42
58
|
},
|
43
59
|
};
|
44
60
|
|
45
|
-
const
|
61
|
+
const { container } = render(
|
46
62
|
<Provider store={store}>
|
47
63
|
<Router history={history}>
|
48
64
|
<Header pathname="/home" />
|
49
65
|
</Router>
|
50
66
|
</Provider>,
|
51
67
|
);
|
52
|
-
|
53
|
-
expect(json).toMatchSnapshot();
|
68
|
+
expect(container).toMatchSnapshot();
|
54
69
|
});
|
55
70
|
|
56
|
-
it('renders a header component', () => {
|
71
|
+
it('renders a header component with homepage_view layout and translations', async () => {
|
57
72
|
const store = mockStore({
|
58
73
|
userSession: { token: null },
|
59
74
|
intl: {
|
@@ -61,47 +76,7 @@ describe('Header', () => {
|
|
61
76
|
messages: {},
|
62
77
|
},
|
63
78
|
navigation: {
|
64
|
-
items: [
|
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'],
|
79
|
+
items: [item],
|
105
80
|
},
|
106
81
|
content: {
|
107
82
|
data: {
|
@@ -123,6 +98,7 @@ describe('Header', () => {
|
|
123
98
|
config.settings = {
|
124
99
|
...config.settings,
|
125
100
|
eea: {
|
101
|
+
...config.settings.eea,
|
126
102
|
headerOpts: {
|
127
103
|
partnerLinks: {
|
128
104
|
links: [{ href: '/link1', title: 'link 1' }],
|
@@ -145,6 +121,9 @@ describe('Header', () => {
|
|
145
121
|
);
|
146
122
|
|
147
123
|
fireEvent.click(container.querySelector('.content'));
|
124
|
+
await waitFor(() => {
|
125
|
+
expect(container.querySelector('.country-code')).not.toBeNull();
|
126
|
+
});
|
148
127
|
fireEvent.keyDown(container.querySelector('.content'), { keyCode: 37 });
|
149
128
|
fireEvent.keyDown(container.querySelector('.content a'), { keyCode: 37 });
|
150
129
|
fireEvent.keyDown(container.querySelector('a[href="/link1"]'), {
|
@@ -152,7 +131,7 @@ describe('Header', () => {
|
|
152
131
|
});
|
153
132
|
fireEvent.click(container.querySelector('.country-code'));
|
154
133
|
|
155
|
-
|
134
|
+
expect(getByText(container, 'RO')).toBeInTheDocument();
|
156
135
|
|
157
136
|
rerender(
|
158
137
|
<Provider store={{ ...store, userSession: { token: '1234' } }}>
|
@@ -163,15 +142,15 @@ describe('Header', () => {
|
|
163
142
|
);
|
164
143
|
});
|
165
144
|
|
166
|
-
it('renders a header component', () => {
|
145
|
+
it('renders a header component with a subsite', async () => {
|
167
146
|
const store = mockStore({
|
168
147
|
userSession: { token: null },
|
169
148
|
intl: {
|
170
|
-
locale:
|
149
|
+
locale: 'en',
|
171
150
|
messages: {},
|
172
151
|
},
|
173
152
|
navigation: {
|
174
|
-
items: [
|
153
|
+
items: [item],
|
175
154
|
},
|
176
155
|
content: {
|
177
156
|
data: {
|
@@ -179,6 +158,7 @@ describe('Header', () => {
|
|
179
158
|
'@components': {
|
180
159
|
subsite: {
|
181
160
|
'@type': 'Subsite',
|
161
|
+
'@id': 'http://localhost:8080/Plone/subsite',
|
182
162
|
title: 'Home Page',
|
183
163
|
subsite_logo: {
|
184
164
|
scales: {
|
@@ -205,6 +185,7 @@ describe('Header', () => {
|
|
205
185
|
config.settings = {
|
206
186
|
...config.settings,
|
207
187
|
eea: {
|
188
|
+
...config.settings.eea,
|
208
189
|
headerOpts: {
|
209
190
|
partnerLinks: {
|
210
191
|
links: [{ href: '/link1', title: 'link 1' }],
|
@@ -227,6 +208,9 @@ describe('Header', () => {
|
|
227
208
|
);
|
228
209
|
|
229
210
|
fireEvent.click(container.querySelector('.content'));
|
211
|
+
await waitFor(() => {
|
212
|
+
expect(container.querySelector('.country-code')).not.toBeNull();
|
213
|
+
});
|
230
214
|
fireEvent.keyDown(container.querySelector('.content'), { keyCode: 37 });
|
231
215
|
fireEvent.keyDown(container.querySelector('.content a'), { keyCode: 37 });
|
232
216
|
fireEvent.keyDown(container.querySelector('a[href="/link1"]'), {
|
@@ -234,7 +218,7 @@ describe('Header', () => {
|
|
234
218
|
});
|
235
219
|
fireEvent.click(container.querySelector('.country-code'));
|
236
220
|
|
237
|
-
|
221
|
+
expect(getByText(container, 'RO')).toBeInTheDocument();
|
238
222
|
|
239
223
|
rerender(
|
240
224
|
<Provider store={{ ...store, userSession: { token: '1234' } }}>
|
@@ -245,17 +229,17 @@ describe('Header', () => {
|
|
245
229
|
);
|
246
230
|
});
|
247
231
|
|
248
|
-
it('renders a header component', () => {
|
232
|
+
it('renders a header component with a subsite and two children', async () => {
|
249
233
|
const store = mockStore({
|
250
234
|
userSession: { token: null },
|
251
235
|
intl: {
|
252
|
-
locale:
|
236
|
+
locale: 'en',
|
253
237
|
messages: {},
|
254
238
|
},
|
255
239
|
navigation: {
|
256
240
|
items: [
|
257
241
|
{ url: '/test1', title: 'test 1', nav_title: 'Test 1', items: [] },
|
258
|
-
{ url:
|
242
|
+
{ url: '/test2', title: 'test 2', items: [] },
|
259
243
|
],
|
260
244
|
},
|
261
245
|
content: {
|
@@ -264,6 +248,7 @@ describe('Header', () => {
|
|
264
248
|
'@components': {
|
265
249
|
subsite: {
|
266
250
|
'@type': 'Subsite',
|
251
|
+
'@id': 'http://localhost:8080/Plone/subsite',
|
267
252
|
title: 'Home Page',
|
268
253
|
subsite_logo: undefined,
|
269
254
|
},
|
@@ -283,6 +268,7 @@ describe('Header', () => {
|
|
283
268
|
config.settings = {
|
284
269
|
...config.settings,
|
285
270
|
eea: {
|
271
|
+
...config.settings.eea,
|
286
272
|
headerOpts: {
|
287
273
|
partnerLinks: {
|
288
274
|
links: [{ href: '/link1', title: 'link 1' }],
|
@@ -305,6 +291,9 @@ describe('Header', () => {
|
|
305
291
|
);
|
306
292
|
|
307
293
|
fireEvent.click(container.querySelector('.content'));
|
294
|
+
await waitFor(() => {
|
295
|
+
expect(container.querySelector('.country-code')).not.toBeNull();
|
296
|
+
});
|
308
297
|
fireEvent.keyDown(container.querySelector('.content'), { keyCode: 37 });
|
309
298
|
fireEvent.keyDown(container.querySelector('.content a'), { keyCode: 37 });
|
310
299
|
fireEvent.keyDown(container.querySelector('a[href="/link1"]'), {
|
@@ -313,7 +302,7 @@ describe('Header', () => {
|
|
313
302
|
fireEvent.click(container.querySelector('.country-code'));
|
314
303
|
fireEvent.click(container.querySelector('a[href="/test1"]'));
|
315
304
|
|
316
|
-
|
305
|
+
expect(getByText(container, 'RO')).toBeInTheDocument();
|
317
306
|
|
318
307
|
rerender(
|
319
308
|
<Provider store={{ ...store, userSession: { token: '1234' } }}>
|
@@ -0,0 +1,71 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { useSelector } from 'react-redux';
|
3
|
+
import { Dropdown, Image } from 'semantic-ui-react';
|
4
|
+
import { flattenToAppURL } from '@plone/volto/helpers';
|
5
|
+
import { find } from 'lodash';
|
6
|
+
import globeIcon from '@eeacms/volto-eea-design-system/../theme/themes/eea/assets/images/Header/global-line.svg';
|
7
|
+
import config from '@plone/volto/registry';
|
8
|
+
import { Header } from '@eeacms/volto-eea-design-system/ui';
|
9
|
+
|
10
|
+
/**
|
11
|
+
* LanguageSwitcher component.
|
12
|
+
* Provides a dropdown menu for language selection, changing the application's
|
13
|
+
* language and navigating to the corresponding translated URL.
|
14
|
+
*
|
15
|
+
* @param {Object} props - The component props.
|
16
|
+
* @param {number} props.width - The viewport width to adjust the dropdown display.
|
17
|
+
* @param {Object} props.history - The history object from React Router for navigation.
|
18
|
+
*/
|
19
|
+
const LanguageSwitcher = ({ width, history }) => {
|
20
|
+
const currentLang = useSelector((state) => state.intl.locale);
|
21
|
+
const translations = useSelector(
|
22
|
+
(state) => state.content.data?.['@components']?.translations?.items,
|
23
|
+
);
|
24
|
+
const { eea } = config.settings;
|
25
|
+
|
26
|
+
const [language, setLanguage] = React.useState(
|
27
|
+
currentLang || eea.defaultLanguage,
|
28
|
+
);
|
29
|
+
|
30
|
+
return (
|
31
|
+
<Header.TopDropdownMenu
|
32
|
+
id="language-switcher"
|
33
|
+
className="item"
|
34
|
+
text={`${language.toUpperCase()}`}
|
35
|
+
mobileText={`${language.toUpperCase()}`}
|
36
|
+
icon={<Image src={globeIcon} alt="language dropdown globe icon"></Image>}
|
37
|
+
viewportWidth={width}
|
38
|
+
>
|
39
|
+
<ul
|
40
|
+
className="wrapper language-list"
|
41
|
+
role="listbox"
|
42
|
+
aria-label="language switcher"
|
43
|
+
>
|
44
|
+
{eea.languages.map((item, index) => (
|
45
|
+
<Dropdown.Item
|
46
|
+
as="li"
|
47
|
+
key={index}
|
48
|
+
text={
|
49
|
+
<span>
|
50
|
+
{item.name}
|
51
|
+
<span className="country-code">{item.code.toUpperCase()}</span>
|
52
|
+
</span>
|
53
|
+
}
|
54
|
+
onClick={() => {
|
55
|
+
const translation = find(translations, {
|
56
|
+
language: item.code,
|
57
|
+
});
|
58
|
+
const to = translation
|
59
|
+
? flattenToAppURL(translation['@id'])
|
60
|
+
: `/${item.code}`;
|
61
|
+
setLanguage(item.code);
|
62
|
+
history.push(to);
|
63
|
+
}}
|
64
|
+
></Dropdown.Item>
|
65
|
+
))}
|
66
|
+
</ul>
|
67
|
+
</Header.TopDropdownMenu>
|
68
|
+
);
|
69
|
+
};
|
70
|
+
|
71
|
+
export default LanguageSwitcher;
|
@@ -0,0 +1,119 @@
|
|
1
|
+
import PropTypes from 'prop-types';
|
2
|
+
import cx from 'classnames';
|
3
|
+
import { flattenToAppURL, flattenScales } from '@plone/volto/helpers';
|
4
|
+
|
5
|
+
/**
|
6
|
+
* Determines the image scale name based on the provided data.
|
7
|
+
*
|
8
|
+
* @param {object} data - The data object containing the image size information.
|
9
|
+
* @param {string} [data.size] - The size of the image, can be 'l', 'm', or 's'.
|
10
|
+
* @returns {string} The name of the image scale, either 'large', 'preview', or 'mini'.
|
11
|
+
*/
|
12
|
+
const imageScaleName = (data) => {
|
13
|
+
if (!data) return 'large';
|
14
|
+
if (data.size === 'l') return 'large';
|
15
|
+
if (data.size === 'm') return 'preview';
|
16
|
+
if (data.size === 's') return 'mini';
|
17
|
+
return 'large';
|
18
|
+
};
|
19
|
+
|
20
|
+
/**
|
21
|
+
* Image component
|
22
|
+
* @param {object} item - Context item that has the image field (can also be a catalog brain or summary)
|
23
|
+
* @param {string} imageField - Key of the image field inside the item, or inside the image_scales object of the item if it is a catalog brain or summary
|
24
|
+
* @param {string} src - URL of the image to be used if the item field is not available
|
25
|
+
* @param {string} alt - Alternative text for the image
|
26
|
+
* @param {boolean} loading - (default: eager) set to `lazy` to lazy load the image
|
27
|
+
* @param {boolean} responsive - (default: false) set to `true` to add the `responsive` class to the image
|
28
|
+
* @param {string} className - Additional classes to add to the image
|
29
|
+
*/
|
30
|
+
export default function Image({
|
31
|
+
item,
|
32
|
+
imageField,
|
33
|
+
src,
|
34
|
+
alt = '',
|
35
|
+
loading = 'eager',
|
36
|
+
responsive = false,
|
37
|
+
className = '',
|
38
|
+
...imageProps
|
39
|
+
}) {
|
40
|
+
if (!item && !src) return null;
|
41
|
+
|
42
|
+
// TypeScript hints for editor autocomplete :)
|
43
|
+
/** @type {React.ImgHTMLAttributes<HTMLImageElement>} */
|
44
|
+
const attrs = {};
|
45
|
+
|
46
|
+
if (!item && src) {
|
47
|
+
attrs.src = src;
|
48
|
+
attrs.className = cx(className, { responsive });
|
49
|
+
} else {
|
50
|
+
const isFromRealObject = !item.image_scales;
|
51
|
+
const imageFieldWithDefault = imageField || item.image_field || 'image';
|
52
|
+
|
53
|
+
const image = isFromRealObject
|
54
|
+
? flattenScales(item['@id'], item[imageFieldWithDefault])
|
55
|
+
: flattenScales(
|
56
|
+
item['@id'],
|
57
|
+
item.image_scales[imageFieldWithDefault]?.[0],
|
58
|
+
);
|
59
|
+
|
60
|
+
if (!image) return null;
|
61
|
+
|
62
|
+
const isSvg = image['content-type'] === 'image/svg+xml';
|
63
|
+
// In case `base_path` is present (`preview_image_link`) use it as base path
|
64
|
+
const basePath = image.base_path || item['@id'];
|
65
|
+
const relativeBasePath = flattenToAppURL(basePath);
|
66
|
+
const selectedScale = imageScaleName(item.data);
|
67
|
+
|
68
|
+
attrs.src = `${relativeBasePath}/${image.download}`;
|
69
|
+
attrs.width = image.width;
|
70
|
+
attrs.height = image.height;
|
71
|
+
attrs.className = cx(className, { responsive });
|
72
|
+
|
73
|
+
if (!isSvg && image.scales && Object.keys(image.scales).length > 0) {
|
74
|
+
const filteredScales = [
|
75
|
+
'mini',
|
76
|
+
'preview',
|
77
|
+
'large',
|
78
|
+
item.data?.align === 'full' ? 'huge' : undefined,
|
79
|
+
]
|
80
|
+
.map((key) => image.scales[key])
|
81
|
+
.filter(Boolean);
|
82
|
+
const imageScale = image.scales[selectedScale];
|
83
|
+
if (imageScale) {
|
84
|
+
// set default image size, width and height to the selected scale
|
85
|
+
attrs.width = imageScale.width;
|
86
|
+
attrs.height = imageScale.height;
|
87
|
+
attrs.src = `${relativeBasePath}/${imageScale.download}`;
|
88
|
+
}
|
89
|
+
|
90
|
+
attrs.srcSet = filteredScales
|
91
|
+
.map((scale) => `${relativeBasePath}/${scale.download} ${scale.width}w`)
|
92
|
+
.join(', ');
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
if (loading === 'lazy') {
|
97
|
+
attrs.loading = 'lazy';
|
98
|
+
attrs.decoding = 'async';
|
99
|
+
} else {
|
100
|
+
attrs.fetchpriority = 'high';
|
101
|
+
}
|
102
|
+
|
103
|
+
return <img {...attrs} alt={alt} {...imageProps} />;
|
104
|
+
}
|
105
|
+
|
106
|
+
Image.propTypes = {
|
107
|
+
item: PropTypes.shape({
|
108
|
+
'@id': PropTypes.string,
|
109
|
+
image_field: PropTypes.string,
|
110
|
+
image_scales: PropTypes.object,
|
111
|
+
image: PropTypes.object,
|
112
|
+
}),
|
113
|
+
imageField: PropTypes.string,
|
114
|
+
src: PropTypes.string,
|
115
|
+
alt: PropTypes.string.isRequired,
|
116
|
+
loading: PropTypes.string,
|
117
|
+
responsive: PropTypes.bool,
|
118
|
+
className: PropTypes.string,
|
119
|
+
};
|
package/src/index.js
CHANGED
@@ -194,6 +194,18 @@ const applyConfig = (config) => {
|
|
194
194
|
if (config.blocks.blocksConfig.image) {
|
195
195
|
config.blocks.blocksConfig.image.schemaEnhancer =
|
196
196
|
addStylingFieldsetSchemaEnhancerImagePosition;
|
197
|
+
config.blocks.blocksConfig.image.getSizes = function (data) {
|
198
|
+
if (data.size === 'm' || data.size === 's') return undefined;
|
199
|
+
|
200
|
+
if (data.align === 'left' || data.align === 'right') {
|
201
|
+
if (data.size === 'l') return '400px';
|
202
|
+
if (data.size === 'm') return '200px';
|
203
|
+
if (data.size === 's') return '200px';
|
204
|
+
}
|
205
|
+
if (data.size === 'l') {
|
206
|
+
return '(max-width: 600px) 400px, (max-width: 1440px) 800px, 100vw';
|
207
|
+
}
|
208
|
+
};
|
197
209
|
}
|
198
210
|
|
199
211
|
// Set Languages in nextcloud-video-block
|