@plone/volto 18.2.3 → 18.3.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.
Files changed (42) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/locales/ca/LC_MESSAGES/volto.po +47 -11
  3. package/locales/ca.json +1 -1
  4. package/locales/de/LC_MESSAGES/volto.po +47 -11
  5. package/locales/de.json +1 -1
  6. package/locales/en/LC_MESSAGES/volto.po +47 -11
  7. package/locales/en.json +1 -1
  8. package/locales/es/LC_MESSAGES/volto.po +47 -11
  9. package/locales/es.json +1 -1
  10. package/locales/eu/LC_MESSAGES/volto.po +47 -11
  11. package/locales/eu.json +1 -1
  12. package/locales/fi/LC_MESSAGES/volto.po +47 -11
  13. package/locales/fi.json +1 -1
  14. package/locales/fr/LC_MESSAGES/volto.po +47 -11
  15. package/locales/fr.json +1 -1
  16. package/locales/hi/LC_MESSAGES/volto.po +47 -11
  17. package/locales/hi.json +1 -1
  18. package/locales/it/LC_MESSAGES/volto.po +71 -35
  19. package/locales/it.json +1 -1
  20. package/locales/ja/LC_MESSAGES/volto.po +47 -11
  21. package/locales/ja.json +1 -1
  22. package/locales/nl/LC_MESSAGES/volto.po +47 -11
  23. package/locales/nl.json +1 -1
  24. package/locales/pt/LC_MESSAGES/volto.po +47 -11
  25. package/locales/pt.json +1 -1
  26. package/locales/pt_BR/LC_MESSAGES/volto.po +47 -11
  27. package/locales/pt_BR.json +1 -1
  28. package/locales/ro/LC_MESSAGES/volto.po +47 -11
  29. package/locales/ro.json +1 -1
  30. package/locales/volto.pot +48 -12
  31. package/locales/zh_CN/LC_MESSAGES/volto.po +47 -11
  32. package/locales/zh_CN.json +1 -1
  33. package/package.json +4 -4
  34. package/src/components/manage/Blocks/Container/EditBlockWrapper.jsx +4 -1
  35. package/src/components/manage/Contents/Contents.jsx +6 -354
  36. package/src/components/manage/Contents/ContentsDeleteModal.jsx +380 -0
  37. package/src/components/manage/Rules/Rules.jsx +7 -1
  38. package/src/components/theme/SlotRenderer/SlotRenderer.tsx +1 -1
  39. package/src/helpers/ScrollToTop/ScrollToTop.jsx +1 -0
  40. package/src/reducers/index.js +2 -0
  41. package/src/reducers/linkIntegrity/linkIntegrity.js +51 -0
  42. package/src/reducers/linkIntegrity/linkIntegrity.test.js +54 -0
@@ -11,7 +11,6 @@ import { createPortal } from 'react-dom';
11
11
  import { Link } from 'react-router-dom';
