@plone/volto 19.0.0-alpha.3 → 19.0.0-alpha.30

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 (502) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc +37 -6
  3. package/CHANGELOG.md +534 -2
  4. package/README.md +23 -21
  5. package/babel.js +1 -9
  6. package/cypress/docker/prefixed-rules.yml +26 -0
  7. package/cypress/docker/prefixed.yml +24 -0
  8. package/cypress/support/commands.js +12 -6
  9. package/cypress/support/guillotina.js +1 -0
  10. package/cypress.config.js +1 -0
  11. package/global-test-setup.js +1 -2
  12. package/locales/af/LC_MESSAGES/volto.po +5500 -0
  13. package/locales/af.json +1 -1
  14. package/locales/ar/LC_MESSAGES/volto.po +5500 -0
  15. package/locales/ar.json +1 -1
  16. package/locales/bg/LC_MESSAGES/volto.po +5500 -0
  17. package/locales/bg.json +1 -1
  18. package/locales/bn/LC_MESSAGES/volto.po +5500 -0
  19. package/locales/bn.json +1 -1
  20. package/locales/ca/LC_MESSAGES/volto.po +559 -349
  21. package/locales/ca.json +1 -1
  22. package/locales/cs/LC_MESSAGES/volto.po +5500 -0
  23. package/locales/cs.json +1 -1
  24. package/locales/cy/LC_MESSAGES/volto.po +5500 -0
  25. package/locales/cy.json +1 -1
  26. package/locales/da/LC_MESSAGES/volto.po +5500 -0
  27. package/locales/da.json +1 -1
  28. package/locales/de/LC_MESSAGES/volto.po +232 -21
  29. package/locales/de.json +1 -1
  30. package/locales/el/LC_MESSAGES/volto.po +5500 -0
  31. package/locales/el.json +1 -1
  32. package/locales/en/LC_MESSAGES/volto.po +226 -11
  33. package/locales/en.json +1 -1
  34. package/locales/en_AU/LC_MESSAGES/volto.po +5500 -0
  35. package/locales/en_AU.json +1 -1
  36. package/locales/en_GB/LC_MESSAGES/volto.po +5500 -0
  37. package/locales/en_GB.json +1 -1
  38. package/locales/eo/LC_MESSAGES/volto.po +5500 -0
  39. package/locales/eo.json +1 -1
  40. package/locales/es/LC_MESSAGES/volto.po +321 -111
  41. package/locales/es.json +1 -1
  42. package/locales/et/LC_MESSAGES/volto.po +5500 -0
  43. package/locales/et.json +1 -1
  44. package/locales/eu/LC_MESSAGES/volto.po +404 -194
  45. package/locales/eu.json +1 -1
  46. package/locales/fa/LC_MESSAGES/volto.po +5500 -0
  47. package/locales/fa.json +1 -1
  48. package/locales/fi/LC_MESSAGES/volto.po +221 -11
  49. package/locales/fi.json +1 -1
  50. package/locales/fr/LC_MESSAGES/volto.po +220 -10
  51. package/locales/fr.json +1 -1
  52. package/locales/fu/LC_MESSAGES/volto.po +5500 -0
  53. package/locales/fu.json +1 -1
  54. package/locales/gl/LC_MESSAGES/volto.po +5501 -0
  55. package/locales/gl.json +1 -1
  56. package/locales/he/LC_MESSAGES/volto.po +5500 -0
  57. package/locales/he.json +1 -1
  58. package/locales/hi/LC_MESSAGES/volto.po +225 -10
  59. package/locales/hi.json +1 -1
  60. package/locales/hr/LC_MESSAGES/volto.po +5500 -0
  61. package/locales/hr.json +1 -1
  62. package/locales/hu/LC_MESSAGES/volto.po +5500 -0
  63. package/locales/hu.json +1 -1
  64. package/locales/hy/LC_MESSAGES/volto.po +5500 -0
  65. package/locales/hy.json +1 -1
  66. package/locales/id/LC_MESSAGES/volto.po +5500 -0
  67. package/locales/id.json +1 -1
  68. package/locales/it/LC_MESSAGES/volto.po +239 -24
  69. package/locales/it.json +1 -1
  70. package/locales/ja/LC_MESSAGES/volto.po +264 -53
  71. package/locales/ja.json +1 -1
  72. package/locales/ka/LC_MESSAGES/volto.po +5500 -0
  73. package/locales/ka.json +1 -1
  74. package/locales/kn/LC_MESSAGES/volto.po +5500 -0
  75. package/locales/kn.json +1 -1
  76. package/locales/ko/LC_MESSAGES/volto.po +5500 -0
  77. package/locales/ko.json +1 -1
  78. package/locales/lt/LC_MESSAGES/volto.po +5500 -0
  79. package/locales/lt.json +1 -1
  80. package/locales/lv/LC_MESSAGES/volto.po +5500 -0
  81. package/locales/lv.json +1 -1
  82. package/locales/mi/LC_MESSAGES/volto.po +5500 -0
  83. package/locales/mi.json +1 -1
  84. package/locales/mk/LC_MESSAGES/volto.po +5500 -0
  85. package/locales/mk.json +1 -1
  86. package/locales/my/LC_MESSAGES/volto.po +5500 -0
  87. package/locales/my.json +1 -1
  88. package/locales/nb_NO/LC_MESSAGES/volto.po +5500 -0
  89. package/locales/nb_NO.json +1 -1
  90. package/locales/nl/LC_MESSAGES/volto.po +243 -32
  91. package/locales/nl.json +1 -1
  92. package/locales/nn/LC_MESSAGES/volto.po +5500 -0
  93. package/locales/nn.json +1 -1
  94. package/locales/pl/LC_MESSAGES/volto.po +5500 -0
  95. package/locales/pl.json +1 -1
  96. package/locales/pt/LC_MESSAGES/volto.po +869 -659
  97. package/locales/pt.json +1 -1
  98. package/locales/pt_BR/LC_MESSAGES/volto.po +229 -19
  99. package/locales/pt_BR.json +1 -1
  100. package/locales/rm/LC_MESSAGES/volto.po +5500 -0
  101. package/locales/rm.json +1 -1
  102. package/locales/ro/LC_MESSAGES/volto.po +252 -42
  103. package/locales/ro.json +1 -1
  104. package/locales/ru/LC_MESSAGES/volto.po +220 -10
  105. package/locales/ru.json +1 -1
  106. package/locales/sk/LC_MESSAGES/volto.po +5500 -0
  107. package/locales/sk.json +1 -1
  108. package/locales/sl/LC_MESSAGES/volto.po +5500 -0
  109. package/locales/sl.json +1 -1
  110. package/locales/sm/LC_MESSAGES/volto.po +5500 -0
  111. package/locales/sm.json +1 -1
  112. package/locales/sq/LC_MESSAGES/volto.po +5500 -0
  113. package/locales/sq.json +1 -1
  114. package/locales/sr/LC_MESSAGES/volto.po +5500 -0
  115. package/locales/sr.json +1 -1
  116. package/locales/sr@cyrl/LC_MESSAGES/volto.po +5500 -0
  117. package/locales/sr@cyrl.json +1 -1
  118. package/locales/sr@latn/LC_MESSAGES/volto.po +5500 -0
  119. package/locales/sr@latn.json +1 -1
  120. package/locales/sv/LC_MESSAGES/volto.po +5500 -0
  121. package/locales/sv.json +1 -1
  122. package/locales/ta/LC_MESSAGES/volto.po +5501 -0
  123. package/locales/ta.json +1 -1
  124. package/locales/te/LC_MESSAGES/volto.po +5500 -0
  125. package/locales/te.json +1 -1
  126. package/locales/th/LC_MESSAGES/volto.po +5500 -0
  127. package/locales/th.json +1 -1
  128. package/locales/to/LC_MESSAGES/volto.po +5500 -0
  129. package/locales/to.json +1 -1
  130. package/locales/tr/LC_MESSAGES/volto.po +5501 -0
  131. package/locales/tr.json +1 -1
  132. package/locales/uk/LC_MESSAGES/volto.po +5500 -0
  133. package/locales/uk.json +1 -1
  134. package/locales/vi/LC_MESSAGES/volto.po +5500 -0
  135. package/locales/vi.json +1 -1
  136. package/locales/volto.pot +220 -10
  137. package/locales/zh_CN/LC_MESSAGES/volto.po +221 -10
  138. package/locales/zh_CN.json +1 -1
  139. package/locales/zh_Hant/LC_MESSAGES/volto.po +5500 -0
  140. package/locales/zh_Hant.json +1 -1
  141. package/locales/zh_Hant_HK/LC_MESSAGES/volto.po +5500 -0
  142. package/locales/zh_Hant_HK.json +1 -1
  143. package/package.json +72 -146
  144. package/razzle.config.js +32 -25
  145. package/src/actions/blockTypes/blockTypes.ts +24 -0
  146. package/src/components/manage/Actions/Actions.test.jsx +1 -5
  147. package/src/components/manage/Add/Add.jsx +15 -10
  148. package/src/components/manage/BlockChooser/BlockChooser.jsx +1 -0
  149. package/src/components/manage/Blocks/Block/BlocksForm.jsx +10 -7
  150. package/src/components/manage/Blocks/Block/BlocksForm.test.jsx +3 -14
  151. package/src/components/manage/Blocks/Block/EditBlockWrapper.jsx +9 -4
  152. package/src/components/manage/Blocks/Block/Order/Item.jsx +27 -13
  153. package/src/components/manage/Blocks/Block/Order/Item.test.jsx +90 -0
  154. package/src/components/manage/Blocks/Block/Order/Order.jsx +116 -67
  155. package/src/components/manage/Blocks/Block/Order/utilities.js +28 -11
  156. package/src/components/manage/Blocks/Block/Settings.test.jsx +1 -5
  157. package/src/components/manage/Blocks/Grid/View.jsx +14 -11
  158. package/src/components/manage/Blocks/Grid/context.js +3 -0
  159. package/src/components/manage/Blocks/HTML/Edit.test.jsx +1 -5
  160. package/src/components/manage/Blocks/Image/Edit.jsx +5 -1
  161. package/src/components/manage/Blocks/Image/ImageSidebar.test.jsx +2 -5
  162. package/src/components/manage/Blocks/LeadImage/Edit.jsx +2 -2
  163. package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.jsx +1 -1
  164. package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.test.jsx +2 -5
  165. package/src/components/manage/Blocks/Listing/Edit.jsx +1 -0
  166. package/src/components/manage/Blocks/Listing/ImageGallery.jsx +6 -4
  167. package/src/components/manage/Blocks/Listing/ListingBody.jsx +4 -0
  168. package/src/components/manage/Blocks/Maps/Edit.jsx +2 -1
  169. package/src/components/manage/Blocks/Maps/MapsSidebar.test.jsx +1 -5
  170. package/src/components/manage/Blocks/Search/SearchBlockView.jsx +21 -4
  171. package/src/components/manage/Blocks/Search/components/DateRangeFacet.test.jsx +1 -6
  172. package/src/components/manage/Blocks/Search/components/SelectFacet.jsx +22 -1
  173. package/src/components/manage/Blocks/Search/components/SelectFacet.test.jsx +1 -6
  174. package/src/components/manage/Blocks/Search/components/SortOn.jsx +8 -2
  175. package/src/components/manage/Blocks/Search/components/ToggleFacet.jsx +14 -0
  176. package/src/components/manage/Blocks/Teaser/Data.jsx +21 -7
  177. package/src/components/manage/Blocks/Teaser/DefaultBody.jsx +11 -3
  178. package/src/components/manage/Blocks/Teaser/View.jsx +0 -1
  179. package/src/components/manage/Blocks/Teaser/utils.js +13 -0
  180. package/src/components/manage/Blocks/Teaser/utils.test.js +34 -0
  181. package/src/components/manage/Blocks/Title/Edit.jsx +5 -0
  182. package/src/components/manage/Blocks/Video/Body.jsx +69 -43
  183. package/src/components/manage/Blocks/Video/Body.test.jsx +122 -5
  184. package/src/components/manage/Blocks/Video/Edit.jsx +22 -3
  185. package/src/components/manage/Blocks/Video/Edit.test.jsx +6 -0
  186. package/src/components/manage/Blocks/Video/VideoSidebar.test.jsx +1 -5
  187. package/src/components/manage/Blocks/Video/View.jsx +1 -0
  188. package/src/components/manage/Blocks/Video/View.test.jsx +29 -15
  189. package/src/components/manage/Blocks/Video/schema.js +14 -1
  190. package/src/components/manage/Contents/Contents.jsx +697 -659
  191. package/src/components/manage/Contents/Contents.test.jsx +1 -5
  192. package/src/components/manage/Contents/ContentsBreadcrumbs.jsx +6 -5
  193. package/src/components/manage/Contents/ContentsItem.jsx +1 -1
  194. package/src/components/manage/Contents/ContentsPropertiesModal.test.jsx +1 -5
  195. package/src/components/manage/Contents/ContentsRenameModal.test.jsx +1 -5
  196. package/src/components/manage/Contents/ContentsTagsModal.test.jsx +1 -5
  197. package/src/components/manage/Contents/ContentsWorkflowModal.test.jsx +1 -5
  198. package/src/components/manage/Contents/DropZoneContent.jsx +338 -0
  199. package/src/components/manage/Contents/__mocks__/index.tsx +2 -18
  200. package/src/components/manage/Controlpanels/AddonsControlpanel.jsx +7 -0
  201. package/src/components/manage/Controlpanels/Aliases.test.jsx +1 -5
  202. package/src/components/manage/Controlpanels/BlockType.tsx +166 -0
  203. package/src/components/manage/Controlpanels/BlockTypes.tsx +145 -0
  204. package/src/components/manage/Controlpanels/ContentType.jsx +1 -1
  205. package/src/components/manage/Controlpanels/ContentType.test.jsx +1 -5
  206. package/src/components/manage/Controlpanels/ContentTypeSchema.jsx +1 -1
  207. package/src/components/manage/Controlpanels/Controlpanels.jsx +28 -5
  208. package/src/components/manage/Controlpanels/Controlpanels.test.jsx +10 -0
  209. package/src/components/manage/Controlpanels/DatabaseInformation.jsx +9 -0
  210. package/src/components/manage/Controlpanels/Groups/GroupsControlpanel.jsx +3 -2
  211. package/src/components/manage/Controlpanels/ModerateComments.jsx +8 -0
  212. package/src/components/manage/Controlpanels/Relations/Relations.jsx +1 -1
  213. package/src/components/manage/Controlpanels/Rules/AddRule.test.jsx +1 -5
  214. package/src/components/manage/Controlpanels/Rules/EditRule.test.jsx +1 -5
  215. package/src/components/manage/Controlpanels/UndoControlpanel.test.jsx +1 -5
  216. package/src/components/manage/Controlpanels/Users/RenderUsers.jsx +156 -175
  217. package/src/components/manage/Controlpanels/Users/UserGroupMembershipControlPanel.test.jsx +3 -0
  218. package/src/components/manage/Controlpanels/Users/UsersControlpanel.jsx +575 -631
  219. package/src/components/manage/Controlpanels/Users/UsersControlpanel.test.jsx +58 -11
  220. package/src/components/manage/Diff/Diff.jsx +201 -298
  221. package/src/components/manage/Diff/Diff.test.jsx +1 -6
  222. package/src/components/manage/Diff/DiffField.test.jsx +1 -6
  223. package/src/components/manage/Display/Display.test.jsx +2 -11
  224. package/src/components/manage/Edit/Edit.test.jsx +1 -5
  225. package/src/components/manage/Form/BlockDataForm.test.jsx +1 -5
  226. package/src/components/manage/Form/Form.jsx +3 -3
  227. package/src/components/manage/Form/Form.test.jsx +1 -5
  228. package/src/components/manage/Form/InlineForm.jsx +2 -2
  229. package/src/components/manage/Form/InlineForm.test.jsx +1 -5
  230. package/src/components/manage/Form/ModalForm.jsx +12 -10
  231. package/src/components/manage/Form/ModalForm.test.jsx +27 -5
  232. package/src/components/manage/Form/__mocks__/index.tsx +9 -27
  233. package/src/components/manage/Multilingual/CompareLanguages.jsx +6 -6
  234. package/src/components/manage/Multilingual/CreateTranslation.jsx +16 -13
  235. package/src/components/manage/Multilingual/ManageTranslations.jsx +5 -5
  236. package/src/components/manage/Multilingual/TranslationObject.jsx +11 -8
  237. package/src/components/manage/Preferences/ChangePassword.test.jsx +1 -5
  238. package/src/components/manage/Preferences/PersonalPreferences.jsx +8 -5
  239. package/src/components/manage/Preferences/PersonalPreferences.test.jsx +1 -17
  240. package/src/components/manage/Sharing/Sharing.jsx +21 -15
  241. package/src/components/manage/Sidebar/ObjectBrowser.jsx +3 -0
  242. package/src/components/manage/Sidebar/ObjectBrowserBody.jsx +18 -2
  243. package/src/components/manage/Sidebar/ObjectBrowserNav.jsx +2 -1
  244. package/src/components/manage/Sidebar/SidebarPortal.test.tsx +42 -0
  245. package/src/components/manage/Sidebar/SidebarPortal.tsx +48 -0
  246. package/src/components/manage/TemplateChooser/TemplateChooser.jsx +2 -1
  247. package/src/components/manage/TemplateChooser/TemplateChooser.test.jsx +1 -0
  248. package/src/components/manage/Toast/Toast.jsx +32 -0
  249. package/src/components/manage/Toast/Toast.test.jsx +9 -5
  250. package/src/components/manage/Toolbar/PersonalTools.jsx +2 -1
  251. package/src/components/manage/Toolbar/PersonalTools.test.jsx +15 -0
  252. package/src/components/manage/Toolbar/Toolbar.jsx +14 -4
  253. package/src/components/manage/Toolbar/Types.crash.test.jsx +48 -0
  254. package/src/components/manage/Toolbar/Types.jsx +6 -4
  255. package/src/components/manage/UniversalLink/UniversalLink.test.jsx +16 -0
  256. package/src/components/manage/UniversalLink/UniversalLink.tsx +2 -0
  257. package/src/components/manage/Widgets/AlignWidget.stories.jsx +9 -0
  258. package/src/components/manage/Widgets/AlignWidget.test.tsx +95 -0
  259. package/src/components/manage/Widgets/{AlignWidget.jsx → AlignWidget.tsx} +23 -7
  260. package/src/components/manage/Widgets/ArrayWidget.test.jsx +1 -6
  261. package/src/components/manage/Widgets/BlockAlignment.stories.tsx +104 -0
  262. package/src/components/manage/Widgets/BlockAlignment.test.tsx +104 -0
  263. package/src/components/manage/Widgets/BlockAlignment.tsx +88 -0
  264. package/src/components/manage/Widgets/BlockWidth.stories.tsx +69 -0
  265. package/src/components/manage/Widgets/BlockWidth.test.tsx +62 -0
  266. package/src/components/manage/Widgets/BlockWidth.tsx +101 -0
  267. package/src/components/manage/Widgets/ButtonsWidget.stories.jsx +61 -0
  268. package/src/components/manage/Widgets/ButtonsWidget.test.tsx +138 -0
  269. package/src/components/manage/Widgets/ButtonsWidget.tsx +195 -0
  270. package/src/components/manage/Widgets/CheckboxGroupWidget.test.jsx +1 -6
  271. package/src/components/manage/Widgets/DatetimeWidget.jsx +102 -53
  272. package/src/components/manage/Widgets/DatetimeWidget.test.jsx +56 -6
  273. package/src/components/manage/Widgets/FileWidget.jsx +21 -8
  274. package/src/components/manage/Widgets/FormFieldWrapper.jsx +146 -168
  275. package/src/components/manage/Widgets/ImageWidget.jsx +177 -38
  276. package/src/components/manage/Widgets/InternalUrlWidget.jsx +2 -0
  277. package/src/components/manage/Widgets/ObjectBrowserWidget.jsx +8 -0
  278. package/src/components/manage/Widgets/ObjectListWidget.test.jsx +2 -11
  279. package/src/components/manage/Widgets/ObjectWidget.test.jsx +1 -5
  280. package/src/components/manage/Widgets/QueryWidget.jsx +137 -9
  281. package/src/components/manage/Widgets/RadioGroupWidget.test.jsx +1 -6
  282. package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.test.jsx +1 -6
  283. package/src/components/manage/Widgets/RegistryImageWidget.jsx +1 -1
  284. package/src/components/manage/Widgets/RegistryImageWidget.test.jsx +4 -2
  285. package/src/components/manage/Widgets/SchemaWidget.test.jsx +1 -6
  286. package/src/components/manage/Widgets/SchemaWidgetFieldset.test.jsx +1 -6
  287. package/src/components/manage/Widgets/SelectAutoComplete.jsx +29 -12
  288. package/src/components/manage/Widgets/SelectAutoComplete.test.jsx +1 -6
  289. package/src/components/manage/Widgets/SelectWidget.test.jsx +1 -6
  290. package/src/components/manage/Widgets/Size.stories.tsx +69 -0
  291. package/src/components/manage/Widgets/Size.test.tsx +59 -0
  292. package/src/components/manage/Widgets/Size.tsx +78 -0
  293. package/src/components/manage/Widgets/TimeWidget.test.jsx +1 -6
  294. package/src/components/manage/Widgets/TokenWidget.test.jsx +1 -6
  295. package/src/components/manage/Widgets/UrlWidget.jsx +49 -18
  296. package/src/components/manage/Widgets/VocabularyTermsWidget.test.jsx +2 -11
  297. package/src/components/manage/Widgets/__mocks__/index.tsx +33 -51
  298. package/src/components/manage/Widgets/index.tsx +21 -0
  299. package/src/components/manage/Workflow/Workflow.test.jsx +2 -11
  300. package/src/components/theme/AlternateHrefLangs/AlternateHrefLangs.jsx +1 -0
  301. package/src/components/theme/AlternateHrefLangs/AlternateHrefLangs.test.jsx +30 -0
  302. package/src/components/theme/App/App.jsx +5 -1
  303. package/src/components/theme/Avatar/Avatar.jsx +2 -1
  304. package/src/components/theme/Comments/CommentEditModal.test.jsx +1 -5
  305. package/src/components/theme/Comments/Comments.test.jsx +2 -11
  306. package/src/components/theme/ConnectionRefused/ConnectionRefused.jsx +3 -2
  307. package/src/components/theme/ContactForm/ContactForm.test.jsx +1 -5
  308. package/src/components/theme/Image/Image.jsx +25 -13
  309. package/src/components/theme/Image/Image.test.jsx +247 -146
  310. package/src/components/theme/InjectPloneComponentsCSS/InjectPloneComponentsCSS.tsx +7 -0
  311. package/src/components/theme/LanguageSelector/LanguageSelector.tsx +89 -0
  312. package/src/components/theme/MultilingualRedirector/MultilingualRedirector.jsx +42 -12
  313. package/src/components/theme/PasswordReset/PasswordReset.jsx +108 -191
  314. package/src/components/theme/PasswordReset/RequestPasswordReset.test.jsx +1 -5
  315. package/src/components/theme/PreviewImage/PreviewImage.jsx +1 -1
  316. package/src/components/theme/Register/Register.test.jsx +1 -5
  317. package/src/components/theme/RequestTimeout/RequestTimeout.jsx +1 -1
  318. package/src/components/theme/Sitemap/Sitemap.stories.jsx +82 -0
  319. package/src/components/theme/SlotRenderer/SlotRenderer.tsx +12 -6
  320. package/src/components/theme/Unauthorized/Unauthorized.jsx +35 -25
  321. package/src/components/theme/Unauthorized/Unauthorized.test.jsx +28 -1
  322. package/src/components/theme/VideoEmbed/VideoEmbed.jsx +100 -0
  323. package/src/components/theme/View/EventDatesInfo.test.jsx +1 -6
  324. package/src/components/theme/View/EventView.stories.jsx +89 -0
  325. package/src/components/theme/View/EventView.test.jsx +1 -6
  326. package/src/components/theme/View/FileView.stories.jsx +50 -0
  327. package/src/components/theme/View/ImageView.jsx +2 -1
  328. package/src/components/theme/View/ImageView.test.jsx +3 -0
  329. package/src/components/theme/View/LinkView.stories.jsx +57 -0
  330. package/src/components/theme/View/ListingView.stories.jsx +70 -0
  331. package/src/components/theme/View/NewsItemView.stories.jsx +58 -0
  332. package/src/components/theme/View/RenderBlocks.jsx +8 -10
  333. package/src/components/theme/View/RenderBlocks.stories.jsx +112 -0
  334. package/src/components/theme/View/RenderBlocks.test.jsx +14 -4
  335. package/src/components/theme/View/SummaryView.stories.jsx +71 -0
  336. package/src/components/theme/View/TabularView.stories.jsx +66 -0
  337. package/src/components/theme/View/View.jsx +8 -1
  338. package/src/components/theme/Widgets/ImageWidget.jsx +2 -1
  339. package/src/components/theme/Widgets/ImageWidget.test.jsx +31 -11
  340. package/src/config/Blocks.jsx +3 -0
  341. package/src/config/ControlPanels.js +3 -0
  342. package/src/config/Widgets.jsx +7 -0
  343. package/src/config/index.js +19 -12
  344. package/src/config/server.js +0 -2
  345. package/src/config/slots.js +19 -0
  346. package/src/config/validation.ts +8 -0
  347. package/src/constants/ActionTypes.js +1 -0
  348. package/src/express-middleware/devproxy.js +22 -5
  349. package/src/express-middleware/files.js +1 -0
  350. package/src/express-middleware/files.test.js +59 -0
  351. package/src/express-middleware/images.js +1 -0
  352. package/src/express-middleware/images.test.js +50 -0
  353. package/src/helpers/Api/APIResourceWithAuth.js +8 -3
  354. package/src/helpers/Api/Api.js +7 -4
  355. package/src/helpers/AsyncConnect/ssr.js +4 -1
  356. package/src/helpers/AuthToken/AuthToken.js +1 -6
  357. package/src/helpers/Blocks/Blocks.js +113 -28
  358. package/src/helpers/Blocks/Blocks.test.js +100 -0
  359. package/src/helpers/Content/Content.js +23 -0
  360. package/src/helpers/Content/Content.test.js +39 -0
  361. package/src/helpers/Content/withClientSideContent.jsx +35 -0
  362. package/src/helpers/Extensions/withBlockSchemaEnhancer.jsx +4 -1
  363. package/src/helpers/FormValidation/FormValidation.test.js +31 -0
  364. package/src/helpers/FormValidation/validators.ts +52 -6
  365. package/src/helpers/Html/Html.jsx +13 -4
  366. package/src/helpers/Loadable/__mocks__/Loadable.jsx +7 -22
  367. package/src/helpers/MessageLabels/MessageLabels.js +10 -0
  368. package/src/helpers/Sitemap/Sitemap.js +4 -4
  369. package/src/helpers/Url/Url.js +33 -2
  370. package/src/helpers/Url/Url.test.js +62 -0
  371. package/src/helpers/Utils/Utils.jsx +17 -0
  372. package/src/helpers/Utils/Utils.test.jsx +39 -0
  373. package/src/hooks/user/useUser.js +1 -1
  374. package/src/internalChecks.test.ts +11 -0
  375. package/src/middleware/api.js +17 -8
  376. package/src/middleware/storeProtectLoadUtils.test.js +3 -3
  377. package/src/reducers/blockTypes/blockTypes.js +38 -0
  378. package/src/reducers/content/content.js +3 -18
  379. package/src/reducers/diff/diff.js +5 -1
  380. package/src/reducers/diff/diff.test.js +60 -4
  381. package/src/reducers/index.js +2 -0
  382. package/src/reducers/querystring/querystring.js +8 -1
  383. package/src/reducers/users/users.js +1 -1
  384. package/src/routes.js +13 -1
  385. package/src/server.jsx +47 -13
  386. package/src/start-client.jsx +9 -2
  387. package/src/start-server.js +9 -3
  388. package/test-addons-loader.js +3 -0
  389. package/test-setup-globals.js +56 -2
  390. package/theme/themes/default/elements/segment.variables +9 -16
  391. package/theme/themes/pastanaga/collections/form.overrides +1 -1
  392. package/theme/themes/pastanaga/elements/segment.variables +1 -4
  393. package/theme/themes/pastanaga/extras/block-types.less +17 -0
  394. package/theme/themes/pastanaga/extras/blocks.less +19 -0
  395. package/theme/themes/pastanaga/extras/contents.less +75 -0
  396. package/theme/themes/pastanaga/extras/main.less +20 -4
  397. package/theme/themes/pastanaga/extras/toolbar.less +10 -5
  398. package/theme/themes/pastanaga/extras/videoembed.less +22 -0
  399. package/theme/themes/pastanaga/extras/widgets.less +79 -0
  400. package/tsconfig.declarations.json +1 -1
  401. package/tsconfig.json +4 -5
  402. package/types/actions/blockTypes/blockTypes.d.ts +7 -0
  403. package/types/components/index.d.ts +1 -1
  404. package/types/components/manage/Blocks/Block/Order/Item.test.d.ts +1 -0
  405. package/types/components/manage/Blocks/Block/Order/utilities.d.ts +2 -1
  406. package/types/components/manage/Blocks/Grid/context.d.ts +1 -0
  407. package/types/components/manage/Blocks/Teaser/utils.d.ts +5 -0
  408. package/types/components/manage/Blocks/Video/Body.d.ts +4 -2
  409. package/types/components/manage/Blocks/Video/schema.d.ts +4 -0
  410. package/types/components/manage/Contents/DropZoneContent.d.ts +2 -0
  411. package/types/components/manage/Contents/__mocks__/index.d.ts +2 -2
  412. package/types/components/manage/Controlpanels/BlockType.d.ts +7 -0
  413. package/types/components/manage/Controlpanels/BlockTypes.d.ts +7 -0
  414. package/types/components/manage/Controlpanels/Relations/RelationsMatrix.d.ts +1 -1
  415. package/types/components/manage/Controlpanels/Users/RenderUsers.d.ts +18 -2
  416. package/types/components/manage/Controlpanels/Users/UsersControlpanel.d.ts +6 -2
  417. package/types/components/manage/Controlpanels/index.d.ts +2 -2
  418. package/types/components/manage/Diff/Diff.d.ts +7 -2
  419. package/types/components/manage/Form/__mocks__/index.d.ts +8 -8
  420. package/types/components/manage/Multilingual/ManageTranslations.d.ts +1 -1
  421. package/types/components/manage/Sidebar/ObjectBrowser.d.ts +1 -1
  422. package/types/components/manage/Sidebar/SidebarPortal.d.ts +7 -15
  423. package/types/components/manage/Toolbar/Types.crash.test.d.ts +1 -0
  424. package/types/components/manage/Widgets/AlignWidget.d.ts +8 -10
  425. package/types/components/manage/Widgets/AlignWidget.stories.d.ts +1 -0
  426. package/types/components/manage/Widgets/BlockAlignment.d.ts +7 -0
  427. package/types/components/manage/Widgets/BlockAlignment.stories.d.ts +8 -0
  428. package/types/components/manage/Widgets/BlockWidth.d.ts +7 -0
  429. package/types/components/manage/Widgets/BlockWidth.stories.d.ts +6 -0
  430. package/types/components/manage/Widgets/ButtonsWidget.d.ts +48 -1
  431. package/types/components/manage/Widgets/ButtonsWidget.stories.d.ts +3 -0
  432. package/types/components/manage/Widgets/FormFieldWrapper.d.ts +28 -5
  433. package/types/components/manage/Widgets/ImageWidget.d.ts +41 -1
  434. package/types/components/manage/Widgets/InternalUrlWidget.d.ts +1 -1
  435. package/types/components/manage/Widgets/ObjectBrowserWidget.d.ts +2 -0
  436. package/types/components/manage/Widgets/QueryWidget.d.ts +5 -2
  437. package/types/components/manage/Widgets/RecurrenceWidget/Utils.d.ts +12 -18
  438. package/types/components/manage/Widgets/Size.d.ts +7 -0
  439. package/types/components/manage/Widgets/Size.stories.d.ts +6 -0
  440. package/types/components/manage/Widgets/UrlWidget.d.ts +1 -1
  441. package/types/components/manage/Widgets/__mocks__/index.d.ts +33 -33
  442. package/types/components/manage/Widgets/index.d.ts +11 -6
  443. package/types/components/theme/ConnectionRefused/ConnectionRefused.d.ts +2 -2
  444. package/types/components/theme/InjectPloneComponentsCSS/InjectPloneComponentsCSS.d.ts +3 -0
  445. package/types/components/theme/LanguageSelector/LanguageSelector.d.ts +3 -10
  446. package/types/components/theme/PasswordReset/PasswordReset.d.ts +6 -2
  447. package/types/components/theme/Sitemap/Sitemap.stories.d.ts +13 -0
  448. package/types/components/theme/SlotRenderer/SlotRenderer.d.ts +4 -5
  449. package/types/components/theme/Unauthorized/Unauthorized.d.ts +2 -2
  450. package/types/components/theme/VideoEmbed/VideoEmbed.d.ts +2 -0
  451. package/types/components/theme/View/EventView.stories.d.ts +19 -0
  452. package/types/components/theme/View/FileView.stories.d.ts +18 -0
  453. package/types/components/theme/View/LinkView.stories.d.ts +18 -0
  454. package/types/components/theme/View/ListingView.stories.d.ts +24 -0
  455. package/types/components/theme/View/NewsItemView.stories.d.ts +23 -0
  456. package/types/components/theme/View/RenderBlocks.stories.d.ts +23 -0
  457. package/types/components/theme/View/SummaryView.stories.d.ts +23 -0
  458. package/types/components/theme/View/TabularView.stories.d.ts +23 -0
  459. package/types/config/ControlPanels.d.ts +1 -0
  460. package/types/config/Views.d.ts +1 -1
  461. package/types/config/Widgets.d.ts +6 -0
  462. package/types/config/slots.d.ts +7 -0
  463. package/types/constants/ActionTypes.d.ts +1 -0
  464. package/types/helpers/Blocks/Blocks.d.ts +4 -0
  465. package/types/helpers/Content/Content.d.ts +7 -0
  466. package/types/helpers/Content/withClientSideContent.d.ts +1 -0
  467. package/types/helpers/Extensions/withBlockSchemaEnhancer.d.ts +4 -5
  468. package/types/helpers/FormValidation/validators.d.ts +18 -1
  469. package/types/helpers/Helmet/Helmet.d.ts +1 -1
  470. package/types/helpers/Loadable/__mocks__/Loadable.d.ts +2 -2
  471. package/types/helpers/MessageLabels/MessageLabels.d.ts +105 -93
  472. package/types/helpers/Url/Url.d.ts +14 -0
  473. package/types/helpers/Url/bulkFlattenToAppURL.d.ts +5 -0
  474. package/types/helpers/Utils/Utils.d.ts +1 -0
  475. package/types/reducers/blockTypes/blockTypes.d.ts +16 -0
  476. package/types/reducers/index.d.ts +3 -0
  477. package/types/routes.d.ts +7 -5
  478. package/types/start-client.d.ts +0 -1
  479. package/vitest.config.mjs +84 -42
  480. package/webpack-plugins/webpack-less-plugin.js +1 -1
  481. package/webpack-plugins/webpack-scss-plugin.js +172 -0
  482. package/cypress/downloads/downloads.html +0 -0
  483. package/jest-addons-loader.js +0 -3
  484. package/jest-extender-plugin.js +0 -39
  485. package/jest-setup-afterenv.js +0 -2
  486. package/jest-svgsystem-transform.js +0 -10
  487. package/package-why.json +0 -34
  488. package/patches/patchit.sh +0 -2
  489. package/patches/razzle-jest.patch +0 -10
  490. package/src/components/manage/Contents/__mocks__/index.vitest.tsx +0 -5
  491. package/src/components/manage/Form/__mocks__/index.vitest.tsx +0 -73
  492. package/src/components/manage/Sidebar/SidebarPortal.jsx +0 -47
  493. package/src/components/manage/Sidebar/SidebarPortal.test.jsx +0 -26
  494. package/src/components/manage/Widgets/AlignWidget.test.jsx +0 -59
  495. package/src/components/manage/Widgets/ButtonsWidget.jsx +0 -41
  496. package/src/components/manage/Widgets/ButtonsWidget.test.jsx +0 -70
  497. package/src/components/manage/Widgets/__mocks__/index.vitest.tsx +0 -41
  498. package/src/components/theme/LanguageSelector/LanguageSelector.jsx +0 -79
  499. package/src/helpers/Loadable/__mocks__/Loadable.vitest.jsx +0 -39
  500. package/test-setup-globals-vitest.js +0 -46
  501. package/theme/themes/pastanaga/extras/utils.less +0 -63
  502. /package/src/components/theme/LanguageSelector/{LanguageSelector.test.jsx → LanguageSelector.test.tsx} +0 -0
