@plone/volto 18.0.0-alpha.42 → 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 (137) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/finalreleasechangelog.py +48 -0
  3. package/locales/ca/LC_MESSAGES/volto.po +8 -12
  4. package/locales/ca.json +1 -1
  5. package/locales/de/LC_MESSAGES/volto.po +9 -13
  6. package/locales/de.json +1 -1
  7. package/locales/en/LC_MESSAGES/volto.po +8 -12
  8. package/locales/en.json +1 -1
  9. package/locales/es/LC_MESSAGES/volto.po +9 -13
  10. package/locales/es.json +1 -1
  11. package/locales/eu/LC_MESSAGES/volto.po +9 -13
  12. package/locales/eu.json +1 -1
  13. package/locales/fi/LC_MESSAGES/volto.po +9 -13
  14. package/locales/fi.json +1 -1
  15. package/locales/fr/LC_MESSAGES/volto.po +9 -13
  16. package/locales/fr.json +1 -1
  17. package/locales/hi/LC_MESSAGES/volto.po +9 -13
  18. package/locales/hi.json +1 -1
  19. package/locales/it/LC_MESSAGES/volto.po +9 -13
  20. package/locales/it.json +1 -1
  21. package/locales/ja/LC_MESSAGES/volto.po +8 -12
  22. package/locales/ja.json +1 -1
  23. package/locales/nl/LC_MESSAGES/volto.po +8 -12
  24. package/locales/nl.json +1 -1
  25. package/locales/pt/LC_MESSAGES/volto.po +8 -12
  26. package/locales/pt.json +1 -1
  27. package/locales/pt_BR/LC_MESSAGES/volto.po +9 -13
  28. package/locales/pt_BR.json +1 -1
  29. package/locales/ro/LC_MESSAGES/volto.po +8 -12
  30. package/locales/ro.json +1 -1
  31. package/locales/volto.pot +9 -13
  32. package/locales/zh_CN/LC_MESSAGES/volto.po +9 -13
  33. package/locales/zh_CN.json +1 -1
  34. package/package.json +3 -3
  35. package/razzle.config.js +1 -1
  36. package/src/components/manage/Actions/Actions.stories.jsx +138 -0
  37. package/src/components/manage/Add/Add.jsx +7 -4
  38. package/src/components/manage/BlockChooser/BlockChooser.jsx +9 -1
  39. package/src/components/manage/Blocks/Block/Edit.jsx +24 -8
  40. package/src/components/manage/Blocks/Block/EditBlockWrapper.jsx +17 -1
  41. package/src/components/manage/Blocks/Block/Order/Item.jsx +3 -1
  42. package/src/components/manage/Blocks/Grid/View.jsx +3 -0
  43. package/src/components/manage/Blocks/LeadImage/Edit.jsx +74 -126
  44. package/src/components/manage/Blocks/Search/components/SortOn.jsx +82 -55
  45. package/src/components/manage/Blocks/Search/widgets/SelectMetadataField.jsx +107 -176
  46. package/src/components/manage/Blocks/Teaser/DefaultBody.jsx +15 -8
  47. package/src/components/manage/Blocks/ToC/Edit.jsx +36 -29
  48. package/src/components/manage/Blocks/Video/Edit.jsx +105 -172
  49. package/src/components/manage/Blocks/Video/Edit.stories.jsx +57 -0
  50. package/src/components/manage/Contents/Contents.jsx +3 -0
  51. package/src/components/manage/Contents/ContentsBreadcrumbs.stories.jsx +46 -0
  52. package/src/components/manage/Contents/ContentsPropertiesModal.jsx +85 -52
  53. package/src/components/manage/Contents/ContentsUploadModal.jsx +230 -323
  54. package/src/components/manage/Contents/ContentsUploadModal.stories.jsx +56 -0
  55. package/src/components/manage/Controlpanels/AddonsControlpanel.jsx +323 -441
  56. package/src/components/manage/Controlpanels/Aliases.jsx +452 -580
  57. package/src/components/manage/Controlpanels/Aliases.stories.jsx +74 -0
  58. package/src/components/manage/Controlpanels/Controlpanel.jsx +41 -2
  59. package/src/components/manage/Controlpanels/Controlpanel.test.jsx +55 -24
  60. package/src/components/manage/Controlpanels/DatabaseInformation.jsx +162 -229
  61. package/src/components/manage/Controlpanels/Groups/RenderGroups.jsx +74 -122
  62. package/src/components/manage/Display/Display.jsx +92 -148
  63. package/src/components/manage/Display/Display.stories.jsx +46 -0
  64. package/src/components/manage/Edit/Edit.jsx +2 -4
  65. package/src/components/manage/Preferences/ChangePassword.jsx +94 -172
  66. package/src/components/manage/Preferences/ChangePassword.stories.jsx +41 -0
  67. package/src/components/manage/Preferences/PersonalInformation.jsx +50 -115
  68. package/src/components/manage/Preferences/PersonalPreferences.jsx +46 -100
  69. package/src/components/manage/Preferences/PersonalPreferences.stories.jsx +48 -0
  70. package/src/components/manage/Toolbar/More.jsx +308 -399
  71. package/src/components/manage/Widgets/DatetimeWidget.jsx +121 -175
  72. package/src/components/manage/Widgets/ReferenceWidget.jsx +134 -210
  73. package/src/components/theme/Register/Register.jsx +70 -142
  74. package/src/components/theme/Register/Register.stories.jsx +49 -0
  75. package/src/components/theme/Tags/Tags.jsx +19 -10
  76. package/src/components/theme/Tags/Tags.test.jsx +9 -11
  77. package/src/components/theme/View/AlbumView.jsx +122 -167
  78. package/src/components/theme/View/LinkView.jsx +4 -0
  79. package/src/components/theme/View/LinkView.test.jsx +2 -0
  80. package/src/components/theme/View/View.jsx +0 -6
  81. package/src/config/ControlPanels.js +49 -43
  82. package/src/config/config.test.js +1 -0
  83. package/src/config/index.js +16 -0
  84. package/src/config/slots.js +12 -0
  85. package/src/helpers/Blocks/Blocks.js +12 -7
  86. package/src/helpers/Blocks/Blocks.test.js +15 -0
  87. package/src/helpers/Blocks/cloneBlocks.ts +1 -1
  88. package/src/helpers/FormValidation/FormValidation.jsx +19 -2
  89. package/src/helpers/FormValidation/validators.ts +1 -1
  90. package/src/helpers/Url/Url.test.js +15 -2
  91. package/src/helpers/Url/urlRegex.js +1 -1
  92. package/src/helpers/index.js +2 -0
  93. package/src/middleware/api.js +4 -2
  94. package/src/middleware/index.js +1 -0
  95. package/src/middleware/userSessionReset.js +46 -0
  96. package/src/store.js +2 -0
  97. package/test-setup-config.jsx +3 -0
  98. package/theme/themes/pastanaga/extras/blocks.less +6 -0
  99. package/types/components/manage/Actions/Actions.stories.d.ts +8 -0
  100. package/types/components/manage/Blocks/LeadImage/Edit.d.ts +14 -5
  101. package/types/components/manage/Blocks/Search/widgets/SelectMetadataField.d.ts +0 -5
  102. package/types/components/manage/Blocks/ToC/Edit.d.ts +1 -6
  103. package/types/components/manage/Blocks/Video/Edit.d.ts +1 -1
  104. package/types/components/manage/Blocks/Video/Edit.stories.d.ts +8 -0
  105. package/types/components/manage/Contents/ContentsBreadcrumbs.stories.d.ts +8 -0
  106. package/types/components/manage/Contents/ContentsUploadModal.d.ts +14 -2
  107. package/types/components/manage/Contents/ContentsUploadModal.stories.d.ts +8 -0
  108. package/types/components/manage/Contents/index.d.ts +1 -1
  109. package/types/components/manage/Controlpanels/AddonsControlpanel.d.ts +2 -2
  110. package/types/components/manage/Controlpanels/Aliases.d.ts +2 -2
  111. package/types/components/manage/Controlpanels/Aliases.stories.d.ts +8 -0
  112. package/types/components/manage/Controlpanels/DatabaseInformation.d.ts +2 -2
  113. package/types/components/manage/Controlpanels/Groups/RenderGroups.d.ts +10 -5
  114. package/types/components/manage/Controlpanels/index.d.ts +4 -4
  115. package/types/components/manage/Display/Display.stories.d.ts +8 -0
  116. package/types/components/manage/Preferences/ChangePassword.d.ts +2 -2
  117. package/types/components/manage/Preferences/ChangePassword.stories.d.ts +8 -0
  118. package/types/components/manage/Preferences/PersonalInformation.d.ts +7 -2
  119. package/types/components/manage/Preferences/PersonalPreferences.d.ts +5 -1
  120. package/types/components/manage/Preferences/PersonalPreferences.stories.d.ts +8 -0
  121. package/types/components/manage/Toolbar/More.d.ts +8 -5
  122. package/types/components/manage/Widgets/DatetimeWidget.d.ts +0 -85
  123. package/types/components/manage/Widgets/DatetimeWidget.stories.d.ts +0 -1
  124. package/types/components/manage/Widgets/ReferenceWidget.d.ts +27 -2
  125. package/types/components/manage/Widgets/index.d.ts +1 -1
  126. package/types/components/theme/Register/Register.d.ts +2 -2
  127. package/types/components/theme/Register/Register.stories.d.ts +9 -0
  128. package/types/components/theme/Tags/Tags.d.ts +15 -7
  129. package/types/components/theme/View/AlbumView.d.ts +3 -17
  130. package/types/config/ControlPanels.d.ts +8 -0
  131. package/types/config/Widgets.d.ts +1 -1
  132. package/types/config/slots.d.ts +21 -0
  133. package/types/helpers/Blocks/Blocks.d.ts +6 -0
  134. package/types/helpers/FormValidation/FormValidation.d.ts +1 -0
  135. package/types/helpers/index.d.ts +2 -2
  136. package/types/middleware/index.d.ts +1 -0
  137. package/types/middleware/userSessionReset.d.ts +5 -0