12
12
  import {
13
13
  Button,
14
- Confirm,
15
14
  Container as SemanticContainer,
16
15
  Divider,
17
16
  Dropdown,
@@ -33,7 +32,7 @@ import pull from 'lodash/pull';
33
32
  import move from 'lodash-move';
34
33
  import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
35
34
  import { asyncConnect } from '@plone/volto/helpers/AsyncConnect';
36
- import { flattenToAppURL, getBaseUrl } from '@plone/volto/helpers/Url/Url';
35
+ import { getBaseUrl } from '@plone/volto/helpers/Url/Url';
37
36
 
38
37
  import { searchContent } from '@plone/volto/actions/search/search';
39
38
  import {
@@ -41,7 +40,6 @@ import {
41
40
  orderContent,
42
41
  sortContent,
43
42
  updateColumnsContent,
44
- linkIntegrityCheck,
45
43
  getContent,
46
44
  } from '@plone/volto/actions/content/content';
47
45
  import {
@@ -63,6 +61,7 @@ import ContentsIndexHeader from '@plone/volto/components/manage/Contents/Content
63
61
  import ContentsItem from '@plone/volto/components/manage/Contents/ContentsItem';
64
62
  import { ContentsRenameModal } from '@plone/volto/components/manage/Contents';
65
63
  import ContentsUploadModal from '@plone/volto/components/manage/Contents/ContentsUploadModal';
64
+ import ContentsDeleteModal from '@plone/volto/components/manage/Contents/ContentsDeleteModal';
66
65
  import ContentsWorkflowModal from '@plone/volto/components/manage/Contents/ContentsWorkflowModal';
67
66
  import ContentsTagsModal from '@plone/volto/components/manage/Contents/ContentsTagsModal';
68
67
  import ContentsPropertiesModal from '@plone/volto/components/manage/Contents/ContentsPropertiesModal';
@@ -117,14 +116,6 @@ const messages = defineMessages({
117
116
  id: 'Delete',
118
117
  defaultMessage: 'Delete',
119
118
  },
120
- deleteConfirmSingleItem: {
121
- id: 'Delete this item?',
122
- defaultMessage: 'Delete this item?',
123
- },
124
- deleteConfirmMultipleItems: {
125
- id: 'Delete selected items?',
126
- defaultMessage: 'Delete selected items?',
127
- },
128
119
  deleteError: {
129
120
  id: 'The item could not be deleted.',
130
121
  defaultMessage: 'The item could not be deleted.',
@@ -298,7 +289,6 @@ class Contents extends Component {
298
289
  orderContent: PropTypes.func.isRequired,
299
290
  sortContent: PropTypes.func.isRequired,
300
291
  updateColumnsContent: PropTypes.func.isRequired,
301
- linkIntegrityCheck: PropTypes.func.isRequired,
302
292
  clipboardRequest: PropTypes.shape({
303
293
  loading: PropTypes.bool,
304
294
  loaded: PropTypes.bool,
@@ -397,7 +387,6 @@ class Contents extends Component {
397
387
  this.paste = this.paste.bind(this);
398
388
  this.fetchContents = this.fetchContents.bind(this);
399
389
  this.orderTimeout = null;
400
- this.deleteItemsToShowThreshold = 10;
401
390
 
402
391
  this.state = {
403
392
  selected: [],
@@ -408,10 +397,6 @@ class Contents extends Component {
408
397
  showProperties: false,
409
398
  showWorkflow: false,
410
399
  itemsToDelete: [],
411
- containedItemsToDelete: [],
412
- brokenReferences: 0,
413
- breaches: [],
414
- showAllItemsToDelete: true,
415
400
  items: this.props.items,
416
401
  filter: '',
417
402
  currentPage: 0,
@@ -427,7 +412,6 @@ class Contents extends Component {
427
412
  sort_on: this.props.sort?.on || 'getObjPositionInParent',
428
413
  sort_order: this.props.sort?.order || 'ascending',
429
414
  isClient: false,
430
- linkIntegrityBreakages: [],
431
415
  };
432
416
  this.filterTimeout = null;
433
417
  }
@@ -441,50 +425,6 @@ class Contents extends Component {
441
425
  this.fetchContents();
442
426
  this.setState({ isClient: true });
443
427
  }
444
- async componentDidUpdate(_, prevState) {
445
- if (
446
- this.state.itemsToDelete !== prevState.itemsToDelete &&
447
- this.state.itemsToDelete.length > 0
448
- ) {
449
- const linkintegrityInfo = await this.props.linkIntegrityCheck(
450
- map(this.state.itemsToDelete, (item) => this.getFieldById(item, 'UID')),
451
- );
452
- const containedItems = linkintegrityInfo
453
- .map((result) => result.items_total ?? 0)
454
- .reduce((acc, value) => acc + value, 0);
455
- const breaches = linkintegrityInfo.flatMap((result) =>
456
- result.breaches.map((source) => ({
457
- source: source,
458
- target: result,
459
- })),
460
- );
461
- const source_by_uid = breaches.reduce(
462
- (acc, value) => acc.set(value.source.uid, value.source),
463
- new Map(),
464
- );
465
- const by_source = breaches.reduce((acc, value) => {
466
- if (acc.get(value.source.uid) === undefined) {
467
- acc.set(value.source.uid, new Set());
468
- }
469
- acc.get(value.source.uid).add(value.target);
470
- return acc;
471
- }, new Map());
472
-
473
- this.setState({
474
- containedItemsToDelete: containedItems,
475
- brokenReferences: by_source.size,
476
- linksAndReferencesViewLink: linkintegrityInfo.length
477
- ? linkintegrityInfo[0]['@id'] + '/links-to-item'
478
- : null,
479
- breaches: Array.from(by_source, (entry) => ({
480
- source: source_by_uid.get(entry[0]),
481
- targets: Array.from(entry[1]),
482
- })),
483
- showAllItemsToDelete:
484
- this.state.itemsToDelete.length < this.deleteItemsToShowThreshold,
485
- });
486
- }
487
- }
488
428
 
489
429
  /**
490
430
  * Component will receive props
@@ -1209,298 +1149,12 @@ class Contents extends Component {
1209
1149
  />
1210
1150
  <div className="container">
1211
1151
  <article id="content">
1212
- <Confirm
1152
+ <ContentsDeleteModal
1213
1153
  open={this.state.showDelete}
1214
- confirmButton={
1215
- this.state.brokenReferences === 0
1216
- ? 'Delete'
1217
- : 'Delete item and break links'
1218
- }
1219
- header={
1220
- this.state.itemsToDelete.length === 1
1221
- ? this.props.intl.formatMessage(
1222
- messages.deleteConfirmSingleItem,
1223
- )
1224
- : this.props.intl.formatMessage(
1225
- messages.deleteConfirmMultipleItems,
1226
- )
1227
- }
1228
- content={
1229
- <div className="content">
1230
- {this.state.itemsToDelete.length > 1 ? (
1231
- this.state.containedItemsToDelete > 0 ? (
1232
- <>
1233
- <FormattedMessage
1234
- id="Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders."
1235
- defaultMessage="Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders."
1236
- values={{
1237
- containedItemsToDelete: (
1238
- <span>
1239
- {this.state.containedItemsToDelete}
1240
- </span>
1241
- ),
1242
- variation: (
1243
- <span>
1244
- {this.state.containedItemsToDelete ===
1245
- 1 ? (
1246
- <FormattedMessage
1247
- id="item"
1248
- defaultMessage="item"
1249
- />
1250
- ) : (
1251
- <FormattedMessage
1252
- id="items"
1253
- defaultMessage="items"
1254
- />
1255
- )}
1256
- </span>
1257
- ),
1258
- }}
1259
- />
1260
- {this.state.brokenReferences > 0 && (
1261
- <>
1262
- <br />
1263
- <FormattedMessage
1264
- id="Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken."
1265
- defaultMessage="Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken."
1266
- values={{
1267
- brokenReferences: (
1268
- <span>
1269
- {this.state.brokenReferences}
1270
- </span>
1271
- ),
1272
- variation: (
1273
- <span>
1274
- {this.state.brokenReferences === 1 ? (
1275
- <FormattedMessage
1276
- id="reference"
1277
- defaultMessage="reference"
1278
- />
1279
- ) : (
1280
- <FormattedMessage
1281
- id="references"
1282
- defaultMessage="references"
1283
- />
1284
- )}
1285
- </span>
1286
- ),
1287
- }}
1288
- />
1289
- </>
1290
- )}
1291
- </>
1292
- ) : (
1293
- <>
1294
- {this.state.brokenReferences > 0 && (
1295
- <>
1296
- <FormattedMessage
1297
- id="Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken."
1298
- defaultMessage="Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken."
1299
- values={{
1300
- brokenReferences: (
1301
- <span>
1302
- {this.state.brokenReferences}
1303
- </span>
1304
- ),
1305
- variation: (
1306
- <span>
1307
- {this.state.brokenReferences === 1 ? (
1308
- <FormattedMessage
1309
- id="reference"
1310
- defaultMessage="reference"
1311
- />
1312
- ) : (
1313
- <FormattedMessage
1314
- id="references"
1315
- defaultMessage="references"
1316
- />
1317
- )}
1318
- </span>
1319
- ),
1320
- }}
1321
- />
1322
- </>
1323
- )}
1324
- </>
1325
- )
1326
- ) : this.state.containedItemsToDelete > 0 ? (
1327
- <>
1328
- <FormattedMessage
1329
- id="This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder."
1330
- defaultMessage="This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder."
1331
- values={{
1332
- containedItemsToDelete: (
1333
- <span>
1334
- {this.state.containedItemsToDelete}
1335
- </span>
1336
- ),
1337
- variation: (
1338
- <span>
1339
- {this.state.containedItemsToDelete === 1 ? (
1340
- <FormattedMessage
1341
- id="item"
1342
- defaultMessage="item"
1343
- />
1344
- ) : (
1345
- <FormattedMessage
1346
- id="items"
1347
- defaultMessage="items"
1348
- />
1349
- )}
1350
- </span>
1351
- ),
1352
- }}
1353
- />
1354
- {this.state.brokenReferences > 0 && (
1355
- <>
1356
- <br />
1357
- <FormattedMessage
1358
- id="Deleting this item breaks {brokenReferences} {variation}."
1359
- defaultMessage="Deleting this item breaks {brokenReferences} {variation}."
1360
- values={{
1361
- brokenReferences: (
1362
- <span>{this.state.brokenReferences}</span>
1363
- ),
1364
- variation: (
1365
- <span>
1366
- {this.state.brokenReferences === 1 ? (
1367
- <FormattedMessage
1368
- id="reference"
1369
- defaultMessage="reference"
1370
- />
1371
- ) : (
1372
- <FormattedMessage
1373
- id="references"
1374
- defaultMessage="references"
1375
- />
1376
- )}
1377
- </span>
1378
- ),
1379
- }}
1380
- />
1381
- <div className="broken-links-list">
1382
- <FormattedMessage id="These items will have broken links" />
1383
- <ul>
1384
- {this.state.breaches.map((breach) => (
1385
- <li key={breach.source['@id']}>
1386
- <Link
1387
- to={flattenToAppURL(
1388
- breach.source['@id'],
1389
- )}
1390
- title="Navigate to this item"
1391
- >
1392
- {breach.source.title}
1393
- </Link>{' '}
1394
- refers to{' '}
1395
- {breach.targets
1396
- .map((target) => (
1397
- <Link
1398
- key={target['@id']}
1399
- to={flattenToAppURL(
1400
- target['@id'],
1401
- )}
1402
- title="Navigate to this item"
1403
- >
1404
- {target.title}
1405
- </Link>
1406
- ))
1407
- .reduce((result, item) => (
1408
- <>
1409
- {result}, {item}
1410
- </>
1411
- ))}
1412
- </li>
1413
- ))}
1414
- </ul>
1415
- {this.state.linksAndReferencesViewLink && (
1416
- <Link
1417
- to={flattenToAppURL(
1418
- this.state.linksAndReferencesViewLink,
1419
- )}
1420
- >
1421
- <FormattedMessage
1422
- id="View links and references to this item"
1423
- defaultMessage="View links and references to this item"
1424
- />
1425
- </Link>
1426
- )}
1427
- </div>
1428
- </>
1429
- )}
1430
- </>
1431
- ) : this.state.brokenReferences > 0 ? (
1432
- <>
1433
- <FormattedMessage
1434
- id="Deleting this item breaks {brokenReferences} {variation}."
1435
- defaultMessage="Deleting this item breaks {brokenReferences} {variation}."
1436
- values={{
1437
- brokenReferences: (
1438
- <span>{this.state.brokenReferences}</span>
1439
- ),
1440
- variation: (
1441
- <span>
1442
- {this.state.brokenReferences === 1 ? (
1443
- <FormattedMessage
1444
- id="reference"
1445
- defaultMessage="reference"
1446
- />
1447
- ) : (
1448
- <FormattedMessage id="references" />
1449
- )}
1450
- </span>
1451
- ),
1452
- }}
1453
- />
1454
- <div className="broken-links-list">
1455
- <FormattedMessage id="These items will have broken links" />
1456
- <ul>
1457
- {this.state.breaches.map((breach) => (
1458
- <li key={breach.source['@id']}>
1459
- <Link
1460
- to={flattenToAppURL(breach.source['@id'])}
1461
- title="Navigate to this item"
1462
- >
1463
- {breach.source.title}
1464
- </Link>{' '}
1465
- refers to{' '}
1466
- {breach.targets
1467
- .map((target) => (
1468
- <Link
1469
- key={target['@id']}
1470
- to={flattenToAppURL(target['@id'])}
1471
- title="Navigate to this item"
1472
- >
1473
- {target.title}
1474
- </Link>
1475
- ))
1476
- .reduce((result, item) => (
1477
- <>
1478
- {result}, {item}
1479
- </>
1480
- ))}
1481
- </li>
1482
- ))}
1483
- </ul>
1484
- {this.state.linksAndReferencesViewLink && (
1485
- <Link
1486
- to={flattenToAppURL(
1487
- this.state.linksAndReferencesViewLink,
1488
- )}
1489
- >
1490
- <FormattedMessage
1491
- id="View links and references to this item"
1492
- defaultMessage="View links and references to this item"
1493
- />
1494
- </Link>
1495
- )}
1496
- </div>
1497
- </>
1498
- ) : null}
1499
- </div>
1500
- }
1501
1154
  onCancel={this.onDeleteCancel}
1502
- onConfirm={this.onDeleteOk}
1503
- size="medium"
1155
+ onOk={this.onDeleteOk}
1156
+ items={this.state.items}
1157
+ itemsToDelete={this.state.itemsToDelete}
1504
1158
  />
1505
1159
  <ContentsUploadModal
1506
1160
  open={this.state.showUpload}
@@ -2252,7 +1906,6 @@ export const __test__ = compose(
2252
1906
  orderContent,
2253
1907
  sortContent,
2254
1908
  updateColumnsContent,
2255
- linkIntegrityCheck,
2256
1909
  getContent,
2257
1910
  },
2258
1911
  ),
@@ -2294,7 +1947,6 @@ export default compose(
2294
1947
  orderContent,
2295
1948
  sortContent,
2296
1949
  updateColumnsContent,
2297
- linkIntegrityCheck,
2298
1950
  getContent,
2299
1951
  },
2300
1952
  ),