@@ -8,17 +8,8 @@ import Display from './Display';
8
8
 
9
9
  const mockStore = configureStore();
10
10
 
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
-
11
+ vi.mock('@plone/volto/components/manage/Widgets');
12
+ vi.mock('@plone/volto/helpers/Loadable/Loadable');
22
13
  beforeAll(async () => {
23
14
  const { __setLoadables } = await import(
24
15
  '@plone/volto/helpers/Loadable/Loadable'
@@ -8,11 +8,7 @@ import { __test__ as Edit } from './Edit';
8
8
 
9
9
  const mockStore = configureStore();
10
10
 
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
- });
11
+ vi.mock('@plone/volto/components/manage/Form');
16
12
  vi.mock('../Toolbar/Toolbar', () => ({
17
13
  default: vi.fn(() => <div id="Portal" />),
18
14
  }));
@@ -5,11 +5,7 @@ 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
- vi.mock('@plone/volto/components/manage/Form', async () => {
9
- return await import(
10
- '@plone/volto/components/manage/Form/__mocks__/index.vitest.tsx'
11
- );
12
- });
8
+ vi.mock('@plone/volto/components/manage/Form');
13
9
 
14
10
  const mockStore = configureStore();
15
11
 
@@ -191,8 +191,8 @@ class Form extends Component {
191
191
  // Adding fallback in case the fields are empty, so we are sure that the edit form
192
192
  // shows at least the default blocks
193
193
  if (
194
- formData.hasOwnProperty(blocksFieldname) &&
195
- formData.hasOwnProperty(blocksLayoutFieldname)
194
+ formData?.hasOwnProperty(blocksFieldname) &&
195
+ formData?.hasOwnProperty(blocksLayoutFieldname)
196
196
  ) {
197
197
  if (
198
198
  !formData[blocksLayoutFieldname] ||
@@ -216,7 +216,7 @@ class Form extends Component {
216
216
 
217
217
  let selectedBlock = null;
218
218
  if (
219
- formData.hasOwnProperty(blocksLayoutFieldname) &&
219
+ formData?.hasOwnProperty(blocksLayoutFieldname) &&
220
220
  formData[blocksLayoutFieldname].items.length > 0
221
221
  ) {
222
222
  if (config.blocks?.initialBlocksFocus === null) {
@@ -9,11 +9,7 @@ const mockStore = configureStore();
9
9
  const errorMessage =
10
10
  "[{'message': 'The specified email is not valid.', 'field': 'contact_email', 'error': 'ValidationError'}";
11
11
 
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
- });
12
+ vi.mock('@plone/volto/components/manage/Form');
17
13
 
18
14
  describe('Form', () => {
19
15
  it('renders a form component', () => {
@@ -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,11 +6,7 @@ import config from '@plone/volto/registry';
6
6
 
7
7
  import InlineForm from './InlineForm';
8
8
 
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
- });
9
+ vi.mock('@plone/volto/components/manage/Form');
14
10
 
15
11
  const mockStore = configureStore();
16
12
 
@@ -245,15 +245,17 @@ class ModalForm extends Component {
245
245
  const { schema, onCancel, description } = this.props;
246
246
  const currentFieldset = schema.fieldsets[this.state.currentTab];
247
247
 
248
- const fields = map(currentFieldset.fields, (field) => ({
249
- ...schema.properties[field],
250
- id: field,
251
- value: this.state.formData[field],
252
- required: schema.required.indexOf(field) !== -1,
253
- onChange: this.onChangeField,
254
- onBlur: this.onBlurField,
255
- onClick: this.onClickInput,
256
- }));
248
+ const fields = currentFieldset
249
+ ? map(currentFieldset.fields, (field) => ({
250
+ ...schema.properties[field],
251
+ id: field,
252
+ value: this.state.formData[field],
253
+ required: schema.required.indexOf(field) !== -1,
254
+ onChange: this.onChangeField,
255
+ onBlur: this.onBlurField,
256
+ onClick: this.onClickInput,
257
+ }))
258
+ : [];
257
259
 
258
260
  const state_errors = keys(this.state.errors).length > 0;
259
261
  return (
@@ -288,7 +290,7 @@ class ModalForm extends Component {
288
290
  )}
289
291
  <div>{this.props.submitError}</div>
290
292
  </Message>
291
- {schema.fieldsets.length > 1 && (
293
+ {schema.fieldsets?.length > 1 && (
292
294
  <Menu tabular stackable>
293
295
  {map(schema.fieldsets, (item, index) => (
294
296
  <Menu.Item
@@ -8,11 +8,7 @@ import ModalForm from './ModalForm';
8
8
 
9
9
  const mockStore = configureStore();
10
10
 
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
- });
11
+ vi.mock('@plone/volto/components/manage/Form');
16
12
 
17
13
  describe('ModalForm', () => {
18
14
  it('renders a modal form component', () => {
@@ -93,4 +89,30 @@ describe('ModalForm', () => {
93
89
  const loadingMessage = getByText(/renaming items.../i);
94
90
  expect(loadingMessage).toBeInTheDocument();
95
91
  });
92
+
93
+ it('renders with empty fieldsets array', () => {
94
+ const store = mockStore({
95
+ intl: {
96
+ locale: 'en',
97
+ messages: {},
98
+ },
99
+ });
100
+ const component = renderer.create(
101
+ <Provider store={store}>
102
+ <ModalForm
103
+ schema={{
104
+ fieldsets: [],
105
+ properties: {},
106
+ required: [],
107
+ }}
108
+ onSubmit={() => {}}
109
+ onCancel={() => {}}
110
+ open={false}
111
+ title="Action without form"
112
+ />
113
+ </Provider>,
114
+ );
115
+ const json = component.toJSON();
116
+ expect(json).toMatchSnapshot();
117
+ });
96
118
  });
@@ -1,25 +1,7 @@
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
-
18
1
  import type { JSONSchema } from '@plone/types';
19
2
  import type { Ref } from 'react';
20
- const { forwardRef } = jest.requireActual('react');
3
+ import { forwardRef } from 'react';
21
4
 
22
- // Field descriptions can contain react elements and those are not JSON stringifiable
23
5
  const cleanupSchema = (schema: JSONSchema | null): JSONSchema | null => {
24
6
  if (!schema || !schema.properties) return schema;
25
7
  return {
@@ -40,38 +22,38 @@ const cleanupSchema = (schema: JSONSchema | null): JSONSchema | null => {
40
22
  };
41
23
  };
42
24
 
43
- export const Field = jest.fn((props) => (
25
+ export const Field = vi.fn((props) => (
44
26
  <div className="Field" id={props.id}>
45
27
  {props.title}
46
28
  </div>
47
29
  ));
48
30
 
49
- export const InlineForm = jest.fn((props) => (
31
+ export const InlineForm = vi.fn((props) => (
50
32
  <div
51
33
  id="InlineForm"
52
34
  data-schema={JSON.stringify(cleanupSchema(props.schema), null, 2)}
53
35
  />
54
36
  ));
55
37
 
56
- export const ModalForm = jest.fn((props) => (
38
+ export const ModalForm = vi.fn((props) => (
57
39
  <div
58
40
  id="ModalForm"
59
41
  data-schema={JSON.stringify(cleanupSchema(props.schema), null, 2)}
60
42
  />
61
43
  ));
62
44
 
63
- export const UndoToolbar = jest.fn(() => <div id="UndoToolbar" />);
45
+ export const UndoToolbar = vi.fn(() => <div id="UndoToolbar" />);
64
46
 
65
- export const BlocksToolbar = jest.fn(() => <div id="BlocksToolbar" />);
47
+ export const BlocksToolbar = vi.fn(() => <div id="BlocksToolbar" />);
66
48
 
67
- export const BlockDataForm = jest.fn((props) => (
49
+ export const BlockDataForm = vi.fn((props) => (
68
50
  <div
69
51
  id="BlockDataForm"
70
52
  data-schema={JSON.stringify(cleanupSchema(props.schema), null, 2)}
71
53
  />
72
54
  ));
73
55
 
74
- export const BlocksForm = jest.fn((props) => (
56
+ export const BlocksForm = vi.fn((props) => (
75
57
  <div
76
58
  id="BlocksForm"
77
59
  data-schema={JSON.stringify(cleanupSchema(props.schema), null, 2)}
@@ -88,4 +70,4 @@ const MockForm = forwardRef(
88
70
  ),
89
71
  );
90
72
 
91
- export const Form = jest.fn((props) => <MockForm {...props} />);
73
+ export const Form = vi.fn((props) => <MockForm {...props} />);
@@ -56,33 +56,33 @@ const CompareLanguagesMenu = ({
56
56
  {comparingLanguage === t.language ? (
57
57
  <button
58
58
  aria-label={`${intl.formatMessage(messages.stop_compare)} ${
59
- langmap[t.language].nativeName
59
+ langmap[t.language]?.nativeName || t.language
60
60
  }`}
61
61
  title={`${intl.formatMessage(messages.stop_compare)} ${
62
- langmap[t.language].nativeName
62
+ langmap[t.language]?.nativeName || t.language
63
63
  }`}
64
64
  onClick={() => {
65
65
  setComparingLanguage(null);
66
66
  closeMenu();
67
67
  }}
68
68
  >
69
- {langmap[t.language].nativeName}
69
+ {langmap[t.language]?.nativeName || t.language}
70
70
  <Icon name={clearSVG} size="30px" />
71
71
  </button>
72
72
  ) : (
73
73
  <button
74
74
  aria-label={`${intl.formatMessage(
75
75
  messages.compare_to,
76
- )} ${langmap[t.language].nativeName.toLowerCase()}`}
76
+ )} ${(langmap[t.language]?.nativeName || t.language).toLowerCase()}`}
77
77
  title={`${intl.formatMessage(
78
78
  messages.compare_to,
79
- )} ${langmap[t.language].nativeName.toLowerCase()}`}
79
+ )} ${(langmap[t.language]?.nativeName || t.language).toLowerCase()}`}
80
80
  onClick={() => {
81
81
  setComparingLanguage(t.language);
82
82
  closeMenu();
83
83
  }}
84
84
  >
85
- {langmap[t.language].nativeName}
85
+ {langmap[t.language]?.nativeName || t.language}
86
86
  </button>
87
87
  )}
88
88
  </li>
@@ -12,9 +12,12 @@ const CreateTranslation = (props) => {
12
12
  const dispatch = useDispatch();
13
13
  const { language, translationOf } = props.location.state;
14
14
  const [translationLocation, setTranslationLocation] = React.useState(null);
15
- const [translationObject, setTranslationObject] = React.useState(null);
16
15
  const languageFrom = useSelector((state) => state.intl.locale);
17
16
 
17
+ const translationObject = useSelector(
18
+ (state) => state.content.subrequests['translationObject'],
19
+ );
20
+
18
21
  React.useEffect(() => {
19
22
  // Only on mount, we dispatch the locator query
20
23
  dispatch(getTranslationLocator(translationOf, language)).then((resp) => {
@@ -22,22 +25,21 @@ const CreateTranslation = (props) => {
22
25
  });
23
26
 
24
27
  //and we load the translationObject
25
- dispatch(getContent(translationOf, null, 'translationObject')).then(
26
- (resp) => {
27
- setTranslationObject(resp);
28
- },
29
- );
28
+ dispatch(getContent(translationOf, null, 'translationObject'));
30
29
 
31
30
  // On unmount we dispatch the language change
32
31
  return () => {
33
32
  // We change the interface language
34
33
  if (config.settings.supportedLanguages.includes(language)) {
35
34
  const langFileName = toGettextLang(language);
36
- import(
37
- /* @vite-ignore */ '@root/../locales/' + langFileName + '.json'
38
- ).then((locale) => {
39
- dispatch(changeLanguage(language, locale.default));
40
- });
35
+ import(/* @vite-ignore */ '@root/../locales/' + langFileName + '.json')
36
+ .then((locale) => {
37
+ dispatch(changeLanguage(language, locale.default));
38
+ })
39
+ .catch(() => {
40
+ // If locale file doesn't exist, still switch language with empty locale
41
+ dispatch(changeLanguage(language, {}));
42
+ });
41
43
  }
42
44
  };
43
45
  // On mount only
@@ -46,7 +48,8 @@ const CreateTranslation = (props) => {
46
48
 
47
49
  return (
48
50
  translationLocation &&
49
- translationObject && (
51
+ translationObject.data &&
52
+ translationObject.loaded > 0 && (
50
53
  <Redirect
51
54
  to={{
52
55
  pathname: `${flattenToAppURL(translationLocation)}/add`,
@@ -54,7 +57,7 @@ const CreateTranslation = (props) => {
54
57
  state: {
55
58
  translationOf: props.location.state.translationOf,
56
59
  language: props.location.state.language,
57
- translationObject: translationObject,
60
+ translationObject: translationObject.data,
58
61
  languageFrom,
59
62
  },
60
63
  }}
@@ -178,7 +178,7 @@ const ManageTranslations = (props) => {
178
178
  <FormattedMessage
179
179
  id="Manage translations for {title}"
180
180
  defaultMessage="Manage translations for {title}"
181
- values={{ title: <q>{content.title}</q> }}
181
+ values={{ title: <q>{content?.title || ''}</q> }}
182
182
  />
183
183
  </Segment>
184
184
  {content && (
@@ -195,9 +195,9 @@ const ManageTranslations = (props) => {
195
195
  <Table.Row key={lang}>
196
196
  <Table.Cell collapsing>
197
197
  {lang === content.language.token ? (
198
- <strong>{langmap[lang].nativeName}</strong>
198
+ <strong>{langmap[lang]?.nativeName || lang}</strong>
199
199
  ) : (
200
- langmap[lang].nativeName
200
+ langmap[lang]?.nativeName || lang
201
201
  )}
202
202
  </Table.Cell>
203
203
  <Table.Cell>
@@ -235,7 +235,7 @@ const ManageTranslations = (props) => {
235
235
  <Button
236
236
  aria-label={`${intl.formatMessage(
237
237
  messages.unlink,
238
- )} ${langmap[lang].nativeName.toLowerCase()}`}
238
+ )} ${(langmap[lang]?.nativeName || lang).toLowerCase()}`}
239
239
  basic
240
240
  icon
241
241
  disabled={lang === content.language.token}
@@ -256,7 +256,7 @@ const ManageTranslations = (props) => {
256
256
  <Button
257
257
  aria-label={`${intl.formatMessage(
258
258
  messages.link,
259
- )} ${langmap[lang].nativeName.toLowerCase()}`}
259
+ )} ${(langmap[lang]?.nativeName || lang).toLowerCase()}`}
260
260
  basic
261
261
  icon
262
262
  disabled={lang === content.language.token}
@@ -48,12 +48,15 @@ const TranslationObject = ({
48
48
  let lang =
49
49
  config.settings.supportedLanguages[Object.keys(locales).length];
50
50
  const langFileName = toGettextLang(lang);
51
- import(
52
- /* @vite-ignore */ '@root/../locales/' + langFileName + '.json'
53
- ).then((locale) => {
54
- setLocales({ ...locales, [toReactIntlLang(lang)]: locale.default });
55
- setLoadingLocale(false);
56
- });
51
+ import(/* @vite-ignore */ '@root/../locales/' + langFileName + '.json')
52
+ .then((locale) => {
53
+ setLocales({ ...locales, [toReactIntlLang(lang)]: locale.default });
54
+ setLoadingLocale(false);
55
+ })
56
+ .catch(() => {
57
+ setLocales({ ...locales, [toReactIntlLang(lang)]: {} });
58
+ setLoadingLocale(false);
59
+ });
57
60
  }
58
61
  }, [loadingLocale, locales]);
59
62
 
@@ -83,7 +86,7 @@ const TranslationObject = ({
83
86
  active={activeMenu === 'language'}
84
87
  onClick={handleMenuClick}
85
88
  >
86
- {langmap[lang].nativeName}
89
+ {langmap[lang]?.nativeName || lang}
87
90
  </Menu.Item>
88
91
  {visual && (
89
92
  <Menu.Item
@@ -107,7 +110,7 @@ const TranslationObject = ({
107
110
  hideActions
108
111
  pathname={flattenToAppURL(translationObject['@id'])}
109
112
  visual={visual}
110
- title={langmap[lang].nativeName}
113
+ title={langmap[lang]?.nativeName || lang}
111
114
  loading={false}
112
115
  isFormSelected={isFormSelected}
113
116
  onSelectForm={onSelectForm}
@@ -9,11 +9,7 @@ import ChangePassword from './ChangePassword';
9
9
 
10
10
  const mockStore = configureStore();
11
11
 
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
- });
12
+ vi.mock('@plone/volto/components/manage/Form');
17
13
 
18
14
  vi.mock('../Toolbar/Toolbar', () => ({
19
15
  default: vi.fn(() => <div id="Portal" />),
@@ -53,11 +53,14 @@ const PersonalPreferences = (props) => {
53
53
  let language = data.language || 'en';
54
54
  if (config.settings.supportedLanguages.includes(language)) {
55
55
  const langFileName = toGettextLang(language);
56
- import(
57
- /* @vite-ignore */ '@root/../locales/' + langFileName + '.json'
58
- ).then((locale) => {
59
- dispatch(changeLanguage(language, locale.default));
60
- });
56
+ import(/* @vite-ignore */ '@root/../locales/' + langFileName + '.json')
57
+ .then((locale) => {
58
+ dispatch(changeLanguage(language, locale.default));
59
+ })
60
+ .catch(() => {
61
+ // If locale file doesn't exist, still switch language with empty locale
62
+ dispatch(changeLanguage(language, {}));
63
+ });
61
64
  }
62
65
  toast.success(<Toast success title={intl.formatMessage(messages.saved)} />);
63
66
  closeMenu();
@@ -12,23 +12,7 @@ vi.mock('../Toolbar/Toolbar', () => ({
12
12
  default: vi.fn(() => <div id="Portal" />),
13
13
  }));
14
14
 
15
- vi.mock('@plone/volto/components/manage/Form', async () => {
16
- return await import(
17
- '@plone/volto/components/manage/Form/__mocks__/index.vitest.tsx'
18
- );
19
- });
20
- vi.mock('@plone/volto/helpers/Loadable/Loadable', async () => {
21
- return await import(
22
- '@plone/volto/helpers/Loadable/__mocks__/Loadable.vitest.jsx'
23
- );
24
- });
25
-
26
- beforeAll(async () => {
27
- const { __setLoadables } = await import(
28
- '@plone/volto/helpers/Loadable/Loadable'
29
- );
30
- await __setLoadables();
31
- });
15
+ vi.mock('@plone/volto/components/manage/Form');
32
16
 
33
17
  describe('PersonalPreferences', () => {
34
18
  it('renders a personal preferences component', () => {
@@ -473,23 +473,39 @@ class SharingComponent extends Component {
473
473
  <p className="help">
474
474
  <FormattedMessage
475
475
  id="By default, permissions from the container of this item are inherited. If you disable this, only the explicitly defined sharing permissions will be valid. In the overview, the symbol {inherited} indicates an inherited value. Similarly, the symbol {global} indicates a global role, which is managed by the site administrator."
476
- defaultMessage="By default, permissions from the container of this item are inherited. If you disable this, only the explicitly defined sharing permissions will be valid. In the overview, the symbol {inherited} indicates an inherited value. Similarly, the symbol {global} indicates a global role, which is managed by the site administrator."
476
+ defaultMessage="By default, permissions from the container of this item are inherited. If you disable this, only the explicitly defined sharing permissions will be valid. In the overview, inherited values are explicitly labeled as 'Inherited value' and receive a green check mark {inherited}. Similarly, roles managed by the site administrator are labeled as 'Global role' and receive a blue check mark {global}."
477
477
  values={{
478
478
  inherited: (
479
- <IconOld name="check circle outline" color="green" />
479
+ <IconOld
480
+ aria-hidden="true"
481
+ name="check circle outline"
482
+ color="green"
483
+ />
480
484
  ),
481
485
  global: (
482
- <IconOld name="check circle outline" color="blue" />
486
+ <IconOld
487
+ aria-hidden="true"
488
+ name="check circle outline"
489
+ color="blue"
490
+ />
483
491
  ),
484
492
  }}
485
493
  />
486
494
  </p>
487
495
  </Segment>
488
- <Segment className="actions" attached clearing>
496
+ <Segment className="right aligned actions" attached clearing>
497
+ <Button
498
+ basic
499
+ secondary
500
+ aria-label={this.props.intl.formatMessage(messages.cancel)}
501
+ title={this.props.intl.formatMessage(messages.cancel)}
502
+ onClick={this.onCancel}
503
+ >
504
+ <Icon className="circled" name={clearSVG} size="30px" />
505
+ </Button>
489
506
  <Button
490
507
  basic
491
508
  primary
492
- floated="right"
493
509
  type="submit"
494
510
  aria-label={this.props.intl.formatMessage(messages.save)}
495
511
  title={this.props.intl.formatMessage(messages.save)}
@@ -498,16 +514,6 @@ class SharingComponent extends Component {
498
514
  >
499
515
  <Icon className="circled" name={aheadSVG} size="30px" />
500
516
  </Button>
501
- <Button
502
- basic
503
- secondary
504
- aria-label={this.props.intl.formatMessage(messages.cancel)}
505
- title={this.props.intl.formatMessage(messages.cancel)}
506
- floated="right"
507
- onClick={this.onCancel}
508
- >
509
- <Icon className="circled" name={clearSVG} size="30px" />
510
- </Button>
511
517
  </Segment>
512
518
  </Form>
513
519
  </Plug>
@@ -58,6 +58,7 @@ const withObjectBrowser = (WrappedComponent) =>
58
58
  selectableTypes,
59
59
  maximumSelectionSize,
60
60
  currentPath,
61
+ onlyFolderishSelectable,
61
62
  } = {}) =>
62
63
  this.setState(() => ({
63
64
  isObjectBrowserOpen: true,
@@ -70,6 +71,7 @@ const withObjectBrowser = (WrappedComponent) =>
70
71
  selectableTypes,
71
72
  maximumSelectionSize,
72
73
  currentPath,
74
+ onlyFolderishSelectable,
73
75
  }));
74
76
 
75
77
  closeObjectBrowser = () => this.setState({ isObjectBrowserOpen: false });
@@ -110,6 +112,7 @@ const withObjectBrowser = (WrappedComponent) =>
110
112
  searchableTypes={this.state.searchableTypes}
111
113
  selectableTypes={this.state.selectableTypes}
112
114
  maximumSelectionSize={this.state.maximumSelectionSize}
115
+ onlyFolderishSelectable={this.state.onlyFolderishSelectable}
113
116
  />
114
117
  </SidebarPopup>
115
118
  </>
@@ -86,6 +86,7 @@ class ObjectBrowserBody extends Component {
86
86
  maximumSelectionSize: PropTypes.number,
87
87
  contextURL: PropTypes.string,
88
88
  searchableTypes: PropTypes.arrayOf(PropTypes.string),
89
+ onlyFolderishSelectable: PropTypes.bool,
89
90
  };
90
91
 
91
92
  /**
@@ -101,6 +102,7 @@ class ObjectBrowserBody extends Component {
101
102
  selectableTypes: [],
102
103
  searchableTypes: null,
103
104
  maximumSelectionSize: null,
105
+ onlyFolderishSelectable: false,
104
106
  };
105
107
 
106
108
  /**
@@ -142,10 +144,14 @@ class ObjectBrowserBody extends Component {
142
144
  showSearchInput: false,
143
145
  // In image mode, the searchable types default to the image types which
144
146
  // can be overridden with the property if specified.
147
+ // If selectableTypes are passed, the searchableTypes are the selectableTypes
145
148
  searchableTypes:
146
149
  this.props.mode === 'image'
147
150
  ? this.props.searchableTypes || config.settings.imageObjects
148
- : this.props.searchableTypes,
151
+ : [
152
+ ...(this.props.searchableTypes ?? []),
153
+ ...(this.props.selectableTypes ?? []),
154
+ ],
149
155
  view: this.props.mode === 'image' ? 'icons' : 'list',
150
156
  };
151
157
  this.searchInputRef = React.createRef();
@@ -329,7 +335,17 @@ class ObjectBrowserBody extends Component {
329
335
  };
330
336
 
331
337
  isSelectable = (item) => {
332
- const { maximumSelectionSize, data, mode, selectableTypes } = this.props;
338
+ const {
339
+ maximumSelectionSize,
340
+ data,
341
+ mode,
342
+ selectableTypes,
343
+ onlyFolderishSelectable,
344
+ } = this.props;
345
+
346
+ if (onlyFolderishSelectable && !item.is_folderish) {
347
+ return false;
348
+ }
333
349
  if (
334
350
  maximumSelectionSize &&
335
351
  data &&