@plone/volto 19.0.0-alpha.36 → 19.0.0-alpha.37

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 (176) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +1 -1
  3. package/locales/af/LC_MESSAGES/volto.po +29 -3
  4. package/locales/af.json +1 -1
  5. package/locales/ar/LC_MESSAGES/volto.po +29 -3
  6. package/locales/ar.json +1 -1
  7. package/locales/bg/LC_MESSAGES/volto.po +29 -3
  8. package/locales/bg.json +1 -1
  9. package/locales/bn/LC_MESSAGES/volto.po +29 -3
  10. package/locales/bn.json +1 -1
  11. package/locales/ca/LC_MESSAGES/volto.po +32 -6
  12. package/locales/ca.json +1 -1
  13. package/locales/cs/LC_MESSAGES/volto.po +30 -4
  14. package/locales/cs.json +1 -1
  15. package/locales/cy/LC_MESSAGES/volto.po +29 -3
  16. package/locales/cy.json +1 -1
  17. package/locales/da/LC_MESSAGES/volto.po +29 -3
  18. package/locales/da.json +1 -1
  19. package/locales/de/LC_MESSAGES/volto.po +32 -6
  20. package/locales/de.json +1 -1
  21. package/locales/el/LC_MESSAGES/volto.po +29 -3
  22. package/locales/el.json +1 -1
  23. package/locales/en/LC_MESSAGES/volto.po +25 -0
  24. package/locales/en.json +1 -1
  25. package/locales/en_AU/LC_MESSAGES/volto.po +29 -3
  26. package/locales/en_AU.json +1 -1
  27. package/locales/en_GB/LC_MESSAGES/volto.po +29 -3
  28. package/locales/en_GB.json +1 -1
  29. package/locales/eo/LC_MESSAGES/volto.po +29 -3
  30. package/locales/eo.json +1 -1
  31. package/locales/es/LC_MESSAGES/volto.po +30 -5
  32. package/locales/es.json +1 -1
  33. package/locales/et/LC_MESSAGES/volto.po +29 -3
  34. package/locales/et.json +1 -1
  35. package/locales/eu/LC_MESSAGES/volto.po +30 -5
  36. package/locales/eu.json +1 -1
  37. package/locales/fa/LC_MESSAGES/volto.po +29 -3
  38. package/locales/fa.json +1 -1
  39. package/locales/fi/LC_MESSAGES/volto.po +30 -4
  40. package/locales/fi.json +1 -1
  41. package/locales/fr/LC_MESSAGES/volto.po +208 -183
  42. package/locales/fr.json +1 -1
  43. package/locales/fu/LC_MESSAGES/volto.po +29 -3
  44. package/locales/fu.json +1 -1
  45. package/locales/gl/LC_MESSAGES/volto.po +27 -2
  46. package/locales/gl.json +1 -1
  47. package/locales/he/LC_MESSAGES/volto.po +29 -3
  48. package/locales/he.json +1 -1
  49. package/locales/hi/LC_MESSAGES/volto.po +34 -8
  50. package/locales/hi.json +1 -1
  51. package/locales/hr/LC_MESSAGES/volto.po +30 -4
  52. package/locales/hr.json +1 -1
  53. package/locales/hu/LC_MESSAGES/volto.po +29 -3
  54. package/locales/hu.json +1 -1
  55. package/locales/hy/LC_MESSAGES/volto.po +29 -3
  56. package/locales/hy.json +1 -1
  57. package/locales/id/LC_MESSAGES/volto.po +29 -3
  58. package/locales/id.json +1 -1
  59. package/locales/it/LC_MESSAGES/volto.po +29 -4
  60. package/locales/it.json +1 -1
  61. package/locales/ja/LC_MESSAGES/volto.po +29 -3
  62. package/locales/ja.json +1 -1
  63. package/locales/ka/LC_MESSAGES/volto.po +29 -3
  64. package/locales/ka.json +1 -1
  65. package/locales/kn/LC_MESSAGES/volto.po +29 -3
  66. package/locales/kn.json +1 -1
  67. package/locales/ko/LC_MESSAGES/volto.po +29 -3
  68. package/locales/ko.json +1 -1
  69. package/locales/lt/LC_MESSAGES/volto.po +30 -4
  70. package/locales/lt.json +1 -1
  71. package/locales/lv/LC_MESSAGES/volto.po +29 -3
  72. package/locales/lv.json +1 -1
  73. package/locales/mi/LC_MESSAGES/volto.po +29 -3
  74. package/locales/mi.json +1 -1
  75. package/locales/mk/LC_MESSAGES/volto.po +29 -3
  76. package/locales/mk.json +1 -1
  77. package/locales/my/LC_MESSAGES/volto.po +29 -3
  78. package/locales/my.json +1 -1
  79. package/locales/nb_NO/LC_MESSAGES/volto.po +29 -3
  80. package/locales/nb_NO.json +1 -1
  81. package/locales/nl/LC_MESSAGES/volto.po +69 -43
  82. package/locales/nl.json +1 -1
  83. package/locales/nn/LC_MESSAGES/volto.po +29 -3
  84. package/locales/nn.json +1 -1
  85. package/locales/pl/LC_MESSAGES/volto.po +30 -4
  86. package/locales/pl.json +1 -1
  87. package/locales/pt/LC_MESSAGES/volto.po +30 -4
  88. package/locales/pt.json +1 -1
  89. package/locales/pt_BR/LC_MESSAGES/volto.po +54 -29
  90. package/locales/pt_BR.json +1 -1
  91. package/locales/rm/LC_MESSAGES/volto.po +29 -3
  92. package/locales/rm.json +1 -1
  93. package/locales/ro/LC_MESSAGES/volto.po +30 -5
  94. package/locales/ro.json +1 -1
  95. package/locales/ru/LC_MESSAGES/volto.po +30 -4
  96. package/locales/ru.json +1 -1
  97. package/locales/sk/LC_MESSAGES/volto.po +30 -4
  98. package/locales/sk.json +1 -1
  99. package/locales/sl/LC_MESSAGES/volto.po +29 -3
  100. package/locales/sl.json +1 -1
  101. package/locales/sm/LC_MESSAGES/volto.po +29 -3
  102. package/locales/sm.json +1 -1
  103. package/locales/sq/LC_MESSAGES/volto.po +29 -3
  104. package/locales/sq.json +1 -1
  105. package/locales/sr/LC_MESSAGES/volto.po +30 -4
  106. package/locales/sr.json +1 -1
  107. package/locales/sr@cyrl/LC_MESSAGES/volto.po +29 -3
  108. package/locales/sr@cyrl.json +1 -1
  109. package/locales/sr@latn/LC_MESSAGES/volto.po +29 -3
  110. package/locales/sr@latn.json +1 -1
  111. package/locales/sv/LC_MESSAGES/volto.po +31 -5
  112. package/locales/sv.json +1 -1
  113. package/locales/ta/LC_MESSAGES/volto.po +30 -5
  114. package/locales/ta.json +1 -1
  115. package/locales/te/LC_MESSAGES/volto.po +29 -3
  116. package/locales/te.json +1 -1
  117. package/locales/th/LC_MESSAGES/volto.po +29 -3
  118. package/locales/th.json +1 -1
  119. package/locales/to/LC_MESSAGES/volto.po +29 -3
  120. package/locales/to.json +1 -1
  121. package/locales/tr/LC_MESSAGES/volto.po +29 -4
  122. package/locales/tr.json +1 -1
  123. package/locales/uk/LC_MESSAGES/volto.po +30 -4
  124. package/locales/uk.json +1 -1
  125. package/locales/vi/LC_MESSAGES/volto.po +29 -3
  126. package/locales/vi.json +1 -1
  127. package/locales/volto.pot +26 -1
  128. package/locales/zh_CN/LC_MESSAGES/volto.po +29 -4
  129. package/locales/zh_CN.json +1 -1
  130. package/locales/zh_Hant/LC_MESSAGES/volto.po +29 -3
  131. package/locales/zh_Hant.json +1 -1
  132. package/locales/zh_Hant_HK/LC_MESSAGES/volto.po +29 -3
  133. package/locales/zh_Hant_HK.json +1 -1
  134. package/package.json +8 -8
  135. package/src/components/manage/BlockChooser/BlockChooser.jsx +7 -10
  136. package/src/components/manage/Blocks/Block/Edit.jsx +19 -10
  137. package/src/components/manage/Blocks/Block/Order/Item.jsx +9 -4
  138. package/src/components/manage/Contents/DropZoneContent.jsx +1 -0
  139. package/src/components/manage/Controlpanels/BlockType.tsx +2 -3
  140. package/src/components/manage/Controlpanels/ContentTypes.jsx +9 -2
  141. package/src/components/manage/Controlpanels/Users/UsersControlpanel.jsx +58 -5
  142. package/src/components/manage/Controlpanels/Users/UsersControlpanel.ssr.test.jsx +624 -0
  143. package/src/components/manage/Controlpanels/Users/UsersControlpanel.test.jsx +8 -0
  144. package/src/components/manage/Form/Form.jsx +6 -1
  145. package/src/components/manage/Form/ModalForm.jsx +164 -88
  146. package/src/components/manage/Sidebar/ObjectBrowser.jsx +7 -0
  147. package/src/components/manage/Sidebar/ObjectBrowserBody.jsx +7 -3
  148. package/src/components/manage/Sidebar/ObjectBrowserBody.test.jsx +52 -0
  149. package/src/components/manage/Sidebar/Sidebar.jsx +2 -0
  150. package/src/components/manage/Toolbar/Toolbar.jsx +89 -7
  151. package/src/components/manage/Widgets/ObjectBrowserWidget.jsx +1 -0
  152. package/src/components/manage/Widgets/TokenWidget.jsx +142 -186
  153. package/src/components/theme/Search/Search.jsx +218 -328
  154. package/src/components/theme/Search/Search.test.jsx +5 -10
  155. package/src/components/theme/Sitemap/Sitemap.jsx +22 -30
  156. package/src/components/theme/Sitemap/Sitemap.test.jsx +18 -0
  157. package/src/config/index.js +1 -0
  158. package/src/helpers/I18n/I18n.test.ts +44 -0
  159. package/src/helpers/I18n/I18n.ts +31 -0
  160. package/src/helpers/index.js +1 -0
  161. package/theme/themes/pastanaga/collections/form.overrides +21 -0
  162. package/theme/themes/pastanaga/elements/button.overrides +30 -3
  163. package/types/components/manage/Controlpanels/Relations/RelationsMatrix.d.ts +1 -1
  164. package/types/components/manage/Controlpanels/Users/UsersControlpanel.d.ts +2 -6
  165. package/types/components/manage/Controlpanels/Users/UsersControlpanel.ssr.test.d.ts +1 -0
  166. package/types/components/manage/Controlpanels/index.d.ts +1 -1
  167. package/types/components/manage/Multilingual/ManageTranslations.d.ts +1 -1
  168. package/types/components/manage/Sidebar/ObjectBrowser.d.ts +1 -1
  169. package/types/components/manage/Sidebar/ObjectBrowserBody.test.d.ts +1 -0
  170. package/types/components/manage/Widgets/ImageWidget.d.ts +1 -1
  171. package/types/components/manage/Widgets/InternalUrlWidget.d.ts +1 -1
  172. package/types/components/manage/Widgets/UrlWidget.d.ts +1 -1
  173. package/types/components/manage/Widgets/index.d.ts +2 -2
  174. package/types/components/theme/Search/Search.d.ts +1 -1
  175. package/types/helpers/I18n/I18n.d.ts +20 -0
  176. package/types/helpers/index.d.ts +1 -0
