@plone/volto 15.1.0 → 15.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/docs.yml +6 -2
- package/CHANGELOG.md +32 -0
- package/addon-registry.js +20 -2
- package/dist/assets.json +1 -1
- package/dist/chunks.json +3 -3
- package/dist/loadable-stats.json +16 -16
- package/dist/public/static/css/{client.75e09347.chunk.css → client.596efd64.chunk.css} +1 -1
- package/dist/public/static/js/client.596efd64.chunk.js +2 -0
- package/dist/server.js +1 -1
- package/package.json +2 -1
- package/razzle.config.js +13 -7
- package/src/components/manage/Blocks/Listing/SummaryTemplate.jsx +1 -1
- package/src/components/manage/Controlpanels/VersionOverview.jsx +2 -2
- package/src/components/theme/PreviewImage/PreviewImage.jsx +2 -2
- package/src/components/theme/PreviewImage/PreviewImage.test.js +24 -0
- package/src/helpers/LanguageMap/LanguageMap.js +4 -0
- package/src/helpers/Utils/Utils.js +51 -0
- package/src/helpers/Utils/Utils.test.js +33 -2
- package/dist/public/static/js/client.75e09347.chunk.js +0 -2
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
}
|
|
10
10
|
],
|
|
11
11
|
"license": "MIT",
|
|
12
|
-
"version": "15.
|
|
12
|
+
"version": "15.2.0",
|
|
13
13
|
"repository": {
|
|
14
14
|
"type": "git",
|
|
15
15
|
"url": "git@github.com:plone/volto.git"
|
|
@@ -296,6 +296,7 @@
|
|
|
296
296
|
"cypress-axe": "0.12.2",
|
|
297
297
|
"cypress-file-upload": "5.0.7",
|
|
298
298
|
"debug": "4.3.2",
|
|
299
|
+
"deep-freeze": "0.0.1",
|
|
299
300
|
"dependency-graph": "0.10.0",
|
|
300
301
|
"detect-browser": "5.1.0",
|
|
301
302
|
"diff": "3.5.0",
|
package/razzle.config.js
CHANGED
|
@@ -5,6 +5,7 @@ const nodeExternals = require('webpack-node-externals');
|
|
|
5
5
|
const LoadablePlugin = require('@loadable/webpack-plugin');
|
|
6
6
|
const LodashModuleReplacementPlugin = require('lodash-webpack-plugin');
|
|
7
7
|
const fs = require('fs');
|
|
8
|
+
const { pickBy } = require('lodash');
|
|
8
9
|
const RootResolverPlugin = require('./webpack-plugins/webpack-root-resolver');
|
|
9
10
|
const RelativeResolverPlugin = require('./webpack-plugins/webpack-relative-resolver');
|
|
10
11
|
const createAddonsLoader = require('./create-addons-loader');
|
|
@@ -188,7 +189,7 @@ const defaultModify = ({
|
|
|
188
189
|
|
|
189
190
|
const addonsLoaderPath = createAddonsLoader(
|
|
190
191
|
registry.getAddonDependencies(),
|
|
191
|
-
registry.
|
|
192
|
+
registry.getAddons(),
|
|
192
193
|
);
|
|
193
194
|
|
|
194
195
|
config.resolve.plugins = [
|
|
@@ -230,15 +231,17 @@ const defaultModify = ({
|
|
|
230
231
|
if (packageJson.name !== '@plone/volto') {
|
|
231
232
|
include.push(fs.realpathSync(`${registry.voltoPath}/src`));
|
|
232
233
|
}
|
|
234
|
+
|
|
233
235
|
// Add babel support external (ie. node_modules npm published packages)
|
|
234
|
-
|
|
235
|
-
|
|
236
|
+
const packagesNames = Object.keys(registry.packages);
|
|
237
|
+
if (registry.packages && packagesNames.length > 0) {
|
|
238
|
+
packagesNames.forEach((addon) => {
|
|
236
239
|
const p = fs.realpathSync(registry.packages[addon].modulePath);
|
|
237
240
|
if (include.indexOf(p) === -1) {
|
|
238
241
|
include.push(p);
|
|
239
242
|
}
|
|
240
243
|
});
|
|
241
|
-
addonsAsExternals =
|
|
244
|
+
addonsAsExternals = packagesNames.map((addon) => new RegExp(addon));
|
|
242
245
|
}
|
|
243
246
|
|
|
244
247
|
if (process.env.ADDONS) {
|
|
@@ -250,9 +253,12 @@ const defaultModify = ({
|
|
|
250
253
|
if (include.indexOf(p) === -1) {
|
|
251
254
|
include.push(p);
|
|
252
255
|
}
|
|
253
|
-
addonsAsExternals =
|
|
254
|
-
|
|
255
|
-
|
|
256
|
+
addonsAsExternals = [
|
|
257
|
+
...addonsAsExternals,
|
|
258
|
+
...packagesNames.map(
|
|
259
|
+
(normalizedAddonName) => new RegExp(normalizedAddonName),
|
|
260
|
+
),
|
|
261
|
+
];
|
|
256
262
|
});
|
|
257
263
|
}
|
|
258
264
|
|
|
@@ -25,7 +25,7 @@ const SummaryTemplate = ({ items, linkTitle, linkHref, isEditMode }) => {
|
|
|
25
25
|
{items.map((item) => (
|
|
26
26
|
<div className="listing-item" key={item['@id']}>
|
|
27
27
|
<ConditionalLink item={item} condition={!isEditMode}>
|
|
28
|
-
<Component componentName="PreviewImage" item={item} />
|
|
28
|
+
<Component componentName="PreviewImage" item={item} alt="" />
|
|
29
29
|
<div className="listing-body">
|
|
30
30
|
<h3>{item.title ? item.title : item.id}</h3>
|
|
31
31
|
<p>{item.description}</p>
|
|
@@ -53,8 +53,8 @@ const VersionOverview = ({
|
|
|
53
53
|
<p>{intl.formatMessage(messages.no_addons)}</p>
|
|
54
54
|
) : (
|
|
55
55
|
<ul style={{ fontSize: '16px', fontFamily: 'Monospace' }}>
|
|
56
|
-
{
|
|
57
|
-
<li>{`${addon} ${
|
|
56
|
+
{addonsInfo.map((addon) => (
|
|
57
|
+
<li>{`${addon.name} ${addon.version || ''}`}</li>
|
|
58
58
|
))}
|
|
59
59
|
</ul>
|
|
60
60
|
)}
|
|
@@ -10,12 +10,12 @@ import DefaultImageSVG from '@plone/volto/components/manage/Blocks/Listing/defau
|
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
function PreviewImage(props) {
|
|
13
|
-
const { item, size = 'preview', ...rest } = props;
|
|
13
|
+
const { item, size = 'preview', alt, ...rest } = props;
|
|
14
14
|
const src = item.image_field
|
|
15
15
|
? flattenToAppURL(`${item['@id']}/@@images/${item.image_field}/${size}`)
|
|
16
16
|
: DefaultImageSVG;
|
|
17
17
|
|
|
18
|
-
return <img src={src} alt={item.title} {...rest} />;
|
|
18
|
+
return <img src={src} alt={alt ?? item.title} {...rest} />;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
PreviewImage.propTypes = {
|
|
@@ -62,4 +62,28 @@ describe('PreviewImage', () => {
|
|
|
62
62
|
const json = component.toJSON();
|
|
63
63
|
expect(json).toMatchSnapshot();
|
|
64
64
|
});
|
|
65
|
+
|
|
66
|
+
it('renders a fallback image with alt prop empty', () => {
|
|
67
|
+
const item = {
|
|
68
|
+
title: 'Item title',
|
|
69
|
+
'@id': 'http://localhost:3000/something',
|
|
70
|
+
};
|
|
71
|
+
const component = renderer.create(
|
|
72
|
+
<PreviewImage item={item} className="extra" alt="" />,
|
|
73
|
+
);
|
|
74
|
+
const json = component.toJSON();
|
|
75
|
+
expect(json).toMatchSnapshot();
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('renders a fallback image with alt prop', () => {
|
|
79
|
+
const item = {
|
|
80
|
+
title: 'Item title',
|
|
81
|
+
'@id': 'http://localhost:3000/something',
|
|
82
|
+
};
|
|
83
|
+
const component = renderer.create(
|
|
84
|
+
<PreviewImage item={item} className="extra" alt="Alt prop" />,
|
|
85
|
+
);
|
|
86
|
+
const json = component.toJSON();
|
|
87
|
+
expect(json).toMatchSnapshot();
|
|
88
|
+
});
|
|
65
89
|
});
|
|
@@ -109,6 +109,7 @@ const safeColors = [
|
|
|
109
109
|
'Teal',
|
|
110
110
|
];
|
|
111
111
|
const namedColors = {};
|
|
112
|
+
|
|
112
113
|
/**
|
|
113
114
|
* Will generate initials from string
|
|
114
115
|
* @param {string} name
|
|
@@ -198,3 +199,53 @@ export const hasApiExpander = (expander, path = '', type = 'GET_CONTENT') => {
|
|
|
198
199
|
.map((expand) => expand[type]),
|
|
199
200
|
).includes(expander);
|
|
200
201
|
};
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Insert element into array at a give index
|
|
205
|
+
* @param {Array} array Array with data
|
|
206
|
+
* @param {*} element Element to be inserted
|
|
207
|
+
* @param {number} index Index of item to be inserted at
|
|
208
|
+
* @returns {Array} Array with inserted element
|
|
209
|
+
*/
|
|
210
|
+
export const insertInArray = (array, element, index) => [
|
|
211
|
+
...array.slice(0, index),
|
|
212
|
+
element,
|
|
213
|
+
...array.slice(index),
|
|
214
|
+
];
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Replace element in array at a give index
|
|
218
|
+
* @param {Array} array Array with data
|
|
219
|
+
* @param {*} element Element to be replaced
|
|
220
|
+
* @param {number} index Index of item to be replaced at
|
|
221
|
+
* @returns {Array} Array with replaced element
|
|
222
|
+
*/
|
|
223
|
+
export const replaceItemOfArray = (array, index, value) =>
|
|
224
|
+
Object.assign([...array], { [index]: value });
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Remove item from array at given index
|
|
228
|
+
* @param {Array} array Array with data
|
|
229
|
+
* @param {number} index Index of item to be removed
|
|
230
|
+
* @returns {Array} Array without deleted element
|
|
231
|
+
*/
|
|
232
|
+
export const removeFromArray = (array, index) => {
|
|
233
|
+
let newArray = array.slice();
|
|
234
|
+
newArray.splice(index, 1);
|
|
235
|
+
return newArray;
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Reorder array
|
|
240
|
+
* @param {Array} array Array with data
|
|
241
|
+
* @param {number} origin Index of item to be reordered
|
|
242
|
+
* @param {number} target Index of item to be reordered to
|
|
243
|
+
* @returns {Array} Array with reordered elements
|
|
244
|
+
*/
|
|
245
|
+
export const reorderArray = (array, origin, target) => {
|
|
246
|
+
const result = Array.from(array);
|
|
247
|
+
const [removed] = result.splice(origin, 1);
|
|
248
|
+
result.splice(target, 0, removed);
|
|
249
|
+
|
|
250
|
+
return result;
|
|
251
|
+
};
|
|
@@ -4,12 +4,16 @@ import {
|
|
|
4
4
|
difference,
|
|
5
5
|
getColor,
|
|
6
6
|
getInitials,
|
|
7
|
-
safeWrapper,
|
|
8
|
-
normalizeLanguageName,
|
|
9
7
|
hasApiExpander,
|
|
8
|
+
normalizeLanguageName,
|
|
10
9
|
parseDateTime,
|
|
10
|
+
removeFromArray,
|
|
11
|
+
reorderArray,
|
|
12
|
+
replaceItemOfArray,
|
|
13
|
+
safeWrapper,
|
|
11
14
|
} from './Utils';
|
|
12
15
|
import moment from 'moment';
|
|
16
|
+
import deepFreeze from 'deep-freeze';
|
|
13
17
|
|
|
14
18
|
describe('Utils tests', () => {
|
|
15
19
|
describe('difference', () => {
|
|
@@ -345,4 +349,31 @@ describe('Utils tests', () => {
|
|
|
345
349
|
).toBe(`${isoDate}Z`);
|
|
346
350
|
});
|
|
347
351
|
});
|
|
352
|
+
|
|
353
|
+
describe('replaceItemOfArray', () => {
|
|
354
|
+
it('replaces the position of an element into an array immutable-ish', () => {
|
|
355
|
+
const array = ['a', 'b', 'c'];
|
|
356
|
+
deepFreeze(array);
|
|
357
|
+
const result = replaceItemOfArray(array, 2, 'v');
|
|
358
|
+
expect(result).toEqual(['a', 'b', 'v']);
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
describe('removeFromArray', () => {
|
|
363
|
+
it('removes an element from the array immutable-ish', () => {
|
|
364
|
+
const array = ['a', 'b', 'c'];
|
|
365
|
+
deepFreeze(array);
|
|
366
|
+
const result = removeFromArray(array, 2);
|
|
367
|
+
expect(result).toEqual(['a', 'b']);
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
describe('reorderArray', () => {
|
|
372
|
+
it('reorders an array immutable-ish', () => {
|
|
373
|
+
const array = ['a', 'b', 'c'];
|
|
374
|
+
deepFreeze(array);
|
|
375
|
+
const result = reorderArray(array, 2, 0);
|
|
376
|
+
expect(result).toEqual(['c', 'a', 'b']);
|
|
377
|
+
});
|
|
378
|
+
});
|
|
348
379
|
});
|