@plone/volto 18.0.0-alpha.41 → 18.0.0-alpha.43

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 (187) hide show
  1. package/CHANGELOG.md +114 -0
  2. package/finalreleasechangelog.py +48 -0
  3. package/locales/ca/LC_MESSAGES/volto.po +39 -13
  4. package/locales/ca.json +1 -1
  5. package/locales/de/LC_MESSAGES/volto.po +40 -14
  6. package/locales/de.json +1 -1
  7. package/locales/en/LC_MESSAGES/volto.po +39 -13
  8. package/locales/en.json +1 -1
  9. package/locales/es/LC_MESSAGES/volto.po +40 -14
  10. package/locales/es.json +1 -1
  11. package/locales/eu/LC_MESSAGES/volto.po +40 -14
  12. package/locales/eu.json +1 -1
  13. package/locales/fi/LC_MESSAGES/volto.po +40 -14
  14. package/locales/fi.json +1 -1
  15. package/locales/fr/LC_MESSAGES/volto.po +40 -14
  16. package/locales/fr.json +1 -1
  17. package/locales/hi/LC_MESSAGES/volto.po +40 -14
  18. package/locales/hi.json +1 -1
  19. package/locales/it/LC_MESSAGES/volto.po +40 -14
  20. package/locales/it.json +1 -1
  21. package/locales/ja/LC_MESSAGES/volto.po +39 -13
  22. package/locales/ja.json +1 -1
  23. package/locales/nl/LC_MESSAGES/volto.po +39 -13
  24. package/locales/nl.json +1 -1
  25. package/locales/pt/LC_MESSAGES/volto.po +39 -13
  26. package/locales/pt.json +1 -1
  27. package/locales/pt_BR/LC_MESSAGES/volto.po +40 -14
  28. package/locales/pt_BR.json +1 -1
  29. package/locales/ro/LC_MESSAGES/volto.po +39 -13
  30. package/locales/ro.json +1 -1
  31. package/locales/volto.pot +40 -14
  32. package/locales/zh_CN/LC_MESSAGES/volto.po +40 -14
  33. package/locales/zh_CN.json +1 -1
  34. package/package.json +5 -6
  35. package/razzle.config.js +3 -3
  36. package/src/components/index.js +0 -1
  37. package/src/components/manage/Actions/Actions.stories.jsx +138 -0
  38. package/src/components/manage/Add/Add.jsx +7 -4
  39. package/src/components/manage/BlockChooser/BlockChooser.jsx +9 -1
  40. package/src/components/manage/Blocks/Block/BlocksForm.jsx +5 -0
  41. package/src/components/manage/Blocks/Block/Edit.jsx +24 -8
  42. package/src/components/manage/Blocks/Block/EditBlockWrapper.jsx +17 -1
  43. package/src/components/manage/Blocks/Block/Order/Item.jsx +8 -2
  44. package/src/components/manage/Blocks/Block/Order/Order.jsx +2 -0
  45. package/src/components/manage/Blocks/Container/Data.jsx +10 -2
  46. package/src/components/manage/Blocks/Grid/View.jsx +3 -0
  47. package/src/components/manage/Blocks/Image/ImageSidebar.jsx +10 -2
  48. package/src/components/manage/Blocks/LeadImage/Edit.jsx +74 -126
  49. package/src/components/manage/Blocks/Listing/ListingData.jsx +10 -2
  50. package/src/components/manage/Blocks/Maps/MapsSidebar.jsx +3 -1
  51. package/src/components/manage/Blocks/Search/SearchBlockEdit.jsx +2 -0
  52. package/src/components/manage/Blocks/Search/SearchBlockView.jsx +18 -2
  53. package/src/components/manage/Blocks/Search/components/SortOn.jsx +82 -55
  54. package/src/components/manage/Blocks/Search/hocs/withSearch.jsx +1 -1
  55. package/src/components/manage/Blocks/Search/widgets/SelectMetadataField.jsx +107 -176
  56. package/src/components/manage/Blocks/Teaser/Data.jsx +10 -2
  57. package/src/components/manage/Blocks/Teaser/DefaultBody.jsx +15 -8
  58. package/src/components/manage/Blocks/ToC/Edit.jsx +36 -28
  59. package/src/components/manage/Blocks/Video/Edit.jsx +105 -172
  60. package/src/components/manage/Blocks/Video/Edit.stories.jsx +57 -0
  61. package/src/components/manage/Blocks/Video/VideoSidebar.jsx +3 -1
  62. package/src/components/manage/Contents/Contents.jsx +4 -1
  63. package/src/components/manage/Contents/ContentsBreadcrumbs.stories.jsx +46 -0
  64. package/src/components/manage/Contents/ContentsPropertiesModal.jsx +85 -52
  65. package/src/components/manage/Contents/ContentsUploadModal.jsx +230 -323
  66. package/src/components/manage/Contents/ContentsUploadModal.stories.jsx +56 -0
  67. package/src/components/manage/Controlpanels/AddonsControlpanel.jsx +323 -441
  68. package/src/components/manage/Controlpanels/Aliases.jsx +452 -580
  69. package/src/components/manage/Controlpanels/Aliases.stories.jsx +74 -0
  70. package/src/components/manage/Controlpanels/ContentTypeSchema.jsx +1 -0
  71. package/src/components/manage/Controlpanels/Controlpanel.jsx +41 -2
  72. package/src/components/manage/Controlpanels/Controlpanel.test.jsx +55 -24
  73. package/src/components/manage/Controlpanels/DatabaseInformation.jsx +162 -229
  74. package/src/components/manage/Controlpanels/Groups/RenderGroups.jsx +74 -122
  75. package/src/components/manage/Controlpanels/UndoControlpanel.jsx +3 -3
  76. package/src/components/manage/Controlpanels/Users/UserGroupMembershipListing.jsx +28 -12
  77. package/src/components/manage/Controlpanels/Users/UserGroupMembershipMatrix.jsx +12 -4
  78. package/src/components/manage/Display/Display.jsx +92 -148
  79. package/src/components/manage/Display/Display.stories.jsx +46 -0
  80. package/src/components/manage/Edit/Edit.jsx +2 -4
  81. package/src/components/manage/Form/Form.jsx +85 -20
  82. package/src/components/manage/Form/InlineForm.jsx +2 -4
  83. package/src/components/manage/Form/ModalForm.jsx +1 -1
  84. package/src/components/manage/History/History.jsx +1 -1
  85. package/src/components/manage/Pluggable/Pluggable.test.js +1 -1
  86. package/src/components/manage/Preferences/ChangePassword.jsx +94 -172
  87. package/src/components/manage/Preferences/ChangePassword.stories.jsx +41 -0
  88. package/src/components/manage/Preferences/PersonalInformation.jsx +50 -115
  89. package/src/components/manage/Preferences/PersonalPreferences.jsx +46 -100
  90. package/src/components/manage/Preferences/PersonalPreferences.stories.jsx +48 -0
  91. package/src/components/manage/Toolbar/More.jsx +308 -399
  92. package/src/components/manage/Toolbar/Toolbar.jsx +1 -1
  93. package/src/components/manage/Widgets/ArrayWidget.jsx +2 -2
  94. package/src/components/manage/Widgets/DatetimeWidget.jsx +121 -175
  95. package/src/components/manage/Widgets/ImageWidget.jsx +6 -5
  96. package/src/components/manage/Widgets/RecurrenceWidget/EndField.jsx +7 -1
  97. package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.jsx +80 -31
  98. package/src/components/manage/Widgets/ReferenceWidget.jsx +134 -210
  99. package/src/components/theme/Register/Register.jsx +70 -142
  100. package/src/components/theme/Register/Register.stories.jsx +49 -0
  101. package/src/components/theme/Search/Search.jsx +13 -5
  102. package/src/components/theme/Tags/Tags.jsx +19 -10
  103. package/src/components/theme/Tags/Tags.test.jsx +9 -11
  104. package/src/components/theme/View/AlbumView.jsx +122 -167
  105. package/src/components/theme/View/LinkView.jsx +4 -0
  106. package/src/components/theme/View/LinkView.test.jsx +2 -0
  107. package/src/components/theme/View/View.jsx +0 -13
  108. package/src/components/theme/View/View.test.jsx +0 -3
  109. package/src/config/ControlPanels.js +49 -43
  110. package/src/config/Widgets.jsx +1 -1
  111. package/src/config/config.test.js +1 -0
  112. package/src/config/index.js +23 -2
  113. package/src/config/slots.js +12 -0
  114. package/src/config/validation.ts +155 -0
  115. package/src/helpers/Blocks/Blocks.js +12 -7
  116. package/src/helpers/Blocks/Blocks.test.js +15 -0
  117. package/src/helpers/Blocks/cloneBlocks.ts +1 -1
  118. package/src/helpers/Extensions/withBlockExtensions.jsx +1 -1
  119. package/src/helpers/FormValidation/FormValidation.jsx +128 -172
  120. package/src/helpers/FormValidation/FormValidation.test.js +836 -8
  121. package/src/helpers/FormValidation/validators.ts +203 -0
  122. package/src/helpers/MessageLabels/MessageLabels.js +28 -0
  123. package/src/helpers/Url/Url.test.js +19 -6
  124. package/src/helpers/Url/urlRegex.js +1 -1
  125. package/src/helpers/User/User.js +1 -1
  126. package/src/helpers/index.js +2 -0
  127. package/src/hooks/client/useClient.js +1 -1
  128. package/src/middleware/api.js +4 -2
  129. package/src/middleware/index.js +1 -0
  130. package/src/middleware/userSessionReset.js +46 -0
  131. package/src/store.js +2 -0
  132. package/test-setup-config.jsx +10 -0
  133. package/theme/themes/default/modules/embed.variables +1 -1
  134. package/theme/themes/pastanaga/collections/form.overrides +34 -0
  135. package/theme/themes/pastanaga/extras/blocks.less +6 -0
  136. package/theme/themes/pastanaga/extras/sidebar.less +4 -0
  137. package/theme/themes/pastanaga/extras/toolbar.less +10 -3
  138. package/tsconfig.declarations.json +3 -2
  139. package/types/components/index.d.ts +0 -1
  140. package/types/components/manage/Actions/Actions.stories.d.ts +8 -0
  141. package/types/components/manage/Blocks/Block/Order/Order.d.ts +2 -1
  142. package/types/components/manage/Blocks/LeadImage/Edit.d.ts +14 -5
  143. package/types/components/manage/Blocks/Search/widgets/SelectMetadataField.d.ts +0 -5
  144. package/types/components/manage/Blocks/ToC/Edit.d.ts +1 -6
  145. package/types/components/manage/Blocks/Video/Edit.d.ts +1 -1
  146. package/types/components/manage/Blocks/Video/Edit.stories.d.ts +8 -0
  147. package/types/components/manage/Contents/ContentsBreadcrumbs.stories.d.ts +8 -0
  148. package/types/components/manage/Contents/ContentsUploadModal.d.ts +14 -2
  149. package/types/components/manage/Contents/ContentsUploadModal.stories.d.ts +8 -0
  150. package/types/components/manage/Contents/index.d.ts +1 -1
  151. package/types/components/manage/Controlpanels/AddonsControlpanel.d.ts +2 -2
  152. package/types/components/manage/Controlpanels/Aliases.d.ts +2 -2
  153. package/types/components/manage/Controlpanels/Aliases.stories.d.ts +8 -0
  154. package/types/components/manage/Controlpanels/DatabaseInformation.d.ts +2 -2
  155. package/types/components/manage/Controlpanels/Groups/RenderGroups.d.ts +10 -5
  156. package/types/components/manage/Controlpanels/index.d.ts +4 -4
  157. package/types/components/manage/Display/Display.stories.d.ts +8 -0
  158. package/types/components/manage/Preferences/ChangePassword.d.ts +2 -2
  159. package/types/components/manage/Preferences/ChangePassword.stories.d.ts +8 -0
  160. package/types/components/manage/Preferences/PersonalInformation.d.ts +7 -2
  161. package/types/components/manage/Preferences/PersonalPreferences.d.ts +5 -1
  162. package/types/components/manage/Preferences/PersonalPreferences.stories.d.ts +8 -0
  163. package/types/components/manage/Toolbar/More.d.ts +8 -5
  164. package/types/components/manage/Widgets/DatetimeWidget.d.ts +0 -85
  165. package/types/components/manage/Widgets/DatetimeWidget.stories.d.ts +0 -1
  166. package/types/components/manage/Widgets/ReferenceWidget.d.ts +27 -2
  167. package/types/components/manage/Widgets/index.d.ts +1 -1
  168. package/types/components/theme/Register/Register.d.ts +2 -2
  169. package/types/components/theme/Register/Register.stories.d.ts +9 -0
  170. package/types/components/theme/Tags/Tags.d.ts +15 -7
  171. package/types/components/theme/View/AlbumView.d.ts +3 -17
  172. package/types/config/ControlPanels.d.ts +8 -0
  173. package/types/config/RichTextEditor/ToHTML.d.ts +1 -1
  174. package/types/config/Widgets.d.ts +3 -3
  175. package/types/config/slots.d.ts +21 -0
  176. package/types/config/validation.d.ts +3 -0
  177. package/types/helpers/Blocks/Blocks.d.ts +6 -0
  178. package/types/helpers/Extensions/withBlockExtensions.d.ts +1 -1
  179. package/types/helpers/FormValidation/FormValidation.d.ts +2 -0
  180. package/types/helpers/FormValidation/validators.d.ts +29 -0
  181. package/types/helpers/MessageLabels/MessageLabels.d.ts +36 -0
  182. package/types/helpers/User/User.d.ts +1 -1
  183. package/types/helpers/index.d.ts +2 -2
  184. package/types/middleware/index.d.ts +1 -0
  185. package/types/middleware/userSessionReset.d.ts +5 -0
  186. package/src/components/theme/SocialSharing/SocialSharing.jsx +0 -48
  187. package/src/components/theme/SocialSharing/SocialSharing.test.jsx +0 -14