@@ -10,6 +10,7 @@ import { useIntl, defineMessages } from 'react-intl';
10
10
  import Icon from '@plone/volto/components/theme/Icon/Icon';
11
11
  import AnimateHeight from 'react-animate-height';
12
12
  import config from '@plone/volto/registry';
13
+ import { formatMessageWithFallback } from '@plone/volto/helpers/I18n/I18n';
13
14
  import upSVG from '@plone/volto/icons/up-key.svg';
14
15
  import downSVG from '@plone/volto/icons/down-key.svg';
15
16
  import BlockChooserSearch from './BlockChooserSearch';
@@ -98,16 +99,10 @@ const BlockChooser = ({
98
99
  }
99
100
  const [filterValue, setFilterValue] = React.useState('');
100
101
 
101
- const getFormatMessage = (message) =>
102
- intl.formatMessage({
103
- id: message,
104
- defaultMessage: message,
105
- });
106
-
107
102
  function blocksAvailableFilter(blocks) {
108
103
  return blocks.filter(
109
104
  (block) =>
110
- getFormatMessage(block.title)
105
+ formatMessageWithFallback(intl, block.title)
111
106
  .toLowerCase()
112
107
  .includes(filterValue.toLowerCase()) ||
113
108
  block.title.toLowerCase().includes(filterValue.toLowerCase()) ||
@@ -117,7 +112,7 @@ const BlockChooser = ({
117
112
  function filterVariations(block) {
118
113
  return block.variations?.filter(
119
114
  (variation) =>
120
- getFormatMessage(variation.title)
115
+ formatMessageWithFallback(intl, variation.title)
121
116
  .toLowerCase()
122
117
  .includes(filterValue.toLowerCase()) &&
123
118
  !variation.title.toLowerCase().includes('default'),
@@ -145,9 +140,11 @@ const BlockChooser = ({
145
140
  }}
146
141
  >
147
142
  <Icon name={block.icon} size="36px" />
148
- {getFormatMessage(block.title)}
143
+ {formatMessageWithFallback(intl, block.title)}
149
144
  {filterValue && variations?.[0]?.title && (
150
- <small>{getFormatMessage(variations[0].title)}</small>
145
+ <small>
146
+ {formatMessageWithFallback(intl, variations[0].title)}
147
+ </small>
151
148
  )}
152
149
  </Button>
153
150
  </Button.Group>
@@ -149,15 +149,6 @@ export class Edit extends Component {
149
149
  this.props.setUIState({ hovered: this.props.id });
150
150
  }
151
151
  }}
152
- onFocus={(e) => {
153
- // TODO: This `onFocus` steals somehow the focus from the slate block
154
- // we have to investigate why this is happening
155
- // Apparently, I can't see any difference in the behavior
156
- // If any, we can fix it in successive iterations
157
- // if (this.props.hovered !== this.props.id) {
158
- // this.props.setUIState({ hovered: this.props.id });
159
- // }
160
- }}
161
152
  onMouseLeave={(e) => {
162
153
  e.preventDefault();
163
154
  e.stopPropagation();
@@ -172,6 +163,24 @@ export class Edit extends Component {
172
163
  e,
173
164
  );
174
165
  }}
166
+ // onFocus={(e) => {
167
+ // // TODO: This `onFocus` steals somehow the focus from the slate block
168
+ // // we have to investigate why this is happening
169
+ // // Apparently, I can't see any difference in the behavior
170
+ // // If any, we can fix it in successive iterations
171
+ // // if (this.props.hovered !== this.props.id) {
172
+ // // this.props.setUIState({ hovered: this.props.id });
173
+ // // }
174
+ // }}
175
+ onFocus={(e) => {
176
+ const isMultipleSelection = e.shiftKey || e.ctrlKey || e.metaKey;
177
+ !this.props.selected &&
178
+ this.props.onSelectBlock(
179
+ this.props.id,
180
+ this.props.selected ? false : isMultipleSelection,
181
+ e,
182
+ );
183
+ }}
175
184
  onKeyDown={
176
185
  !(blockHasOwnFocusManagement || disableNewBlocks)
177
186
  ? (e) =>
@@ -218,6 +227,7 @@ export class Edit extends Component {
218
227
  e.stopPropagation();
219
228
  this.props.setUIState({ hovered: this.props.id });
220
229
  }}
230
+ // Mantenha apenas este onFocus ou remova se não for necessário
221
231
  onFocus={(e) => {
222
232
  e.preventDefault();
223
233
  e.stopPropagation();
@@ -245,7 +255,6 @@ export class Edit extends Component {
245
255
  className={cx(`block ${type}`, { selected: this.props.selected })}
246
256
  style={{ outline: 'none' }}
247
257
  ref={this.blockNode}
248
- // The tabIndex is required for the keyboard navigation
249
258
  tabIndex={-1}
250
259
  >
251
260
  {this.props.intl.formatMessage(messages.unknownBlock, {
@@ -5,7 +5,9 @@ import includes from 'lodash/includes';
5
5
  import cx from 'classnames';
6
6
  import Icon from '@plone/volto/components/theme/Icon/Icon';
7
7
  import { setUIState } from '@plone/volto/actions/form/form';
8
+ import { formatMessageWithFallback } from '@plone/volto/helpers/I18n/I18n';
8
9
  import config from '@plone/volto/registry';
10
+ import { useIntl } from 'react-intl';
9
11
 
10
12
  import deleteSVG from '@plone/volto/icons/delete.svg';
11
13
  import dragSVG from '@plone/volto/icons/drag.svg';
@@ -34,6 +36,7 @@ export const Item = forwardRef(
34
36
  },
35
37
  ref,
36
38
  ) => {
39
+ const intl = useIntl();
37
40
  const selected = useSelector((state) => state.form.ui.selected);
38
41
  const hovered = useSelector((state) => state.form.ui.hovered);
39
42
  const multiSelected = useSelector((state) => state.form.ui.multiSelected);
@@ -49,7 +52,11 @@ export const Item = forwardRef(
49
52
  ? data.required
50
53
  : includes(config.blocks.requiredBlocks, data?.['@type']);
51
54
  const fixed = !!data?.fixed;
52
-
55
+ const configTitle = config.blocks.blocksConfig[data?.['@type']]?.title;
56
+ const blockTitle =
57
+ data?.plaintext ||
58
+ formatMessageWithFallback(intl, configTitle) ||
59
+ data?.title;
53
60
  return (
54
61
  <li
55
62
  className={classNames(
@@ -122,9 +129,7 @@ export const Item = forwardRef(
122
129
  style={{ verticalAlign: 'middle' }}
123
130
  />
124
131
  )}{' '}
125
- {data?.plaintext ||
126
- config.blocks.blocksConfig[data?.['@type']]?.title ||
127
- data?.title}
132
+ {blockTitle}
128
133
  </span>
129
134
  {!clone && onRemove && !required && (
130
135
  <button
@@ -113,6 +113,7 @@ const DropZoneContent = (props) => {
113
113
  };
114
114
 
115
115
  const onDrop = async (e) => {
116
+ e.preventDefault();
116
117
  if (!hasFiles(e)) {
117
118
  return;
118
119
  }
@@ -2,6 +2,7 @@ import { getBlockTypes } from '@plone/volto/actions/blockTypes/blockTypes';
2
2
  import Toolbar from '@plone/volto/components/manage/Toolbar/Toolbar';
3
3
  import Icon from '@plone/volto/components/theme/Icon/Icon';
4
4
  import { getParentUrl, flattenToAppURL } from '@plone/volto/helpers/Url/Url';
5
+ import { formatMessageWithFallback } from '@plone/volto/helpers/I18n/I18n';
5
6
  import { useClient } from '@plone/volto/hooks';
6
7
  import config from '@plone/volto/registry';
7
8
  import { useEffect } from 'react';
@@ -86,9 +87,7 @@ const BlockTypeControlpanel = (props: RouteProps) => {
86
87
  return <Error error={blockTypes.error} />;
87
88
  }
88
89
 
89
- const translatedTitle = block?.title
90
- ? intl.formatMessage({ id: block.title, defaultMessage: block.title })
91
- : id;
90
+ const translatedTitle = formatMessageWithFallback(intl, block?.title) || id;
92
91
 
93
92
  return (
94
93
  blockTypes.loaded && (
@@ -227,6 +227,7 @@ class ContentTypes extends Component {
227
227
  addTypeError: undefined,
228
228
  addTypeSetFormDataCallback: undefined,
229
229
  });
230
+ this._addTypeTrigger?.focus();
230
231
  toast.success(
231
232
  <Toast
232
233
  success
@@ -369,10 +370,13 @@ class ContentTypes extends Component {
369
370
  />
370
371
  <ModalForm
371
372
  open={this.state.showAddType}
372
- className="modal"
373
+ className="modal add-content-type"
373
374
  onSubmit={this.onAddTypeSubmit}
374
375
  submitError={this.state.addTypeError}
375
- onCancel={() => this.setState({ showAddType: false })}
376
+ onCancel={() => {
377
+ this.setState({ showAddType: false });
378
+ this._addTypeTrigger?.focus();
379
+ }}
376
380
  title={this.props.intl.formatMessage(messages.addTypeFormTitle)}
377
381
  loading={this.props.cpanelRequest.post.loading}
378
382
  schema={{
@@ -474,6 +478,9 @@ class ContentTypes extends Component {
474
478
  aria-label={this.props.intl.formatMessage(messages.add)}
475
479
  tabIndex={0}
476
480
  id="toolbar-add"
481
+ ref={(el) => {
482
+ this._addTypeTrigger = el;
483
+ }}
477
484
  onClick={() => {
478
485
  this.setState({ showAddType: true });
479
486
  }}
@@ -13,6 +13,7 @@ import { listRoles } from '@plone/volto/actions/roles/roles';
13
13
  import { listGroups, updateGroup } from '@plone/volto/actions/groups/groups';
14
14
  import { getControlpanel } from '@plone/volto/actions/controlpanels/controlpanels';
15
15
  import { getUserSchema } from '@plone/volto/actions/userschema/userschema';
16
+ import { asyncConnect } from '@plone/volto/helpers/AsyncConnect';
16
17
  import jwtDecode from 'jwt-decode';
17
18
  import Icon from '@plone/volto/components/theme/Icon/Icon';
18
19
  import Toast from '@plone/volto/components/manage/Toast/Toast';
@@ -57,7 +58,8 @@ import {
57
58
  * UsersControlpanel functional component.
58
59
  * @function UsersControlpanel
59
60
  */
60
- const UsersControlpanel = () => {
61
+ const UsersControlpanel = (props) => {
62
+ const { staticContext } = props;
61
63
  const intl = useIntl();
62
64
  const dispatch = useDispatch();
63
65
 
@@ -143,7 +145,10 @@ const UsersControlpanel = () => {
143
145
  await listUsersAction();
144
146
  setEntries(users);
145
147
  }
146
- await getUserSchemaAction();
148
+ // Only fetch user schema if it hasn't been loaded yet (e.g. by asyncConnect SSR)
149
+ if (!userschema?.loaded) {
150
+ await getUserSchemaAction();
151
+ }
147
152
  await getUserAction(userId);
148
153
  }, [
149
154
  getControlpanelAction,
@@ -152,6 +157,7 @@ const UsersControlpanel = () => {
152
157
  listGroupsAction,
153
158
  listUsersAction,
154
159
  users,
160
+ userschema,
155
161
  getUserSchemaAction,
156
162
  getUserAction,
157
163
  userId,
@@ -451,6 +457,8 @@ const UsersControlpanel = () => {
451
457
 
452
458
  useEffect(() => {
453
459
  setIsClient(true);
460
+ // Skip fetching if the store already has an error.
461
+ if (loadRolesRequest?.error) return;
454
462
  fetchData();
455
463
  checkLoginUsingEmailStatus();
456
464
  }, []); // eslint-disable-line react-hooks/exhaustive-deps
@@ -471,8 +479,14 @@ const UsersControlpanel = () => {
471
479
  }
472
480
  }, [loadRolesRequest?.error, loadRolesRequest?.loading]);
473
481
 
474
- if (error) {
475
- return <Error error={error} />;
482
+ const effectiveError =
483
+ error ||
484
+ (loadRolesRequest?.error && !loadRolesRequest?.loading
485
+ ? loadRolesRequest.error
486
+ : null);
487
+
488
+ if (effectiveError) {
489
+ return <Error error={effectiveError} staticContext={staticContext} />;
476
490
  }
477
491
 
478
492
  const usernameToDelete = userToDelete ? userToDelete.username : '';
@@ -729,4 +743,43 @@ const UsersControlpanel = () => {
729
743
  );
730
744
  };
731
745
 
732
- export default UsersControlpanel;
746
+ export default asyncConnect([
747
+ {
748
+ key: 'controlpanels',
749
+ promise: ({ store: { dispatch, getState } }) => {
750
+ return dispatch(getControlpanel('usergroup')).then(() => {
751
+ const state = getState();
752
+ const many_users = state.controlpanels?.controlpanel?.data?.many_users;
753
+ if (!many_users) {
754
+ dispatch(listUsers());
755
+ dispatch(listGroups());
756
+ }
757
+ });
758
+ },
759
+ },
760
+ {
761
+ key: 'roles',
762
+ promise: ({ store: { dispatch } }) => {
763
+ return dispatch(listRoles());
764
+ },
765
+ },
766
+ {
767
+ key: 'userschema',
768
+ promise: ({ store: { dispatch } }) => {
769
+ return dispatch(getUserSchema());
770
+ },
771
+ },
772
+ {
773
+ key: 'user',
774
+ promise: ({ store: { dispatch, getState } }) => {
775
+ const state = getState();
776
+ const token = state.userSession.token;
777
+ if (token) {
778
+ const userId = jwtDecode(token).sub;
779
+ if (userId) {
780
+ return dispatch(getUser(userId));
781
+ }
782
+ }
783
+ },
784
+ },
785
+ ])(UsersControlpanel);