@plone/volto 17.0.0-alpha.20 → 17.0.0-alpha.22

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 (108) hide show
  1. package/.gitignore~ +71 -0
  2. package/.yarn/install-state.gz +0 -0
  3. package/CHANGELOG.md +49 -0
  4. package/cypress/support/commands.js +2 -1
  5. package/cypress/support/e2e.js +1 -2
  6. package/locales/ca/LC_MESSAGES/volto.po +24 -5
  7. package/locales/ca.json +1 -1
  8. package/locales/de/LC_MESSAGES/volto.po +37 -18
  9. package/locales/de.json +1 -1
  10. package/locales/en/LC_MESSAGES/volto.po +25 -6
  11. package/locales/en.json +1 -1
  12. package/locales/es/LC_MESSAGES/volto.po +25 -6
  13. package/locales/es.json +1 -1
  14. package/locales/eu/LC_MESSAGES/volto.po +24 -5
  15. package/locales/eu.json +1 -1
  16. package/locales/fi/LC_MESSAGES/volto.po +24 -5
  17. package/locales/fi.json +1 -1
  18. package/locales/fr/LC_MESSAGES/volto.po +24 -5
  19. package/locales/fr.json +1 -1
  20. package/locales/it/LC_MESSAGES/volto.po +250 -231
  21. package/locales/it.json +1 -1
  22. package/locales/ja/LC_MESSAGES/volto.po +24 -5
  23. package/locales/ja.json +1 -1
  24. package/locales/nl/LC_MESSAGES/volto.po +24 -5
  25. package/locales/nl.json +1 -1
  26. package/locales/pt/LC_MESSAGES/volto.po +24 -5
  27. package/locales/pt.json +1 -1
  28. package/locales/pt_BR/LC_MESSAGES/volto.po +25 -6
  29. package/locales/pt_BR.json +1 -1
  30. package/locales/ro/LC_MESSAGES/volto.po +24 -5
  31. package/locales/ro.json +1 -1
  32. package/locales/volto.pot +25 -6
  33. package/locales/zh_CN/LC_MESSAGES/volto.po +24 -5
  34. package/locales/zh_CN.json +1 -1
  35. package/news/4547.breaking~ +1 -0
  36. package/package.json +6 -6
  37. package/packages/volto-slate/package.json +1 -1
  38. package/src/actions/relations/rebuild.js +7 -7
  39. package/src/components/index.js +1 -0
  40. package/src/components/manage/Actions/Actions.jsx +133 -243
  41. package/src/components/manage/Blocks/Container/Edit.jsx +4 -1
  42. package/src/components/manage/Blocks/Container/EditBlockWrapper.jsx +1 -0
  43. package/src/components/manage/Blocks/Grid/Edit.jsx +13 -1
  44. package/src/components/manage/Blocks/Image/Edit.jsx +40 -5
  45. package/src/components/manage/Blocks/Image/Edit.test.jsx +2 -0
  46. package/src/components/manage/Blocks/Image/ImageSidebar.jsx +64 -15
  47. package/src/components/manage/Blocks/Image/View.jsx +26 -5
  48. package/src/components/manage/Blocks/Image/View.test.jsx +20 -0
  49. package/src/components/manage/Blocks/Image/schema.js +1 -9
  50. package/src/components/manage/Blocks/Image/utils.js +14 -0
  51. package/src/components/manage/Blocks/LeadImage/Edit.jsx +32 -10
  52. package/src/components/manage/Blocks/LeadImage/Edit.test.jsx +11 -1
  53. package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.jsx +28 -9
  54. package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.test.jsx +8 -2
  55. package/src/components/manage/Blocks/LeadImage/View.jsx +50 -38
  56. package/src/components/manage/Blocks/LeadImage/View.test.jsx +11 -1
  57. package/src/components/manage/Blocks/Listing/SummaryTemplate.jsx +1 -1
  58. package/src/components/manage/Blocks/Maps/Edit.jsx +135 -209
  59. package/src/components/manage/Blocks/Search/SearchBlockView.jsx +3 -2
  60. package/src/components/manage/Blocks/Teaser/DefaultBody.jsx +13 -23
  61. package/src/components/manage/Contents/Contents.jsx +8 -6
  62. package/src/components/manage/Contents/ContentsPropertiesModal.jsx +1 -13
  63. package/src/components/manage/Controlpanels/Groups/RenderGroups.jsx +2 -2
  64. package/src/components/manage/Controlpanels/Relations/BrokenRelations.jsx +30 -7
  65. package/src/components/manage/Controlpanels/Relations/Relations.jsx +2 -2
  66. package/src/components/manage/Controlpanels/Relations/RelationsMatrix.jsx +53 -59
  67. package/src/components/manage/Controlpanels/Users/RenderUsers.jsx +2 -2
  68. package/src/components/manage/Delete/Delete.jsx +96 -171
  69. package/src/components/manage/Sidebar/AlignBlock.jsx +1 -1
  70. package/src/components/manage/Widgets/SelectUtils.js +1 -1
  71. package/src/components/manage/Workflow/Workflow.jsx +75 -184
  72. package/src/components/theme/Image/Image.jsx +96 -0
  73. package/src/components/theme/Image/Image.test.jsx +125 -0
  74. package/src/components/theme/Logo/Logo.jsx +2 -0
  75. package/src/components/theme/PasswordReset/RequestPasswordReset.jsx +95 -170
  76. package/src/components/theme/PreviewImage/PreviewImage.jsx +25 -14
  77. package/src/components/theme/PreviewImage/PreviewImage.test.js +39 -16
  78. package/src/components/theme/View/AlbumView.jsx +11 -15
  79. package/src/components/theme/View/EventView.jsx +30 -23
  80. package/src/components/theme/View/ImageView.jsx +5 -2
  81. package/src/components/theme/View/ImageView.test.jsx +4 -0
  82. package/src/components/theme/View/ListingView.jsx +5 -3
  83. package/src/components/theme/View/NewsItemView.jsx +7 -13
  84. package/src/components/theme/View/SummaryView.jsx +4 -3
  85. package/src/config/Blocks.jsx +2 -0
  86. package/src/config/Components.jsx +3 -1
  87. package/src/config/index.js~ +223 -0
  88. package/src/express-middleware/files.js +8 -6
  89. package/src/express-middleware/images.js +7 -1
  90. package/src/helpers/MessageLabels/MessageLabels.js +6 -0
  91. package/src/helpers/Url/Url.js +22 -1
  92. package/src/helpers/Url/Url.test.js +41 -0
  93. package/src/reducers/relations/relations.js +1 -1
  94. package/test-setup-config.js +9 -1
  95. package/theme/themes/pastanaga/extras/blocks.less +3 -1
  96. package/theme/themes/pastanaga/extras/main.less +5 -0
  97. package/packages/volto-slate/build/messages/src/blocks/Table/TableBlockEdit.json +0 -90
  98. package/packages/volto-slate/build/messages/src/blocks/Text/DefaultTextBlockEditor.json +0 -6
  99. package/packages/volto-slate/build/messages/src/blocks/Text/DetachedTextBlockEditor.json +0 -6
  100. package/packages/volto-slate/build/messages/src/blocks/Text/SlashMenu.json +0 -6
  101. package/packages/volto-slate/build/messages/src/editor/plugins/AdvancedLink/index.json +0 -10
  102. package/packages/volto-slate/build/messages/src/editor/plugins/Link/index.json +0 -10
  103. package/packages/volto-slate/build/messages/src/editor/plugins/Table/index.json +0 -30
  104. package/packages/volto-slate/build/messages/src/elementEditor/messages.json +0 -10
  105. package/packages/volto-slate/build/messages/src/widgets/HtmlSlateWidget.json +0 -6
  106. package/packages/volto-slate/build/messages/src/widgets/RichTextWidgetView.json +0 -6
  107. package/src/components/manage/Blocks/Teaser/utils.js +0 -44
  108. package/src/components/manage/Blocks/Teaser/utils.test.jsx +0 -229
