@plone/volto 17.20.1 → 17.20.2

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