@plone/volto 17.0.0-alpha.21 → 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 (70) hide show
  1. package/.gitignore~ +71 -0
  2. package/.yarn/install-state.gz +0 -0
  3. package/CHANGELOG.md +30 -0
  4. package/locales/ca/LC_MESSAGES/volto.po +14 -4
  5. package/locales/ca.json +1 -1
  6. package/locales/de/LC_MESSAGES/volto.po +27 -17
  7. package/locales/de.json +1 -1
  8. package/locales/en/LC_MESSAGES/volto.po +15 -5
  9. package/locales/en.json +1 -1
  10. package/locales/es/LC_MESSAGES/volto.po +15 -5
  11. package/locales/es.json +1 -1
  12. package/locales/eu/LC_MESSAGES/volto.po +14 -4
  13. package/locales/eu.json +1 -1
  14. package/locales/fi/LC_MESSAGES/volto.po +14 -4
  15. package/locales/fi.json +1 -1
  16. package/locales/fr/LC_MESSAGES/volto.po +14 -4
  17. package/locales/fr.json +1 -1
  18. package/locales/it/LC_MESSAGES/volto.po +239 -229
  19. package/locales/it.json +1 -1
  20. package/locales/ja/LC_MESSAGES/volto.po +14 -4
  21. package/locales/ja.json +1 -1
  22. package/locales/nl/LC_MESSAGES/volto.po +14 -4
  23. package/locales/nl.json +1 -1
  24. package/locales/pt/LC_MESSAGES/volto.po +14 -4
  25. package/locales/pt.json +1 -1
  26. package/locales/pt_BR/LC_MESSAGES/volto.po +15 -5
  27. package/locales/pt_BR.json +1 -1
  28. package/locales/ro/LC_MESSAGES/volto.po +14 -4
  29. package/locales/ro.json +1 -1
  30. package/locales/volto.pot +15 -5
  31. package/locales/zh_CN/LC_MESSAGES/volto.po +14 -4
  32. package/locales/zh_CN.json +1 -1
  33. package/news/4547.breaking~ +1 -0
  34. package/package.json +3 -3
  35. package/packages/volto-slate/package.json +1 -1
  36. package/src/actions/relations/rebuild.js +7 -7
  37. package/src/components/manage/Actions/Actions.jsx +133 -243
  38. package/src/components/manage/Blocks/Container/Edit.jsx +4 -1
  39. package/src/components/manage/Blocks/Container/EditBlockWrapper.jsx +1 -0
  40. package/src/components/manage/Blocks/Grid/Edit.jsx +13 -1
  41. package/src/components/manage/Blocks/Image/View.jsx +2 -1
  42. package/src/components/manage/Blocks/Maps/Edit.jsx +135 -209
  43. package/src/components/manage/Blocks/Search/SearchBlockView.jsx +3 -2
  44. package/src/components/manage/Contents/ContentsPropertiesModal.jsx +1 -13
  45. package/src/components/manage/Controlpanels/Groups/RenderGroups.jsx +2 -2
  46. package/src/components/manage/Controlpanels/Relations/BrokenRelations.jsx +30 -7
  47. package/src/components/manage/Controlpanels/Relations/Relations.jsx +2 -2
  48. package/src/components/manage/Controlpanels/Relations/RelationsMatrix.jsx +53 -59
  49. package/src/components/manage/Controlpanels/Users/RenderUsers.jsx +2 -2
  50. package/src/components/manage/Delete/Delete.jsx +96 -171
  51. package/src/components/manage/Widgets/SelectUtils.js +1 -1
  52. package/src/components/manage/Workflow/Workflow.jsx +75 -184
  53. package/src/components/theme/PasswordReset/RequestPasswordReset.jsx +95 -170
  54. package/src/config/Components.jsx +1 -0
  55. package/src/config/index.js~ +223 -0
  56. package/src/express-middleware/files.js +8 -6
  57. package/src/express-middleware/images.js +7 -1
  58. package/src/helpers/MessageLabels/MessageLabels.js +6 -0
  59. package/src/reducers/relations/relations.js +1 -1
  60. package/theme/themes/pastanaga/extras/blocks.less +1 -1
  61. package/packages/volto-slate/build/messages/src/blocks/Table/TableBlockEdit.json +0 -90
  62. package/packages/volto-slate/build/messages/src/blocks/Text/DefaultTextBlockEditor.json +0 -6
  63. package/packages/volto-slate/build/messages/src/blocks/Text/DetachedTextBlockEditor.json +0 -6
  64. package/packages/volto-slate/build/messages/src/blocks/Text/SlashMenu.json +0 -6
  65. package/packages/volto-slate/build/messages/src/editor/plugins/AdvancedLink/index.json +0 -10
  66. package/packages/volto-slate/build/messages/src/editor/plugins/Link/index.json +0 -10
  67. package/packages/volto-slate/build/messages/src/editor/plugins/Table/index.json +0 -30
  68. package/packages/volto-slate/build/messages/src/elementEditor/messages.json +0 -10
  69. package/packages/volto-slate/build/messages/src/widgets/HtmlSlateWidget.json +0 -6
  70. package/packages/volto-slate/build/messages/src/widgets/RichTextWidgetView.json +0 -6
