@plone/volto 18.0.0-alpha.14 → 18.0.0-alpha.15

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 (150) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/jest-setup-afterenv.js +2 -0
  3. package/package.json +24 -20
  4. package/src/components/manage/Add/Add.jsx +9 -11
  5. package/src/components/manage/Add/Add.test.jsx +11 -13
  6. package/src/components/manage/Aliases/Aliases.jsx +6 -6
  7. package/src/components/manage/Aliases/Aliases.test.jsx +7 -7
  8. package/src/components/manage/BlockChooser/BlockChooser.test.jsx +0 -1
  9. package/src/components/manage/BlockChooser/BlockChooserButton.jsx +6 -6
  10. package/src/components/manage/BlockChooser/BlockChooserSearch.test.jsx +0 -1
  11. package/src/components/manage/Blocks/Block/Settings.test.jsx +0 -1
  12. package/src/components/manage/Blocks/Container/NewBlockAddButton.jsx +20 -19
  13. package/src/components/manage/Blocks/Image/View.test.jsx +0 -1
  14. package/src/components/manage/Blocks/Table/Edit.jsx +7 -6
  15. package/src/components/manage/Contents/Contents.jsx +6 -6
  16. package/src/components/manage/Contents/Contents.test.jsx +7 -7
  17. package/src/components/manage/Contents/ContentsPropertiesModal.test.jsx +4 -4
  18. package/src/components/manage/Controlpanels/AddonsControlpanel.jsx +6 -6
  19. package/src/components/manage/Controlpanels/AddonsControlpanel.test.jsx +6 -7
  20. package/src/components/manage/Controlpanels/Aliases.jsx +6 -6
  21. package/src/components/manage/Controlpanels/Aliases.test.jsx +6 -7
  22. package/src/components/manage/Controlpanels/ContentType.jsx +6 -6
  23. package/src/components/manage/Controlpanels/ContentType.test.jsx +7 -7
  24. package/src/components/manage/Controlpanels/ContentTypeLayout.jsx +93 -85
  25. package/src/components/manage/Controlpanels/ContentTypeLayout.test.jsx +7 -7
  26. package/src/components/manage/Controlpanels/ContentTypeSchema.jsx +6 -6
  27. package/src/components/manage/Controlpanels/ContentTypes.jsx +6 -6
  28. package/src/components/manage/Controlpanels/ContentTypes.test.jsx +7 -7
  29. package/src/components/manage/Controlpanels/Controlpanel.jsx +6 -6
  30. package/src/components/manage/Controlpanels/Controlpanel.test.jsx +7 -7
  31. package/src/components/manage/Controlpanels/Controlpanels.jsx +6 -6
  32. package/src/components/manage/Controlpanels/Controlpanels.test.jsx +10 -10
  33. package/src/components/manage/Controlpanels/DatabaseInformation.jsx +6 -6
  34. package/src/components/manage/Controlpanels/Groups/GroupsControlpanel.jsx +6 -6
  35. package/src/components/manage/Controlpanels/Groups/GroupsControlpanel.test.jsx +7 -7
  36. package/src/components/manage/Controlpanels/ModerateComments.jsx +6 -6
  37. package/src/components/manage/Controlpanels/ModerateComments.test.jsx +7 -7
  38. package/src/components/manage/Controlpanels/Relations/Relations.jsx +13 -7
  39. package/src/components/manage/Controlpanels/Rules/AddRule.jsx +6 -6
  40. package/src/components/manage/Controlpanels/Rules/AddRule.test.jsx +6 -7
  41. package/src/components/manage/Controlpanels/Rules/ConfigureRule.jsx +6 -6
  42. package/src/components/manage/Controlpanels/Rules/ConfigureRule.test.jsx +6 -7
  43. package/src/components/manage/Controlpanels/Rules/EditRule.jsx +6 -6
  44. package/src/components/manage/Controlpanels/Rules/EditRule.test.jsx +6 -7
  45. package/src/components/manage/Controlpanels/Rules/Rules.jsx +6 -6
  46. package/src/components/manage/Controlpanels/Rules/Rules.test.jsx +6 -7
  47. package/src/components/manage/Controlpanels/Rules/components/{VariableModal.test.jsx → VariableModal.test.jsx.removed} +6 -7
  48. package/src/components/manage/Controlpanels/UndoControlpanel.jsx +6 -6
  49. package/src/components/manage/Controlpanels/UndoControlpanel.test.jsx +7 -7
  50. package/src/components/manage/Controlpanels/UpgradeControlPanel.jsx +6 -6
  51. package/src/components/manage/Controlpanels/Users/UserGroupMembershipControlPanel.jsx +14 -8
  52. package/src/components/manage/Controlpanels/Users/UserGroupMembershipControlPanel.test.jsx +7 -7
  53. package/src/components/manage/Controlpanels/Users/UsersControlpanel.jsx +6 -6
  54. package/src/components/manage/Controlpanels/Users/UsersControlpanel.test.jsx +7 -7
  55. package/src/components/manage/Delete/Delete.jsx +6 -6
  56. package/src/components/manage/Delete/Delete.test.jsx +10 -10
  57. package/src/components/manage/Diff/Diff.jsx +6 -6
  58. package/src/components/manage/Diff/Diff.test.jsx +2 -3
  59. package/src/components/manage/Edit/Edit.jsx +10 -11
  60. package/src/components/manage/Edit/Edit.test.jsx +14 -10
  61. package/src/components/manage/Form/BlockDataForm.test.jsx +0 -1
  62. package/src/components/manage/Form/Form.jsx +16 -8
  63. package/src/components/manage/Form/ModalForm.test.jsx +0 -1
  64. package/src/components/manage/History/History.jsx +6 -6
  65. package/src/components/manage/History/History.test.jsx +14 -13
  66. package/src/components/manage/LinksToItem/LinksToItem.jsx +78 -49
  67. package/src/components/manage/LinksToItem/LinksToItem.test.jsx +7 -7
  68. package/src/components/manage/Multilingual/ManageTranslations.jsx +13 -7
  69. package/src/components/manage/Multilingual/ManageTranslations.test.jsx +6 -7
  70. package/src/components/manage/Preferences/ChangePassword.jsx +6 -6
  71. package/src/components/manage/Preferences/ChangePassword.test.jsx +6 -7
  72. package/src/components/manage/Preferences/PersonalInformation.test.jsx +1 -3
  73. package/src/components/manage/Preferences/PersonalPreferences.test.jsx +1 -3
  74. package/src/components/manage/Rules/Rules.jsx +6 -6
  75. package/src/components/manage/Rules/Rules.test.jsx +7 -7
  76. package/src/components/manage/Sharing/Sharing.jsx +6 -6
  77. package/src/components/manage/Sharing/Sharing.test.jsx +7 -7
  78. package/src/components/manage/Sidebar/ObjectBrowser.jsx +1 -1
  79. package/src/components/manage/Sidebar/Sidebar.jsx +2 -0
  80. package/src/components/manage/Sidebar/SidebarPopup.jsx +28 -21
  81. package/src/components/manage/Sidebar/SidebarPortal.jsx +7 -6
  82. package/src/components/manage/Widgets/FileWidget.jsx +1 -1
  83. package/src/components/manage/Widgets/ObjectBrowserWidget.test.jsx +4 -4
  84. package/src/components/manage/Widgets/ObjectListWidget.test.js +0 -1
  85. package/src/components/manage/Widgets/ObjectWidget.test.jsx +0 -1
  86. package/src/components/manage/Widgets/SchemaWidget.test.jsx +4 -4
  87. package/src/components/manage/Widgets/SchemaWidgetFieldset.test.jsx +5 -5
  88. package/src/components/manage/Widgets/UrlWidget.test.jsx +4 -4
  89. package/src/components/manage/Widgets/VocabularyTermsWidget.test.jsx +4 -4
  90. package/src/components/theme/Comments/Comments.jsx +7 -8
  91. package/src/components/theme/Component/Component.test.jsx +0 -1
  92. package/src/components/theme/ContactForm/ContactForm.jsx +6 -6
  93. package/src/components/theme/ContactForm/ContactForm.test.jsx +12 -10
  94. package/src/components/theme/Footer/Footer.test.jsx +0 -1
  95. package/src/components/theme/Logout/Logout.test.jsx +8 -5
  96. package/src/components/theme/Search/Search.jsx +6 -6
  97. package/src/components/theme/Search/Search.test.jsx +13 -10
  98. package/src/components/theme/SlotRenderer/SlotRenderer.test.jsx +0 -1
  99. package/src/components/theme/View/View.jsx +6 -6
  100. package/src/components/theme/View/View.test.jsx +25 -18
  101. package/src/helpers/AsyncConnect/AsyncConnect.test.js +0 -2
  102. package/src/helpers/Utils/UseDetectClickOutside.stories.jsx +8 -8
  103. package/src/start-client.jsx +3 -3
  104. package/types/components/manage/Add/Add.d.ts +1 -4
  105. package/types/components/manage/Aliases/Aliases.d.ts +1 -4
  106. package/types/components/manage/Blocks/Block/Edit.d.ts +1 -3
  107. package/types/components/manage/Blocks/HeroImageLeft/Edit.d.ts +1 -4
  108. package/types/components/manage/Blocks/Image/Edit.d.ts +1 -4
  109. package/types/components/manage/Contents/Contents.d.ts +2 -7
  110. package/types/components/manage/Contents/ContentsUploadModal.d.ts +1 -4
  111. package/types/components/manage/Controlpanels/AddonsControlpanel.d.ts +1 -4
  112. package/types/components/manage/Controlpanels/Aliases.d.ts +1 -4
  113. package/types/components/manage/Controlpanels/ContentType.d.ts +1 -4
  114. package/types/components/manage/Controlpanels/ContentTypeLayout.d.ts +1 -4
  115. package/types/components/manage/Controlpanels/ContentTypeSchema.d.ts +1 -4
  116. package/types/components/manage/Controlpanels/ContentTypes.d.ts +1 -4
  117. package/types/components/manage/Controlpanels/DatabaseInformation.d.ts +1 -4
  118. package/types/components/manage/Controlpanels/Groups/GroupsControlpanel.d.ts +1 -4
  119. package/types/components/manage/Controlpanels/ModerateComments.d.ts +1 -4
  120. package/types/components/manage/Controlpanels/Rules/AddRule.d.ts +1 -4
  121. package/types/components/manage/Controlpanels/Rules/ConfigureRule.d.ts +1 -4
  122. package/types/components/manage/Controlpanels/Rules/EditRule.d.ts +1 -4
  123. package/types/components/manage/Controlpanels/Rules/Rules.d.ts +1 -4
  124. package/types/components/manage/Controlpanels/Rules/components/VariableModal.d.ts +1 -4
  125. package/types/components/manage/Controlpanels/UndoControlpanel.d.ts +1 -4
  126. package/types/components/manage/Controlpanels/UpgradeControlPanel.d.ts +1 -4
  127. package/types/components/manage/Controlpanels/Users/RenderUsers.d.ts +1 -4
  128. package/types/components/manage/Controlpanels/Users/UsersControlpanel.d.ts +1 -4
  129. package/types/components/manage/Display/Display.d.ts +1 -4
  130. package/types/components/manage/Edit/Edit.d.ts +2 -7
  131. package/types/components/manage/Form/BlocksToolbar.d.ts +1 -3
  132. package/types/components/manage/History/History.d.ts +1 -4
  133. package/types/components/manage/Preferences/PersonalPreferences.d.ts +1 -4
  134. package/types/components/manage/Rules/Rules.d.ts +1 -4
  135. package/types/components/manage/Sidebar/ObjectBrowserBody.d.ts +1 -4
  136. package/types/components/manage/Toolbar/Toolbar.d.ts +1 -4
  137. package/types/components/manage/Widgets/ArrayWidget.d.ts +1 -3
  138. package/types/components/manage/Widgets/IdWidget.d.ts +1 -4
  139. package/types/components/manage/Widgets/QueryWidget.d.ts +1 -3
  140. package/types/components/manage/Widgets/ReferenceWidget.d.ts +1 -4
  141. package/types/components/manage/Widgets/SchemaWidget.d.ts +1 -4
  142. package/types/components/manage/Widgets/SelectAutoComplete.d.ts +1 -3
  143. package/types/components/manage/Widgets/TokenWidget.d.ts +1 -4
  144. package/types/components/manage/Widgets/WysiwygWidget.d.ts +1 -4
  145. package/types/components/theme/Search/Search.d.ts +2 -7
  146. package/types/components/theme/Sitemap/Sitemap.d.ts +2 -6
  147. package/types/components/theme/View/View.d.ts +1 -4
  148. package/types/config/Widgets.d.ts +1 -3
  149. package/src/components/manage/Multilingual/CreateTranslation.test.jsx +0 -46
  150. package/src/helpers/Utils/usePagination.test.js +0 -115
