@eeacms/volto-eea-website-theme 1.26.2 → 1.27.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 CHANGED
@@ -4,6 +4,20 @@ 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
+ ### [1.27.0](https://github.com/eea/volto-eea-website-theme/compare/1.26.2...1.27.0) - 17 January 2024
8
+
9
+ #### :rocket: New Features
10
+
11
+ - feat: Put cloneData function for slate block, in order to change the uuids of fragments - refs #261770 [dobri1408 - [`069bffc`](https://github.com/eea/volto-eea-website-theme/commit/069bffcf114a886690408bbc2c2909c298b5e1aa)]
12
+
13
+ #### :bug: Bug Fixes
14
+
15
+ - fix: noreferrer on links - refs #263008 [ichim-david - [`d8f81e0`](https://github.com/eea/volto-eea-website-theme/commit/d8f81e01d9d2666e834ac92b2f34976f25156ea2)]
16
+ - fix: History diff page overlap - refs #262216 [dobri1408 - [`f580b16`](https://github.com/eea/volto-eea-website-theme/commit/f580b16f24faacb9318402699a1b616814840d63)]
17
+
18
+ #### :hammer_and_wrench: Others
19
+
20
+ - Release 1.27.0 [Alin Voinea - [`e7acf6d`](https://github.com/eea/volto-eea-website-theme/commit/e7acf6dd3332c090f75a6b1f63fc772912406ec0)]
7
21
  ### [1.26.2](https://github.com/eea/volto-eea-website-theme/compare/1.26.1...1.26.2) - 4 January 2024
8
22
 
9
23
  ### [1.26.1](https://github.com/eea/volto-eea-website-theme/compare/1.26.0...1.26.1) - 14 December 2023
@@ -76,11 +90,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
76
90
  - test: Add real image to cypress test [Alin Voinea - [`4ff591a`](https://github.com/eea/volto-eea-website-theme/commit/4ff591ae3318c9588b4e2114582c0fa6cfdf31ae)]
77
91
  - test: Add cypress tests for Image block styling position and align [Alin Voinea - [`7341ef7`](https://github.com/eea/volto-eea-website-theme/commit/7341ef7b92714fc0cc3ab0c31c39033e7b3e19e7)]
78
92
  - 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)]
79
- - test: [JENKINS] Use java17 for sonarqube scanner [valentinab25 - [`6a3be30`](https://github.com/eea/volto-eea-website-theme/commit/6a3be3092589411af7808a235f76de5222fd3868)]
80
- - test: [JENKINS] Run cypress in started frontend container [valentinab25 - [`c3978f2`](https://github.com/eea/volto-eea-website-theme/commit/c3978f23375ef066e9fd6f6c2e34ba6c1c058f69)]
81
- - test: [JENKINS] Add cpu limit on cypress docker [valentinab25 - [`f672779`](https://github.com/eea/volto-eea-website-theme/commit/f672779e845bec9240ccc901e9f53ec80c5a1819)]
82
- - test: [JENKINS] Increase shm-size to cypress docker [valentinab25 - [`ae5d8e3`](https://github.com/eea/volto-eea-website-theme/commit/ae5d8e3f4e04dc2808d47ce2ee886e1b23b528da)]
83
- - test: [JENKINS] Improve cypress time [valentinab25 - [`170ff0c`](https://github.com/eea/volto-eea-website-theme/commit/170ff0c8e3b30e69479bdf1117e811fea94f1027)]
84
93
  ### [1.23.0](https://github.com/eea/volto-eea-website-theme/compare/1.22.1...1.23.0) - 2 November 2023
85
94
 
86
95
  #### :rocket: New Features
@@ -93,7 +102,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
93
102
 
94
103
  #### :house: Internal changes
95
104
 
96
- - chore: [JENKINS] Refactor automated testing [valentinab25 - [`f28fce3`](https://github.com/eea/volto-eea-website-theme/commit/f28fce3d1eb815f95fb9aa40de42b10b7e8e30c5)]
97
105
  - chore: husky, lint-staged use fixed versions [valentinab25 - [`6d15088`](https://github.com/eea/volto-eea-website-theme/commit/6d150886c5aeb2ca0b569270486e60f7cc274e2c)]
98
106
  - chore:volto 16 in tests, update docs, fix stylelint overrides [valentinab25 - [`20c0323`](https://github.com/eea/volto-eea-website-theme/commit/20c032380b33c0077c869a05136f93e2fb68e5d4)]
99
107
 
@@ -279,7 +287,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
279
287
 
280
288
  #### :house: Internal changes
281
289
 
282
- - chore: [JENKINS] Deprecate circularity website [valentinab25 - [`370dcbf`](https://github.com/eea/volto-eea-website-theme/commit/370dcbfbf1a8135ce7b1b3b271b004552a631837)]
283
290
 
284
291
  #### :hammer_and_wrench: Others
285
292
 
@@ -435,7 +442,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
435
442
 
436
443
  #### :hammer_and_wrench: Others
437
444
 
438
- - Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`6c5e2f8`](https://github.com/eea/volto-eea-website-theme/commit/6c5e2f80456e2061d9e9c15fd0a0b91b9ac70568)]
439
445
  ### [1.9.1](https://github.com/eea/volto-eea-website-theme/compare/1.9.0...1.9.1) - 28 February 2023
440
446
 
441
447
  #### :bug: Bug Fixes
@@ -582,7 +588,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
582
588
 
583
589
  - For some reasons types is a string [Alin Voinea - [`3769a09`](https://github.com/eea/volto-eea-website-theme/commit/3769a0981181d5b633f3498daebbe96be8b4b833)]
584
590
  - Fix(redirect): o.filter - refs #157627 [Alin Voinea - [`deb23da`](https://github.com/eea/volto-eea-website-theme/commit/deb23da846444cc96539697fd798429ae0abe89e)]
585
- - Add Sonarqube tag using advisory-board-frontend addons list [EEA Jenkins - [`f1fffc5`](https://github.com/eea/volto-eea-website-theme/commit/f1fffc5db96725440863d545580b4e76cce4b796)]
586
591
  ### [1.5.0](https://github.com/eea/volto-eea-website-theme/compare/1.4.2...1.5.0) - 9 January 2023
587
592
 
588
593
  #### :hammer_and_wrench: Others
@@ -616,7 +621,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
616
621
 
617
622
  - Release 1.4.0 [Alin Voinea - [`bd42a0d`](https://github.com/eea/volto-eea-website-theme/commit/bd42a0d26e928cac5d99933194755da3db06b341)]
618
623
  - bump version to use as volto-eea-design-system [David Ichim - [`f4be047`](https://github.com/eea/volto-eea-website-theme/commit/f4be047328b46399b03b612d378b18aaf82e7dc1)]
619
- - Add Sonarqube tag using advisory-board-frontend addons list [EEA Jenkins - [`9b7cfef`](https://github.com/eea/volto-eea-website-theme/commit/9b7cfefb4d34fc1c948015e491feb370f9795bd8)]
620
624
  - test(Jenkins): Run tests and cypress with latest canary @plone/volto [Alin Voinea - [`df252a9`](https://github.com/eea/volto-eea-website-theme/commit/df252a9bfed0bb86cadf53c59dd1603b1e2cd822)]
621
625
  ### [1.3.2](https://github.com/eea/volto-eea-website-theme/compare/1.3.1...1.3.2) - 16 December 2022
622
626
 
@@ -626,7 +630,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
626
630
 
627
631
  #### :hammer_and_wrench: Others
628
632
 
629
- - Add Sonarqube tag using cca-frontend addons list [EEA Jenkins - [`a43c658`](https://github.com/eea/volto-eea-website-theme/commit/a43c658a7920c8df95e763b9a637f38ce77eba2c)]
630
633
  - Better razzle.config [Tiberiu Ichim - [`81dbf48`](https://github.com/eea/volto-eea-website-theme/commit/81dbf48815fb27facb4f82c9b764540fdf188b2e)]
631
634
  - Better razzle.config [Tiberiu Ichim - [`7bc9da2`](https://github.com/eea/volto-eea-website-theme/commit/7bc9da2cd837ab62a95cd29979cdd9b0055b7d67)]
632
635
  ### [1.3.1](https://github.com/eea/volto-eea-website-theme/compare/1.3.0...1.3.1) - 28 November 2022
@@ -637,7 +640,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
637
640
 
638
641
  #### :hammer_and_wrench: Others
639
642
 
640
- - yarn 3 [Alin Voinea - [`ea7a709`](https://github.com/eea/volto-eea-website-theme/commit/ea7a7094945312776e9b6f44e371178603e92139)]
641
643
  ### [1.3.0](https://github.com/eea/volto-eea-website-theme/compare/1.2.0...1.3.0) - 22 November 2022
642
644
 
643
645
  #### :rocket: New Features
@@ -678,7 +680,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
678
680
  - Add subsite class to body [Tiberiu Ichim - [`74d700f`](https://github.com/eea/volto-eea-website-theme/commit/74d700fbfd6249a8604762a7e4e49cce857db0f3)]
679
681
  - Add subsite info to header [Tiberiu Ichim - [`47daf8b`](https://github.com/eea/volto-eea-website-theme/commit/47daf8bb6374a1222040626b19d4154df7ba1b83)]
680
682
  - fix eslint [Miu Razvan - [`eb8d0a7`](https://github.com/eea/volto-eea-website-theme/commit/eb8d0a790bc70c0aae256c6ff35f63c4885f338e)]
681
- - Add Sonarqube tag using circularity-frontend addons list [EEA Jenkins - [`cc578a4`](https://github.com/eea/volto-eea-website-theme/commit/cc578a413b205a8e61e091fab3a88f94cedefc89)]
682
683
  ### [1.1.0](https://github.com/eea/volto-eea-website-theme/compare/1.0.0...1.1.0) - 28 October 2022
683
684
 
684
685
  #### :nail_care: Enhancements
@@ -726,7 +727,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
726
727
 
727
728
  #### :hammer_and_wrench: Others
728
729
 
729
- - Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`33b56ac`](https://github.com/eea/volto-eea-website-theme/commit/33b56acb13fbaf0c5b79e8fc6e13c4b699c79c90)]
730
730
  ### [0.7.3](https://github.com/eea/volto-eea-website-theme/compare/0.7.2...0.7.3) - 22 September 2022
731
731
 
732
732
  #### :hammer_and_wrench: Others
@@ -994,7 +994,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
994
994
  - Header refactor, add custom logo #5 [ichim-david - [`4950235`](https://github.com/eea/volto-eea-website-theme/commit/49502358105437cfeac3b144e6d301cb59aa2346)]
995
995
  - Update footer.config with new publication card component [ichim-david - [`2e38e9a`](https://github.com/eea/volto-eea-website-theme/commit/2e38e9a417f835009d60c80d4eb4b30229f55e45)]
996
996
  - 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)]
997
- - Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`da8ceb6`](https://github.com/eea/volto-eea-website-theme/commit/da8ceb68ea68bfbc9504e48ccd4d68277f11ab9a)]
998
997
  - use breadcrumbs from eea-design-system [nileshgulia1 - [`db2f9e9`](https://github.com/eea/volto-eea-website-theme/commit/db2f9e9a4327420a3cce9a9903cd88549b129eab)]
999
998
  - Update theme.config [ichim-david - [`8eca4f4`](https://github.com/eea/volto-eea-website-theme/commit/8eca4f40397a4aeca6d39029c92db78968d37064)]
1000
999
  - Added keyContent component to theme.config [ichim-david - [`d86f202`](https://github.com/eea/volto-eea-website-theme/commit/d86f202d0274d839487a88b51cae9a0e899beb23)]
@@ -1036,5 +1035,4 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
1036
1035
 
1037
1036
  #### :hammer_and_wrench: Others
1038
1037
 
1039
- - yarn bootstrap [Alin Voinea - [`6995e9e`](https://github.com/eea/volto-eea-website-theme/commit/6995e9e091f21fdbbdffa8a44fc0e2c626f6d46a)]
1040
1038
  - Initial commit [Alin Voinea - [`6a9c03a`](https://github.com/eea/volto-eea-website-theme/commit/6a9c03a7cebe71ca87e82cf58c42904063e9d8d3)]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-eea-website-theme",
3
- "version": "1.26.2",
3
+ "version": "1.27.0",
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",
@@ -0,0 +1,351 @@
1
+ /**
2
+ * Diff field component.
3
+ * @module components/manage/Diff/DiffField
4
+ */
5
+
6
+ import React from 'react';
7
+ // import { diffWords as dWords } from 'diff';
8
+ import { join, map } from 'lodash';
9
+ import PropTypes from 'prop-types';
10
+ import { Grid } from 'semantic-ui-react';
11
+ import ReactDOMServer from 'react-dom/server';
12
+ import { Provider } from 'react-intl-redux';
13
+ import { createBrowserHistory } from 'history';
14
+ import { ConnectedRouter } from 'connected-react-router';
15
+ import { useSelector } from 'react-redux';
16
+
17
+ import { Api } from '@plone/volto/helpers';
18
+ import configureStore from '@plone/volto/store';
19
+ import { DefaultView } from '@plone/volto/components/';
20
+ import { serializeNodes } from '@plone/volto-slate/editor/render';
21
+
22
+ import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
23
+
24
+ /**
25
+ * Enhanced diff words utility
26
+ * @function diffWords
27
+ * @param oneStr Field one
28
+ * @param twoStr Field two
29
+ */
30
+
31
+ /**
32
+ * Diff field component.
33
+ * @function DiffField
34
+ * @param {*} one Field one
35
+ * @param {*} two Field two
36
+ * @param {Object} schema Field schema
37
+ * @returns {string} Markup of the component.
38
+ */
39
+ const DiffField = ({
40
+ one,
41
+ two,
42
+ contentOne,
43
+ contentTwo,
44
+ view,
45
+ schema,
46
+ diffLib,
47
+ }) => {
48
+ const language = useSelector((state) => state.intl.locale);
49
+ const readable_date_format = {
50
+ dateStyle: 'full',
51
+ timeStyle: 'short',
52
+ };
53
+ const splitWords = (str) => {
54
+ if (!str) return [];
55
+ const splitedArray = [];
56
+ let elementCurent = '';
57
+ let insideTag = false;
58
+ for (let i = 0; i < str.length; i++)
59
+ if (str[i] === '<') {
60
+ if (elementCurent) splitedArray.push(elementCurent);
61
+ elementCurent = '<';
62
+ insideTag = true;
63
+ } else if (str[i] === '>') {
64
+ elementCurent += '>';
65
+ splitedArray.push(elementCurent);
66
+ elementCurent = '';
67
+ insideTag = false;
68
+ } else if (str[i] === ' ' && insideTag === false) {
69
+ elementCurent += ' ';
70
+ splitedArray.push(elementCurent);
71
+ elementCurent = '';
72
+ } else elementCurent += str[i];
73
+ if (elementCurent) splitedArray.push(elementCurent);
74
+ return splitedArray;
75
+ };
76
+
77
+ const diffWords = (oneStr, twoStr) => {
78
+ return diffLib.diffArrays(splitWords(oneStr), splitWords(twoStr));
79
+ };
80
+
81
+ let parts, oneArray, twoArray;
82
+ if (schema.widget && schema.title !== 'Data sources and providers') {
83
+ switch (schema.widget) {
84
+ case 'richtext':
85
+ parts = diffWords(one?.data, two?.data);
86
+ break;
87
+ case 'datetime':
88
+ parts = diffWords(
89
+ new Intl.DateTimeFormat(language, readable_date_format)
90
+ .format(new Date(one))
91
+ .replace('\u202F', ' '),
92
+ new Intl.DateTimeFormat(language, readable_date_format)
93
+ .format(new Date(two))
94
+ .replace('\u202F', ' '),
95
+ );
96
+ break;
97
+ case 'json': {
98
+ const api = new Api();
99
+ const history = createBrowserHistory();
100
+ const store = configureStore(window.__data, history, api);
101
+ parts = diffWords(
102
+ ReactDOMServer.renderToStaticMarkup(
103
+ <Provider store={store}>
104
+ <ConnectedRouter history={history}>
105
+ <DefaultView content={contentOne} />
106
+ </ConnectedRouter>
107
+ </Provider>,
108
+ ),
109
+ ReactDOMServer.renderToStaticMarkup(
110
+ <Provider store={store}>
111
+ <ConnectedRouter history={history}>
112
+ <DefaultView content={contentTwo} />
113
+ </ConnectedRouter>
114
+ </Provider>,
115
+ ),
116
+ );
117
+ break;
118
+ }
119
+ case 'slate': {
120
+ const api = new Api();
121
+ const history = createBrowserHistory();
122
+ const store = configureStore(window.__data, history, api);
123
+ parts = diffWords(
124
+ ReactDOMServer.renderToStaticMarkup(
125
+ <Provider store={store}>
126
+ <ConnectedRouter history={history}>
127
+ {serializeNodes(one)}
128
+ </ConnectedRouter>
129
+ </Provider>,
130
+ ),
131
+ ReactDOMServer.renderToStaticMarkup(
132
+ <Provider store={store}>
133
+ <ConnectedRouter history={history}>
134
+ {serializeNodes(two)}
135
+ </ConnectedRouter>
136
+ </Provider>,
137
+ ),
138
+ );
139
+ break;
140
+ }
141
+ case 'temporal': {
142
+ if (one?.temporal?.length > 0 && two.temporal?.length > 0) {
143
+ let firstString = one.temporal.reduce((acc, cur) => {
144
+ return acc + cur?.label + ', ';
145
+ }, '');
146
+ firstString = firstString.substring(0, firstString.length - 2);
147
+ let secondString = two.temporal.reduce((acc, cur) => {
148
+ return acc + cur?.label + ', ';
149
+ }, '');
150
+ secondString = secondString.substring(0, secondString.length - 2);
151
+ parts = diffWords(firstString, secondString);
152
+ }
153
+ break;
154
+ }
155
+ case 'geolocation': {
156
+ if (one?.geolocation?.length > 0 && two.geolocation?.length > 0) {
157
+ let firstString = one.geolocation.reduce((acc, cur) => {
158
+ return acc + cur?.label + ', ';
159
+ }, '');
160
+ firstString = firstString.substring(0, firstString.length - 2);
161
+ let secondString = two.geolocation.reduce((acc, cur) => {
162
+ return acc + cur?.label + ', ';
163
+ }, '');
164
+ secondString = secondString.substring(0, secondString.length - 2);
165
+ parts = diffWords(firstString, secondString);
166
+ }
167
+ break;
168
+ }
169
+ case 'textarea':
170
+ default:
171
+ parts = diffWords(one, two);
172
+ break;
173
+ }
174
+ } else if (schema.title === 'Data sources and providers') {
175
+ if (one?.data?.length > 0 && two.data?.length > 0) {
176
+ let firstString = one.data.reduce((acc, cur) => {
177
+ return acc + cur?.title + ', ' + cur?.organisation + '<br/>';
178
+ }, '');
179
+ firstString = firstString.substring(0, firstString.length - 2);
180
+ let secondString = two.data.reduce((acc, cur) => {
181
+ return acc + cur?.title + ', ' + cur?.organisation + '<br/>';
182
+ }, '');
183
+ secondString = secondString.substring(0, secondString.length - 2);
184
+ parts = diffWords(firstString, secondString);
185
+ }
186
+ } else if (schema.type === 'object') {
187
+ parts = diffWords(one?.filename || one, two?.filename || two);
188
+ } else if (schema.type === 'array') {
189
+ oneArray = (one || []).map((i) => i?.title || i);
190
+ twoArray = (two || []).map((j) => j?.title || j);
191
+ parts = diffWords(oneArray, twoArray);
192
+ } else {
193
+ parts = diffWords(one?.title || one, two?.title || two);
194
+ }
195
+
196
+ return (
197
+ <Grid data-testid="DiffField">
198
+ <Grid.Row>
199
+ <Grid.Column width={12}>{schema.title}</Grid.Column>
200
+ </Grid.Row>
201
+
202
+ {view === 'split' && (
203
+ <Grid.Row>
204
+ <Grid.Column width={6} verticalAlign="top">
205
+ <span
206
+ dangerouslySetInnerHTML={{
207
+ __html: join(
208
+ map(parts, (part) => {
209
+ let combined = (part.value || []).reduce((acc, value) => {
210
+ if (
211
+ part.removed &&
212
+ !value.includes('<') &&
213
+ !value.includes('>') &&
214
+ !value.includes('>') &&
215
+ !value.includes('</') &&
216
+ !value.includes('"') &&
217
+ !value.includes('src') &&
218
+ !value.includes('href') &&
219
+ !value.includes('=')
220
+ )
221
+ return acc + `<span class="deletion">${value}</span>`;
222
+ if (
223
+ part.added &&
224
+ !value.includes('<') &&
225
+ !value.includes('>') &&
226
+ !value.includes('>') &&
227
+ !value.includes('</') &&
228
+ !value.includes('"') &&
229
+ !value.includes('src') &&
230
+ !value.includes('href') &&
231
+ !value.includes('=')
232
+ )
233
+ return acc;
234
+ return acc + value;
235
+ }, '');
236
+ return combined;
237
+ }),
238
+ '',
239
+ ),
240
+ }}
241
+ />
242
+ </Grid.Column>
243
+ <Grid.Column width={6} verticalAlign="top">
244
+ <span
245
+ dangerouslySetInnerHTML={{
246
+ __html: join(
247
+ map(parts, (part) => {
248
+ let combined = (part.value || []).reduce((acc, value) => {
249
+ if (
250
+ part.added &&
251
+ !value.includes('<') &&
252
+ !value.includes('>') &&
253
+ !value.includes('>') &&
254
+ !value.includes('</') &&
255
+ !value.includes('"') &&
256
+ !value.includes('src') &&
257
+ !value.includes('href') &&
258
+ !value.includes('=')
259
+ )
260
+ return acc + `<span class="addition">${value}</span>`;
261
+ if (
262
+ part.removed &&
263
+ !value.includes('<') &&
264
+ !value.includes('>') &&
265
+ !value.includes('>') &&
266
+ !value.includes('</') &&
267
+ !value.includes('"') &&
268
+ !value.includes('src') &&
269
+ !value.includes('href') &&
270
+ !value.includes('=')
271
+ )
272
+ return acc;
273
+ return acc + value;
274
+ }, '');
275
+ return combined;
276
+ }),
277
+ '',
278
+ ),
279
+ }}
280
+ />
281
+ </Grid.Column>
282
+ </Grid.Row>
283
+ )}
284
+ {view === 'unified' && (
285
+ <Grid.Row>
286
+ <Grid.Column width={16} verticalAlign="top">
287
+ <span
288
+ dangerouslySetInnerHTML={{
289
+ __html: join(
290
+ map(parts, (part) => {
291
+ let combined = (part.value || []).reduce((acc, value) => {
292
+ if (
293
+ part.removed &&
294
+ !value.includes('<') &&
295
+ !value.includes('>') &&
296
+ !value.includes('>') &&
297
+ !value.includes('</') &&
298
+ !value.includes('"') &&
299
+ !value.includes('src') &&
300
+ !value.includes('href') &&
301
+ !value.includes('=')
302
+ )
303
+ return acc + `<span class="deletion">${value}</span>`;
304
+
305
+ if (
306
+ part.added &&
307
+ !value.includes('<') &&
308
+ !value.includes('>') &&
309
+ !value.includes('>') &&
310
+ !value.includes('</') &&
311
+ !value.includes('"') &&
312
+ !value.includes('src') &&
313
+ !value.includes('href') &&
314
+ !value.includes('=')
315
+ )
316
+ return acc + `<span class="addition">${value}</span>`;
317
+
318
+ return acc + value;
319
+ }, '');
320
+ return combined;
321
+ }),
322
+ '',
323
+ ),
324
+ }}
325
+ />
326
+ </Grid.Column>
327
+ </Grid.Row>
328
+ )}
329
+ </Grid>
330
+ );
331
+ };
332
+
333
+ /**
334
+ * Property types.
335
+ * @property {Object} propTypes Property types.
336
+ * @static
337
+ */
338
+ DiffField.propTypes = {
339
+ one: PropTypes.any.isRequired,
340
+ two: PropTypes.any.isRequired,
341
+ contentOne: PropTypes.any,
342
+ contentTwo: PropTypes.any,
343
+ view: PropTypes.string.isRequired,
344
+ schema: PropTypes.shape({
345
+ widget: PropTypes.string,
346
+ type: PropTypes.string,
347
+ title: PropTypes.string,
348
+ }).isRequired,
349
+ };
350
+
351
+ export default injectLazyLibs('diffLib')(DiffField);
@@ -0,0 +1,154 @@
1
+ /*
2
+ * UniversalLink
3
+ * @module components/UniversalLink
4
+ * Removed noreferrer from rel attribute
5
+ */
6
+
7
+ import React from 'react';
8
+ import PropTypes from 'prop-types';
9
+ import { HashLink as Link } from 'react-router-hash-link';
10
+ import { useSelector } from 'react-redux';
11
+ import {
12
+ flattenToAppURL,
13
+ isInternalURL,
14
+ URLUtils,
15
+ } from '@plone/volto/helpers/Url/Url';
16
+
17
+ import config from '@plone/volto/registry';
18
+
19
+ const UniversalLink = ({
20
+ href,
21
+ item = null,
22
+ openLinkInNewTab,
23
+ download = false,
24
+ children,
25
+ className = null,
26
+ title = null,
27
+ ...props
28
+ }) => {
29
+ const token = useSelector((state) => state.userSession?.token);
30
+
31
+ let url = href;
32
+ if (!href && item) {
33
+ if (!item['@id']) {
34
+ // eslint-disable-next-line no-console
35
+ console.error(
36
+ 'Invalid item passed to UniversalLink',
37
+ item,
38
+ props,
39
+ children,
40
+ );
41
+ url = '#';
42
+ } else {
43
+ //case: generic item
44
+ url = flattenToAppURL(item['@id']);
45
+
46
+ //case: item like a Link
47
+ let remoteUrl = item.remoteUrl || item.getRemoteUrl;
48
+ if (!token && remoteUrl) {
49
+ url = remoteUrl;
50
+ }
51
+
52
+ //case: item of type 'File'
53
+ if (
54
+ !token &&
55
+ config.settings.downloadableObjects.includes(item['@type'])
56
+ ) {
57
+ url = `${url}/@@download/file`;
58
+ }
59
+
60
+ if (
61
+ !token &&
62
+ config.settings.viewableInBrowserObjects.includes(item['@type'])
63
+ ) {
64
+ url = `${url}/@@display-file/file`;
65
+ }
66
+ }
67
+ }
68
+
69
+ const isExternal = !isInternalURL(url);
70
+
71
+ const isDownload = (!isExternal && url.includes('@@download')) || download;
72
+ const isDisplayFile =
73
+ (!isExternal && url.includes('@@display-file')) || false;
74
+
75
+ const checkedURL = URLUtils.checkAndNormalizeUrl(url);
76
+
77
+ url = checkedURL.url;
78
+ let tag = (
79
+ <Link
80
+ to={flattenToAppURL(url)}
81
+ target={openLinkInNewTab ?? false ? '_blank' : null}
82
+ title={title}
83
+ className={className}
84
+ smooth={config.settings.hashLinkSmoothScroll}
85
+ {...props}
86
+ >
87
+ {children}
88
+ </Link>
89
+ );
90
+
91
+ if (isExternal) {
92
+ tag = (
93
+ <a
94
+ href={url}
95
+ title={title}
96
+ target={
97
+ !checkedURL.isMail &&
98
+ !checkedURL.isTelephone &&
99
+ !(openLinkInNewTab === false)
100
+ ? '_blank'
101
+ : null
102
+ }
103
+ rel="noopener"
104
+ className={className}
105
+ {...props}
106
+ >
107
+ {children}
108
+ </a>
109
+ );
110
+ } else if (isDownload) {
111
+ tag = (
112
+ <a
113
+ href={flattenToAppURL(url)}
114
+ download
115
+ title={title}
116
+ className={className}
117
+ {...props}
118
+ >
119
+ {children}
120
+ </a>
121
+ );
122
+ } else if (isDisplayFile) {
123
+ tag = (
124
+ <a
125
+ href={flattenToAppURL(url)}
126
+ title={title}
127
+ rel="noopener"
128
+ className={className}
129
+ {...props}
130
+ >
131
+ {children}
132
+ </a>
133
+ );
134
+ }
135
+ return tag;
136
+ };
137
+
138
+ UniversalLink.propTypes = {
139
+ href: PropTypes.string,
140
+ openLinkInNewTab: PropTypes.bool,
141
+ download: PropTypes.bool,
142
+ className: PropTypes.string,
143
+ title: PropTypes.string,
144
+ item: PropTypes.shape({
145
+ '@id': PropTypes.string.isRequired,
146
+ remoteUrl: PropTypes.string, //of plone @type 'Link'
147
+ }),
148
+ children: PropTypes.oneOfType([
149
+ PropTypes.arrayOf(PropTypes.node),
150
+ PropTypes.node,
151
+ ]),
152
+ };
153
+
154
+ export default UniversalLink;
@@ -0,0 +1,27 @@
1
+ //this should be deleted when upgraded to a volto version that supports App Extras exceptions
2
+ import React from 'react';
3
+ import { matchPath } from 'react-router';
4
+ import config from '@plone/volto/registry';
5
+
6
+ const AppExtras = (props) => {
7
+ const { settings } = config;
8
+ const { appExtras = [] } = settings;
9
+ const { pathname } = props;
10
+ const active = appExtras
11
+ .map((reg) => {
12
+ const excluded = matchPath(pathname, reg.exclude);
13
+ if (excluded) return null;
14
+ const match = matchPath(pathname, reg.match);
15
+ return match ? { reg, match } : null;
16
+ })
17
+ .filter((reg) => reg);
18
+
19
+ return active.map(({ reg: { component, props: extraProps }, match }, i) => {
20
+ const Insert = component;
21
+ return (
22
+ <Insert key={`appextra-${i}`} match={match} {...props} {...extraProps} />
23
+ );
24
+ });
25
+ };
26
+
27
+ export default AppExtras;
package/src/index.js CHANGED
@@ -29,6 +29,9 @@ import installSlate from './slate';
29
29
  import installReducers from './reducers';
30
30
  import installMiddlewares from './middleware';
31
31
 
32
+ import { nanoid } from '@plone/volto-slate/utils';
33
+ import { v4 as uuid } from 'uuid';
34
+
32
35
  import * as eea from './config';
33
36
  import React from 'react';
34
37
 
@@ -98,6 +101,7 @@ function tabVariationCustomization(tabs_block_variations, config) {
98
101
  };
99
102
  return schema;
100
103
  };
104
+
101
105
  const oldDefaultSchemaEnhancer = defaultVariation.schemaEnhancer;
102
106
  defaultVariation.schemaEnhancer = (props) => {
103
107
  const newSchema = oldDefaultSchemaEnhancer(props);
@@ -110,7 +114,6 @@ function tabVariationCustomization(tabs_block_variations, config) {
110
114
  ];
111
115
  return newSchema;
112
116
  };
113
-
114
117
  const oldHorizontalSchemaEnhancer = horizontalVariation.schemaEnhancer;
115
118
  horizontalVariation.schemaEnhancer = (props) => {
116
119
  const newSchema = oldHorizontalSchemaEnhancer(props);
@@ -139,6 +142,40 @@ const applyConfig = (config) => {
139
142
  if (config.settings?.serverConfig?.extractScripts) {
140
143
  config.settings.serverConfig.extractScripts.errorPages = true;
141
144
  }
145
+ // Set cloneData function for slate block, in order to change the uuids of fragments in the copy process
146
+ if (config.blocks?.blocksConfig?.slate) {
147
+ config.blocks.blocksConfig.slate.cloneData = (data) => {
148
+ const replaceAllUidsWithNewOnes = (value) => {
149
+ if (value?.children?.length > 0) {
150
+ const newChildren = value.children.map((childrenData) => {
151
+ if (childrenData?.data?.uid) {
152
+ return {
153
+ ...childrenData,
154
+ data: { ...childrenData.data, uid: nanoid(5) },
155
+ };
156
+ }
157
+ return childrenData;
158
+ });
159
+ return {
160
+ ...value,
161
+ children: newChildren,
162
+ };
163
+ }
164
+ return value;
165
+ };
166
+ return [
167
+ uuid(),
168
+ {
169
+ ...data,
170
+ value: [
171
+ ...(data?.value || []).map((value) =>
172
+ replaceAllUidsWithNewOnes(value),
173
+ ),
174
+ ],
175
+ },
176
+ ];
177
+ };
178
+ }
142
179
 
143
180
  // Disable tags on View
144
181
  config.settings.showTags = false;
package/src/index.test.js CHANGED
@@ -144,7 +144,7 @@ describe('applyConfig', () => {
144
144
  { match: '', component: 'MockedDraftBackground' },
145
145
  { match: '', component: 'MockedSubsiteClass' },
146
146
  { match: '', component: BaseTag },
147
- { match: '*', component: 'MockedRemoveSchema' },
147
+ { match: '*', exclude: '/**/diff', component: 'MockedRemoveSchema' },
148
148
  ]);
149
149
  expect(config.settings.available_colors).toEqual(eea.colors);
150
150
  expect(config.settings.hasLanguageDropdown).toBe(false);
@@ -303,7 +303,7 @@ describe('applyConfig', () => {
303
303
  { match: '', component: 'MockedDraftBackground' },
304
304
  { match: '', component: 'MockedSubsiteClass' },
305
305
  { match: '', component: BaseTag },
306
- { match: '*', component: 'MockedRemoveSchema' },
306
+ { match: '*', exclude: '/**/diff', component: 'MockedRemoveSchema' },
307
307
  ]);
308
308
  expect(config.settings.available_colors).toEqual(eea.colors);
309
309
  expect(config.settings.hasLanguageDropdown).toBe(false);
@@ -9,6 +9,7 @@ export default function applyConfig(config) {
9
9
  ...(config.settings.appExtras || []),
10
10
  {
11
11
  match: '*',
12
+ exclude: '/**/diff',
12
13
  component: RemoveSchema,
13
14
  },
14
15
  ];