@@ -1,16 +1,10 @@
1
- /**
2
- * Actions component.
3
- * @module components/manage/Actions/Actions
4
- */
5
-
6
- import React, { Component } from 'react';
1
+ import { useState } from 'react';
7
2
  import PropTypes from 'prop-types';
8
- import { compose } from 'redux';
9
- import { connect } from 'react-redux';
3
+ import { useDispatch, useSelector, shallowEqual } from 'react-redux';
10
4
  import { Link } from 'react-router-dom';
11
5
  import { Dropdown, Icon } from 'semantic-ui-react';
12
6
  import { toast } from 'react-toastify';
13
- import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
7
+ import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
14
8
 
15
9
  import { cut, copy, copyContent, moveContent } from '@plone/volto/actions';
16
10
  import { getBaseUrl } from '@plone/volto/helpers';
@@ -55,267 +49,163 @@ const messages = defineMessages({
55
49
  },
56
50
  });
57
51
 
58
- /**
59
- * Actions container class.
60
- * @class Actions
61
- * @extends Component
62
- */
63
- class Actions extends Component {
64
- /**
65
- * Property types.
66
- * @property {Object} propTypes Property types.
67
- * @static
68
- */
69
- static propTypes = {
70
- actions: PropTypes.shape({
71
- object: PropTypes.arrayOf(PropTypes.object),
72
- object_buttons: PropTypes.arrayOf(PropTypes.object),
73
- user: PropTypes.arrayOf(PropTypes.object),
74
- }),
75
- pathname: PropTypes.string.isRequired,
76
- id: PropTypes.string.isRequired,
77
- title: PropTypes.string.isRequired,
78
- action: PropTypes.string,
79
- source: PropTypes.arrayOf(PropTypes.string),
80
- cut: PropTypes.func.isRequired,
81
- copy: PropTypes.func.isRequired,
82
- copyContent: PropTypes.func.isRequired,
83
- moveContent: PropTypes.func.isRequired,
84
- };
52
+ const Actions = (props) => {
53
+ const intl = useIntl();
54
+ const dispatch = useDispatch();
55
+ const [showRename, setshowRename] = useState(false);
56
+ const actions = useSelector((state) => state.actions.actions, shallowEqual);
57
+ const action = useSelector((state) => state.clipboard.action);
58
+ const source = useSelector((state) => state.clipboard.source, shallowEqual);
85
59
 
86
- /**
87
- * Default properties
88
- * @property {Object} defaultProps Default properties.
89
- * @static
90
- */
91
- static defaultProps = {
92
- action: null,
93
- actions: null,
94
- source: null,
95
- };
60
+ const id = useSelector((state) =>
61
+ state.content.data ? state.content.data.id : '',
62
+ );
63
+ const title = useSelector((state) =>
64
+ state.content.data ? state.content.data.title : '',
65
+ );
96
66
 
97
- /**
98
- * Constructor
99
- * @method constructor
100
- * @param {Object} props Component properties
101
- * @constructs Actions
102
- */
103
- constructor(props) {
104
- super(props);
105
- this.cut = this.cut.bind(this);
106
- this.copy = this.copy.bind(this);
107
- this.paste = this.paste.bind(this);
108
- this.rename = this.rename.bind(this);
109
- this.onRenameOk = this.onRenameOk.bind(this);
110
- this.onRenameCancel = this.onRenameCancel.bind(this);
111
- this.state = {
112
- showRename: false,
113
- };
114
- }
67
+ const onRenameOk = () => {
68
+ setshowRename(false);
69
+ };
115
70
 
116
- /**
117
- * On rename ok
118
- * @method onRenameOk
119
- * @returns {undefined}
120
- */
121
- onRenameOk() {
122
- this.setState({
123
- showRename: false,
124
- });
125
- }
71
+ const onRenameCancel = () => {
72
+ setshowRename(false);
73
+ };
126
74
 
127
- /**
128
- * On rename cancel
129
- * @method onRenameCancel
130
- * @returns {undefined}
131
- */
132
- onRenameCancel() {
133
- this.setState({
134
- showRename: false,
135
- });
136
- }
75
+ const fncut = () => {
76
+ dispatch(cut([getBaseUrl(props.pathname)]));
137
77
 
138
- /**
139
- * Cut handler
140
- * @method cut
141
- * @returns {undefined}
142
- */
143
- cut() {
144
- this.props.cut([getBaseUrl(this.props.pathname)]);
145
78
  toast.success(
146
79
  <Toast
147
80
  success
148
- title={this.props.intl.formatMessage(messages.success)}
149
- content={this.props.intl.formatMessage(messages.messageCut, {
150
- title: this.props.title,
81
+ title={intl.formatMessage(messages.success)}
82
+ content={intl.formatMessage(messages.messageCut, {
83
+ title: title,
151
84
  })}
152
85
  />,
153
86
  );
154
- }
87
+ };
155
88
 
156
- /**
157
- * Copy handler
158
- * @method copy
159
- * @returns {undefined}
160
- */
161
- copy() {
162
- this.props.copy([getBaseUrl(this.props.pathname)]);
89
+ const fncopy = () => {
90
+ dispatch(copy([getBaseUrl(props.pathname)]));
163
91
  toast.success(
164
92
  <Toast
165
93
  success
166
- title={this.props.intl.formatMessage(messages.success)}
167
- content={this.props.intl.formatMessage(messages.messageCopied, {
168
- title: this.props.title,
94
+ title={intl.formatMessage(messages.success)}
95
+ content={intl.formatMessage(messages.messageCopied, {
96
+ title: title,
169
97
  })}
170
98
  />,
171
99
  );
172
- }
100
+ };
173
101
 
174
- /**
175
- * Paste handler
176
- * @method paste
177
- * @returns {undefined}
178
- */
179
- paste() {
180
- if (this.props.action === 'copy') {
181
- this.props.copyContent(
182
- this.props.source,
183
- getBaseUrl(this.props.pathname),
184
- );
102
+ const paste = () => {
103
+ if (action === 'copy') {
104
+ dispatch(copyContent(source, getBaseUrl(props.pathname)));
185
105
  }
186
- if (this.props.action === 'cut') {
187
- this.props.moveContent(
188
- this.props.source,
189
- getBaseUrl(this.props.pathname),
190
- );
106
+ if (action === 'cut') {
107
+ dispatch(moveContent(source, getBaseUrl(props.pathname)));
191
108
  }
192
109
  toast.success(
193
110
  <Toast
194
111
  success
195
- title={this.props.intl.formatMessage(messages.success)}
196
- content={this.props.intl.formatMessage(messages.messagePasted)}
112
+ title={intl.formatMessage(messages.success)}
113
+ content={intl.formatMessage(messages.messagePasted)}
197
114
  />,
198
115
  );
199
- }
116
+ };
200
117
 
201
- /**
202
- * Rename handler
203
- * @method rename
204
- * @returns {undefined}
205
- */
206
- rename() {
207
- this.setState({
208
- showRename: true,
209
- });
210
- }
118
+ const rename = () => {
119
+ setshowRename(true);
120
+ };
211
121
 
212
- /**
213
- * Render method.
214
- * @method render
215
- * @returns {string} Markup for the component.
216
- */
217
- render() {
218
- return (
219
- <Dropdown
220
- item
221
- id="toolbar-actions"
222
- trigger={
223
- <span>
224
- <Icon name="lightning" size="big" />{' '}
225
- <FormattedMessage id="Actions" defaultMessage="Actions" />
226
- </span>
227
- }
228
- >
229
- <Dropdown.Menu>
230
- {this.props.actions.object_buttons &&
231
- this.props.actions.object_buttons.map((item) => {
232
- switch (item.id) {
233
- case 'cut':
234
- return (
235
- <Dropdown.Item
236
- key={item.id}
237
- icon="cut"
238
- text={item.title}
239
- onClick={this.cut}
240
- />
241
- );
242
- case 'copy':
243
- return (
244
- <Dropdown.Item
245
- key={item.id}
246
- icon="copy"
247
- text={item.title}
248
- onClick={this.copy}
249
- />
250
- );
251
- case 'paste':
252
- return (
253
- <Dropdown.Item
254
- key={item.id}
255
- icon="paste"
256
- text={item.title}
257
- onClick={this.paste}
258
- disabled={this.props.action === null}
259
- />
260
- );
261
- case 'delete':
262
- return (
263
- <Link
264
- key={item.id}
265
- to={`${this.props.pathname}/delete`}
266
- className="item"
267
- >
268
- <Icon name="trash" />
269
- {item.title}
270
- </Link>
271
- );
272
- case 'rename':
273
- return (
274
- <Dropdown.Item
275
- key={item.id}
276
- icon="text cursor"
277
- text={item.title}
278
- onClick={this.rename}
279
- />
280
- );
281
- default:
282
- return null;
283
- }
284
- })}
122
+ return (
123
+ <Dropdown
124
+ item
125
+ id="toolbar-actions"
126
+ trigger={
127
+ <span>
128
+ <Icon name="lightning" size="big" />{' '}
129
+ <FormattedMessage id="Actions" defaultMessage="Actions" />
130
+ </span>
131
+ }
132
+ >
133
+ <Dropdown.Menu>
134
+ {actions.object_buttons &&
135
+ actions.object_buttons.map((item) => {
136
+ switch (item.id) {
137
+ case 'cut':
138
+ return (
139
+ <Dropdown.Item
140
+ key={item.id}
141
+ icon="cut"
142
+ text={item.title}
143
+ onClick={fncut}
144
+ />
145
+ );
146
+ case 'copy':
147
+ return (
148
+ <Dropdown.Item
149
+ key={item.id}
150
+ icon="copy"
151
+ text={item.title}
152
+ onClick={fncopy}
153
+ />
154
+ );
155
+ case 'paste':
156
+ return (
157
+ <Dropdown.Item
158
+ key={item.id}
159
+ icon="paste"
160
+ text={item.title}
161
+ onClick={paste}
162
+ disabled={action === null}
163
+ />
164
+ );
165
+ case 'delete':
166
+ return (
167
+ <Link
168
+ key={item.id}
169
+ to={`${props.pathname}/delete`}
170
+ className="item"
171
+ >
172
+ <Icon name="trash" />
173
+ {item.title}
174
+ </Link>
175
+ );
176
+ case 'rename':
177
+ return (
178
+ <Dropdown.Item
179
+ key={item.id}
180
+ icon="text cursor"
181
+ text={item.title}
182
+ onClick={rename}
183
+ />
184
+ );
185
+ default:
186
+ return null;
187
+ }
188
+ })}
285
189
 
286
- <ContentsRenameModal
287
- open={this.state.showRename}
288
- onCancel={this.onRenameCancel}
289
- onOk={this.onRenameOk}
290
- items={[
291
- {
292
- url: this.props.pathname,
293
- title: this.props.title,
294
- id: this.props.id,
295
- },
296
- ]}
297
- />
298
- </Dropdown.Menu>
299
- </Dropdown>
300
- );
301
- }
302
- }
190
+ <ContentsRenameModal
191
+ open={showRename}
192
+ onCancel={onRenameCancel}
193
+ onOk={onRenameOk}
194
+ items={[
195
+ {
196
+ url: props.pathname,
197
+ title: title,
198
+ id: id,
199
+ },
200
+ ]}
201
+ />
202
+ </Dropdown.Menu>
203
+ </Dropdown>
204
+ );
205
+ };
206
+
207
+ Actions.propTypes = {
208
+ pathname: PropTypes.string.isRequired,
209
+ };
303
210
 
304
- export default compose(
305
- injectIntl,
306
- connect(
307
- (state) => ({
308
- actions: state.actions.actions,
309
- action: state.clipboard.action,
310
- source: state.clipboard.source,
311
- id: state.content.data ? state.content.data.id : '',
312
- title: state.content.data ? state.content.data.title : '',
313
- }),
314
- {
315
- cut,
316
- copy,
317
- copyContent,
318
- moveContent,
319
- },
320
- ),
321
- )(Actions);
211
+ export default Actions;
@@ -43,9 +43,12 @@ const ContainerBlockEdit = (props) => {
43
43
  const EditBlockWrapper =
44
44
  blockConfig.editBlockWrapper || DefaultEditBlockWrapper;
45
45
 
46
- const [selectedBlock, setSelectedBlock] = useState(
46
+ let [selectedBlock, setSelectedBlock] = useState(
47
47
  properties.blocks_layout.items[0],
48
48
  );
49
+ if (props.setSelectedBlock) {
50
+ ({ selectedBlock, setSelectedBlock } = props);
51
+ }
49
52
 
50
53
  const blockState = {};
51
54
 
@@ -49,6 +49,7 @@ const EditBlockWrapper = (props) => {
49
49
  role="presentation"
50
50
  className="cell-wrapper"
51
51
  onClick={(e) => {
52
+ e.stopPropagation();
52
53
  onSelectBlock(block);
53
54
  }}
54
55
  >
@@ -1,5 +1,6 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import cx from 'classnames';
3
+ import { useState } from 'react';
3
4
  import ContainerEdit from '../Container/Edit';
4
5
 
5
6
  const GridBlockEdit = (props) => {
@@ -7,6 +8,8 @@ const GridBlockEdit = (props) => {
7
8
 
8
9
  const columnsLength = data?.blocks_layout?.items?.length || 0;
9
10
 
11
+ const [selectedBlock, setSelectedBlock] = useState(null);
12
+
10
13
  return (
11
14
  <div
12
15
  className={cx({
@@ -16,8 +19,17 @@ const GridBlockEdit = (props) => {
16
19
  four: columnsLength >= 4,
17
20
  'grid-items': true,
18
21
  })}
22
+ // This is required to enabling a small "in-between" clickable area
23
+ // for bringing the Grid sidebar alive once you have selected an inner block
24
+ onClick={(e) => setSelectedBlock(null)}
25
+ role="presentation"
19
26
  >
20
- <ContainerEdit {...props} direction="horizontal" />
27
+ <ContainerEdit
28
+ {...props}
29
+ selectedBlock={selectedBlock}
30
+ setSelectedBlock={setSelectedBlock}
31
+ direction="horizontal"
32
+ />
21
33
  </div>
22
34
  );
23
35
  };
@@ -19,7 +19,7 @@ import config from '@plone/volto/registry';
19
19
  * @class View
20
20
  * @extends Component
21
21
  */
22
- export const View = ({ data, detached, properties }) => {
22
+ export const View = ({ className, data, detached, properties }) => {
23
23
  const href = data?.href?.[0]?.['@id'] || '';
24
24
 
25
25
  const Image = config.getComponent({ name: 'Image' }).component;
@@ -33,6 +33,7 @@ export const View = ({ data, detached, properties }) => {
33
33
  detached,
34
34
  },
35
35
  data.align,
36
+ className,
36
37
  )}
37
38
  >
38
39
  {data.url && (