@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,4 +1,3 @@
1
- import React from 'react';
2
1
  import { Button } from 'semantic-ui-react';
3
2
  import { defineMessages, injectIntl } from 'react-intl';
4
3
  import cx from 'classnames';
@@ -31,6 +30,10 @@ const messages = defineMessages({
31
30
  id: 'Descending',
32
31
  defaultMessage: 'Descending',
33
32
  },
33
+ sortedOn: {
34
+ id: 'Sorted on',
35
+ defaultMessage: 'Sorted on',
36
+ },
34
37
  });
35
38
 
36
39
  const SortOn = (props) => {
@@ -48,9 +51,17 @@ const SortOn = (props) => {
48
51
  const { sortable_indexes } = querystring;
49
52
  const Select = reactSelect.default;
50
53
 
51
- const activeSortOn = sortOn || data?.query?.sort_on || '';
54
+ const defaultSortOn = data?.query?.sort_on || '';
55
+ const activeSortOn = sortOn || defaultSortOn;
56
+
57
+ let { sortOnOptions = [] } = data;
58
+ sortOnOptions = [defaultSortOn, ...sortOnOptions];
59
+ sortOnOptions = [...new Set(sortOnOptions)];
52
60
 
53
- const { sortOnOptions = [] } = data;
61
+ const showSelectField = sortOnOptions.length > 1;
62
+ if (!showSelectField && !activeSortOn) {
63
+ return null;
64
+ }
54
65
  const value = {
55
66
  value: activeSortOn || intl.formatMessage(messages.noSelection),
56
67
  label:
@@ -62,59 +73,75 @@ const SortOn = (props) => {
62
73
  return (
63
74
  <div className="search-sort-wrapper">
64
75
  <div className="search-sort-on">
65
- <span className="sort-label">
66
- {intl.formatMessage(messages.sortOn)}
67
- </span>
68
- <Select
69
- id="select-search-sort-on"
70
- name="select-searchblock-sort-on"
71
- className="search-react-select-container"
72
- classNamePrefix="react-select"
73
- placeholder={intl.formatMessage(messages.sortOn)}
74
- styles={sortOnSelectStyles}
75
- theme={selectTheme}
76
- components={{ DropdownIndicator, Option }}
77
- options={[
78
- ...sortOnOptions.map((k) => ({
79
- value: k,
80
- label: sortable_indexes[k]?.title || k,
81
- })),
82
- ]}
83
- isSearchable={false}
84
- value={value}
85
- onChange={(data) => {
86
- !isEditMode && setSortOn(data.value);
87
- }}
88
- />
76
+ {showSelectField ? (
77
+ <>
78
+ <span className="sort-label">
79
+ {intl.formatMessage(messages.sortOn)}
80
+ </span>
81
+ <Select
82
+ id="select-search-sort-on"
83
+ name="select-searchblock-sort-on"
84
+ className="search-react-select-container"
85
+ classNamePrefix="react-select"
86
+ placeholder={intl.formatMessage(messages.sortOn)}
87
+ styles={sortOnSelectStyles}
88
+ theme={selectTheme}
89
+ components={{ DropdownIndicator, Option }}
90
+ options={[
91
+ ...sortOnOptions.map((k) => ({
92
+ value: k,
93
+ label:
94
+ sortable_indexes[k]?.title ||
95
+ k ||
96
+ intl.formatMessage(messages.noSelection),
97
+ })),
98
+ ]}
99
+ isSearchable={false}
100
+ value={value}
101
+ onChange={(data) => {
102
+ !isEditMode && setSortOn(data.value);
103
+ }}
104
+ />
105
+ </>
106
+ ) : (
107
+ <span className="sorted-label">
108
+ {intl.formatMessage(messages.sortedOn)}
109
+ <span className="sorted-label-value">{value.label}</span>
110
+ </span>
111
+ )}
89
112
  </div>
90
- <Button
91
- icon
92
- basic
93
- compact
94
- title={intl.formatMessage(messages.ascending)}
95
- className={cx({
96
- active: sortOrder === 'ascending',
97
- })}
98
- onClick={() => {
99
- !isEditMode && setSortOrder('ascending');
100
- }}
101
- >
102
- <Icon name={upSVG} size="25px" />
103
- </Button>
104
- <Button
105
- icon
106
- basic
107
- compact
108
- title={intl.formatMessage(messages.descending)}
109
- className={cx({
110
- active: sortOrder === 'descending',
111
- })}
112
- onClick={() => {
113
- !isEditMode && setSortOrder('descending');
114
- }}
115
- >
116
- <Icon name={downSVG} size="25px" />
117
- </Button>
113
+ {activeSortOn ? (
114
+ <>
115
+ <Button
116
+ icon
117
+ basic
118
+ compact
119
+ title={intl.formatMessage(messages.ascending)}
120
+ className={cx({
121
+ active: sortOrder === 'ascending',
122
+ })}
123
+ onClick={() => {
124
+ !isEditMode && setSortOrder('ascending');
125
+ }}
126
+ >
127
+ <Icon name={downSVG} size="25px" />
128
+ </Button>
129
+ <Button
130
+ icon
131
+ basic
132
+ compact
133
+ title={intl.formatMessage(messages.descending)}
134
+ className={cx({
135
+ active: sortOrder === 'descending',
136
+ })}
137
+ onClick={() => {
138
+ !isEditMode && setSortOrder('descending');
139
+ }}
140
+ >
141
+ <Icon name={upSVG} size="25px" />
142
+ </Button>
143
+ </>
144
+ ) : null}
118
145
  </div>
119
146
  );
120
147
  };
@@ -321,7 +321,7 @@ const withSearch = (options) => (WrappedComponent) => {
321
321
  const previousUrlQuery = usePrevious(urlQuery);
322
322
 
323
323
  // During first render the previousUrlQuery is undefined and urlQuery
324
- // is empty so it ressetting the facet when you are navigating but during reload we have urlQuery and we need
324
+ // is empty so it resetting the facet when you are navigating but during reload we have urlQuery and we need
325
325
  // to set the facet at first render.
326
326
  const preventOverrideOfFacetState =
327
327
  previousUrlQuery === undefined && urlQuery.length === 0;
@@ -3,8 +3,8 @@
3
3
  * @module components/manage/Widgets/SelectWidget
4
4
  */
5
5
 
6
- import { map, intersection, filter, toPairs, groupBy } from 'lodash';
7
- import React, { Component } from 'react';
6
+ import { map, filter, toPairs, groupBy } from 'lodash';
7
+ import { useEffect } from 'react';
8
8
  import PropTypes from 'prop-types';
9
9
  import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
10
10
  import { compose } from 'redux';
@@ -30,187 +30,118 @@ const messages = defineMessages({
30
30
  });
31
31
 
32
32
  /**
33
- * SelectWidget component class.
33
+ * SelectWidget component function.
34
34
  * @function SelectWidget
35
35
  * @returns {string} Markup of the component.
36
36
  */
37
- class SelectWidget extends Component {
38
- /**
39
- * Property types.
40
- * @property {Object} propTypes Property types.
41
- * @static
42
- */
43
- static propTypes = {
44
- id: PropTypes.string.isRequired,
45
- title: PropTypes.string.isRequired,
46
- description: PropTypes.string,
47
- required: PropTypes.bool,
48
- error: PropTypes.arrayOf(PropTypes.string),
49
- loading: PropTypes.bool,
50
- value: PropTypes.oneOfType([
51
- PropTypes.object,
52
- PropTypes.string,
53
- PropTypes.bool,
54
- ]),
55
- onChange: PropTypes.func.isRequired,
56
- onBlur: PropTypes.func,
57
- onClick: PropTypes.func,
58
- onEdit: PropTypes.func,
59
- onDelete: PropTypes.func,
60
- wrapped: PropTypes.bool,
61
- querystring: PropTypes.object,
62
- };
37
+ const SelectWidget = (props) => {
38
+ const { choices, vocabBaseUrl, getVocabulary } = props;
63
39
 
64
- /**
65
- * Default properties
66
- * @property {Object} defaultProps Default properties.
67
- * @static
68
- */
69
- static defaultProps = {
70
- description: null,
71
- required: false,
72
- items: {
73
- vocabulary: null,
74
- },
75
- widgetOptions: {
76
- vocabulary: null,
77
- },
78
- error: [],
79
- choices: [],
80
- loading: false,
81
- value: null,
82
- onChange: () => {},
83
- onBlur: () => {},
84
- onClick: () => {},
85
- onEdit: null,
86
- onDelete: null,
87
- };
88
-
89
- state = {
90
- selectedOption: this.props.value
91
- ? { label: this.props.value.title, value: this.props.value.value }
92
- : {},
93
- };
94
-
95
- /**
96
- * Component did mount
97
- * @method componentDidMount
98
- * @returns {undefined}
99
- */
100
- componentDidMount() {
101
- if (!this.props.choices && this.props.vocabBaseUrl) {
102
- this.props.getVocabulary({ vocabNameOrURL: this.props.vocabBaseUrl });
40
+ useEffect(() => {
41
+ if (!choices && vocabBaseUrl) {
42
+ getVocabulary({ vocabNameOrURL: vocabBaseUrl });
103
43
  }
104
- }
105
-
106
- /**
107
- * Initiate search with new query
108
- * @method loadOptions
109
- * @param {string} search Search query.
110
- * @param {string} previousOptions The previous options rendered.
111
- * @param {string} additional Additional arguments to pass to the next loadOptions.
112
- * @returns {undefined}
113
- */
114
- loadOptions = (search, previousOptions, additional) => {
115
- let hasMore = this.props.itemsTotal > previousOptions.length;
116
- if (hasMore) {
117
- const offset = this.state.search !== search ? 0 : additional.offset;
118
- this.props.getVocabulary({
119
- vocabNameOrURL: this.props.vocabBaseUrl,
120
- query: search,
121
- start: offset,
122
- });
123
- this.setState({ search });
124
-
125
- return {
126
- options:
127
- intersection(previousOptions, this.props.choices).length ===
128
- this.props.choices.length
129
- ? []
130
- : this.props.choices,
131
- hasMore: hasMore,
132
- additional: {
133
- offset: offset === additional.offset ? offset + 25 : offset,
134
- },
135
- };
136
- }
137
- return null;
138
- };
139
-
140
- /* Customized to pass object instead of plain string value */
141
- handleChange = (selectedOption) => {
142
- this.setState({ selectedOption });
143
- this.props.onChange(this.props.id, {
144
- value: selectedOption.value,
145
- title: selectedOption.label,
146
- });
147
- };
148
-
149
- /**
150
- * Render method.
151
- * @method render
152
- * @returns {string} Markup for the component.
153
- */
154
- render() {
155
- const {
156
- id,
157
- // choices,
158
- value,
159
- onChange,
160
- placeholder,
161
- querystring,
162
- filterOptions = identity,
163
- } = this.props;
164
- const isDisabled = false;
165
- const { indexes = [] } = querystring;
166
-
167
- const Select = this.props.reactSelect.default;
168
-
169
- return (
170
- <FormFieldWrapper {...this.props}>
171
- <Select
172
- id={`field-${id}`}
173
- name={id}
174
- placeholder={
175
- placeholder ?? this.props.intl.formatMessage(messages.select)
176
- }
177
- isDisabled={isDisabled}
178
- className="react-select-container"
179
- classNamePrefix="react-select"
180
- options={map(
181
- toPairs(
182
- groupBy(toPairs(filterOptions(indexes)), (item) => item[1].group),
44
+ }, [choices, vocabBaseUrl, getVocabulary]);
45
+
46
+ const {
47
+ id,
48
+ value,
49
+ onChange,
50
+ placeholder,
51
+ querystring,
52
+ filterOptions = identity,
53
+ } = props;
54
+
55
+ const isDisabled = false;
56
+ const { indexes = [] } = querystring;
57
+ const Select = props.reactSelect.default;
58
+
59
+ return (
60
+ <FormFieldWrapper {...props}>
61
+ <Select
62
+ id={`field-${id}`}
63
+ name={id}
64
+ placeholder={placeholder ?? props.intl.formatMessage(messages.select)}
65
+ isDisabled={isDisabled}
66
+ className="react-select-container"
67
+ classNamePrefix="react-select"
68
+ options={map(
69
+ toPairs(
70
+ groupBy(toPairs(filterOptions(indexes)), (item) => item[1].group),
71
+ ),
72
+ (group) => ({
73
+ label: group[0],
74
+ options: map(
75
+ filter(group[1], (item) => item[1].enabled),
76
+ (field) => ({
77
+ label: field[1].title,
78
+ value: field[0],
79
+ }),
183
80
  ),
184
- (group) => ({
185
- label: group[0],
186
- options: map(
187
- filter(group[1], (item) => item[1].enabled),
188
- (field) => ({
189
- label: field[1].title,
190
- value: field[0],
191
- }),
192
- ),
193
- }),
194
- )}
195
- styles={customSelectStyles}
196
- theme={selectTheme}
197
- components={{ DropdownIndicator, Option }}
198
- value={{ value: value?.value, label: indexes[value?.value]?.title }}
199
- onChange={(data) => {
200
- let dataValue = [];
201
- if (Array.isArray(data)) {
202
- for (let obj of data) {
203
- dataValue.push(obj.value);
204
- }
205
- return onChange(id, dataValue);
81
+ }),
82
+ )}
83
+ styles={customSelectStyles}
84
+ theme={selectTheme}
85
+ components={{ DropdownIndicator, Option }}
86
+ value={{
87
+ value: value?.value,
88
+ label: indexes[value?.value]?.title,
89
+ }}
90
+ onChange={(data) => {
91
+ let dataValue = [];
92
+ if (Array.isArray(data)) {
93
+ for (let obj of data) {
94
+ dataValue.push(obj.value);
206
95
  }
207
- return onChange(id, data);
208
- }}
209
- />
210
- </FormFieldWrapper>
211
- );
212
- }
213
- }
96
+ return onChange(id, dataValue);
97
+ }
98
+ return onChange(id, data);
99
+ }}
100
+ />
101
+ </FormFieldWrapper>
102
+ );
103
+ };
104
+
105
+ SelectWidget.propTypes = {
106
+ id: PropTypes.string.isRequired,
107
+ title: PropTypes.string.isRequired,
108
+ description: PropTypes.string,
109
+ required: PropTypes.bool,
110
+ error: PropTypes.arrayOf(PropTypes.string),
111
+ loading: PropTypes.bool,
112
+ value: PropTypes.oneOfType([
113
+ PropTypes.object,
114
+ PropTypes.string,
115
+ PropTypes.bool,
116
+ ]),
117
+ onChange: PropTypes.func.isRequired,
118
+ onBlur: PropTypes.func,
119
+ onClick: PropTypes.func,
120
+ onEdit: PropTypes.func,
121
+ onDelete: PropTypes.func,
122
+ wrapped: PropTypes.bool,
123
+ querystring: PropTypes.object,
124
+ };
125
+
126
+ SelectWidget.defaultProps = {
127
+ description: null,
128
+ required: false,
129
+ items: {
130
+ vocabulary: null,
131
+ },
132
+ widgetOptions: {
133
+ vocabulary: null,
134
+ },
135
+ error: [],
136
+ choices: [],
137
+ loading: false,
138
+ value: null,
139
+ onChange: () => {},
140
+ onBlur: () => {},
141
+ onClick: () => {},
142
+ onEdit: null,
143
+ onDelete: null,
144
+ };
214
145
 
215
146
  export default compose(
216
147
  withQueryString,
@@ -31,8 +31,15 @@ const messages = defineMessages({
31
31
  });
32
32
 
33
33
  const TeaserData = (props) => {
34
- const { block, blocksConfig, data, onChangeBlock, navRoot, contentType } =
35
- props;
34
+ const {
35
+ block,
36
+ blocksConfig,
37
+ blocksErrors,
38
+ data,
39
+ onChangeBlock,
40
+ navRoot,
41
+ contentType,
42
+ } = props;
36
43
  const dispatch = useDispatch();
37
44
  const intl = useIntl();
38
45
 
@@ -161,6 +168,7 @@ const TeaserData = (props) => {
161
168
  actionButton={data.overwrite && ActionButton}
162
169
  navRoot={navRoot}
163
170
  contentType={contentType}
171
+ errors={blocksErrors}
164
172
  />
165
173
  );
166
174
  };
@@ -22,6 +22,7 @@ const TeaserDefaultTemplate = (props) => {
22
22
  const intl = useIntl();
23
23
  const href = data.href?.[0];
24
24
  const image = data.preview_image?.[0];
25
+ const url = data.preview_image?.[0]?.['@id'];
25
26
 
26
27
  const Image = config.getComponent('Image').component;
27
28
  const { openExternalLinkInNewTab } = config.settings;
@@ -50,16 +51,22 @@ const TeaserDefaultTemplate = (props) => {
50
51
  }
51
52
  >
52
53
  <div className="teaser-item default">
53
- {(href.hasPreviewImage || href.image_field || image) && (
54
+ {url && !image?.image_field ? (
54
55
  <div className="image-wrapper">
55
- <Image
56
- item={image || href}
57
- imageField={image ? image.image_field : href.image_field}
58
- alt=""
59
- loading="lazy"
60
- responsive={true}
61
- />
56
+ <Image src={url} alt="" loading="lazy" responsive={true} />
62
57
  </div>
58
+ ) : (
59
+ (href.hasPreviewImage || href.image_field || image) && (
60
+ <div className="image-wrapper">
61
+ <Image
62
+ item={image || href}
63
+ imageField={image ? image.image_field : href.image_field}
64
+ alt=""
65
+ loading="lazy"
66
+ responsive={true}
67
+ />
68
+ </div>
69
+ )
63
70
  )}
64
71
  <div className="content">
65
72
  {data?.head_title && (
@@ -1,4 +1,4 @@
1
- import React, { Component } from 'react';
1
+ import React from 'react';
2
2
 
3
3
  import { SidebarPortal } from '@plone/volto/components';
4
4
  import { BlockDataForm } from '@plone/volto/components/manage/Form';
@@ -6,34 +6,42 @@ import { BlockDataForm } from '@plone/volto/components/manage/Form';
6
6
  import TableOfContentsSchema from './Schema';
7
7
  import View from './View';
8
8
 
9
- class Edit extends Component {
10
- render() {
11
- const schema = TableOfContentsSchema(this.props);
9
+ const Edit = (props) => {
10
+ const {
11
+ onChangeBlock,
12
+ data,
13
+ block,
14
+ selected,
15
+ navRoot,
16
+ contentType,
17
+ blocksErrors,
18
+ } = props;
19
+ const schema = TableOfContentsSchema(props);
12
20
 
13
- return (
14
- <>
15
- <View {...this.props} mode="edit" />
21
+ return (
22
+ <>
23
+ <View {...props} mode="edit" />
16
24
 
17
- <SidebarPortal selected={this.props.selected}>
18
- <BlockDataForm
19
- schema={schema}
20
- title={schema.title}
21
- onChangeField={(id, value) => {
22
- this.props.onChangeBlock(this.props.block, {
23
- ...this.props.data,
24
- [id]: value,
25
- });
26
- }}
27
- onChangeBlock={this.props.onChangeBlock}
28
- formData={this.props.data}
29
- block={this.props.block}
30
- navRoot={this.props.navRoot}
31
- contentType={this.props.contentType}
32
- />
33
- </SidebarPortal>
34
- </>
35
- );
36
- }
37
- }
25
+ <SidebarPortal selected={selected}>
26
+ <BlockDataForm
27
+ schema={schema}
28
+ title={schema.title}
29
+ onChangeField={(id, value) => {
30
+ onChangeBlock(block, {
31
+ ...data,
32
+ [id]: value,
33
+ });
34
+ }}
35
+ onChangeBlock={onChangeBlock}
36
+ formData={data}
37
+ block={block}
38
+ navRoot={navRoot}
39
+ contentType={contentType}
40
+ errors={blocksErrors}
41
+ />
42
+ </SidebarPortal>
43
+ </>
44
+ );
45
+ };
38
46
 
39
47
  export default Edit;