@@ -2,11 +2,11 @@
2
2
  * LinksToItem component
3
3
  * @module components/manage/LinksToItem/LinksToItem
4
4
  */
5
- import { useEffect } from 'react';
5
+ import React, { useEffect, useState } from 'react';
6
6
  import { find } from 'lodash';
7
7
  import { Helmet } from '@plone/volto/helpers';
8
8
  import { Link } from 'react-router-dom';
9
- import { Portal } from 'react-portal';
9
+ import { createPortal } from 'react-dom';
10
10
  import { Container, Segment, Table } from 'semantic-ui-react';
11
11
  import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
12
12
  import { useDispatch, useSelector } from 'react-redux';
@@ -19,7 +19,6 @@ import {
19
19
  UniversalLink,
20
20
  Unauthorized,
21
21
  } from '@plone/volto/components';
22
- import { compose } from 'redux';
23
22
 
24
23
  import { getBaseUrl } from '@plone/volto/helpers';
25
24
  import backSVG from '@plone/volto/icons/back.svg';
@@ -57,6 +56,12 @@ const LinksToItem = (props) => {
57
56
  id: 'plone_setup',
58
57
  });
59
58
 
59
+ const [isClient, setIsClient] = useState(false);
60
+
61
+ useEffect(() => {
62
+ setIsClient(true);
63
+ }, []);
64
+
60
65
  useEffect(() => {
61
66
  dispatch(queryRelations(null, false, itempath, null, [itempath]));
62
67
  }, [dispatch, itempath]);
