@plone/volto 19.0.0-alpha.0 → 19.0.0-alpha.10

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 (367) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc +37 -0
  3. package/CHANGELOG.md +274 -2
  4. package/README.md +3 -6
  5. package/cypress/docker/prefixed-rules.yml +26 -0
  6. package/cypress/docker/prefixed.yml +24 -0
  7. package/cypress/support/commands.js +12 -6
  8. package/cypress/support/guillotina.js +1 -0
  9. package/cypress.config.js +1 -0
  10. package/locales/af.json +1 -0
  11. package/locales/ar.json +1 -0
  12. package/locales/bg.json +1 -0
  13. package/locales/bn.json +1 -0
  14. package/locales/ca/LC_MESSAGES/volto.po +96 -17
  15. package/locales/ca.json +1 -1
  16. package/locales/cs.json +1 -0
  17. package/locales/cy.json +1 -0
  18. package/locales/da.json +1 -0
  19. package/locales/de/LC_MESSAGES/volto.po +104 -25
  20. package/locales/de.json +1 -1
  21. package/locales/el.json +1 -0
  22. package/locales/en/LC_MESSAGES/volto.po +97 -18
  23. package/locales/en.json +1 -1
  24. package/locales/en_AU.json +1 -0
  25. package/locales/en_GB.json +1 -0
  26. package/locales/eo.json +1 -0
  27. package/locales/es/LC_MESSAGES/volto.po +97 -18
  28. package/locales/es.json +1 -1
  29. package/locales/et.json +1 -0
  30. package/locales/eu/LC_MESSAGES/volto.po +96 -17
  31. package/locales/eu.json +1 -1
  32. package/locales/fa.json +1 -0
  33. package/locales/fi/LC_MESSAGES/volto.po +96 -17
  34. package/locales/fi.json +1 -1
  35. package/locales/fr/LC_MESSAGES/volto.po +97 -18
  36. package/locales/fr.json +1 -1
  37. package/locales/fu.json +1 -0
  38. package/locales/gl.json +1 -0
  39. package/locales/he.json +1 -0
  40. package/locales/hi/LC_MESSAGES/volto.po +100 -21
  41. package/locales/hi.json +1 -1
  42. package/locales/hr.json +1 -0
  43. package/locales/hu.json +1 -0
  44. package/locales/hy.json +1 -0
  45. package/locales/id.json +1 -0
  46. package/locales/it/LC_MESSAGES/volto.po +101 -22
  47. package/locales/it.json +1 -1
  48. package/locales/ja/LC_MESSAGES/volto.po +96 -17
  49. package/locales/ja.json +1 -1
  50. package/locales/ka.json +1 -0
  51. package/locales/kn.json +1 -0
  52. package/locales/ko.json +1 -0
  53. package/locales/lt.json +1 -0
  54. package/locales/lv.json +1 -0
  55. package/locales/mi.json +1 -0
  56. package/locales/mk.json +1 -0
  57. package/locales/my.json +1 -0
  58. package/locales/nb_NO.json +1 -0
  59. package/locales/nl/LC_MESSAGES/volto.po +100 -21
  60. package/locales/nl.json +1 -1
  61. package/locales/nn.json +1 -0
  62. package/locales/pl.json +1 -0
  63. package/locales/pt/LC_MESSAGES/volto.po +96 -17
  64. package/locales/pt.json +1 -1
  65. package/locales/pt_BR/LC_MESSAGES/volto.po +116 -37
  66. package/locales/pt_BR.json +1 -1
  67. package/locales/rm.json +1 -0
  68. package/locales/ro/LC_MESSAGES/volto.po +100 -21
  69. package/locales/ro.json +1 -1
  70. package/locales/ru/LC_MESSAGES/volto.po +100 -21
  71. package/locales/ru.json +1 -1
  72. package/locales/sk.json +1 -0
  73. package/locales/sl.json +1 -0
  74. package/locales/sm.json +1 -0
  75. package/locales/sq.json +1 -0
  76. package/locales/sr.json +1 -0
  77. package/locales/sr@cyrl.json +1 -0
  78. package/locales/sr@latn.json +1 -0
  79. package/locales/sv.json +1 -1
  80. package/locales/ta.json +1 -0
  81. package/locales/te.json +1 -0
  82. package/locales/th.json +1 -0
  83. package/locales/to.json +1 -0
  84. package/locales/tr.json +1 -0
  85. package/locales/uk.json +1 -0
  86. package/locales/vi.json +1 -0
  87. package/locales/volto.pot +97 -18
  88. package/locales/zh_CN/LC_MESSAGES/volto.po +96 -17
  89. package/locales/zh_CN.json +1 -1
  90. package/locales/zh_Hant.json +1 -0
  91. package/locales/zh_Hant_HK.json +1 -0
  92. package/package.json +36 -27
  93. package/razzle.config.js +16 -0
  94. package/src/actions/actions/actions.test.js +3 -3
  95. package/src/actions/addons/addons.test.js +15 -12
  96. package/src/actions/aliases/aliases.test.js +1 -1
  97. package/src/actions/content/content.js +0 -1
  98. package/src/actions/controlpanels/controlpanels.js +13 -7
  99. package/src/actions/controlpanels/controlpanels.test.js +11 -5
  100. package/src/actions/querystring/querystring.test.js +2 -2
  101. package/src/actions/types/types.test.js +1 -1
  102. package/src/actions/users/users.js +2 -2
  103. package/src/components/manage/Actions/Actions.test.jsx +5 -1
  104. package/src/components/manage/Add/Add.jsx +27 -26
  105. package/src/components/manage/Add/Add.test.jsx +6 -3
  106. package/src/components/manage/Aliases/Aliases.test.jsx +7 -7
  107. package/src/components/manage/Blocks/Block/BlocksForm.jsx +1 -0
  108. package/src/components/manage/Blocks/Block/BlocksForm.test.jsx +48 -16
  109. package/src/components/manage/Blocks/Block/Edit.jsx +3 -1
  110. package/src/components/manage/Blocks/Block/EditBlockWrapper.jsx +9 -4
  111. package/src/components/manage/Blocks/Block/Settings.test.jsx +5 -1
  112. package/src/components/manage/Blocks/Block/StyleWrapper.jsx +11 -3
  113. package/src/components/manage/Blocks/Description/View.test.jsx +1 -1
  114. package/src/components/manage/Blocks/HTML/Edit.test.jsx +12 -5
  115. package/src/components/manage/Blocks/HTML/View.test.jsx +1 -1
  116. package/src/components/manage/Blocks/Image/Edit.jsx +5 -1
  117. package/src/components/manage/Blocks/Image/ImageSidebar.test.jsx +6 -2
  118. package/src/components/manage/Blocks/LeadImage/Edit.jsx +2 -2
  119. package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.jsx +1 -1
  120. package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.test.jsx +8 -1
  121. package/src/components/manage/Blocks/Listing/ImageGallery.jsx +6 -4
  122. package/src/components/manage/Blocks/Listing/View.test.jsx +3 -1
  123. package/src/components/manage/Blocks/Maps/Edit.jsx +2 -1
  124. package/src/components/manage/Blocks/Maps/MapsSidebar.test.jsx +5 -1
  125. package/src/components/manage/Blocks/Search/SearchBlockView.jsx +21 -4
  126. package/src/components/manage/Blocks/Search/components/DateRangeFacet.test.jsx +13 -7
  127. package/src/components/manage/Blocks/Search/components/SelectFacet.test.jsx +12 -6
  128. package/src/components/manage/Blocks/Teaser/Data.jsx +21 -7
  129. package/src/components/manage/Blocks/Teaser/DefaultBody.jsx +1 -1
  130. package/src/components/manage/Blocks/Teaser/schema.js +8 -3
  131. package/src/components/manage/Blocks/Title/Edit.jsx +8 -2
  132. package/src/components/manage/Blocks/ToC/variations/DefaultTocRenderer.test.jsx +11 -1
  133. package/src/components/manage/Blocks/Video/Edit.jsx +2 -1
  134. package/src/components/manage/Blocks/Video/VideoSidebar.test.jsx +5 -1
  135. package/src/components/manage/ConditionalLink/ConditionalLink.test.tsx +109 -0
  136. package/src/components/manage/ConditionalLink/ConditionalLink.tsx +36 -0
  137. package/src/components/manage/Contents/Contents.jsx +23 -2
  138. package/src/components/manage/Contents/Contents.test.jsx +36 -13
  139. package/src/components/manage/Contents/ContentsBreadcrumbs.Multilingual.test.jsx +18 -5
  140. package/src/components/manage/Contents/ContentsBreadcrumbs.jsx +20 -26
  141. package/src/components/manage/Contents/ContentsBreadcrumbs.test.jsx +14 -0
  142. package/src/components/manage/Contents/ContentsDeleteModal.jsx +258 -206
  143. package/src/components/manage/Contents/ContentsDeleteModal.stories.jsx +26 -8
  144. package/src/components/manage/Contents/ContentsItem.jsx +10 -2
  145. package/src/components/manage/Contents/ContentsPropertiesModal.test.jsx +5 -1
  146. package/src/components/manage/Contents/ContentsRenameModal.test.jsx +5 -1
  147. package/src/components/manage/Contents/ContentsTagsModal.test.jsx +5 -1
  148. package/src/components/manage/Contents/ContentsUploadModal.test.jsx +13 -22
  149. package/src/components/manage/Contents/ContentsWorkflowModal.test.jsx +5 -1
  150. package/src/components/manage/Contents/__mocks__/index.tsx +16 -0
  151. package/src/components/manage/Contents/__mocks__/index.vitest.tsx +5 -0
  152. package/src/components/manage/Controlpanels/AddonsControlpanel.test.jsx +28 -3
  153. package/src/components/manage/Controlpanels/Aliases.test.jsx +35 -3
  154. package/src/components/manage/Controlpanels/ContentType.jsx +1 -1
  155. package/src/components/manage/Controlpanels/ContentType.test.jsx +29 -3
  156. package/src/components/manage/Controlpanels/ContentTypeLayout.test.jsx +4 -2
  157. package/src/components/manage/Controlpanels/ContentTypes.test.jsx +25 -2
  158. package/src/components/manage/Controlpanels/Controlpanel.test.jsx +37 -6
  159. package/src/components/manage/Controlpanels/Controlpanels.test.jsx +47 -3
  160. package/src/components/manage/Controlpanels/Groups/GroupsControlpanel.jsx +3 -2
  161. package/src/components/manage/Controlpanels/Groups/GroupsControlpanel.test.jsx +15 -9
  162. package/src/components/manage/Controlpanels/ModerateComments.test.jsx +31 -5
  163. package/src/components/manage/Controlpanels/Rules/AddRule.test.jsx +13 -4
  164. package/src/components/manage/Controlpanels/Rules/ConfigureRule.test.jsx +9 -5
  165. package/src/components/manage/Controlpanels/Rules/EditRule.test.jsx +12 -4
  166. package/src/components/manage/Controlpanels/Rules/Rules.test.jsx +7 -3
  167. package/src/components/manage/Controlpanels/UndoControlpanel.test.jsx +33 -4
  168. package/src/components/manage/Controlpanels/Users/RenderUsers.jsx +156 -175
  169. package/src/components/manage/Controlpanels/Users/UserGroupMembershipControlPanel.test.jsx +3 -1
  170. package/src/components/manage/Controlpanels/Users/UsersControlpanel.jsx +575 -630
  171. package/src/components/manage/Controlpanels/Users/UsersControlpanel.test.jsx +16 -9
  172. package/src/components/manage/Delete/Delete.test.jsx +45 -4
  173. package/src/components/manage/Diff/Diff.test.jsx +15 -6
  174. package/src/components/manage/Diff/DiffField.test.jsx +12 -6
  175. package/src/components/manage/Display/Display.test.jsx +17 -6
  176. package/src/components/manage/Edit/Edit.jsx +2 -3
  177. package/src/components/manage/Edit/Edit.test.jsx +11 -3
  178. package/src/components/manage/Form/BlockDataForm.test.jsx +5 -1
  179. package/src/components/manage/Form/Form.jsx +32 -0
  180. package/src/components/manage/Form/Form.test.jsx +27 -19
  181. package/src/components/manage/Form/InlineForm.jsx +2 -2
  182. package/src/components/manage/Form/InlineForm.test.jsx +5 -1
  183. package/src/components/manage/Form/ModalForm.test.jsx +5 -1
  184. package/src/components/manage/Form/__mocks__/index.tsx +17 -0
  185. package/src/components/manage/Form/__mocks__/index.vitest.tsx +73 -0
  186. package/src/components/manage/History/History.test.jsx +3 -1
  187. package/src/components/manage/LinksToItem/LinksToItem.test.jsx +6 -4
  188. package/src/components/manage/MaybeWrap/MaybeWrap.tsx +15 -0
  189. package/src/components/manage/Multilingual/CompareLanguages.jsx +2 -5
  190. package/src/components/manage/Multilingual/CreateTranslation.jsx +8 -8
  191. package/src/components/manage/Multilingual/ManageTranslations.jsx +4 -2
  192. package/src/components/manage/Multilingual/ManageTranslations.test.jsx +8 -3
  193. package/src/components/manage/Multilingual/TranslationObject.jsx +1 -1
  194. package/src/components/manage/Preferences/ChangePassword.test.jsx +9 -2
  195. package/src/components/manage/Preferences/PersonalInformation.test.jsx +3 -1
  196. package/src/components/manage/Preferences/PersonalPreferences.test.jsx +20 -7
  197. package/src/components/manage/Rules/Rules.test.jsx +6 -3
  198. package/src/components/manage/Sharing/Sharing.test.jsx +3 -1
  199. package/src/components/manage/Sidebar/ObjectBrowserNav.jsx +2 -1
  200. package/src/components/manage/Sidebar/ObjectBrowserNav.test.jsx +3 -3
  201. package/src/components/manage/Sidebar/SidebarPortal.test.tsx +42 -0
  202. package/src/components/manage/Sidebar/SidebarPortal.tsx +48 -0
  203. package/src/components/manage/TemplateChooser/TemplateChooser.jsx +2 -1
  204. package/src/components/manage/Toolbar/More.jsx +4 -1
  205. package/src/components/manage/Toolbar/More.test.jsx +9 -7
  206. package/src/components/manage/Toolbar/PersonalTools.jsx +2 -1
  207. package/src/components/manage/Toolbar/Toolbar.jsx +3 -4
  208. package/src/components/manage/Toolbar/Types.jsx +7 -7
  209. package/src/components/manage/UniversalLink/UniversalLink.test.jsx +196 -14
  210. package/src/components/manage/UniversalLink/UniversalLink.tsx +215 -0
  211. package/src/components/manage/Widgets/ArrayWidget.test.jsx +22 -5
  212. package/src/components/manage/Widgets/CheckboxGroupWidget.test.jsx +12 -5
  213. package/src/components/manage/Widgets/DatetimeWidget.jsx +5 -0
  214. package/src/components/manage/Widgets/DatetimeWidget.test.jsx +21 -6
  215. package/src/components/manage/Widgets/FileWidget.jsx +14 -8
  216. package/src/components/manage/Widgets/ImageWidget.jsx +176 -40
  217. package/src/components/manage/Widgets/InternalUrlWidget.jsx +2 -0
  218. package/src/components/manage/Widgets/NumberWidget.test.jsx +8 -7
  219. package/src/components/manage/Widgets/ObjectBrowserWidget.jsx +3 -0
  220. package/src/components/manage/Widgets/ObjectListWidget.jsx +11 -1
  221. package/src/components/manage/Widgets/ObjectListWidget.test.jsx +18 -8
  222. package/src/components/manage/Widgets/ObjectWidget.test.jsx +5 -1
  223. package/src/components/manage/Widgets/RadioGroupWidget.test.jsx +12 -5
  224. package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.test.jsx +12 -6
  225. package/src/components/manage/Widgets/RegistryImageWidget.test.jsx +44 -41
  226. package/src/components/manage/Widgets/SchemaWidget.test.jsx +12 -5
  227. package/src/components/manage/Widgets/SchemaWidgetFieldset.test.jsx +12 -5
  228. package/src/components/manage/Widgets/SelectAutoComplete.jsx +29 -12
  229. package/src/components/manage/Widgets/SelectAutoComplete.test.jsx +12 -6
  230. package/src/components/manage/Widgets/SelectWidget.jsx +3 -1
  231. package/src/components/manage/Widgets/SelectWidget.test.jsx +12 -6
  232. package/src/components/manage/Widgets/TimeWidget.test.jsx +13 -5
  233. package/src/components/manage/Widgets/TokenWidget.test.jsx +12 -6
  234. package/src/components/manage/Widgets/UrlWidget.jsx +2 -0
  235. package/src/components/manage/Widgets/VocabularyTermsWidget.test.jsx +18 -9
  236. package/src/components/manage/Widgets/__mocks__/index.tsx +16 -0
  237. package/src/components/manage/Widgets/__mocks__/index.vitest.tsx +41 -0
  238. package/src/components/manage/Workflow/Workflow.test.jsx +17 -7
  239. package/src/components/theme/AlternateHrefLangs/AlternateHrefLangs.jsx +1 -3
  240. package/src/components/theme/AlternateHrefLangs/AlternateHrefLangs.test.jsx +0 -4
  241. package/src/components/theme/App/App.jsx +3 -1
  242. package/src/components/theme/App/App.test.jsx +22 -17
  243. package/src/components/theme/AppExtras/AppExtras.test.jsx +6 -6
  244. package/src/components/theme/Avatar/Avatar.jsx +2 -1
  245. package/src/components/theme/Comments/CommentEditModal.test.jsx +5 -1
  246. package/src/components/theme/Comments/Comments.test.jsx +29 -12
  247. package/src/components/theme/ContactForm/ContactForm.test.jsx +8 -4
  248. package/src/components/theme/FormattedDate/FormattedDate.stories.jsx +20 -2
  249. package/src/components/theme/Header/Header.test.jsx +19 -13
  250. package/src/components/theme/Image/Image.jsx +11 -8
  251. package/src/components/theme/LanguageSelector/{LanguageSelector.test.jsx → LanguageSelector.test.tsx} +6 -6
  252. package/src/components/theme/LanguageSelector/LanguageSelector.tsx +89 -0
  253. package/src/components/theme/Logo/Logo.Multilingual.test.jsx +0 -5
  254. package/src/components/theme/Logout/Logout.test.jsx +1 -1
  255. package/src/components/theme/MultilingualRedirector/MultilingualRedirector.jsx +8 -12
  256. package/src/components/theme/MultilingualRedirector/MultilingualRedirector.test.jsx +3 -5
  257. package/src/components/theme/Navigation/NavItem.jsx +1 -5
  258. package/src/components/theme/Navigation/Navigation.Multilingual.test.jsx +0 -5
  259. package/src/components/theme/NotFound/NotFound.jsx +5 -2
  260. package/src/components/theme/NotFound/NotFound.test.jsx +3 -0
  261. package/src/components/theme/PasswordReset/PasswordReset.test.jsx +10 -1
  262. package/src/components/theme/PasswordReset/RequestPasswordReset.test.jsx +5 -1
  263. package/src/components/theme/PreviewImage/PreviewImage.jsx +1 -1
  264. package/src/components/theme/Register/Register.test.jsx +5 -1
  265. package/src/components/theme/RequestTimeout/RequestTimeout.jsx +1 -1
  266. package/src/components/theme/Search/Search.test.jsx +6 -4
  267. package/src/components/theme/Sitemap/Sitemap.jsx +6 -5
  268. package/src/components/theme/Sitemap/Sitemap.test.jsx +0 -1
  269. package/src/components/theme/TsTest/TsTest.test.tsx +0 -1
  270. package/src/components/theme/View/EventDatesInfo.test.jsx +12 -5
  271. package/src/components/theme/View/EventView.test.jsx +12 -5
  272. package/src/components/theme/View/FileView.jsx +9 -1
  273. package/src/components/theme/View/ListingView.test.jsx +2 -0
  274. package/src/components/theme/View/SummaryView.test.jsx +10 -0
  275. package/src/components/theme/View/TabularView.test.jsx +1 -0
  276. package/src/components/theme/View/View.jsx +1 -1
  277. package/src/components/theme/View/View.test.jsx +42 -23
  278. package/src/components/theme/Widgets/ImageWidget.jsx +2 -1
  279. package/src/config/ControlPanels.js +1 -0
  280. package/src/config/index.js +18 -25
  281. package/src/config/server.js +0 -2
  282. package/src/express-middleware/devproxy.js +20 -5
  283. package/src/helpers/Api/APIResourceWithAuth.js +8 -3
  284. package/src/helpers/Api/Api.js +7 -4
  285. package/src/helpers/Api/Api.plone.rest.test.js +11 -9
  286. package/src/helpers/Api/Api.test.js +11 -14
  287. package/src/helpers/AsyncConnect/AsyncConnect.test.jsx +145 -189
  288. package/src/helpers/AsyncConnect/ssr.js +4 -1
  289. package/src/helpers/AuthToken/AuthToken.test.js +60 -22
  290. package/src/helpers/Blocks/Blocks.test.js +1 -1
  291. package/src/helpers/Content/Content.js +23 -0
  292. package/src/helpers/Content/Content.test.js +39 -0
  293. package/src/helpers/Content/withClientSideContent.jsx +35 -0
  294. package/src/helpers/Extensions/withBlockSchemaEnhancer.jsx +4 -1
  295. package/src/helpers/Html/Html.jsx +13 -7
  296. package/src/helpers/Html/Html.test.jsx +32 -28
  297. package/src/helpers/LanguageMap/LanguageMap.js +115 -8
  298. package/src/helpers/Loadable/__mocks__/Loadable.jsx +16 -1
  299. package/src/helpers/Loadable/__mocks__/Loadable.vitest.jsx +39 -0
  300. package/src/helpers/MessageLabels/MessageLabels.js +5 -0
  301. package/src/helpers/Sitemap/Sitemap.js +4 -4
  302. package/src/helpers/Url/Url.js +32 -2
  303. package/src/helpers/Url/Url.test.js +62 -0
  304. package/src/helpers/Utils/withSaveAsDraft.jsx +241 -0
  305. package/src/hooks/user/useUser.js +1 -1
  306. package/src/middleware/Api.test.js +51 -0
  307. package/src/middleware/api.js +78 -29
  308. package/src/middleware/storeProtectLoadUtils.test.js +93 -81
  309. package/src/reducers/content/content.js +3 -18
  310. package/src/reducers/diff/diff.js +5 -1
  311. package/src/reducers/diff/diff.test.js +60 -4
  312. package/src/routes.js +4 -2
  313. package/src/server.jsx +45 -14
  314. package/src/start-client.jsx +9 -6
  315. package/src/start-server.js +9 -3
  316. package/test-setup-config.jsx +0 -2
  317. package/test-setup-globals-vitest.js +46 -0
  318. package/theme/themes/pastanaga/collections/table.overrides +9 -0
  319. package/theme/themes/pastanaga/extras/blocks.less +26 -0
  320. package/theme/themes/pastanaga/extras/contents.less +17 -5
  321. package/theme/themes/pastanaga/extras/main.less +32 -2
  322. package/tsconfig.declarations.json +12 -1
  323. package/tsconfig.json +5 -5
  324. package/types/components/manage/Blocks/Teaser/schema.d.ts +1 -0
  325. package/types/components/manage/ConditionalLink/ConditionalLink.d.ts +11 -15
  326. package/types/components/manage/Contents/__mocks__/index.vitest.d.ts +2 -0
  327. package/types/components/manage/Controlpanels/Users/RenderUsers.d.ts +18 -2
  328. package/types/components/manage/Controlpanels/Users/UsersControlpanel.d.ts +6 -2
  329. package/types/components/manage/Controlpanels/index.d.ts +2 -2
  330. package/types/components/manage/Form/__mocks__/index.vitest.d.ts +8 -0
  331. package/types/components/manage/MaybeWrap/MaybeWrap.d.ts +7 -5
  332. package/types/components/manage/Sidebar/SidebarPortal.d.ts +7 -15
  333. package/types/components/manage/UniversalLink/UniversalLink.d.ts +54 -20
  334. package/types/components/manage/Widgets/ImageWidget.d.ts +41 -1
  335. package/types/components/manage/Widgets/RecurrenceWidget/Utils.d.ts +12 -18
  336. package/types/components/manage/Widgets/__mocks__/index.vitest.d.ts +33 -0
  337. package/types/components/theme/FormattedDate/FormattedDate.stories.d.ts +1 -1
  338. package/types/components/theme/LanguageSelector/LanguageSelector.d.ts +3 -10
  339. package/types/helpers/Content/Content.d.ts +7 -0
  340. package/types/helpers/Content/withClientSideContent.d.ts +1 -0
  341. package/types/helpers/Extensions/withBlockSchemaEnhancer.d.ts +4 -5
  342. package/types/helpers/Helmet/Helmet.d.ts +1 -1
  343. package/types/helpers/LanguageMap/LanguageMap.d.ts +428 -4
  344. package/types/helpers/Loadable/__mocks__/Loadable.vitest.d.ts +3 -0
  345. package/types/helpers/MessageLabels/MessageLabels.d.ts +68 -62
  346. package/types/helpers/Url/Url.d.ts +14 -0
  347. package/types/helpers/Url/bulkFlattenToAppURL.d.ts +5 -0
  348. package/types/helpers/Utils/withSaveAsDraft.d.ts +1 -0
  349. package/types/middleware/api.d.ts +6 -9
  350. package/types/react-router-hash-link.d.ts +12 -0
  351. package/types/reducers/index.d.ts +1 -0
  352. package/types/routes.d.ts +4 -0
  353. package/types/server.d.ts +1 -1
  354. package/types/start-client.d.ts +0 -1
  355. package/vite-plugins/svg.mjs +81 -0
  356. package/vitest.config.mjs +77 -0
  357. package/package-why.json +0 -34
  358. package/src/actions/content/content.multilingual.test.js +0 -17
  359. package/src/components/manage/ConditionalLink/ConditionalLink.jsx +0 -27
  360. package/src/components/manage/ConditionalLink/ConditionalLink.test.jsx +0 -30
  361. package/src/components/manage/MaybeWrap/MaybeWrap.jsx +0 -9
  362. package/src/components/manage/Sidebar/SidebarPortal.jsx +0 -47
  363. package/src/components/manage/Sidebar/SidebarPortal.test.jsx +0 -26
  364. package/src/components/manage/UniversalLink/UniversalLink.jsx +0 -154
  365. package/src/components/manage/Widgets/FileWidget.test.jsx +0 -91
  366. package/src/components/theme/LanguageSelector/LanguageSelector.jsx +0 -77
  367. package/theme/themes/pastanaga/extras/utils.less +0 -63