@@ -1,16 +1,11 @@
1
- /**
2
- * More component.
3
- * @module components/manage/Toolbar/More
4
- */
5
-
6
- import React, { Component } from 'react';
7
- import { defineMessages, injectIntl } from 'react-intl';
1
+ import React, { useState, useEffect } from 'react';
2
+ import { defineMessages, useIntl } from 'react-intl';
8
3
  import PropTypes from 'prop-types';
9
- import { connect } from 'react-redux';
10
- import { compose } from 'redux';
11
- import { Link, withRouter } from 'react-router-dom';
4
+ import { useDispatch, useSelector, shallowEqual } from 'react-redux';
5
+ import { Link, useHistory } from 'react-router-dom';
12
6
  import { find } from 'lodash';
13
7
  import { toast } from 'react-toastify';
8
+
14
9
  import { Toast } from '@plone/volto/components';
15
10
  import { Pluggable, Plug } from '@plone/volto/components/manage/Pluggable';
16
11
  import {
@@ -24,9 +19,8 @@ import {
24
19
  createWorkingCopy,
25
20
  removeWorkingCopy,
26
21
  } from '@plone/volto/actions';
27
- import { flattenToAppURL, getBaseUrl } from '@plone/volto/helpers';
22
+ import { flattenToAppURL, getBaseUrl, usePrevious } from '@plone/volto/helpers';
28
23
  import config from '@plone/volto/registry';
29
-
30
24
  import rightArrowSVG from '@plone/volto/icons/right-key.svg';
31
25
  import userSVG from '@plone/volto/icons/user.svg';
32
26
  import applySVG from '@plone/volto/icons/ready.svg';
@@ -112,80 +106,49 @@ const messages = defineMessages({
112
106
  },
113
107
  });