@@ -101,41 +106,46 @@ const LinksToItem = (props) => {
101
106
  <Table selectable compact singleLine attached>
102
107
  {
103
108
  <Table.Body>
104
- {Object.keys(links_ordered).map((relationtype) => {
109
+ {Object.keys(links_ordered).map((relationtype, index) => {
110
+ // TODO: keys driven by links_ordered[relationtype][index]['@id'])
105
111
  return [].concat(
106
112
  [
107
- <Table.Row>
108
- <Table.HeaderCell>
109
- {relationtype === 'isReferencing' ? (
110
- <FormattedMessage
111
- id="Linking this item with hyperlink in text"
112
- defaultMessage="Linking this item with hyperlink in text"
113
- />
114
- ) : relationtype === 'relatedItems' ? (
115
- <FormattedMessage
116
- id="Referencing this item as related item"
117
- defaultMessage="Referencing this item as related item"
118
- />
119
- ) : (
120
- <>
113
+ <React.Fragment key={index}>
114
+ <Table.Row>
115
+ <Table.HeaderCell>
116
+ {relationtype === 'isReferencing' ? (
121
117
  <FormattedMessage
122
- id="Referencing this item with {relationship}"
123
- defaultMessage="Referencing this item with {relationship}"
124
- values={{ relationship: <q>{relationtype}</q> }}
118
+ id="Linking this item with hyperlink in text"
119
+ defaultMessage="Linking this item with hyperlink in text"
125
120
  />
126
- </>
127
- )}
128
- </Table.HeaderCell>
129
- <Table.HeaderCell>
130
- <FormattedMessage
131
- id="Review state"
132
- defaultMessage="Review state"
133
- />
134
- </Table.HeaderCell>
135
- <Table.HeaderCell>
136
- <FormattedMessage id="Type" defaultMessage="Type" />
137
- </Table.HeaderCell>
138
- </Table.Row>,
121
+ ) : relationtype === 'relatedItems' ? (
122
+ <FormattedMessage
123
+ id="Referencing this item as related item"
124
+ defaultMessage="Referencing this item as related item"
125
+ />
126
+ ) : (
127
+ <>
128
+ <FormattedMessage
129
+ id="Referencing this item with {relationship}"
130
+ defaultMessage="Referencing this item with {relationship}"
131
+ values={{
132
+ relationship: <q>{relationtype}</q>,
133
+ }}
134
+ />
135
+ </>
136
+ )}
137
+ </Table.HeaderCell>
138
+ <Table.HeaderCell>
139
+ <FormattedMessage
140
+ id="Review state"
141
+ defaultMessage="Review state"
142
+ />
143
+ </Table.HeaderCell>
144
+ <Table.HeaderCell>
145
+ <FormattedMessage id="Type" defaultMessage="Type" />
146
+ </Table.HeaderCell>
147
+ </Table.Row>
148
+ </React.Fragment>,
139
149
  ],
140
150
  links_ordered[relationtype].map((link) => {
141
151
  return (
@@ -173,8 +183,8 @@ const LinksToItem = (props) => {
173
183
  </Segment>
174
184
  )}
175
185
  </Segment.Group>
176
- {__CLIENT__ && (
177
- <Portal node={document.getElementById('toolbar')}>
186
+ {isClient &&
187
+ createPortal(
178
188
  <Toolbar
179
189
  pathname={pathname}
180
190
  hideDefaultViewButtons
@@ -208,22 +218,41 @@ const LinksToItem = (props) => {
208
218
  </>
209
219
  </>
210
220
  }
211
- />
212
- </Portal>
213
- )}
221
+ />,
222
+ document.getElementById('toolbar'),
223
+ )}
214
224
  </Container>
215
225
  );
216
226
  };
217
227
 
218
228
  export const __test__ = LinksToItem;
219
- export default compose(
220
- asyncConnect([
221
- {
222
- key: 'actions',
223
- // Dispatch async/await to make the operation synchronous, otherwise it returns
224
- // before the promise is resolved
225
- promise: async ({ location, store: { dispatch } }) =>
226
- await dispatch(listActions(getBaseUrl(location.pathname))),
229
+
230
+ export default asyncConnect([
231
+ {
232
+ key: 'content',
233
+ // Dispatch async/await to make the operation synchronous, otherwise it returns
234
+ // before the promise is resolved
235
+ promise: async ({ location, store: { dispatch } }) => {
236
+ const pathname = getBaseUrl(location.pathname);
237
+ return await dispatch(getContent(pathname));
227
238
  },
228
- ]),
229
- )(LinksToItem);
239
+ },
240
+ {
241
+ key: 'actions',
242
+ // Dispatch async/await to make the operation synchronous, otherwise it returns
243
+ // before the promise is resolved
244
+ promise: async ({ location, store: { dispatch } }) =>
245
+ await dispatch(listActions(getBaseUrl(location.pathname))),
246
+ },
247
+ {
248
+ key: 'relations',
249
+ // Dispatch async/await to make the operation synchronous, otherwise it returns
250
+ // before the promise is resolved
251
+ promise: async ({ location, store: { dispatch } }) => {
252
+ const pathname = getBaseUrl(location.pathname);
253
+ return await dispatch(
254
+ queryRelations(null, false, pathname, null, [pathname]),
255
+ );
256
+ },
257
+ },
258
+ ])(LinksToItem);
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import renderer from 'react-test-renderer';
2
+ import { render } from '@testing-library/react';
3
3
  import { Provider } from 'react-intl-redux';
4
4
  import configureMockStore from 'redux-mock-store';
5
5
  import thunk from 'redux-thunk';
@@ -10,9 +10,8 @@ import { __test__ as LinksToItem } from './LinksToItem';
10
10
  const middlewares = [thunk];
11
11
  const mockStore = configureMockStore(middlewares);
12
12
 
13
- jest.mock('react-portal', () => ({
14
- Portal: jest.fn(() => <div id="Portal" />),
15
- }));
13
+ jest.mock('../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));
14
+
16
15
  jest.mock('../Toolbar/More', () => jest.fn(() => <div className="More" />));
17
16
 
18
17
  describe('LinksToItem', () => {
@@ -99,14 +98,15 @@ describe('LinksToItem', () => {
99
98
  messages: {},
100
99
  },
101
100
  });
102
- const component = renderer.create(
101
+ const { container } = render(
103
102
  <Provider store={store}>
104
103
  <MemoryRouter>
105
104
  <LinksToItem location={{ pathname: '/page-1/links-to-item' }} />
105
+ <div id="toolbar"></div>
106
106
  </MemoryRouter>
107
107
  </Provider>,
108
108
  );
109
- const json = component.toJSON();
110
- expect(json).toMatchSnapshot();
109
+
110
+ expect(container).toMatchSnapshot();
111
111
  });
112
112
  });
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useEffect, useState } from 'react';
2
2
  import { Button, Container, Segment, Table } from 'semantic-ui-react';
3
3
  import { Helmet } from '@plone/volto/helpers';
4
4
  import { flattenToAppURL, getBaseUrl, langmap } from '@plone/volto/helpers';
@@ -15,7 +15,7 @@ import {
15
15
  } from '@plone/volto/actions';
16
16
  import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
17
17
  import { useSelector, useDispatch } from 'react-redux';
18
- import { Portal } from 'react-portal';
18
+ import { createPortal } from 'react-dom';
19
19
  import { toast } from 'react-toastify';
20
20
 
21
21
  import addSVG from '@plone/volto/icons/add.svg';
@@ -64,6 +64,12 @@ const ManageTranslations = (props) => {
64
64
  const content = useSelector((state) => state.content.data);
65
65
  const dispatch = useDispatch();
66
66
 
67
+ const [isClient, setIsClient] = useState(false);
68
+
69
+ useEffect(() => {
70
+ setIsClient(true);
71
+ }, []);
72
+
67
73
  const { isObjectBrowserOpen, openObjectBrowser } = props;
68
74
 
69
75
  const currentSelectedItem = React.useRef(null);
@@ -269,8 +275,8 @@ const ManageTranslations = (props) => {
269
275
  </Table.Body>
270
276
  </Table>
271
277
  )}
272
- {__CLIENT__ && (
273
- <Portal node={document.getElementById('toolbar')}>
278
+ {isClient &&
279
+ createPortal(
274
280
  <Toolbar
275
281
  pathname={pathname}
276
282
  hideDefaultViewButtons
@@ -284,9 +290,9 @@ const ManageTranslations = (props) => {
284
290
  />
285
291
  </Link>
286
292
  }
287
- />
288
- </Portal>
289
- )}
293
+ />,
294
+ document.getElementById('toolbar'),
295
+ )}
290
296
  </Segment.Group>
291
297
  </Container>
292
298
  );
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import renderer from 'react-test-renderer';
2
+ import { render } from '@testing-library/react';
3
3
  import configureStore from 'redux-mock-store';
4
4
  import { Provider } from 'react-intl-redux';
5
5
  import { MemoryRouter } from 'react-router-dom';
@@ -12,9 +12,7 @@ beforeAll(() => {
12
12
  config.settings.supportedLanguages = ['de', 'es'];
13
13
  });
14
14
 
15
- jest.mock('react-portal', () => ({
16
- Portal: jest.fn(() => <div id="Portal" />),
17
- }));
15
+ jest.mock('../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));
18
16
 
19
17
  const mockStore = configureStore();
20
18
 
@@ -36,7 +34,7 @@ describe('ManageTranslations', () => {
36
34
  },
37
35
  },
38
36
  });
39
- const component = renderer.create(
37
+ const { container } = render(
40
38
  <Provider store={store}>
41
39
  <MemoryRouter>
42
40
  <ManageTranslations
@@ -48,10 +46,11 @@ describe('ManageTranslations', () => {
48
46
  },
49
47
  }}
50
48
  />
49
+ <div id="toolbar"></div>
51
50
  </MemoryRouter>
52
51
  </Provider>,
53
52
  );
54
- const json = component.toJSON();
55
- expect(json).toMatchSnapshot();
53
+
54
+ expect(container).toMatchSnapshot();
56
55
  });
57
56
  });
@@ -9,7 +9,7 @@ import { Helmet } from '@plone/volto/helpers';
9
9
  import { connect } from 'react-redux';
10
10
  import { compose } from 'redux';
11
11
  import { Link, withRouter } from 'react-router-dom';
12
- import { Portal } from 'react-portal';
12
+ import { createPortal } from 'react-dom';
13
13
  import { defineMessages, injectIntl } from 'react-intl';
14
14
  import { Container } from 'semantic-ui-react';
15
15
  import jwtDecode from 'jwt-decode';
@@ -195,8 +195,8 @@ class ChangePassword extends Component {
195
195
  onCancel={this.onCancel}
196
196
  loading={this.props.loading}
197
197
  />
198
- {this.state.isClient && (
199
- <Portal node={document.getElementById('toolbar')}>
198
+ {this.state.isClient &&
199
+ createPortal(
200
200
  <Toolbar
201
201
  pathname={this.props.pathname}
202
202
  hideDefaultViewButtons
@@ -213,9 +213,9 @@ class ChangePassword extends Component {
213
213
  />
214
214
  </Link>
215
215
  }
216
- />
217
- </Portal>
218
- )}
216
+ />,
217
+ document.getElementById('toolbar'),
218
+ )}
219
219
  </Container>
220
220
  );
221
221
  }
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import renderer from 'react-test-renderer';
2
+ import { render } from '@testing-library/react';
3
3
  import { Provider } from 'react-intl-redux';
4
4
  import configureStore from 'redux-mock-store';
5
5
  import jwt from 'jsonwebtoken';
@@ -9,9 +9,7 @@ import ChangePassword from './ChangePassword';
9
9
 
10
10
  const mockStore = configureStore();
11
11
 
12
- jest.mock('react-portal', () => ({
13
- Portal: jest.fn(() => <div id="Portal" />),
14
- }));
12
+ jest.mock('../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));
15
13
 
16
14
  describe('ChangePassword', () => {
17
15
  it('renders a change password component', () => {
@@ -36,14 +34,15 @@ describe('ChangePassword', () => {
36
34
  },
37
35
  },
38
36
  });
39
- const component = renderer.create(
37
+ const { container } = render(
40
38
  <Provider store={store}>
41
39
  <MemoryRouter>
42
40
  <ChangePassword location={{ pathname: '/blog' }} />
41
+ <div id="toolbar"></div>
43
42
  </MemoryRouter>
44
43
  </Provider>,
45
44
  );
46
- const json = component.toJSON();
47
- expect(json).toMatchSnapshot();
45
+
46
+ expect(container).toMatchSnapshot();
48
47
  });
49
48
  });
@@ -18,9 +18,7 @@ const userSchema = {
18
18
  loading: false,
19
19
  };
20
20
 
21
- jest.mock('react-portal', () => ({
22
- Portal: jest.fn(() => <div id="Portal" />),
23
- }));
21
+ jest.mock('../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));
24
22
 
25
23
  describe('PersonalInformation', () => {
26
24
  it('renders a personal information component', async () => {
@@ -8,9 +8,7 @@ import PersonalPreferences from './PersonalPreferences';
8
8
 
9
9
  const mockStore = configureStore();
10
10
 
11
- jest.mock('react-portal', () => ({
12
- Portal: jest.fn(() => <div id="Portal" />),
13
- }));
11
+ jest.mock('../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));
14
12
 
15
13
  jest.mock('@plone/volto/helpers/Loadable/Loadable');
16
14
  beforeAll(
@@ -8,7 +8,7 @@ import { Helmet } from '@plone/volto/helpers';
8
8
  import { connect } from 'react-redux';
9
9
  import { compose } from 'redux';
10
10
  import { Link } from 'react-router-dom';
11
- import { Portal } from 'react-portal';
11
+ import { createPortal } from 'react-dom';
12
12
  import {
13
13
  Button,
14
14
  Checkbox,
@@ -484,8 +484,8 @@ class Rules extends Component {
484
484
  </Button>
485
485
  </React.Fragment>
486
486
  )}
487
- {this.state.isClient && (
488
- <Portal node={document.getElementById('toolbar')}>
487
+ {this.state.isClient &&
488
+ createPortal(
489
489
  <Toolbar
490
490
  pathname={this.props.pathname}
491
491
  hideDefaultViewButtons
@@ -502,9 +502,9 @@ class Rules extends Component {
502
502
  />
503
503
  </Link>
504
504
  }
505
- />
506
- </Portal>
507
- )}
505
+ />,
506
+ document.getElementById('toolbar'),
507
+ )}
508
508
  </Container>
509
509
  );
510
510
  }
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import renderer from 'react-test-renderer';
2
+ import { render } from '@testing-library/react';
3
3
  import { Provider } from 'react-intl-redux';
4
4
  import configureMockStore from 'redux-mock-store';
5
5
  import thunk from 'redux-thunk';
@@ -9,9 +9,8 @@ import Rules from './Rules';
9
9
  const middlewares = [thunk];
10
10
  const mockStore = configureMockStore(middlewares);
11
11
 
12
- jest.mock('react-portal', () => ({
13
- Portal: jest.fn(() => <div id="Portal" />),
14
- }));
12
+ jest.mock('../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));
13
+
15
14
  jest.mock('../Toolbar/More', () => jest.fn(() => <div className="More" />));
16
15
 
17
16
  describe('Rules', () => {
@@ -65,12 +64,13 @@ describe('Rules', () => {
65
64
  messages: {},
66
65
  },
67
66
  });
68
- const component = renderer.create(
67
+ const { container } = render(
69
68
  <Provider store={store}>
70
69
  <Rules location={{ pathname: '/blog/rules' }} />
70
+ <div id="toolbar"></div>
71
71
  </Provider>,
72
72
  );
73
- const json = component.toJSON();
74
- expect(json).toMatchSnapshot();
73
+
74
+ expect(container).toMatchSnapshot();
75
75
  });
76
76
  });
@@ -10,7 +10,7 @@ import { connect } from 'react-redux';
10
10
  import { compose } from 'redux';
11
11
  import { Link, withRouter } from 'react-router-dom';
12
12
  import { find, isEqual, map } from 'lodash';
13
- import { Portal } from 'react-portal';
13
+ import { createPortal } from 'react-dom';
14
14
  import {
15
15
  Button,
16
16
  Checkbox,
@@ -505,8 +505,8 @@ class SharingComponent extends Component {
505
505
  </Form>
506
506
  </Plug>
507
507
  </Segment.Group>
508
- {this.state.isClient && (
509
- <Portal node={document.getElementById('toolbar')}>
508
+ {this.state.isClient &&
509
+ createPortal(
510
510
  <Toolbar
511
511
  pathname={this.props.pathname}
512
512
  hideDefaultViewButtons
@@ -523,9 +523,9 @@ class SharingComponent extends Component {
523
523
  />
524
524
  </Link>
525
525
  }
526
- />
527
- </Portal>
528
- )}
526
+ />,
527
+ document.getElementById('toolbar'),
528
+ )}
529
529
  </Container>
530
530
  );
531
531
  }
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import renderer from 'react-test-renderer';
2
+ import { render } from '@testing-library/react';
3
3
  import configureStore from 'redux-mock-store';
4
4
  import { Provider } from 'react-intl-redux';
5
5
  import jwt from 'jsonwebtoken';
@@ -10,9 +10,7 @@ import Sharing from './Sharing';
10
10
 
11
11
  const mockStore = configureStore();
12
12
 
13
- jest.mock('react-portal', () => ({
14
- Portal: jest.fn(() => <div id="Portal" />),
15
- }));
13
+ jest.mock('../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));
16
14
 
17
15
  describe('Sharing', () => {
18
16
  it('renders a sharing component', () => {
@@ -57,16 +55,18 @@ describe('Sharing', () => {
57
55
  messages: {},
58
56
  },
59
57
  });
60
- const component = renderer.create(
58
+
59
+ const { container } = render(
61
60
  <Provider store={store}>
62
61
  <PluggablesProvider>
63
62
  <MemoryRouter>
64
63
  <Sharing location={{ pathname: '/blog' }} />
64
+ <div id="toolbar"></div>
65
65
  </MemoryRouter>
66
66
  </PluggablesProvider>
67
67
  </Provider>,
68
68
  );
69
- const json = component.toJSON();
70
- expect(json).toMatchSnapshot();
69
+
70
+ expect(container).toMatchSnapshot();
71
71
  });
72
72
  });
@@ -98,7 +98,7 @@ const withObjectBrowser = (WrappedComponent) =>
98
98
  <ObjectBrowserBody
99
99
  {...this.props}
100
100
  data={
101
- this.state.propDataName
101
+ this.state.propDataName && this.props[this.state.propDataName]
102
102
  ? this.props[this.state.propDataName]
103
103
  : this.props.data
104
104
  }
@@ -138,6 +138,7 @@ const Sidebar = (props) => {
138
138
  panes={[
139
139
  !!documentTab && {
140
140
  menuItem: {
141
+ key: 'documentTab',
141
142
  as: 'button',
142
143
  className: 'ui button',
143
144
  content: type || intl.formatMessage(messages.document),
@@ -152,6 +153,7 @@ const Sidebar = (props) => {
152
153
  },
153
154
  !!blockTab && {
154
155
  menuItem: {
156
+ key: 'blockTab',
155
157
  as: 'button',
156
158
  className: 'ui button',
157
159
  content: intl.formatMessage(messages.block),
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { Portal } from 'react-portal';
2
+ import { createPortal } from 'react-dom';
3
3
  import { CSSTransition } from 'react-transition-group';
4
4
  import PropTypes from 'prop-types';
5
5
  import { doesNodeContainClick } from 'semantic-ui-react/dist/commonjs/lib';
@@ -32,9 +32,13 @@ const SidebarPopup = (props) => {
32
32
  classNames="overlay-container"
33
33
  unmountOnExit
34
34
  >
35
- <Portal node={document?.body}>
36
- <div className="overlay-container"></div>
37
- </Portal>
35
+ <>
36
+ {document?.body &&
37
+ createPortal(
38
+ <div className="overlay-container"></div>,
39
+ document?.body,
40
+ )}
41
+ </>
38
42
  </CSSTransition>
39
43
  )}
40
44
  <CSSTransition
@@ -43,23 +47,26 @@ const SidebarPopup = (props) => {
43
47
  classNames="sidebar-container"
44
48
  unmountOnExit
45
49
  >
46
- <Portal>
47
- <aside
48
- role="presentation"
49
- onClick={(e) => {
50
- e.stopPropagation();
51
- }}
52
- onKeyDown={(e) => {
53
- e.stopPropagation();
54
- }}
55
- ref={asideElement}
56
- key="sidebarpopup"
57
- className="sidebar-container"
58
- style={{ overflowY: 'auto' }}
59
- >
60
- {children}
61
- </aside>
62
- </Portal>
50
+ <>
51
+ {createPortal(
52
+ <aside
53
+ role="presentation"
54
+ onClick={(e) => {
55
+ e.stopPropagation();
56
+ }}
57
+ onKeyDown={(e) => {
58
+ e.stopPropagation();
59
+ }}
60
+ ref={asideElement}
61
+ key="sidebarpopup"
62
+ className="sidebar-container"
63
+ style={{ overflowY: 'auto' }}
64
+ >
65
+ {children}
66
+ </aside>,
67
+ document.body,
68
+ )}
69
+ </>
63
70
  </CSSTransition>
64
71
  </>
65
72
  );