@@ -1,15 +1,9 @@
1
- /**
2
- * ReferenceWidget component.
3
- * @module components/manage/Widgets/ReferenceWidget
4
- */
5
-
6
- import React, { Component } from 'react';
1
+ import { useState, useEffect } from 'react';
7
2
  import PropTypes from 'prop-types';
8
- import { connect } from 'react-redux';
9
- import { compose } from 'redux';
3
+ import { useDispatch, useSelector } from 'react-redux';
10
4
  import { Label, Dropdown, Popup, Icon } from 'semantic-ui-react';
11
5
  import { compact, concat, fromPairs, map, values, uniqBy } from 'lodash';
12
- import { defineMessages, injectIntl } from 'react-intl';
6
+ import { defineMessages, useIntl } from 'react-intl';
13
7
 
14
8
  import FormFieldWrapper from '@plone/volto/components/manage/Widgets/FormFieldWrapper';
15
9
  import { resetSearchContent, searchContent } from '@plone/volto/actions';
@@ -26,130 +20,16 @@ const messages = defineMessages({
26
20
  },
27
21
  });
28
22
 
29
- /**
30
- * ReferenceWidget component class.
31
- * @class ReferenceWidget
32
- * @extends Component
33
- */
34
- class ReferenceWidget extends Component {
35
- /**
36
- * Property types.
37
- * @property {Object} propTypes Property types.
38
- * @static
39
- */
40
- static propTypes = {
41
- id: PropTypes.string.isRequired,
42
- title: PropTypes.string.isRequired,
43
- description: PropTypes.string,
44
- required: PropTypes.bool,
45
- multiple: PropTypes.bool,
46
- error: PropTypes.arrayOf(PropTypes.string),
47
- value: PropTypes.oneOfType([
48
- PropTypes.arrayOf(PropTypes.object),
49
- PropTypes.object,
50
- ]),
51
- onChange: PropTypes.func.isRequired,
52
- resetSearchContent: PropTypes.func.isRequired,
53
- searchContent: PropTypes.func.isRequired,
54
- search: PropTypes.arrayOf(
55
- PropTypes.shape({
56
- '@id': PropTypes.string,
57
- '@type': PropTypes.string,
58
- title: PropTypes.string,
59
- description: PropTypes.string,
60
- }),
61
- ),
62
- wrapped: PropTypes.bool,
63
- };
64
-
65
- /**
66
- * Default properties
67
- * @property {Object} defaultProps Default properties.
68
- * @static
69
- */
70
- static defaultProps = {
71
- description: null,
72
- required: false,
73
- error: [],
74
- search: [],
75
- value: null,
76
- multiple: true,
77
- };
78
-
79
- /**
80
- * Constructor
81
- * @method constructor
82
- * @param {Object} props Component properties
83
- * @constructs Actions
84
- */
85
- constructor(props) {
86
- super(props);
87
- this.onSearchChange = this.onSearchChange.bind(this);
88
-
89
- this.state = {
90
- choices: props.value
91
- ? props.multiple
92
- ? fromPairs(
93
- map(props.value, (value) => [
94
- value['@id'],
95
- {
96
- key: value['@id'],
97
- text: flattenToAppURL(value['@id']),
98
- value: value['@id'],
99
- label: {
100
- content: value.title,
101
- },
102
- data: value,
103
- },
104
- ]),
105
- )
106
- : {
107
- [props.value['@id']]: {
108
- key: props.value['@id'],
109
- text: flattenToAppURL(props.value),
110
- value: props.value['@id'],
111
- label: {
112
- content: props.value.title,
113
- },
114
- data: props.value,
115
- },
116
- novalue: {
117
- key: 'novalue',
118
- text: this.props.intl.formatMessage(messages.no_value),
119
- value: 'novalue',
120
- data: null,
121
- },
122
- }
123
- : {},
124
- };
125
- }
126
-
127
- componentDidMount() {
128
- this.props.resetSearchContent();
129
- }
130
-
131
- /**
132
- * Component will receive props
133
- * @method componentWillReceiveProps
134
- * @param {Object} nextProps Next properties
135
- * @returns {undefined}
136
- */
137
- UNSAFE_componentWillReceiveProps(nextProps) {
138
- this.setState({
139
- choices: {
140
- ...fromPairs(
141
- map(
142
- uniqBy(
143
- map(
144
- compact(concat(nextProps.value, nextProps.search)),
145
- (item) => ({
146
- ...item,
147
- '@id': flattenToAppURL(item['@id']),
148
- }),
149
- ),
150
- '@id',
151
- ),
152
- (value) => [
23
+ const ReferenceWidget = (props) => {
24
+ const { id, title, value, multiple, onChange } = props;
25
+ const intl = useIntl();
26
+ const dispatch = useDispatch();
27
+ const search = useSelector((state) => state.search.items);
28
+ const [choices, setChoices] = useState(
29
+ value
30
+ ? multiple
31
+ ? fromPairs(
32
+ map(value, (value) => [
153
33
  value['@id'],
154
34
  {
155
35
  key: value['@id'],
@@ -160,37 +40,78 @@ class ReferenceWidget extends Component {
160
40
  },
161
41
  data: value,
162
42
  },
163
- ],
43
+ ]),
44
+ )
45
+ : {
46
+ [value['@id']]: {
47
+ key: value['@id'],
48
+ text: flattenToAppURL(value),
49
+ value: value['@id'],
50
+ label: {
51
+ content: value.title,
52
+ },
53
+ data: value,
54
+ },
55
+ novalue: {
56
+ key: 'novalue',
57
+ text: intl.formatMessage(messages.no_value),
58
+ value: 'novalue',
59
+ data: null,
60
+ },
61
+ }
62
+ : {},
63
+ );
64
+
65
+ useEffect(() => {
66
+ dispatch(resetSearchContent());
67
+ }, [dispatch]);
68
+
69
+ useEffect(() => {
70
+ setChoices({
71
+ ...fromPairs(
72
+ map(
73
+ uniqBy(
74
+ map(compact(concat(value, search)), (item) => ({
75
+ ...item,
76
+ '@id': flattenToAppURL(item['@id']),
77
+ })),
78
+ '@id',
164
79
  ),
80
+ (value) => [
81
+ value['@id'],
82
+ {
83
+ key: value['@id'],
84
+ text: flattenToAppURL(value['@id']),
85
+ value: value['@id'],
86
+ label: {
87
+ content: value.title,
88
+ },
89
+ data: value,
90
+ },
91
+ ],
165
92
  ),
166
- novalue: {
167
- key: 'novalue',
168
- text: this.props.intl.formatMessage(messages.no_value),
169
- value: 'novalue',
170
- data: null,
171
- },
93
+ ),
94
+ novalue: {
95
+ key: 'novalue',
96
+ text: intl.formatMessage(messages.no_value),
97
+ value: 'novalue',
98
+ data: null,
172
99
  },
173
100
  });
174
- }
175
-
176
- /**
177
- * On search change handler
178
- * @method onSearchChange
179
- * @param {object} event Event object.
180
- * @param {object} data Event data.
181
- * @returns {undefined}
182
- */
101
+ }, [intl, search, value]);
183
102
 
184
- onSearchChange(event, data) {
103
+ const onSearchChange = (event, data) => {
185
104
  if (data.searchQuery && data.searchQuery !== '') {
186
- this.props.searchContent('', {
187
- Title: `*${data.searchQuery}*`,
188
- });
105
+ dispatch(
106
+ searchContent('', {
107
+ Title: `*${data.searchQuery}*`,
108
+ }),
109
+ );
189
110
  } else {
190
- this.props.resetSearchContent();
111
+ dispatch(resetSearchContent());
191
112
  }
192
- }
193
- renderLabel = (item, index, defaultProps) => {
113
+ };
114
+ const renderLabel = (item, index, defaultProps) => {
194
115
  return (
195
116
  <Popup
196
117
  key={item.value}
@@ -216,59 +137,62 @@ class ReferenceWidget extends Component {
216
137
  );
217
138
  };
218
139
 
219
- /**
220
- * Render method.
221
- * @method render
222
- * @returns {string} Markup for the component.
223
- */
224
- render() {
225
- const { id, title, value, multiple, onChange } = this.props;
226
-
227
- return (
228
- <FormFieldWrapper {...this.props}>
229
- <Dropdown
230
- options={values(this.state.choices)}
231
- placeholder={title}
232
- search
233
- selection
234
- fluid
235
- noResultsMessage={this.props.intl.formatMessage(
236
- messages.no_results_found,
237
- )}
238
- multiple={multiple}
239
- value={
140
+ return (
141
+ <FormFieldWrapper {...props}>
142
+ <Dropdown
143
+ options={values(choices)}
144
+ placeholder={title}
145
+ search
146
+ selection
147
+ fluid
148
+ noResultsMessage={intl.formatMessage(messages.no_results_found)}
149
+ multiple={multiple}
150
+ value={
151
+ multiple
152
+ ? value
153
+ ? map(value, (item) =>
154
+ item && item['@id'] ? flattenToAppURL(item['@id']) : item,
155
+ )
156
+ : []
157
+ : value
158
+ ? flattenToAppURL(value['@id'])
159
+ : ''
160
+ }
161
+ onChange={(event, data) => {
162
+ return onChange(
163
+ id,
240
164
  multiple
241
- ? value
242
- ? map(value, (item) =>
243
- item && item['@id'] ? flattenToAppURL(item['@id']) : item,
244
- )
245
- : []
246
- : value
247
- ? flattenToAppURL(value['@id'])
248
- : ''
249
- }
250
- onChange={(event, data) => {
251
- return onChange(
252
- id,
253
- multiple
254
- ? map(data.value, (item) => this.state.choices[item].data)
255
- : this.state.choices[data.value].data,
256
- );
257
- }}
258
- onSearchChange={this.onSearchChange}
259
- renderLabel={this.renderLabel}
260
- />
261
- </FormFieldWrapper>
262
- );
263
- }
264
- }
165
+ ? map(data.value, (item) => choices[item].data)
166
+ : choices[data.value].data,
167
+ );
168
+ }}
169
+ onSearchChange={onSearchChange}
170
+ renderLabel={renderLabel}
171
+ />
172
+ </FormFieldWrapper>
173
+ );
174
+ };
175
+
176
+ ReferenceWidget.propTypes = {
177
+ id: PropTypes.string.isRequired,
178
+ title: PropTypes.string.isRequired,
179
+ description: PropTypes.string,
180
+ required: PropTypes.bool,
181
+ multiple: PropTypes.bool,
182
+ error: PropTypes.arrayOf(PropTypes.string),
183
+ value: PropTypes.oneOfType([
184
+ PropTypes.arrayOf(PropTypes.object),
185
+ PropTypes.object,
186
+ ]),
187
+ onChange: PropTypes.func.isRequired,
188
+ wrapped: PropTypes.bool,
189
+ };
265
190
 
266
- export default compose(
267
- injectIntl,
268
- connect(
269
- (state) => ({
270
- search: state.search.items,
271
- }),
272
- { resetSearchContent, searchContent },
273
- ),
274
- )(ReferenceWidget);
191
+ ReferenceWidget.defaultProps = {
192
+ description: null,
193
+ required: false,
194
+ error: [],
195
+ value: null,
196
+ multiple: true,
197
+ };
198
+ export default ReferenceWidget;
@@ -1,17 +1,10 @@
1
- /**
2
- * Register container.
3
- * @module components/theme/Register/Register
4
- */
5
-
6
- import React, { Component } from 'react';
7
- import { Helmet } from '@plone/volto/helpers';
8
- import { connect } from 'react-redux';
9
- import { compose } from 'redux';
10
- import { defineMessages, injectIntl } from 'react-intl';
11
- import PropTypes from 'prop-types';
12
- import { withRouter } from 'react-router-dom';
1
+ import { useEffect, useState } from 'react';
2
+ import { useDispatch, useSelector } from 'react-redux';
3
+ import { defineMessages, useIntl } from 'react-intl';
4
+ import { useHistory } from 'react-router-dom';
13
5
  import { toast } from 'react-toastify';
14
6
 
7
+ import { Helmet, usePrevious } from '@plone/volto/helpers';
15
8
  import { Toast } from '@plone/volto/components';
16
9
  import { Form } from '@plone/volto/components/manage/Form';
17
10
  import { createUser } from '@plone/volto/actions';
@@ -56,146 +49,81 @@ const messages = defineMessages({
56
49
  defaultMessage: 'Register',
57
50
  },
58
51
  });
52
+ const useUsers = () => {
53
+ const error = useSelector((state) => state.users.create.error);
54
+ const loading = useSelector((state) => state.users.create.loading);
55
+ const loaded = useSelector((state) => state.users.create.loaded);
59
56
 
60
- /**
61
- * Register class.
62
- * @class Register
63
- * @extends Component
64
- */
65
- class Register extends Component {
66
- /**
67
- * Property types.
68
- * @property {Object} propTypes Property types.
69
- * @static
70
- */
71
- static propTypes = {
72
- createUser: PropTypes.func.isRequired,
73
- loading: PropTypes.bool.isRequired,
74
- loaded: PropTypes.bool.isRequired,
75
- error: PropTypes.shape({
76
- message: PropTypes.string,
77
- }),
78
- };
57
+ return { error, loaded, loading };
58
+ };
59
+ const Register = () => {
60
+ const dispatch = useDispatch();
61
+ const intl = useIntl();
62
+ const history = useHistory();
63
+ const [errors, setError] = useState(null);
64
+ const { loaded, loading, error } = useUsers();
79
65
 
80
- /**
81
- * Default properties.
82
- * @property {Object} defaultProps Default properties.
83
- * @static
84
- */
85
- static defaultProps = {
86
- error: null,
87
- };
66
+ const prevloading = usePrevious(loading);
88
67
 
89
- /**
90
- * Constructor
91
- * @method constructor
92
- * @param {Object} props Component properties
93
- * @constructs WysiwygEditor
94
- */
95
- constructor(props) {
96
- super(props);
97
- this.onSubmit = this.onSubmit.bind(this);
98
- this.state = {
99
- error: null,
100
- };
101
- }
102
-
103
- /**
104
- * Component will receive props
105
- * @method componentWillReceiveProps
106
- * @param {Object} nextProps Next properties
107
- * @returns {undefined}
108
- */
109
- UNSAFE_componentWillReceiveProps(nextProps) {
110
- if (this.props.loading && nextProps.loaded) {
68
+ useEffect(() => {
69
+ if (prevloading && loaded) {
111
70
  toast.success(
112
71
  <Toast
113
72
  success
114
- title={this.props.intl.formatMessage(
115
- messages.successRegisterCompletedTitle,
116
- )}
117
- content={this.props.intl.formatMessage(
118
- messages.successRegisterCompletedBody,
119
- )}
73
+ title={intl.formatMessage(messages.successRegisterCompletedTitle)}
74
+ content={intl.formatMessage(messages.successRegisterCompletedBody)}
120
75
  />,
121
76
  );
122
- this.props.history.push('/login');
77
+ history.push('/login');
123
78
  }
124
- }
79
+ }, [intl, history, loaded, prevloading]);
125
80
 
126
- /**
127
- * On submit handler
128
- * @method onSubmit
129
- * @param {object} data Form data.
130
- * @returns {undefined}
131
- */
132
- onSubmit(data) {
133
- this.props.createUser({
134
- fullname: data.fullname,
135
- email: data.email,
136
- sendPasswordReset: true,
137
- });
138
- this.setState({
139
- error: null,
140
- });
141
- }
81
+ const onSubmit = (data) => {
82
+ const { fullname, email } = data;
83
+ dispatch(
84
+ createUser({
85
+ fullname: fullname,
86
+ email: email,
87
+ sendPasswordReset: true,
88
+ }),
89
+ );
90
+ setError(null);
91
+ };
142
92
 
143
- /**
144
- * Render method.
145
- * @method render
146
- * @returns {string} Markup for the component.
147
- */
148
- render() {
149
- return (
150
- <div id="page-register">
151
- <Helmet title={this.props.intl.formatMessage(messages.register)} />
152
- <Form
153
- onSubmit={this.onSubmit}
154
- title={this.props.intl.formatMessage(messages.title)}
155
- error={this.state.error || this.props.error}
156
- loading={this.props.loading}
157
- submitLabel={this.props.intl.formatMessage(messages.register)}
158
- schema={{
159
- fieldsets: [
160
- {
161
- id: 'default',
162
- title: this.props.intl.formatMessage(messages.default),
163
- fields: ['fullname', 'email'],
164
- },
165
- ],
166
- properties: {
167
- fullname: {
168
- type: 'string',
169
- title: this.props.intl.formatMessage(messages.fullnameTitle),
170
- description: this.props.intl.formatMessage(
171
- messages.fullnameDescription,
172
- ),
173
- },
174
- email: {
175
- type: 'string',
176
- title: this.props.intl.formatMessage(messages.emailTitle),
177
- description: this.props.intl.formatMessage(
178
- messages.emailDescription,
179
- ),
180
- },
93
+ return (
94
+ <div id="page-register">
95
+ <Helmet title={intl.formatMessage(messages.register)} />
96
+ <Form
97
+ onSubmit={onSubmit}
98
+ title={intl.formatMessage(messages.title)}
99
+ error={errors || error}
100
+ loading={loading}
101
+ submitLabel={intl.formatMessage(messages.register)}
102
+ schema={{
103
+ fieldsets: [
104
+ {
105
+ id: 'default',
106
+ title: intl.formatMessage(messages.default),
107
+ fields: ['fullname', 'email'],
181
108
  },
182
- required: ['fullname', 'email'],
183
- }}
184
- />
185
- </div>
186
- );
187
- }
188
- }
109
+ ],
110
+ properties: {
111
+ fullname: {
112
+ type: 'string',
113
+ title: intl.formatMessage(messages.fullnameTitle),
114
+ description: intl.formatMessage(messages.fullnameDescription),
115
+ },
116
+ email: {
117
+ type: 'string',
118
+ title: intl.formatMessage(messages.emailTitle),
119
+ description: intl.formatMessage(messages.emailDescription),
120
+ },
121
+ },
122
+ required: ['fullname', 'email'],
123
+ }}
124
+ />
125
+ </div>
126
+ );
127
+ };
189
128
 
190
- export default compose(
191
- withRouter,
192
- injectIntl,
193
- connect(
194
- (state) => ({
195
- loading: state.users.create.loading,
196
- loaded: state.users.create.loaded,
197
- error: state.users.create.error,
198
- }),
199
- { createUser },
200
- ),
201
- )(Register);
129
+ export default Register;
@@ -0,0 +1,49 @@
1
+ import { injectIntl } from 'react-intl';
2
+ import React from 'react';
3
+ import RegisterComponent from './Register';
4
+ import { RealStoreWrapper as Wrapper } from '@plone/volto/storybook';
5
+
6
+ const IntlRegister = injectIntl(RegisterComponent);
7
+
8
+ function StoryComponent(args) {
9
+ return (
10
+ <Wrapper
11
+ customStore={{
12
+ users: {
13
+ create: {
14
+ loading: false,
15
+ loaded: true,
16
+ ...args,
17
+ },
18
+ },
19
+ intl: {
20
+ locale: 'en',
21
+ messages: {},
22
+ },
23
+ }}
24
+ >
25
+ <div id="toolbar" style={{ display: 'none' }} />
26
+ <IntlRegister />
27
+ </Wrapper>
28
+ );
29
+ }
30
+
31
+ export const Default = StoryComponent.bind({});
32
+ Default.args = {
33
+ error: false,
34
+ };
35
+
36
+ export default {
37
+ title: 'Public components/Register',
38
+ component: RegisterComponent,
39
+
40
+ decorators: [
41
+ (Story) => (
42
+ <div className="ui segment form attached" style={{ width: '600px' }}>
43
+ <Story />
44
+ </div>
45
+ ),
46
+ ],
47
+
48
+ argTypes: {},
49
+ };