114
108
 
115
- /**
116
- * More container class.
117
- * @class More
118
- * @extends Component
119
- */
120
- class More extends Component {
121
- static propTypes = {
122
- actions: PropTypes.shape({
123
- object: PropTypes.arrayOf(PropTypes.object),
124
- object_buttons: PropTypes.arrayOf(PropTypes.object),
125
- user: PropTypes.arrayOf(PropTypes.object),
126
- }),
127
- pathname: PropTypes.string.isRequired,
128
- content: PropTypes.shape({
129
- title: PropTypes.string,
130
- '@type': PropTypes.string,
131
- is_folderish: PropTypes.bool,
132
- review_state: PropTypes.string,
133
- }),
134
- loadComponent: PropTypes.func.isRequired,
135
- closeMenu: PropTypes.func.isRequired,
136
- };
109
+ const More = (props) => {
110
+ const dispatch = useDispatch();
111
+ const intl = useIntl();
112
+ const history = useHistory();
113
+ const [, setPushed] = useState(false);
114
+ const pathname = props.pathname;
137
115
 
138
- /**
139
- * Default properties.
140
- * @property {Object} defaultProps Default properties.
141
- * @static
142
- */
143
- static defaultProps = {
144
- actions: null,
145
- content: null,
146
- };
147
- state = {
148
- openManageTranslations: false,
149
- pushed: false,
150
- };
116
+ const content = useSelector((state) => state.content?.data, shallowEqual);
117
+ const workingCopy = useSelector((state) => state.workingCopy, shallowEqual);
151
118
 
152
- push = (selector) => {
153
- this.setState(() => ({
154
- pushed: true,
155
- }));
156
- this.props.loadComponent(selector);
157
- document.removeEventListener('mousedown', this.handleClickOutside, false);
158
- };
119
+ const actions = useSelector((state) => state.actions.actions, shallowEqual);
120
+
121
+ const workingCopyApply = workingCopy?.apply.loading;
122
+ const workingCopyCreate = workingCopy?.create.loading;
123
+ const workingCopyRemove = workingCopy?.remove.loading;
159
124
 
160
- componentDidUpdate(prevProps, prevState) {
125
+ const prevWorkingCopyApplyLoading = usePrevious(workingCopyApply);
126
+ const prevWorkingCopyCreateLoading = usePrevious(workingCopyCreate);
127
+ const prevWorkingCopyRemoveLoading = usePrevious(workingCopyRemove);
128
+
129
+ const push = (selector) => {
130
+ setPushed(true);
131
+ props.loadComponent(selector);
132
+ document.removeEventListener('mousedown', props.handleClickOutside, false);
133
+ };
134
+ useEffect(() => {
161
135
  let erroredAction = '';
162
- if (
163
- prevProps.workingCopy.apply.loading &&
164
- this.props.workingCopy.apply.error
165
- ) {
136
+ if (prevWorkingCopyApplyLoading && workingCopy.apply.error) {
166
137
  erroredAction = 'apply';
167
- } else if (
168
- prevProps.workingCopy.create.loading &&
169
- this.props.workingCopy.create.error
170
- ) {
138
+ } else if (prevWorkingCopyCreateLoading && workingCopy.create.error) {
171
139
  erroredAction = 'create';
172
- } else if (
173
- prevProps.workingCopy.remove.loading &&
174
- this.props.workingCopy.remove.error
175
- ) {
140
+ } else if (prevWorkingCopyRemoveLoading && workingCopy.remove.error) {
176
141
  erroredAction = 'remove';
177
142
  }
178
143
 
179
144
  if (erroredAction) {
180
- const errorStatus = this.props.workingCopy[erroredAction].error.status;
145
+ const errorStatus = workingCopy[erroredAction].error.status;
181
146
  if (errorStatus === 401 || errorStatus === 403) {
182
147
  toast.error(
183
148
  <Toast
184
149
  error
185
- title={this.props.intl.formatMessage(messages.Unauthorized)}
186
- content={this.props.intl.formatMessage(
187
- messages.workingCopyErrorUnauthorized,
188
- )}
150
+ title={intl.formatMessage(messages.Unauthorized)}
151
+ content={intl.formatMessage(messages.workingCopyErrorUnauthorized)}
189
152
  />,
190
153
  {
191
154
  toastId: 'workingCopyErrorUnauthorized',
@@ -196,10 +159,8 @@ class More extends Component {
196
159
  toast.error(
197
160
  <Toast
198
161
  error
199
- title={this.props.intl.formatMessage(messages.Error)}
200
- content={this.props.intl.formatMessage(
201
- messages.workingCopyGenericError,
202
- )}
162
+ title={intl.formatMessage(messages.Error)}
163
+ content={intl.formatMessage(messages.workingCopyGenericError)}
203
164
  />,
204
165
  {
205
166
  toastId: 'workingCopyGenericError',
@@ -208,347 +169,295 @@ class More extends Component {
208
169
  );
209
170
  }
210
171
  }
211
- }
172
+ }, [
173
+ workingCopy,
174
+ prevWorkingCopyApplyLoading,
175
+ prevWorkingCopyCreateLoading,
176
+ prevWorkingCopyRemoveLoading,
177
+ intl,
178
+ ]);
212
179
 
213
- /**
214
- * Render method.
215
- * @method render
216
- * @returns {string} Markup for the component.
217
- */
218
- render() {
219
- const path = getBaseUrl(this.props.pathname);
220
- const editAction = find(this.props.actions.object, { id: 'edit' });
221
- const historyAction = find(this.props.actions.object, { id: 'history' });
222
- const sharingAction = find(this.props.actions.object, {
223
- id: 'local_roles',
224
- });
180
+ const path = getBaseUrl(pathname);
181
+ const editAction = find(actions.object, { id: 'edit' });
182
+ const historyAction = find(actions.object, { id: 'history' });
183
+ const sharingAction = find(actions.object, {
184
+ id: 'local_roles',
185
+ });
225
186
 
226
- const rulesAction = find(this.props.actions.object, {
227
- id: 'contentrules',
228
- });
187
+ const rulesAction = find(actions.object, {
188
+ id: 'contentrules',
189
+ });
229
190
 
230
- const aliasesAction = find(this.props.actions.object_buttons, {
231
- id: 'redirection',
232
- });
191
+ const aliasesAction = find(actions.object_buttons, {
192
+ id: 'redirection',
193
+ });
233
194
 
234
- const { content, intl } = this.props;
235
-
236
- const dateOptions = {
237
- year: 'numeric',
238
- month: 'long',
239
- day: 'numeric',
240
- };
195
+ const dateOptions = {
196
+ year: 'numeric',
197
+ month: 'long',
198
+ day: 'numeric',
199
+ };
241
200
 
242
- return (
243
- <div
244
- className="menu-more pastanaga-menu"
245
- style={{
246
- flex: this.props.theToolbar.current
247
- ? `0 0 ${
248
- this.props.theToolbar.current.getBoundingClientRect().width
249
- }px`
250
- : null,
251
- }}
252
- >
253
- <header>
254
- <h2>{this.props.content.title}</h2>
255
- <button
256
- className="more-user"
257
- aria-label={this.props.intl.formatMessage(messages.personalTools)}
258
- onClick={() => this.push('personalTools')}
259
- tabIndex={0}
260
- >
261
- <Icon
262
- name={userSVG}
263
- size="30px"
264
- title={this.props.intl.formatMessage(messages.personalTools)}
265
- />
266
- </button>
267
- </header>
268
- <div className="pastanaga-menu-list">
269
- <ul>
270
- <Pluggable name="toolbar-more-menu-list" />
271
- <Plug pluggable="toolbar-more-menu-list" id="state">
272
- {this.props.content['@type'] !== 'Plone Site' && (
273
- // Plone Site does not have workflow
274
- <li className="state-select">
275
- <Workflow pathname={path} />
276
- </li>
277
- )}
278
- </Plug>
279
- <Plug pluggable="toolbar-more-menu-list" id="view">
280
- {this.props.content['@type'] !== 'Plone Site' && (
281
- // Plone Site does not have view (yet)
282
- <li className="display-select">
283
- {editAction && <Display pathname={path} />}
284
- </li>
285
- )}
286
- </Plug>
287
- <Plug pluggable="toolbar-more-menu-list" id="history">
288
- {this.props.content['@type'] !== 'Plone Site' && (
289
- // Plone Site does not have history (yet)
201
+ return (
202
+ <div
203
+ className="menu-more pastanaga-menu"
204
+ style={{
205
+ flex: props.theToolbar.current
206
+ ? `0 0 ${props.theToolbar.current.getBoundingClientRect().width}px`
207
+ : null,
208
+ }}
209
+ >
210
+ <header>
211
+ <h2>{content.title}</h2>
212
+ <button
213
+ className="more-user"
214
+ aria-label={intl.formatMessage(messages.personalTools)}
215
+ onClick={() => push('personalTools')}
216
+ tabIndex={0}
217
+ >
218
+ <Icon
219
+ name={userSVG}
220
+ size="30px"
221
+ title={intl.formatMessage(messages.personalTools)}
222
+ />
223
+ </button>
224
+ </header>
225
+ <div className="pastanaga-menu-list">
226
+ <ul>
227
+ <Pluggable name="toolbar-more-menu-list" />
228
+ <Plug pluggable="toolbar-more-menu-list" id="state">
229
+ {content['@type'] !== 'Plone Site' && (
230
+ // Plone Site does not have workflow
231
+ <li className="state-select">
232
+ <Workflow pathname={path} />
233
+ </li>
234
+ )}
235
+ </Plug>
236
+ <Plug pluggable="toolbar-more-menu-list" id="view">
237
+ {content['@type'] !== 'Plone Site' && (
238
+ // Plone Site does not have view (yet)
239
+ <li className="display-select">
240
+ {editAction && <Display pathname={path} />}
241
+ </li>
242
+ )}
243
+ </Plug>
244
+ <Plug pluggable="toolbar-more-menu-list" id="history">
245
+ {content['@type'] !== 'Plone Site' && (
246
+ // Plone Site does not have history (yet)
247
+ <li>
248
+ <Link to={`${path}/historyview`}>
249
+ <div>
250
+ <span className="pastanaga-menu-label">
251
+ {historyAction?.title ||
252
+ intl.formatMessage(messages.history)}
253
+ </span>
254
+ <span className="pastanaga-menu-value" />
255
+ </div>
256
+ <Icon name={rightArrowSVG} size="24px" />
257
+ </Link>
258
+ </li>
259
+ )}
260
+ </Plug>
261
+ <Plug pluggable="toolbar-more-menu-list" id="sharing">
262
+ {sharingAction && (
263
+ <li>
264
+ <Link to={`${path}/sharing`}>
265
+ {intl.formatMessage(messages.sharing)}
266
+ <Icon name={rightArrowSVG} size="24px" />
267
+ </Link>
268
+ </li>
269
+ )}
270
+ </Plug>
271
+ <Plug pluggable="toolbar-more-menu-list" id="aliases">
272
+ {aliasesAction && (
273
+ <li>
274
+ <Link to={`${path}/aliases`}>
275
+ {intl.formatMessage(messages.aliases)}
276
+ <Icon name={rightArrowSVG} size="24px" />
277
+ </Link>
278
+ </li>
279
+ )}
280
+ </Plug>
281
+ {path !== '' &&
282
+ !config.settings.excludeLinksAndReferencesMenuItem && (
283
+ <Plug pluggable="toolbar-more-menu-list" id="linkstoitems">
290
284
  <li>
291
- <Link to={`${path}/historyview`}>
292
- <div>
293
- <span className="pastanaga-menu-label">
294
- {historyAction?.title ||
295
- this.props.intl.formatMessage(messages.history)}
296
- </span>
297
- <span className="pastanaga-menu-value" />
298
- </div>
285
+ <Link to={`${path}/links-to-item`}>
286
+ {intl.formatMessage(messages.linkstoitem)}
299
287
  <Icon name={rightArrowSVG} size="24px" />
300
288
  </Link>
301
289
  </li>
302
- )}
303
- </Plug>
304
- <Plug pluggable="toolbar-more-menu-list" id="sharing">
305
- {sharingAction && (
290
+ </Plug>
291
+ )}
292
+ <Plug pluggable="toolbar-more-menu-list" id="rules">
293
+ {rulesAction && (
294
+ <li>
295
+ <Link to={`${path}/rules`}>
296
+ {intl.formatMessage(messages.rules)}
297
+ <Icon name={rightArrowSVG} size="24px" />
298
+ </Link>
299
+ </li>
300
+ )}
301
+ </Plug>
302
+ </ul>
303
+ </div>
304
+ <Pluggable name="toolbar-more-manage-content">
305
+ {(pluggables) => (
306
+ <>
307
+ {pluggables.length > 0 && (
308
+ <>
309
+ <header>
310
+ <h2>{intl.formatMessage(messages.manageContent)}</h2>
311
+ </header>
312
+ <div className="pastanaga-menu-list">
313
+ <ul>
314
+ {pluggables.map((p) => (
315
+ <>{p()}</>
316
+ ))}
317
+ </ul>
318
+ </div>
319
+ </>
320
+ )}
321
+ </>
322
+ )}
323
+ </Pluggable>
324
+ {config.settings.hasWorkingCopySupport &&
325
+ content['@type'] !== 'Plone Site' && (
326
+ <>
327
+ {!content.working_copy && (
328
+ <Plug pluggable="toolbar-more-manage-content" id="workingcopy">
306
329
  <li>
307
- <Link to={`${path}/sharing`}>
308
- {this.props.intl.formatMessage(messages.sharing)}
330
+ <button
331
+ aria-label={intl.formatMessage(messages.CreateWorkingCopy)}
332
+ onClick={() => {
333
+ dispatch(createWorkingCopy(path)).then((response) => {
334
+ history.push(flattenToAppURL(response['@id']));
335
+ props.closeMenu();
336
+ });
337
+ }}
338
+ >
339
+ {intl.formatMessage(messages.CreateWorkingCopy)}
340
+
309
341
  <Icon name={rightArrowSVG} size="24px" />
310
- </Link>
342
+ </button>
311
343
  </li>
312
- )}
313
- </Plug>
314
- <Plug pluggable="toolbar-more-menu-list" id="aliases">
315
- {aliasesAction && (
344
+ </Plug>
345
+ )}
346
+ {content.working_copy && content.working_copy_of && (
347
+ <Plug pluggable="toolbar-more-manage-content" id="workingcopy">
316
348
  <li>
317
- <Link to={`${path}/aliases`}>
318
- {this.props.intl.formatMessage(messages.aliases)}
319
- <Icon name={rightArrowSVG} size="24px" />
320
- </Link>
349
+ <button
350
+ aria-label={intl.formatMessage(messages.applyWorkingCopy)}
351
+ onClick={() => {
352
+ dispatch(applyWorkingCopy(path)).then((response) => {
353
+ history.push(
354
+ flattenToAppURL(content.working_copy_of['@id']),
355
+ );
356
+ props.closeMenu();
357
+ toast.info(
358
+ <Toast
359
+ info
360
+ title={intl.formatMessage(
361
+ messages.workingAppliedTitle,
362
+ )}
363
+ content={intl.formatMessage(
364
+ messages.workingCopyAppliedBy,
365
+ {
366
+ creator: content.working_copy?.creator_name,
367
+ date: (
368
+ <FormattedDate
369
+ date={content.working_copy?.created}
370
+ format={dateOptions}
371
+ />
372
+ ),
373
+ },
374
+ )}
375
+ />,
376
+ {
377
+ toastId: 'workingcopyapplyinfo',
378
+ autoClose: 10000,
379
+ },
380
+ );
381
+ });
382
+ }}
383
+ >
384
+ {intl.formatMessage(messages.applyWorkingCopy)}
385
+
386
+ <Icon
387
+ name={applySVG}
388
+ size="24px"
389
+ title={intl.formatMessage(messages.applyWorkingCopy)}
390
+ />
391
+ </button>
321
392
  </li>
322
- )}
323
- </Plug>
324
- {path !== '' &&
325
- !config.settings.excludeLinksAndReferencesMenuItem && (
326
- <Plug pluggable="toolbar-more-menu-list" id="linkstoitems">
327
- <li>
328
- <Link to={`${path}/links-to-item`}>
329
- {this.props.intl.formatMessage(messages.linkstoitem)}
330
- <Icon name={rightArrowSVG} size="24px" />
331
- </Link>
332
- </li>
333
- </Plug>
334
- )}
335
- <Plug pluggable="toolbar-more-menu-list" id="rules">
336
- {rulesAction && (
337
393
  <li>
338
- <Link to={`${path}/rules`}>
339
- {this.props.intl.formatMessage(messages.rules)}
394
+ <button
395
+ aria-label={intl.formatMessage(messages.removeWorkingCopy)}
396
+ onClick={() => {
397
+ dispatch(removeWorkingCopy(path)).then((response) => {
398
+ history.push(
399
+ flattenToAppURL(content.working_copy_of['@id']),
400
+ );
401
+ props.closeMenu();
402
+ toast.info(
403
+ <Toast
404
+ info
405
+ title={intl.formatMessage(
406
+ messages.workingCopyRemovedTitle,
407
+ )}
408
+ />,
409
+ {
410
+ toastId: 'workingcopyremovednotice',
411
+ autoClose: 10000,
412
+ },
413
+ );
414
+ });
415
+ }}
416
+ >
417
+ {intl.formatMessage(messages.removeWorkingCopy)}
418
+ <Icon
419
+ name={removeSVG}
420
+ size="24px"
421
+ color="#e40166"
422
+ title={intl.formatMessage(messages.removeWorkingCopy)}
423
+ />
424
+ </button>
425
+ </li>
426
+ </Plug>
427
+ )}
428
+ {content.working_copy && !content.working_copy_of && (
429
+ <Plug pluggable="toolbar-more-manage-content" id="workingcopy">
430
+ <li>
431
+ <Link
432
+ to={flattenToAppURL(content.working_copy['@id'])}
433
+ onClick={() => props.closeMenu()}
434
+ >
435
+ {intl.formatMessage(messages.viewWorkingCopy)}
340
436
  <Icon name={rightArrowSVG} size="24px" />
341
437
  </Link>
342
438
  </li>
343
- )}
344
- </Plug>
345
- </ul>
346
- </div>
347
- <Pluggable name="toolbar-more-manage-content">
348
- {(pluggables) => (
349
- <>
350
- {pluggables.length > 0 && (
351
- <>
352
- <header>
353
- <h2>
354
- {this.props.intl.formatMessage(messages.manageContent)}
355
- </h2>
356
- </header>
357
- <div className="pastanaga-menu-list">
358
- <ul>
359
- {pluggables.map((p) => (
360
- <>{p()}</>
361
- ))}
362
- </ul>
363
- </div>
364
- </>
365
- )}
366
- </>
367
- )}
368
- </Pluggable>
369
- {config.settings.hasWorkingCopySupport &&
370
- this.props.content['@type'] !== 'Plone Site' && (
371
- <>
372
- {!this.props.content.working_copy && (
373
- <Plug pluggable="toolbar-more-manage-content" id="workingcopy">
374
- <li>
375
- <button
376
- aria-label={this.props.intl.formatMessage(
377
- messages.CreateWorkingCopy,
378
- )}
379
- onClick={() => {
380
- this.props.createWorkingCopy(path).then((response) => {
381
- this.props.history.push(
382
- flattenToAppURL(response['@id']),
383
- );
384
- this.props.closeMenu();
385
- });
386
- }}
387
- >
388
- {this.props.intl.formatMessage(
389
- messages.CreateWorkingCopy,
390
- )}
391
-
392
- <Icon name={rightArrowSVG} size="24px" />
393
- </button>
394
- </li>
395
- </Plug>
396
- )}
397
- {this.props.content.working_copy &&
398
- this.props.content.working_copy_of && (
399
- <Plug
400
- pluggable="toolbar-more-manage-content"
401
- id="workingcopy"
402
- >
403
- <li>
404
- <button
405
- aria-label={this.props.intl.formatMessage(
406
- messages.applyWorkingCopy,
407
- )}
408
- onClick={() => {
409
- this.props.applyWorkingCopy(path).then((response) => {
410
- this.props.history.push(
411
- flattenToAppURL(
412
- this.props.content.working_copy_of['@id'],
413
- ),
414
- );
415
- this.props.closeMenu();
416
- toast.info(
417
- <Toast
418
- info
419
- title={intl.formatMessage(
420
- messages.workingAppliedTitle,
421
- )}
422
- content={intl.formatMessage(
423
- messages.workingCopyAppliedBy,
424
- {
425
- creator: content.working_copy?.creator_name,
426
- date: (
427
- <FormattedDate
428
- date={content.working_copy?.created}
429
- format={dateOptions}
430
- />
431
- ),
432
- },
433
- )}
434
- />,
435
- {
436
- toastId: 'workingcopyapplyinfo',
437
- autoClose: 10000,
438
- },
439
- );
440
- });
441
- }}
442
- >
443
- {this.props.intl.formatMessage(
444
- messages.applyWorkingCopy,
445
- )}
446
-
447
- <Icon
448
- name={applySVG}
449
- size="24px"
450
- title={this.props.intl.formatMessage(
451
- messages.applyWorkingCopy,
452
- )}
453
- />
454
- </button>
455
- </li>
456
- <li>
457
- <button
458
- aria-label={this.props.intl.formatMessage(
459
- messages.removeWorkingCopy,
460
- )}
461
- onClick={() => {
462
- this.props
463
- .removeWorkingCopy(path)
464
- .then((response) => {
465
- this.props.history.push(
466
- flattenToAppURL(
467
- this.props.content.working_copy_of['@id'],
468
- ),
469
- );
470
- this.props.closeMenu();
471
- toast.info(
472
- <Toast
473
- info
474
- title={intl.formatMessage(
475
- messages.workingCopyRemovedTitle,
476
- )}
477
- />,
478
- {
479
- toastId: 'workingcopyremovednotice',
480
- autoClose: 10000,
481
- },
482
- );
483
- });
484
- }}
485
- >
486
- {this.props.intl.formatMessage(
487
- messages.removeWorkingCopy,
488
- )}
439
+ </Plug>
440
+ )}
441
+ </>
442
+ )}
443
+ {editAction && config.settings.isMultilingual && (
444
+ <Plug pluggable="toolbar-more-manage-content" id="multilingual">
445
+ <li>
446
+ <Link to={`${path}/manage-translations`}>
447
+ {intl.formatMessage(messages.ManageTranslations)}
489
448
 
490
- <Icon
491
- name={removeSVG}
492
- size="24px"
493
- color="#e40166"
494
- title={this.props.intl.formatMessage(
495
- messages.removeWorkingCopy,
496
- )}
497
- />
498
- </button>
499
- </li>
500
- </Plug>
501
- )}
502
- {this.props.content.working_copy &&
503
- !this.props.content.working_copy_of && (
504
- <Plug
505
- pluggable="toolbar-more-manage-content"
506
- id="workingcopy"
507
- >
508
- <li>
509
- <Link
510
- to={flattenToAppURL(
511
- this.props.content.working_copy['@id'],
512
- )}
513
- onClick={() => this.props.closeMenu()}
514
- >
515
- {this.props.intl.formatMessage(
516
- messages.viewWorkingCopy,
517
- )}
518
- <Icon name={rightArrowSVG} size="24px" />
519
- </Link>
520
- </li>
521
- </Plug>
522
- )}
523
- </>
524
- )}
525
- {editAction && config.settings.isMultilingual && (
526
- <Plug pluggable="toolbar-more-manage-content" id="multilingual">
527
- <li>
528
- <Link to={`${path}/manage-translations`}>
529
- {this.props.intl.formatMessage(messages.ManageTranslations)}
449
+ <Icon name={rightArrowSVG} size="24px" />
450
+ </Link>
451
+ </li>
452
+ </Plug>
453
+ )}
454
+ </div>
455
+ );
456
+ };
530
457
 
531
- <Icon name={rightArrowSVG} size="24px" />
532
- </Link>
533
- </li>
534
- </Plug>
535
- )}
536
- </div>
537
- );
538
- }
539
- }
458
+ More.propTypes = {
459
+ loadComponent: PropTypes.func.isRequired,
460
+ closeMenu: PropTypes.func.isRequired,
461
+ };
540
462
 
541
- export default compose(
542
- injectIntl,
543
- withRouter,
544
- connect(
545
- (state, props) => ({
546
- actions: state.actions.actions,
547
- pathname: props.pathname,
548
- content: state.content.data,
549
- lang: state.intl.locale,
550
- workingCopy: state.workingCopy,
551
- }),
552
- { applyWorkingCopy, createWorkingCopy, removeWorkingCopy },
553
- ),
554
- )(More);
463
+ export default More;