@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
@@ -144,12 +144,14 @@ export class Edit extends Component {
144
144
  {Block !== null ? (
145
145
  <div
146
146
  role="presentation"
147
- onMouseOver={() => {
147
+ onMouseEnter={(e) => {
148
+ e.preventDefault();
149
+ e.stopPropagation();
148
150
  if (this.props.hovered !== this.props.id) {
149
151
  this.props.setUIState({ hovered: this.props.id });
150
152
  }
151
153
  }}
152
- onFocus={() => {
154
+ onFocus={(e) => {
153
155
  // TODO: This `onFocus` steals somehow the focus from the slate block
154
156
  // we have to investigate why this is happening
155
157
  // Apparently, I can't see any difference in the behavior
@@ -158,7 +160,11 @@ export class Edit extends Component {
158
160
  // this.props.setUIState({ hovered: this.props.id });
159
161
  // }
160
162
  }}
161
- onMouseLeave={() => this.props.setUIState({ hovered: null })}
163
+ onMouseLeave={(e) => {
164
+ e.preventDefault();
165
+ e.stopPropagation();
166
+ this.props.setUIState({ hovered: null });
167
+ }}
162
168
  onClick={(e) => {
163
169
  const isMultipleSelection = e.shiftKey || e.ctrlKey || e.metaKey;
164
170
  !this.props.selected &&
@@ -207,11 +213,21 @@ export class Edit extends Component {
207
213
  ) : (
208
214
  <div
209
215
  role="presentation"
210
- onMouseOver={() =>
211
- this.props.setUIState({ hovered: this.props.id })
212
- }
213
- onFocus={() => this.props.setUIState({ hovered: this.props.id })}
214
- onMouseLeave={() => this.props.setUIState({ hovered: null })}
216
+ onMouseEnter={(e) => {
217
+ e.preventDefault();
218
+ e.stopPropagation();
219
+ this.props.setUIState({ hovered: this.props.id });
220
+ }}
221
+ onFocus={(e) => {
222
+ e.preventDefault();
223
+ e.stopPropagation();
224
+ this.props.setUIState({ hovered: this.props.id });
225
+ }}
226
+ onMouseLeave={(e) => {
227
+ e.preventDefault();
228
+ e.stopPropagation();
229
+ this.props.setUIState({ hovered: null });
230
+ }}
215
231
  onClick={() =>
216
232
  !this.props.selected && this.props.onSelectBlock(this.props.id)
217
233
  }
@@ -1,6 +1,8 @@
1
1
  import React from 'react';
2
2
  import { Icon } from '@plone/volto/components';
3
3
  import {
4
+ applyBlockInitialValue,
5
+ getBlocksFieldname,
4
6
  blockHasValue,
5
7
  buildStyleClassNamesFromData,
6
8
  buildStyleObjectFromData,
@@ -111,7 +113,21 @@ const EditBlockWrapper = (props) => {
111
113
  if (blockHasValue(data)) {
112
114
  onSelectBlock(onInsertBlock(id, value));
113
115
  } else {
114
- onChangeBlock(id, value);
116
+ const blocksFieldname = getBlocksFieldname(properties);
117
+ const newFormData = applyBlockInitialValue({
118
+ id,
119
+ value,
120
+ blocksConfig,
121
+ formData: {
122
+ ...properties,
123
+ [blocksFieldname]: {
124
+ ...properties[blocksFieldname],
125
+ [id]: value || null,
126
+ },
127
+ },
128
+ });
129
+ const newValue = newFormData[blocksFieldname][id];
130
+ onChangeBlock(id, newValue);
115
131
  }
116
132
  }}
117
133
  onMutateBlock={onMutateBlock}
@@ -2,7 +2,7 @@ import React, { forwardRef } from 'react';
2
2
  import classNames from 'classnames';
3
3
  import { useDispatch, useSelector } from 'react-redux';
4
4
  import { includes } from 'lodash';
5
-
5
+ import cx from 'classnames';
6
6
  import { Icon } from '@plone/volto/components';
7
7
  import { setUIState } from '@plone/volto/actions';
8
8
  import config from '@plone/volto/registry';
@@ -28,6 +28,7 @@ export const Item = forwardRef(
28
28
  style,
29
29
  value,
30
30
  wrapperRef,
31
+ errors,
31
32
  ...props
32
33
  },
33
34
  ref,
@@ -37,6 +38,7 @@ export const Item = forwardRef(
37
38
  const multiSelected = useSelector((state) => state.form.ui.multiSelected);
38
39
  const gridSelected = useSelector((state) => state.form.ui.gridSelected);
39
40
  const dispatch = useDispatch();
41
+
40
42
  return (
41
43
  <li
42
44
  className={classNames(
@@ -95,7 +97,11 @@ export const Item = forwardRef(
95
97
  >
96
98
  <Icon name={dragSVG} size="16px" />
97
99
  </button>
98
- <span className="text">
100
+ <span
101
+ className={cx('text', {
102
+ errored: errors && Object.keys(errors).length > 0,
103
+ })}
104
+ >
99
105
  {config.blocks.blocksConfig[data?.['@type']]?.icon && (
100
106
  <Icon
101
107
  name={config.blocks.blocksConfig[data?.['@type']]?.icon}
@@ -17,6 +17,7 @@ export function Order({
17
17
  dndKitCore,
18
18
  dndKitSortable,
19
19
  dndKitUtilities,
20
+ errors,
20
21
  }) {
21
22
  const [activeId, setActiveId] = useState(null);
22
23
  const [overId, setOverId] = useState(null);
@@ -146,6 +147,7 @@ export function Order({
146
147
  indentationWidth={indentationWidth}
147
148
  onRemove={removable ? () => handleRemove(id) : undefined}
148
149
  onSelectBlock={onSelectBlock}
150
+ errors={errors?.[id] || {}}
149
151
  />
150
152
  ))}
151
153
  {createPortal(
@@ -2,8 +2,15 @@ import { useIntl } from 'react-intl';
2
2
  import { BlockDataForm } from '@plone/volto/components/manage/Form';
3
3
 
4
4
  const ContainerData = (props) => {
5
- const { block, blocksConfig, data, onChangeBlock, navRoot, contentType } =
6
- props;
5
+ const {
6
+ block,
7
+ blocksConfig,
8
+ blocksErrors,
9
+ data,
10
+ onChangeBlock,
11
+ navRoot,
12
+ contentType,
13
+ } = props;
7
14
  const intl = useIntl();
8
15
 
9
16
  const schema = blocksConfig[data['@type']].blockSchema({ intl });
@@ -28,6 +35,7 @@ const ContainerData = (props) => {
28
35
  blocksConfig={blocksConfig}
29
36
  navRoot={navRoot}
30
37
  contentType={contentType}
38
+ errors={blocksErrors}
31
39
  />
32
40
  );
33
41
  };
@@ -7,6 +7,9 @@ import config from '@plone/volto/registry';
7
7
  const GridBlockView = (props) => {
8
8
  const { data, path, className, style } = props;
9
9
  const metadata = props.metadata || props.properties;
10
+ if (data.blocks_layout === undefined) {
11
+ return null;
12
+ }
10
13
  const columns = data.blocks_layout.items;
11
14
  const blocksConfig =
12
15
  config.blocks.blocksConfig[data['@type']].blocksConfig ||
@@ -10,8 +10,15 @@ import imageSVG from '@plone/volto/icons/image.svg';
10
10
  import trashSVG from '@plone/volto/icons/delete.svg';
11
11
 
12
12
  const ImageSidebar = (props) => {
13
- const { blocksConfig, data, block, onChangeBlock, navRoot, contentType } =
14
- props;
13
+ const {
14
+ blocksConfig,
15
+ blocksErrors,
16
+ data,
17
+ block,
18
+ onChangeBlock,
19
+ navRoot,
20
+ contentType,
21
+ } = props;
15
22
  const intl = useIntl();
16
23
  const schema = ImageSchema({ formData: data, intl });
17
24
  return (
@@ -98,6 +105,7 @@ const ImageSidebar = (props) => {
98
105
  blocksConfig={blocksConfig}
99
106
  navRoot={navRoot}
100
107
  contentType={contentType}
108
+ errors={blocksErrors}
101
109
  />
102
110
  </>
103
111
  );
@@ -1,15 +1,8 @@
1
- /**
2
- * Edit image block.
3
- * @module components/manage/Blocks/Image/Edit
4
- */
5
-
6
- import React, { Component } from 'react';
1
+ import React from 'react';
7
2
  import PropTypes from 'prop-types';
8
- import { compose } from 'redux';
9
- import { defineMessages, injectIntl } from 'react-intl';
3
+ import { defineMessages, useIntl } from 'react-intl';
10
4
  import cx from 'classnames';
11
5
  import { Message } from 'semantic-ui-react';
12
- import { isEqual } from 'lodash';
13
6
 
14
7
  import { LeadImageSidebar, SidebarPortal } from '@plone/volto/components';
15
8
  import config from '@plone/volto/registry';
@@ -23,124 +16,79 @@ const messages = defineMessages({
23
16
  },
24
17
  });
25
18
 
26
- /**
27
- * Edit image block class.
28
- * @class Edit
29
- * @extends Component
30
- */
31
- class Edit extends Component {
32
- /**
33
- * Property types.
34
- * @property {Object} propTypes Property types.
35
- * @static
36
- */
37
- static propTypes = {
38
- properties: PropTypes.objectOf(PropTypes.any).isRequired,
39
- selected: PropTypes.bool.isRequired,
40
- block: PropTypes.string.isRequired,
41
- index: PropTypes.number.isRequired,
42
- data: PropTypes.objectOf(PropTypes.any).isRequired,
43
- pathname: PropTypes.string.isRequired,
44
- onChangeBlock: PropTypes.func.isRequired,
45
- openObjectBrowser: PropTypes.func.isRequired,
46
- };
47
-
48
- /**
49
- * Align block handler
50
- * @method onAlignBlock
51
- * @param {string} align Alignment option
52
- * @returns {undefined}
53
- */
54
- onAlignBlock(align) {
55
- this.props.onChangeBlock(this.props.block, {
56
- ...this.props.data,
57
- align,
58
- });
59
- }
60
-
61
- /**
62
- * @param {*} nextProps
63
- * @returns {boolean}
64
- * @memberof Edit
65
- */
66
- shouldComponentUpdate(nextProps) {
67
- return (
68
- this.props.selected ||
69
- nextProps.selected ||
70
- !isEqual(this.props.data, nextProps.data)
71
- );
72
- }
73
-
74
- node = React.createRef();
19
+ const Edit = (props) => {
20
+ const intl = useIntl();
21
+ const { data, properties, selected } = props;
75
22
 
76
- /**
77
- * Render method.
78
- * @method render
79
- * @returns {string} Markup for the component.
80
- */
81
- render() {
82
- const Image = config.getComponent({ name: 'Image' }).component;
83
- const { data, properties } = this.props;
84
- const placeholder =
85
- this.props.data.placeholder ||
86
- this.props.intl.formatMessage(messages.ImageBlockInputPlaceholder);
23
+ const placeholder = () =>
24
+ data.placeholder || intl.formatMessage(messages.ImageBlockInputPlaceholder);
87
25
 
88
- const hasImage = !!properties.image;
89
- const hasImageData = hasImage && !!properties.image.data;
90
- const className = cx('responsive', { 'full-image': data.align === 'full' });
91
- const altText = data.image_caption || properties.image_caption || '';
26
+ const Image = config.getComponent({ name: 'Image' }).component;
27
+ const hasImage = !!properties.image;
28
+ const hasImageData = hasImage && !!properties.image.data;
29
+ const className = cx('responsive', { 'full-image': data.align === 'full' });
30
+ const altText = data.image_caption || properties.image_caption || '';
92
31
 
93
- return (
94
- <div
95
- className={cx(
96
- 'block image align',
97
- {
98
- center: !Boolean(data.align),
99
- },
100
- data.align,
101
- )}
102
- >
103
- {!hasImage && (
104
- <Message>
105
- <center>
106
- <img src={imageBlockSVG} alt="" />
107
- <div className="message-text">{placeholder}</div>
108
- </center>
109
- </Message>
110
- )}
111
- {hasImage && hasImageData && (
112
- <img
113
- className={className}
114
- src={`data:${properties.image['content-type']};base64,${properties.image.data}`}
115
- width={properties.image.width}
116
- height={properties.image.height}
117
- alt={altText}
118
- style={{
119
- aspectRatio: `${properties.image.width}/${properties.image.height}`,
120
- }}
121
- />
122
- )}
123
- {hasImage && !hasImageData && (
124
- <Image
125
- className={className}
126
- item={properties}
127
- imageField="image"
128
- sizes={(() => {
129
- if (data.align === 'full' || data.align === 'center')
130
- return '100vw';
131
- if (data.align === 'left' || data.align === 'right')
132
- return '50vw';
133
- return undefined;
134
- })()}
135
- alt={altText}
136
- />
137
- )}
138
- <SidebarPortal selected={this.props.selected}>
139
- <LeadImageSidebar {...this.props} />
140
- </SidebarPortal>
141
- </div>
142
- );
143
- }
144
- }
32
+ return (
33
+ <div
34
+ className={cx(
35
+ 'block image align',
36
+ {
37
+ center: !Boolean(data.align),
38
+ },
39
+ data.align,
40
+ )}
41
+ >
42
+ {!hasImage && (
43
+ <Message>
44
+ <center>
45
+ <img src={imageBlockSVG} alt="" />
46
+ <div className="message-text">{placeholder}</div>
47
+ </center>
48
+ </Message>
49
+ )}
50
+ {hasImage && hasImageData && (
51
+ <img
52
+ className={className}
53
+ src={`data:${properties.image['content-type']};base64,${properties.image.data}`}
54
+ width={properties.image.width}
55
+ height={properties.image.height}
56
+ alt={altText}
57
+ style={{
58
+ aspectRatio: `${properties.image.width}/${properties.image.height}`,
59
+ }}
60
+ />
61
+ )}
62
+ {hasImage && !hasImageData && (
63
+ <Image
64
+ className={className}
65
+ item={properties}
66
+ imageField="image"
67
+ sizes={(() => {
68
+ return data.align === 'full' || data.align === 'center'
69
+ ? '100vw'
70
+ : data.align === 'left' || data.align === 'right'
71
+ ? '50vw'
72
+ : undefined;
73
+ })()}
74
+ alt={altText}
75
+ />
76
+ )}
77
+ <SidebarPortal selected={selected}>
78
+ <LeadImageSidebar {...props} />
79
+ </SidebarPortal>
80
+ </div>
81
+ );
82
+ };
145
83
 
146
- export default compose(injectIntl)(Edit);
84
+ export default Edit;
85
+ Edit.propTypes = {
86
+ properties: PropTypes.objectOf(PropTypes.any).isRequired,
87
+ selected: PropTypes.bool.isRequired,
88
+ block: PropTypes.string.isRequired,
89
+ index: PropTypes.number.isRequired,
90
+ data: PropTypes.objectOf(PropTypes.any).isRequired,
91
+ pathname: PropTypes.string.isRequired,
92
+ onChangeBlock: PropTypes.func.isRequired,
93
+ openObjectBrowser: PropTypes.func.isRequired,
94
+ };
@@ -4,8 +4,15 @@ import { useIntl } from 'react-intl';
4
4
  import { BlockDataForm } from '@plone/volto/components/manage/Form';
5
5
 
6
6
  const ListingData = (props) => {
7
- const { data, block, blocksConfig, onChangeBlock, navRoot, contentType } =
8
- props;
7
+ const {
8
+ data,
9
+ block,
10
+ blocksConfig,
11
+ blocksErrors,
12
+ onChangeBlock,
13
+ navRoot,
14
+ contentType,
15
+ } = props;
9
16
  const intl = useIntl();
10
17
  const schema = blocksConfig.listing.blockSchema({
11
18
  ...props,
@@ -28,6 +35,7 @@ const ListingData = (props) => {
28
35
  block={block}
29
36
  navRoot={navRoot}
30
37
  contentType={contentType}
38
+ errors={blocksErrors}
31
39
  />
32
40
  );
33
41
  };
@@ -18,7 +18,8 @@ const messages = defineMessages({
18
18
  });
19
19
 
20
20
  const MapsSidebar = (props) => {
21
- const { data, block, onChangeBlock, navRoot, contentType } = props;
21
+ const { data, block, blocksErrors, onChangeBlock, navRoot, contentType } =
22
+ props;
22
23
  const intl = useIntl();
23
24
  const schema = MapsSchema({ ...props, intl });
24
25
 
@@ -44,6 +45,7 @@ const MapsSidebar = (props) => {
44
45
  block={block}
45
46
  navRoot={navRoot}
46
47
  contentType={contentType}
48
+ errors={blocksErrors}
47
49
  />
48
50
  )}
49
51
  </>
@@ -23,6 +23,7 @@ const messages = defineMessages({
23
23
  const SearchBlockEdit = (props) => {
24
24
  const {
25
25
  block,
26
+ blocksErrors,
26
27
  onChangeBlock,
27
28
  data,
28
29
  selected,
@@ -94,6 +95,7 @@ const SearchBlockEdit = (props) => {
94
95
  formData={data}
95
96
  navRoot={navRoot}
96
97
  contentType={contentType}
98
+ errors={blocksErrors}
97
99
  />
98
100
  </SidebarPortal>
99
101
  </>
@@ -49,10 +49,26 @@ const applyDefaults = (data, root) => {
49
49
  v: root || '/',
50
50
  },
51
51
  ];
52
+
53
+ const searchBySearchableText = data.query.filter(
54
+ (item) => item['i'] === 'SearchableText',
55
+ ).length;
56
+
57
+ const sort_on = data?.sort_on
58
+ ? { sort_on: data.sort_on }
59
+ : searchBySearchableText === 0
60
+ ? { sort_on: 'effective' }
61
+ : {};
62
+ const sort_order = data?.sort_order
63
+ ? { sort_order: data.sort_order }
64
+ : searchBySearchableText === 0
65
+ ? { sort_order: 'descending' }
66
+ : {};
67
+
52
68
  return {
53
69
  ...data,
54
- sort_on: data?.sort_on || 'effective',
55
- sort_order: data?.sort_order || 'descending',
70
+ ...sort_on,
71
+ ...sort_order,
56
72
  query: data?.query?.length ? data.query : defaultQuery,
57
73
  };
58
74
  };