@@ -452,68 +452,62 @@ const RelationsMatrix = (props) => {
452
452
  menuItem: intl.formatMessage(messages.fixRelations),
453
453
  pane: (
454
454
  <Tab.Pane attached={true} key="rebuild">
455
- {brokenRelations && Object.keys(brokenRelations).length > 0 ? (
456
- <div>
457
- {can_fix_relations ? (
458
- <React.Fragment>
459
- <Divider hidden />
460
- <h2>
461
- {capitalize(intl.formatMessage(messages.rebuildRelations))}
462
- </h2>
455
+ <div>
456
+ {!(brokenRelations && Object.keys(brokenRelations).length > 0) && (
457
+ <div>
458
+ <FormattedMessage
459
+ id="No broken relations found."
460
+ defaultMessage="No broken relations found."
461
+ />
462
+ </div>
463
+ )}
464
+ {can_fix_relations ? (
465
+ <React.Fragment>
466
+ <Divider hidden />
467
+ <h2>
468
+ {capitalize(intl.formatMessage(messages.rebuildRelations))}
469
+ </h2>
463
470
 
464
- <Button.Group>
465
- <Button
466
- primary
467
- onClick={() => rebuildRelationsHandler(false)}
468
- content={intl.formatMessage(messages.rebuildRelations)}
469
- aria-label={intl.formatMessage(messages.rebuildRelations)}
470
- />
471
- </Button.Group>
471
+ <Button.Group>
472
+ <Button
473
+ primary
474
+ onClick={() => rebuildRelationsHandler(false)}
475
+ content={intl.formatMessage(messages.rebuildRelations)}
476
+ aria-label={intl.formatMessage(messages.rebuildRelations)}
477
+ />
478
+ </Button.Group>
472
479
 
473
- <Divider hidden />
474
- <h2>
475
- {capitalize(
476
- intl.formatMessage(messages.flushAndRebuildRelations),
480
+ <Divider hidden />
481
+ <h2>
482
+ {capitalize(
483
+ intl.formatMessage(messages.flushAndRebuildRelations),
484
+ )}
485
+ </h2>
486
+ <div
487
+ dangerouslySetInnerHTML={{
488
+ __html: intl.formatMessage(
489
+ messages.flushAndRebuildRelationsHints,
490
+ ),
491
+ }}
492
+ />
493
+ <Divider hidden />
494
+ <Button.Group>
495
+ <Button
496
+ secondary
497
+ color="red"
498
+ onClick={() => rebuildRelationsHandler(true)}
499
+ content={intl.formatMessage(
500
+ messages.flushAndRebuildRelations,
477
501
  )}
478
- </h2>
479
- <ul>
480
- <li>
481
- Regenerate intIds (tokens of relations in relation
482
- catalog)
483
- </li>
484
- <li>Rebuild relations</li>
485
- </ul>
486
- <p>Check the log for details!</p>
487
- <p>
488
- <b>Warning</b>: If you have add-ons relying on intIds, you
489
- should not flush them.
490
- </p>
491
- <Divider hidden />
492
- <Button.Group>
493
- <Button
494
- secondary
495
- color="red"
496
- onClick={() => rebuildRelationsHandler(true)}
497
- content={intl.formatMessage(
498
- messages.flushAndRebuildRelations,
499
- )}
500
- aria-label={intl.formatMessage(
501
- messages.flushAndRebuildRelations,
502
- )}
503
- />
504
- </Button.Group>
505
- </React.Fragment>
506
- ) : null}
507
- <BrokenRelations />
508
- </div>
509
- ) : (
510
- <div>
511
- <FormattedMessage
512
- id="No broken relations found."
513
- defaultMessage="No broken relations found."
514
- />
515
- </div>
516
- )}
502
+ aria-label={intl.formatMessage(
503
+ messages.flushAndRebuildRelations,
504
+ )}
505
+ />
506
+ </Button.Group>
507
+ </React.Fragment>
508
+ ) : null}
509
+ <BrokenRelations />
510
+ </div>
517
511
  </Tab.Pane>
518
512
  ),
519
513
  },
@@ -53,7 +53,7 @@ class RenderUsers extends Component {
53
53
  */
54
54
 
55
55
  onChange(event, { value }) {
56
- const [user, role] = value.split('.');
56
+ const [user, role] = value.split('&role=');
57
57
  this.props.updateUser(user, role);
58
58
  }
59
59
  /**
@@ -83,7 +83,7 @@ class RenderUsers extends Component {
83
83
  <Checkbox
84
84
  checked={this.props.user.roles.includes(role.id)}
85
85
  onChange={this.onChange}
86
- value={`${this.props.user.id}.${role.id}`}
86
+ value={`${this.props.user.id}&role=${role.id}`}
87
87
  />
88
88
  )}
89
89
  </Table.Cell>
@@ -1,21 +1,14 @@
1
- /**
2
- * Delete container.
3
- * @module components/manage/Delete/Delete
4
- */
5
-
6
- import React, { Component } from 'react';
7
- import PropTypes from 'prop-types';
8
- import { Helmet } from '@plone/volto/helpers';
9
- import { connect } from 'react-redux';
10
- import { compose } from 'redux';
11
- import { withRouter } from 'react-router-dom';
1
+ import { useEffect, useState } from 'react';
2
+ import { useDispatch, useSelector, shallowEqual } from 'react-redux';
3
+ import { useHistory, useLocation } from 'react-router-dom';
12
4
  import { Portal } from 'react-portal';
13
5
  import { Button, Container, List, Segment } from 'semantic-ui-react';
14
- import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
6
+ import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
15
7
  import qs from 'query-string';
16
8
 
17
- import { deleteContent, getContent } from '@plone/volto/actions';
18
9
  import { Toolbar } from '@plone/volto/components';
10
+ import { Helmet, usePrevious } from '@plone/volto/helpers';
11
+ import { deleteContent, getContent } from '@plone/volto/actions';
19
12
 
20
13
  const messages = defineMessages({
21
14
  delete: {
@@ -32,172 +25,104 @@ const messages = defineMessages({
32
25
  },
33
26
  });
34
27
 
35
- /**
36
- * Delete container class.
37
- * @class Delete
38
- * @extends Component
39
- */
40
- class Delete extends Component {
41
- /**
42
- * Property types.
43
- * @property {Object} propTypes Property types.
44
- * @static
45
- */
46
- static propTypes = {
47
- deleteContent: PropTypes.func.isRequired,
48
- getContent: PropTypes.func.isRequired,
49
- deleteRequest: PropTypes.shape({
50
- loading: PropTypes.bool,
51
- loaded: PropTypes.bool,
52
- }).isRequired,
53
- pathname: PropTypes.string.isRequired,
54
- content: PropTypes.shape({
55
- title: PropTypes.string,
56
- }),
57
- returnUrl: PropTypes.string,
58
- };
28
+ const Delete = () => {
29
+ const dispatch = useDispatch();
30
+ const intl = useIntl();
31
+ const [isClient, setisClient] = useState(false);
32
+ const { pathname, search } = useLocation();
33
+ const history = useHistory();
34
+ const deleteRequest = useSelector((state) => state.content?.delete);
35
+ const content = useSelector((state) => state.content?.data, shallowEqual);
59
36
 
60
- /**
61
- * Default properties
62
- * @property {Object} defaultProps Default properties.
63
- * @static
64
- */
65
- static defaultProps = {
66
- content: null,
67
- returnUrl: null,
68
- };
37
+ const prevdeleteRequestLoading = usePrevious(deleteRequest.loading);
38
+ const returnUrl = qs.parse(search).return_url;
69
39
 
70
- /**
71
- * Constructor
72
- * @method constructor
73
- * @param {Object} props Component properties
74
- * @constructs WysiwygEditor
75
- */
76
- constructor(props) {
77
- super(props);
78
- this.onCancel = this.onCancel.bind(this);
79
- this.onSubmit = this.onSubmit.bind(this);
80
- this.state = { isClient: false };
81
- }
40
+ useEffect(() => {
41
+ setisClient(true);
42
+ }, []);
43
+
44
+ useEffect(() => {
45
+ dispatch(getContent(pathname.split('/delete')[0]));
46
+ }, [dispatch, pathname]);
82
47
 
83
- /**
84
- * Component will receive props
85
- * @method componentWillReceiveProps
86
- * @param {Object} nextProps Next properties
87
- * @returns {undefined}
88
- */
89
- UNSAFE_componentWillReceiveProps(nextProps) {
90
- if (this.props.deleteRequest.loading && nextProps.deleteRequest.loaded) {
91
- this.props.history.push(
92
- this.props.returnUrl ||
93
- this.props.pathname.replace('/delete', '').replace(/\/[^/]*$/, ''),
48
+ useEffect(() => {
49
+ if (prevdeleteRequestLoading && deleteRequest.loaded) {
50
+ history.push(
51
+ returnUrl || pathname.replace('/delete', '').replace(/\/[^/]*$/, ''),
94
52
  );
95
53
  }
96
- }
97
-
98
- /**
99
- * Component did mount
100
- * @method componentDidMount
101
- * @returns {undefined}
102
- */
103
- componentDidMount() {
104
- this.props.getContent(this.props.pathname.split('/delete')[0]);
105
- this.setState({ isClient: true });
106
- }
54
+ }, [
55
+ history,
56
+ pathname,
57
+ returnUrl,
58
+ prevdeleteRequestLoading,
59
+ deleteRequest.loaded,
60
+ ]);
107
61
 
108
- /**
109
- * Submit handler
110
- * @method onSubmit
111
- * @returns {undefined}
112
- */
113
- onSubmit() {
114
- this.props.deleteContent(this.props.pathname.replace('/delete', ''));
115
- }
62
+ const onSubmit = () => {
63
+ dispatch(deleteContent(pathname.replace('/delete', '')));
64
+ };
116
65
 
117
- /**
118
- * Cancel handler
119
- * @method onCancel
120
- * @returns {undefined}
121
- */
122
- onCancel() {
123
- this.props.history.push(this.props.pathname.replace('/delete', ''));
124
- }
66
+ const onCancel = () => {
67
+ history.push(pathname.replace('/delete', ''));
68
+ };
125
69
 
126
- /**
127
- * Render method.
128
- * @method render
129
- * @returns {string} Markup for the component.
130
- */
131
- render() {
132
- if (this.props.content) {
133
- return (
134
- <div id="page-delete">
135
- <Helmet title={this.props.intl.formatMessage(messages.delete)} />
136
- <Container>
137
- <Segment.Group raised>
138
- <Segment className="primary">
139
- <FormattedMessage
140
- id="Do you really want to delete this item?"
141
- defaultMessage="Do you really want to delete this item?"
142
- />
143
- </Segment>
144
- <Segment attached>
145
- <List bulleted>
146
- <List.Item>{this.props.content.title}</List.Item>
147
- </List>
148
- </Segment>
149
- <Segment className="actions" clearing>
150
- <Button
151
- basic
152
- circular
153
- primary
154
- floated="right"
155
- icon="arrow right"
156
- aria-label={this.props.intl.formatMessage(messages.ok)}
157
- title={this.props.intl.formatMessage(messages.ok)}
158
- size="big"
159
- onClick={this.onSubmit}
160
- />
161
- <Button
162
- basic
163
- circular
164
- secondary
165
- icon="remove"
166
- aria-label={this.props.intl.formatMessage(messages.cancel)}
167
- title={this.props.intl.formatMessage(messages.cancel)}
168
- floated="right"
169
- size="big"
170
- onClick={this.onCancel}
171
- />
172
- </Segment>
173
- </Segment.Group>
174
- </Container>
175
- {this.state.isClient && (
176
- <Portal node={document.getElementById('toolbar')}>
177
- <Toolbar
178
- pathname={this.props.pathname}
179
- hideDefaultViewButtons
180
- inner={<span />}
70
+ if (content) {
71
+ return (
72
+ <div id="page-delete">
73
+ <Helmet title={intl.formatMessage(messages.delete)} />
74
+ <Container>
75
+ <Segment.Group raised>
76
+ <Segment className="primary">
77
+ <FormattedMessage
78
+ id="Do you really want to delete this item?"
79
+ defaultMessage="Do you really want to delete this item?"
181
80
  />
182
- </Portal>
183
- )}
184
- </div>
185
- );
186
- }
187
- return <div />;
81
+ </Segment>
82
+ <Segment attached>
83
+ <List bulleted>
84
+ <List.Item>{content.title}</List.Item>
85
+ </List>
86
+ </Segment>
87
+ <Segment className="actions" clearing>
88
+ <Button
89
+ basic
90
+ circular
91
+ primary
92
+ floated="right"
93
+ icon="arrow right"
94
+ aria-label={intl.formatMessage(messages.ok)}
95
+ title={intl.formatMessage(messages.ok)}
96
+ size="big"
97
+ onClick={onSubmit}
98
+ />
99
+ <Button
100
+ basic
101
+ circular
102
+ secondary
103
+ icon="remove"
104
+ aria-label={intl.formatMessage(messages.cancel)}
105
+ title={intl.formatMessage(messages.cancel)}
106
+ floated="right"
107
+ size="big"
108
+ onClick={onCancel}
109
+ />
110
+ </Segment>
111
+ </Segment.Group>
112
+ </Container>
113
+ {isClient && (
114
+ <Portal node={document.getElementById('toolbar')}>
115
+ <Toolbar
116
+ pathname={pathname}
117
+ hideDefaultViewButtons
118
+ inner={<span />}
119
+ />
120
+ </Portal>
121
+ )}
122
+ </div>
123
+ );
188
124
  }
189
- }
125
+ return <div />;
126
+ };
190
127
 
191
- export default compose(
192
- withRouter,
193
- injectIntl,
194
- connect(
195
- (state, props) => ({
196
- content: state.content.data,
197
- deleteRequest: state.content.delete,
198
- pathname: props.location.pathname,
199
- returnUrl: qs.parse(props.location.search).return_url,
200
- }),
201
- { deleteContent, getContent },
202
- ),
203
- )(Delete);
128
+ export default Delete;
@@ -57,7 +57,7 @@ const AlignBlock = ({
57
57
  return (
58
58
  <div className="align-buttons">
59
59
  {actions.map((action) => (
60
- <Button.Group>
60
+ <Button.Group key={action}>
61
61
  <Button
62
62
  icon
63
63
  basic
@@ -111,7 +111,7 @@ export function normalizeValue(choices, value, intl) {
111
111
 
112
112
  if (Array.isArray(value)) {
113
113
  // a list of values, like ['foo', 'bar'];
114
- return value.map((v) => normalizeValue(choices, v));
114
+ return value.map((v) => normalizeValue(choices, v, intl));
115
115
  }
116
116
 
117
117
  if (isObject(value)) {