@@ -1,16 +1,19 @@
1
1
  import React from 'react';
2
- import { render } from '@testing-library/react';
2
+ import { render, act } from '@testing-library/react';
3
3
  import configureStore from 'redux-mock-store';
4
4
  import { Provider } from 'react-intl-redux';
5
+ import { MemoryRouter } from 'react-router-dom';
5
6
  import jwt from 'jsonwebtoken';
6
7
 
7
8
  import UsersControlpanel from './UsersControlpanel';
8
9
 
9
10
  const mockStore = configureStore();
10
- jest.mock('../../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));
11
+ vi.mock('../../Toolbar/Toolbar', () => ({
12
+ default: vi.fn(() => <div id="Portal" />),
13
+ }));
11
14
 
12
15
  describe('UsersControlpanel', () => {
13
- it('renders a user control component', () => {
16
+ it('renders a user control component', async () => {
14
17
  const store = mockStore({
15
18
  userSession: {
16
19
  token: jwt.sign({ sub: 'john' }, 'secret'),
@@ -36,12 +39,16 @@ describe('UsersControlpanel', () => {
36
39
  messages: {},
37
40
  },
38
41
  });
39
- const { container } = render(
40
- <Provider store={store}>
41
- <UsersControlpanel location={{ pathname: '/blog' }} />
42
- <div id="toolbar"></div>
43
- </Provider>,
44
- );
42
+ const { container } = await act(async () => {
43
+ return render(
44
+ <Provider store={store}>
45
+ <MemoryRouter initialEntries={['/controlpanel/users']}>
46
+ <UsersControlpanel />
47
+ <div id="toolbar"></div>
48
+ </MemoryRouter>
49
+ </Provider>,
50
+ );
51
+ });
45
52
 
46
53
  expect(container).toMatchSnapshot();
47
54
  });
@@ -3,12 +3,13 @@ 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';
6
-
7
6
  import Delete from './Delete';
8
7
 
9
8
  const mockStore = configureStore();
10
9
 
11
- jest.mock('../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));
10
+ vi.mock('../../Toolbar/Toolbar', () => ({
11
+ default: vi.fn(() => <div id="Portal" />),
12
+ }));
12
13
 
13
14
  describe('Delete', () => {
14
15
  it('renders an empty delete component', () => {
@@ -19,16 +20,36 @@ describe('Delete', () => {
19
20
  loading: false,
20
21
  loaded: true,
21
22
  },
23
+ get: {
24
+ loading: false,
25
+ loaded: true,
26
+ },
22
27
  },
23
28
  intl: {
24
29
  locale: 'en',
25
30
  messages: {},
26
31
  },
32
+ actions: {
33
+ actions: {},
34
+ },
35
+ userSession: {
36
+ token: null,
37
+ },
38
+ types: {
39
+ types: [],
40
+ get: {
41
+ loading: false,
42
+ loaded: true,
43
+ },
44
+ },
27
45
  });
46
+
47
+ store.dispatch = vi.fn(() => Promise.resolve());
48
+
28
49
  const { container } = render(
29
50
  <Provider store={store}>
30
51
  <MemoryRouter>
31
- <Delete location={{ pathname: '/blog', search: {} }} />
52
+ <Delete location={{ pathname: '/blog', search: '' }} />
32
53
  <div id="toolbar"></div>
33
54
  </MemoryRouter>
34
55
  </Provider>,
@@ -47,16 +68,36 @@ describe('Delete', () => {
47
68
  loading: false,
48
69
  loaded: true,
49
70
  },
71
+ get: {
72
+ loading: false,
73
+ loaded: true,
74
+ },
50
75
  },
51
76
  intl: {
52
77
  locale: 'en',
53
78
  messages: {},
54
79
  },
80
+ actions: {
81
+ actions: {},
82
+ },
83
+ userSession: {
84
+ token: null,
85
+ },
86
+ types: {
87
+ types: [],
88
+ get: {
89
+ loading: false,
90
+ loaded: true,
91
+ },
92
+ },
55
93
  });
94
+
95
+ store.dispatch = vi.fn(() => Promise.resolve());
96
+
56
97
  const { container } = render(
57
98
  <Provider store={store}>
58
99
  <MemoryRouter>
59
- <Delete location={{ pathname: '/blog', search: {} }} />
100
+ <Delete location={{ pathname: '/blog', search: '' }} />
60
101
  <div id="toolbar"></div>
61
102
  </MemoryRouter>
62
103
  </Provider>,
@@ -8,13 +8,22 @@ import Diff from './Diff';
8
8
 
9
9
  const mockStore = configureStore();
10
10
 
11
- jest.mock('../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));
11
+ vi.mock('../Toolbar/Toolbar', () => ({
12
+ default: vi.fn(() => <div id="Portal" />),
13
+ }));
12
14
 
13
- jest.mock('@plone/volto/helpers/Loadable/Loadable');
14
- beforeAll(
15
- async () =>
16
- await require('@plone/volto/helpers/Loadable/Loadable').__setLoadables(),
17
- );
15
+ vi.mock('@plone/volto/helpers/Loadable/Loadable', async () => {
16
+ return await import(
17
+ '@plone/volto/helpers/Loadable/__mocks__/Loadable.vitest.jsx'
18
+ );
19
+ });
20
+
21
+ beforeAll(async () => {
22
+ const { __setLoadables } = await import(
23
+ '@plone/volto/helpers/Loadable/Loadable'
24
+ );
25
+ await __setLoadables();
26
+ });
18
27
 
19
28
  describe('Diff', () => {
20
29
  it('renders a diff component', async () => {
@@ -2,14 +2,20 @@ import React from 'react';
2
2
  import configureStore from 'redux-mock-store';
3
3
  import { Provider } from 'react-intl-redux';
4
4
  import { waitFor, render, screen } from '@testing-library/react';
5
-
6
5
  import DiffField from './DiffField';
7
6
 
8
- jest.mock('@plone/volto/helpers/Loadable/Loadable');
9
- beforeAll(
10
- async () =>
11
- await require('@plone/volto/helpers/Loadable/Loadable').__setLoadables(),
12
- );
7
+ vi.mock('@plone/volto/helpers/Loadable/Loadable', async () => {
8
+ return await import(
9
+ '@plone/volto/helpers/Loadable/__mocks__/Loadable.vitest.jsx'
10
+ );
11
+ });
12
+
13
+ beforeAll(async () => {
14
+ const { __setLoadables } = await import(
15
+ '@plone/volto/helpers/Loadable/Loadable'
16
+ );
17
+ await __setLoadables();
18
+ });
13
19
 
14
20
  const mockStore = configureStore();
15
21
 
@@ -8,12 +8,23 @@ import Display from './Display';
8
8
 
9
9
  const mockStore = configureStore();
10
10
 
11
- jest.mock('@plone/volto/components/manage/Widgets');
12
- jest.mock('@plone/volto/helpers/Loadable/Loadable');
13
- beforeAll(
14
- async () =>
15
- await require('@plone/volto/helpers/Loadable/Loadable').__setLoadables(),
16
- );
11
+ vi.mock('@plone/volto/components/manage/Widgets', async () => {
12
+ return await import(
13
+ '@plone/volto/components/manage/Widgets/__mocks__/index.vitest.tsx'
14
+ );
15
+ });
16
+ vi.mock('@plone/volto/helpers/Loadable/Loadable', async () => {
17
+ return await import(
18
+ '@plone/volto/helpers/Loadable/__mocks__/Loadable.vitest.jsx'
19
+ );
20
+ });
21
+
22
+ beforeAll(async () => {
23
+ const { __setLoadables } = await import(
24
+ '@plone/volto/helpers/Loadable/Loadable'
25
+ );
26
+ await __setLoadables();
27
+ });
17
28
 
18
29
  beforeEach(() => {
19
30
  config.views.layoutViewsNamesMapping = {
@@ -44,8 +44,6 @@ import { tryParseJSON } from '@plone/volto/helpers/FormValidation/FormValidation
44
44
  import saveSVG from '@plone/volto/icons/save.svg';
45
45
  import clearSVG from '@plone/volto/icons/clear.svg';
46
46
 
47
- import config from '@plone/volto/registry';
48
-
49
47
  const messages = defineMessages({
50
48
  edit: {
51
49
  id: 'Edit {title}',
@@ -460,7 +458,7 @@ class Edit extends Component {
460
458
  />
461
459
  </Button>
462
460
 
463
- {config.settings.isMultilingual && (
461
+ {this.props.isMultilingual && (
464
462
  <CompareLanguages
465
463
  content={this.props.content}
466
464
  visual={this.state.visual}
@@ -545,6 +543,7 @@ export default compose(
545
543
  updateRequest: state.content.update,
546
544
  pathname: props.location.pathname,
547
545
  returnUrl: qs.parse(props.location.search).return_url,
546
+ isMultilingual: state.site.data.features?.multilingual,
548
547
  }),
549
548
  {
550
549
  updateContent,
@@ -8,9 +8,17 @@ import { __test__ as Edit } from './Edit';
8
8
 
9
9
  const mockStore = configureStore();
10
10
 
11
- jest.mock('@plone/volto/components/manage/Form');
12
- jest.mock('../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));
13
- jest.mock('../Sidebar/Sidebar', () => jest.fn(() => <div id="Sidebar" />));
11
+ vi.mock('@plone/volto/components/manage/Form', async () => {
12
+ return await import(
13
+ '@plone/volto/components/manage/Form/__mocks__/index.vitest.tsx'
14
+ );
15
+ });
16
+ vi.mock('../Toolbar/Toolbar', () => ({
17
+ default: vi.fn(() => <div id="Portal" />),
18
+ }));
19
+ vi.mock('../Sidebar/Sidebar', () => ({
20
+ default: vi.fn(() => <div id="Sidebar" />),
21
+ }));
14
22
 
15
23
  describe('Edit', () => {
16
24
  it('renders an empty edit component', () => {
@@ -5,7 +5,11 @@ import configureStore from 'redux-mock-store';
5
5
  import config from '@plone/volto/registry';
6
6
  import { Provider } from 'react-intl-redux';
7
7
 
8
- jest.mock('@plone/volto/components/manage/Form');
8
+ vi.mock('@plone/volto/components/manage/Form', async () => {
9
+ return await import(
10
+ '@plone/volto/components/manage/Form/__mocks__/index.vitest.tsx'
11
+ );
12
+ });
9
13
 
10
14
  const mockStore = configureStore();
11
15
 
@@ -9,6 +9,7 @@ import { Field, BlocksForm } from '@plone/volto/components/manage/Form';
9
9
  import BlocksToolbar from '@plone/volto/components/manage/Form/BlocksToolbar';
10
10
  import UndoToolbar from '@plone/volto/components/manage/Form/UndoToolbar';
11
11
  import { difference } from '@plone/volto/helpers/Utils/Utils';
12
+ import withSaveAsDraft from '@plone/volto/helpers/Utils/withSaveAsDraft';
12
13
  import FormValidation from '@plone/volto/helpers/FormValidation/FormValidation';
13
14
  import {
14
15
  getBlocksFieldname,
@@ -265,6 +266,18 @@ class Form extends Component {
265
266
  this.onBlurField = this.onBlurField.bind(this);
266
267
  this.onClickInput = this.onClickInput.bind(this);
267
268
  this.onToggleMetadataFieldset = this.onToggleMetadataFieldset.bind(this);
269
+ this.updateFormDataWithSaved = this.updateFormDataWithSaved.bind(this);
270
+ }
271
+
272
+ /**
273
+ * Function sent as callback to saveAsDraft when user
274
+ * choses to load local data
275
+ * @param {Object} savedFormData
276
+ */
277
+ updateFormDataWithSaved(savedFormData) {
278
+ if (savedFormData) {
279
+ this.setState({ formData: savedFormData });
280
+ }
268
281
  }
269
282
 
270
283
  /**
@@ -278,6 +291,12 @@ class Form extends Component {
278
291
  let errors = {};
279
292
  let activeIndex = 0;
280
293
 
294
+ if (!prevProps.schema && this.props.schema) {
295
+ this.props.checkSavedDraft(
296
+ this.state.formData,
297
+ this.updateFormDataWithSaved,
298
+ );
299
+ }
281
300
  if (!this.props.isFormSelected && prevProps.isFormSelected) {
282
301
  this.props.setUIState({
283
302
  selected: null,
@@ -303,6 +322,10 @@ class Form extends Component {
303
322
  this.props.onChangeFormData(this.state.formData);
304
323
  }
305
324
  }
325
+ // on each formData update it will save the form to the localStorage
326
+ if (!isEqual(prevState?.formData, this.state.formData)) {
327
+ this.props.onSaveDraft(this.state.formData);
328
+ }
306
329
  if (
307
330
  this.props.global &&
308
331
  !isEqual(this.props.globalData, prevProps.globalData)
@@ -395,6 +418,13 @@ class Form extends Component {
395
418
  */
396
419
  componentDidMount() {
397
420
  this.setState({ isClient: true });
421
+ if (this.props.schema) {
422
+ this.props.checkSavedDraft(
423
+ this.state.formData,
424
+ this.updateFormDataWithSaved,
425
+ );
426
+ return;
427
+ }
398
428
  }
399
429
 
400
430
  /**
@@ -653,6 +683,7 @@ class Form extends Component {
653
683
  this.props.setFormData(this.props.formData);
654
684
  }
655
685
  }
686
+ this.props.onCancelDraft();
656
687
  }
657
688
  }
658
689
 
@@ -1136,4 +1167,5 @@ export default compose(
1136
1167
  null,
1137
1168
  { forwardRef: true },
1138
1169
  ),
1170
+ withSaveAsDraft({ forwardRef: true }),
1139
1171
  )(FormIntl);
@@ -2,14 +2,18 @@ import React from 'react';
2
2
  import renderer from 'react-test-renderer';
3
3
  import configureStore from 'redux-mock-store';
4
4
  import { Provider } from 'react-intl-redux';
5
-
5
+ import { MemoryRouter } from 'react-router-dom';
6
6
  import Form from './Form';
7
7
 
8
8
  const mockStore = configureStore();
9
9
  const errorMessage =
10
10
  "[{'message': 'The specified email is not valid.', 'field': 'contact_email', 'error': 'ValidationError'}";
11
11
 
12
- jest.mock('@plone/volto/components/manage/Form');
12
+ vi.mock('@plone/volto/components/manage/Form', async () => {
13
+ return await import(
14
+ '@plone/volto/components/manage/Form/__mocks__/index.vitest.tsx'
15
+ );
16
+ });
13
17
 
14
18
  describe('Form', () => {
15
19
  it('renders a form component', () => {
@@ -26,26 +30,30 @@ describe('Form', () => {
26
30
  },
27
31
  },
28
32
  });
33
+ const route = '/some-route';
29
34
  const component = renderer.create(
30
35
  <Provider store={store}>
31
- <Form
32
- schema={{
33
- fieldsets: [
34
- {
35
- id: 'default',
36
- title: 'Default',
37
- fields: ['title'],
36
+ <MemoryRouter initialEntries={[route]}>
37
+ <Form
38
+ schema={{
39
+ fieldsets: [
40
+ {
41
+ id: 'default',
42
+ title: 'Default',
43
+ fields: ['title'],
44
+ },
45
+ ],
46
+ properties: {
47
+ title: {},
38
48
  },
39
- ],
40
- properties: {
41
- title: {},
42
- },
43
- required: [],
44
- }}
45
- requestError={errorMessage}
46
- onSubmit={() => {}}
47
- onCancel={() => {}}
48
- />
49
+ required: [],
50
+ }}
51
+ requestError={errorMessage}
52
+ onSubmit={() => {}}
53
+ onCancel={() => {}}
54
+ />
55
+ </MemoryRouter>
56
+ ,
49
57
  </Provider>,
50
58
  );
51
59
  const json = component.toJSON();
@@ -158,7 +158,7 @@ const InlineForm = (props) => {
158
158
  onChangeField(id, value, itemInfo);
159
159
  }}
160
160
  key={field}
161
- error={errors?.[block]?.[field] || {}}
161
+ error={errors?.[block]?.[field] || []}
162
162
  block={block}
163
163
  />
164
164
  ))}
@@ -199,7 +199,7 @@ const InlineForm = (props) => {
199
199
  onChangeField(id, value);
200
200
  }}
201
201
  key={field}
202
- error={errors?.[block]?.[field] || {}}
202
+ error={errors?.[block]?.[field] || []}
203
203
  block={block}
204
204
  />
205
205
  ))}
@@ -6,7 +6,11 @@ import config from '@plone/volto/registry';
6
6
 
7
7
  import InlineForm from './InlineForm';
8
8
 
9
- jest.mock('@plone/volto/components/manage/Form');
9
+ vi.mock('@plone/volto/components/manage/Form', async () => {
10
+ return await import(
11
+ '@plone/volto/components/manage/Form/__mocks__/index.vitest.tsx'
12
+ );
13
+ });
10
14
 
11
15
  const mockStore = configureStore();
12
16
 
@@ -8,7 +8,11 @@ import ModalForm from './ModalForm';
8
8
 
9
9
  const mockStore = configureStore();
10
10
 
11
- jest.mock('@plone/volto/components/manage/Form');
11
+ vi.mock('@plone/volto/components/manage/Form', async () => {
12
+ return await import(
13
+ '@plone/volto/components/manage/Form/__mocks__/index.vitest.tsx'
14
+ );
15
+ });
12
16
 
13
17
  describe('ModalForm', () => {
14
18
  it('renders a modal form component', () => {
@@ -1,3 +1,20 @@
1
+ /* TODO: When the Volto Team removes Jest configuration support from Volto core, update this file with the Vitest version of the mock.
2
+ Then, in the tests, we need to replace:
3
+
4
+ vi.mock('@plone/volto/components/manage/Form', async () => {
5
+ return await import(
6
+ '@plone/volto/components/manage/Form/__mocks__/index.vitest.tsx'
7
+ );
8
+ });
9
+
10
+
11
+ with the following:
12
+
13
+ vi.mock('@plone/volto/components/manage/Form');
14
+
15
+ Finally, remove this comment.
16
+ */
17
+
1
18
  import type { JSONSchema } from '@plone/types';
2
19
  import type { Ref } from 'react';
3
20
  const { forwardRef } = jest.requireActual('react');
@@ -0,0 +1,73 @@
1
+ import type { JSONSchema } from '@plone/types';
2
+ import type { Ref } from 'react';
3
+ import { forwardRef } from 'react';
4
+
5
+ const cleanupSchema = (schema: JSONSchema | null): JSONSchema | null => {
6
+ if (!schema || !schema.properties) return schema;
7
+ return {
8
+ ...schema,
9
+ properties: Object.entries(schema.properties).reduce<Record<string, any>>(
10
+ (acc, [key, value]) => {
11
+ acc[key] = {
12
+ ...value,
13
+ description:
14
+ typeof value.description === 'string'
15
+ ? value.description
16
+ : undefined,
17
+ };
18
+ return acc;
19
+ },
20
+ {},
21
+ ),
22
+ };
23
+ };
24
+
25
+ export const Field = vi.fn((props) => (
26
+ <div className="Field" id={props.id}>
27
+ {props.title}
28
+ </div>
29
+ ));
30
+
31
+ export const InlineForm = vi.fn((props) => (
32
+ <div
33
+ id="InlineForm"
34
+ data-schema={JSON.stringify(cleanupSchema(props.schema), null, 2)}
35
+ />
36
+ ));
37
+
38
+ export const ModalForm = vi.fn((props) => (
39
+ <div
40
+ id="ModalForm"
41
+ data-schema={JSON.stringify(cleanupSchema(props.schema), null, 2)}
42
+ />
43
+ ));
44
+
45
+ export const UndoToolbar = vi.fn(() => <div id="UndoToolbar" />);
46
+
47
+ export const BlocksToolbar = vi.fn(() => <div id="BlocksToolbar" />);
48
+
49
+ export const BlockDataForm = vi.fn((props) => (
50
+ <div
51
+ id="BlockDataForm"
52
+ data-schema={JSON.stringify(cleanupSchema(props.schema), null, 2)}
53
+ />
54
+ ));
55
+
56
+ export const BlocksForm = vi.fn((props) => (
57
+ <div
58
+ id="BlocksForm"
59
+ data-schema={JSON.stringify(cleanupSchema(props.schema), null, 2)}
60
+ />
61
+ ));
62
+
63
+ const MockForm = forwardRef(
64
+ (props: { schema: JSONSchema | null }, ref: Ref<any>) => (
65
+ <div
66
+ id="Form"
67
+ data-schema={JSON.stringify(cleanupSchema(props.schema), null, 2)}
68
+ ref={ref}
69
+ />
70
+ ),
71
+ );
72
+
73
+ export const Form = vi.fn((props) => <MockForm {...props} />);
@@ -9,7 +9,9 @@ import FakeTimers from '@sinonjs/fake-timers';
9
9
  import History from './History';
10
10
 
11
11
  const mockStore = configureStore();
12
- jest.mock('../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));
12
+ vi.mock('../Toolbar/Toolbar', () => ({
13
+ default: vi.fn(() => <div id="Portal" />),
14
+ }));
13
15
 
14
16
  const FIXED_SYSTEM_TIME = '2017-04-23T15:38:00.000Z';
15
17
 
@@ -10,10 +10,12 @@ import { __test__ as LinksToItem } from './LinksToItem';
10
10
  const middlewares = [thunk];
11
11
  const mockStore = configureMockStore(middlewares);
12
12
 
13
- jest.mock('../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));
14
-
15
- jest.mock('../Toolbar/More', () => jest.fn(() => <div className="More" />));
16
-
13
+ vi.mock('../Toolbar/Toolbar', () => ({
14
+ default: vi.fn(() => <div id="Portal" />),
15
+ }));
16
+ vi.mock('../Toolbar/More', () => ({
17
+ default: vi.fn(() => <div className="More" />),
18
+ }));
17
19
  describe('LinksToItem', () => {
18
20
  it('renders "links and references" view', () => {
19
21
  const store = mockStore({
@@ -0,0 +1,15 @@
1
+ import React, { ComponentPropsWithoutRef } from 'react';
2
+
3
+ type MaybeWrapProps<T extends React.ElementType> = {
4
+ condition: boolean;
5
+ as: T;
6
+ } & ComponentPropsWithoutRef<React.ElementType extends T ? 'div' : T>;
7
+
8
+ function MaybeWrap<T extends React.ElementType = 'div'>(
9
+ props: MaybeWrapProps<T>,
10
+ ) {
11
+ const { as: Component = 'div', condition, ...rest } = props;
12
+ return condition ? <Component {...rest} /> : props.children;
13
+ }
14
+
15
+ export default MaybeWrap;
@@ -1,6 +1,5 @@
1
1
  import React, { useState } from 'react';
2
2
  import { defineMessages, useIntl } from 'react-intl';
3
- import config from '@plone/volto/registry';
4
3
  import langmap from '@plone/volto/helpers/LanguageMap/LanguageMap';
5
4
  import { useDetectClickOutside } from '@plone/volto/helpers/Utils/useDetectClickOutside';
6
5
 
@@ -106,16 +105,14 @@ const CompareLanguages = React.forwardRef((props, ref) => {
106
105
 
107
106
  const intl = useIntl();
108
107
  const [viewMenu, setViewMenu] = useState(false);
109
- const translations = config.settings.isMultilingual
110
- ? content?.['@components']?.translations?.items || []
111
- : [];
108
+ const translations = content?.['@components']?.translations?.items || [];
112
109
 
113
110
  const translationsObject = {};
114
111
  translations.forEach((t) => {
115
112
  translationsObject[t.language] = t['@id'];
116
113
  });
117
114
 
118
- if (config.settings.isMultilingual && translations.length > 0) {
115
+ if (translations.length > 0) {
119
116
  return (
120
117
  <div className="toolbar-compare-translations-wrapper">
121
118
  <div className="toolbar-button-spacer" />