@plone/volto 19.0.0-alpha.9 → 19.1.0

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 (535) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc +26 -15
  3. package/AGENTS.md +47 -0
  4. package/CHANGELOG.md +543 -12
  5. package/README.md +22 -19
  6. package/babel.js +1 -9
  7. package/cypress/support/guillotina.js +1 -0
  8. package/cypress.config.js +1 -0
  9. package/global-test-setup.js +1 -2
  10. package/locales/af/LC_MESSAGES/volto.po +5516 -0
  11. package/locales/af.json +1 -1
  12. package/locales/ar/LC_MESSAGES/volto.po +5516 -0
  13. package/locales/ar.json +1 -1
  14. package/locales/bg/LC_MESSAGES/volto.po +5516 -0
  15. package/locales/bg.json +1 -1
  16. package/locales/bn/LC_MESSAGES/volto.po +5516 -0
  17. package/locales/bn.json +1 -1
  18. package/locales/ca/LC_MESSAGES/volto.po +551 -359
  19. package/locales/ca.json +1 -1
  20. package/locales/cs/LC_MESSAGES/volto.po +5516 -0
  21. package/locales/cs.json +1 -1
  22. package/locales/cy/LC_MESSAGES/volto.po +5516 -0
  23. package/locales/cy.json +1 -1
  24. package/locales/da/LC_MESSAGES/volto.po +5516 -0
  25. package/locales/da.json +1 -1
  26. package/locales/de/LC_MESSAGES/volto.po +222 -29
  27. package/locales/de.json +1 -1
  28. package/locales/el/LC_MESSAGES/volto.po +5516 -0
  29. package/locales/el.json +1 -1
  30. package/locales/en/LC_MESSAGES/volto.po +211 -15
  31. package/locales/en.json +1 -1
  32. package/locales/en_AU/LC_MESSAGES/volto.po +5516 -0
  33. package/locales/en_AU.json +1 -1
  34. package/locales/en_GB/LC_MESSAGES/volto.po +5516 -0
  35. package/locales/en_GB.json +1 -1
  36. package/locales/eo/LC_MESSAGES/volto.po +5516 -0
  37. package/locales/eo.json +1 -1
  38. package/locales/es/LC_MESSAGES/volto.po +336 -145
  39. package/locales/es.json +1 -1
  40. package/locales/et/LC_MESSAGES/volto.po +5516 -0
  41. package/locales/et.json +1 -1
  42. package/locales/eu/LC_MESSAGES/volto.po +413 -222
  43. package/locales/eu.json +1 -1
  44. package/locales/fa/LC_MESSAGES/volto.po +5516 -0
  45. package/locales/fa.json +1 -1
  46. package/locales/fi/LC_MESSAGES/volto.po +212 -20
  47. package/locales/fi.json +1 -1
  48. package/locales/fr/LC_MESSAGES/volto.po +369 -178
  49. package/locales/fr.json +1 -1
  50. package/locales/fu/LC_MESSAGES/volto.po +5516 -0
  51. package/locales/fu.json +1 -1
  52. package/locales/gl/LC_MESSAGES/volto.po +5516 -0
  53. package/locales/gl.json +1 -1
  54. package/locales/he/LC_MESSAGES/volto.po +5516 -0
  55. package/locales/he.json +1 -1
  56. package/locales/hi/LC_MESSAGES/volto.po +220 -23
  57. package/locales/hi.json +1 -1
  58. package/locales/hr/LC_MESSAGES/volto.po +5516 -0
  59. package/locales/hr.json +1 -1
  60. package/locales/hu/LC_MESSAGES/volto.po +5516 -0
  61. package/locales/hu.json +1 -1
  62. package/locales/hy/LC_MESSAGES/volto.po +5516 -0
  63. package/locales/hy.json +1 -1
  64. package/locales/id/LC_MESSAGES/volto.po +5516 -0
  65. package/locales/id.json +1 -1
  66. package/locales/it/LC_MESSAGES/volto.po +236 -39
  67. package/locales/it.json +1 -1
  68. package/locales/ja/LC_MESSAGES/volto.po +254 -61
  69. package/locales/ja.json +1 -1
  70. package/locales/ka/LC_MESSAGES/volto.po +5516 -0
  71. package/locales/ka.json +1 -1
  72. package/locales/kn/LC_MESSAGES/volto.po +5516 -0
  73. package/locales/kn.json +1 -1
  74. package/locales/ko/LC_MESSAGES/volto.po +5516 -0
  75. package/locales/ko.json +1 -1
  76. package/locales/lt/LC_MESSAGES/volto.po +5516 -0
  77. package/locales/lt.json +1 -1
  78. package/locales/lv/LC_MESSAGES/volto.po +5516 -0
  79. package/locales/lv.json +1 -1
  80. package/locales/mi/LC_MESSAGES/volto.po +5516 -0
  81. package/locales/mi.json +1 -1
  82. package/locales/mk/LC_MESSAGES/volto.po +5516 -0
  83. package/locales/mk.json +1 -1
  84. package/locales/my/LC_MESSAGES/volto.po +5516 -0
  85. package/locales/my.json +1 -1
  86. package/locales/nb_NO/LC_MESSAGES/volto.po +5516 -0
  87. package/locales/nb_NO.json +1 -1
  88. package/locales/nl/LC_MESSAGES/volto.po +264 -71
  89. package/locales/nl.json +1 -1
  90. package/locales/nn/LC_MESSAGES/volto.po +5516 -0
  91. package/locales/nn.json +1 -1
  92. package/locales/pl/LC_MESSAGES/volto.po +5516 -0
  93. package/locales/pl.json +1 -1
  94. package/locales/pt/LC_MESSAGES/volto.po +862 -670
  95. package/locales/pt.json +1 -1
  96. package/locales/pt_BR/LC_MESSAGES/volto.po +216 -25
  97. package/locales/pt_BR.json +1 -1
  98. package/locales/rm/LC_MESSAGES/volto.po +5516 -0
  99. package/locales/rm.json +1 -1
  100. package/locales/ro/LC_MESSAGES/volto.po +248 -57
  101. package/locales/ro.json +1 -1
  102. package/locales/ru/LC_MESSAGES/volto.po +211 -19
  103. package/locales/ru.json +1 -1
  104. package/locales/sk/LC_MESSAGES/volto.po +5516 -0
  105. package/locales/sk.json +1 -1
  106. package/locales/sl/LC_MESSAGES/volto.po +5516 -0
  107. package/locales/sl.json +1 -1
  108. package/locales/sm/LC_MESSAGES/volto.po +5516 -0
  109. package/locales/sm.json +1 -1
  110. package/locales/sq/LC_MESSAGES/volto.po +5516 -0
  111. package/locales/sq.json +1 -1
  112. package/locales/sr/LC_MESSAGES/volto.po +5516 -0
  113. package/locales/sr.json +1 -1
  114. package/locales/sr@cyrl/LC_MESSAGES/volto.po +5516 -0
  115. package/locales/sr@cyrl.json +1 -1
  116. package/locales/sr@latn/LC_MESSAGES/volto.po +5516 -0
  117. package/locales/sr@latn.json +1 -1
  118. package/locales/sv/LC_MESSAGES/volto.po +5516 -0
  119. package/locales/sv.json +1 -1
  120. package/locales/ta/LC_MESSAGES/volto.po +5516 -0
  121. package/locales/ta.json +1 -1
  122. package/locales/te/LC_MESSAGES/volto.po +5516 -0
  123. package/locales/te.json +1 -1
  124. package/locales/th/LC_MESSAGES/volto.po +5516 -0
  125. package/locales/th.json +1 -1
  126. package/locales/to/LC_MESSAGES/volto.po +5516 -0
  127. package/locales/to.json +1 -1
  128. package/locales/tr/LC_MESSAGES/volto.po +5516 -0
  129. package/locales/tr.json +1 -1
  130. package/locales/uk/LC_MESSAGES/volto.po +5516 -0
  131. package/locales/uk.json +1 -1
  132. package/locales/vi/LC_MESSAGES/volto.po +5516 -0
  133. package/locales/vi.json +1 -1
  134. package/locales/volto.pot +205 -14
  135. package/locales/zh_CN/LC_MESSAGES/volto.po +211 -19
  136. package/locales/zh_CN.json +1 -1
  137. package/locales/zh_Hant/LC_MESSAGES/volto.po +5516 -0
  138. package/locales/zh_Hant.json +1 -1
  139. package/locales/zh_Hant_HK/LC_MESSAGES/volto.po +5516 -0
  140. package/locales/zh_Hant_HK.json +1 -1
  141. package/package.json +71 -149
  142. package/razzle.config.js +16 -25
  143. package/src/actions/blockTypes/blockTypes.ts +24 -0
  144. package/src/actions/controlpanels/controlpanels.js +7 -12
  145. package/src/actions/controlpanels/controlpanels.test.js +2 -3
  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/Add/Add.test.jsx +10 -3
  149. package/src/components/manage/Aliases/Aliases.test.jsx +5 -2
  150. package/src/components/manage/BlockChooser/BlockChooser.jsx +8 -10
  151. package/src/components/manage/Blocks/Block/BlocksForm.jsx +10 -7
  152. package/src/components/manage/Blocks/Block/BlocksForm.test.jsx +3 -14
  153. package/src/components/manage/Blocks/Block/Edit.jsx +19 -10
  154. package/src/components/manage/Blocks/Block/Order/Item.jsx +33 -14
  155. package/src/components/manage/Blocks/Block/Order/Item.test.jsx +90 -0
  156. package/src/components/manage/Blocks/Block/Order/Order.jsx +116 -67
  157. package/src/components/manage/Blocks/Block/Order/utilities.js +28 -11
  158. package/src/components/manage/Blocks/Block/Settings.test.jsx +1 -5
  159. package/src/components/manage/Blocks/Grid/View.jsx +14 -11
  160. package/src/components/manage/Blocks/Grid/context.js +3 -0
  161. package/src/components/manage/Blocks/HTML/Edit.test.jsx +1 -5
  162. package/src/components/manage/Blocks/Image/ImageSidebar.test.jsx +2 -5
  163. package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.test.jsx +2 -5
  164. package/src/components/manage/Blocks/Listing/Edit.jsx +1 -0
  165. package/src/components/manage/Blocks/Listing/ListingBody.jsx +4 -0
  166. package/src/components/manage/Blocks/Maps/Body.jsx +37 -0
  167. package/src/components/manage/Blocks/Maps/Edit.jsx +6 -21
  168. package/src/components/manage/Blocks/Maps/MapsSidebar.test.jsx +1 -5
  169. package/src/components/manage/Blocks/Maps/View.jsx +16 -25
  170. package/src/components/manage/Blocks/Search/components/DateRangeFacet.test.jsx +1 -6
  171. package/src/components/manage/Blocks/Search/components/SelectFacet.jsx +22 -1
  172. package/src/components/manage/Blocks/Search/components/SelectFacet.test.jsx +1 -6
  173. package/src/components/manage/Blocks/Search/components/SortOn.jsx +8 -2
  174. package/src/components/manage/Blocks/Search/components/ToggleFacet.jsx +14 -0
  175. package/src/components/manage/Blocks/Teaser/DefaultBody.jsx +10 -2
  176. package/src/components/manage/Blocks/Teaser/View.jsx +0 -1
  177. package/src/components/manage/Blocks/Teaser/utils.js +13 -0
  178. package/src/components/manage/Blocks/Teaser/utils.test.js +34 -0
  179. package/src/components/manage/Blocks/Title/Edit.jsx +5 -0
  180. package/src/components/manage/Blocks/Video/Body.jsx +69 -43
  181. package/src/components/manage/Blocks/Video/Body.test.jsx +122 -5
  182. package/src/components/manage/Blocks/Video/Edit.jsx +20 -2
  183. package/src/components/manage/Blocks/Video/Edit.test.jsx +6 -0
  184. package/src/components/manage/Blocks/Video/VideoSidebar.test.jsx +1 -5
  185. package/src/components/manage/Blocks/Video/View.jsx +1 -0
  186. package/src/components/manage/Blocks/Video/View.test.jsx +29 -15
  187. package/src/components/manage/Blocks/Video/schema.js +14 -1
  188. package/src/components/manage/Contents/Contents.jsx +854 -747
  189. package/src/components/manage/Contents/Contents.test.jsx +9 -10
  190. package/src/components/manage/Contents/ContentsBreadcrumbs.jsx +4 -3
  191. package/src/components/manage/Contents/ContentsIndexHeader.jsx +47 -81
  192. package/src/components/manage/Contents/ContentsIndexHeader.test.jsx +10 -3
  193. package/src/components/manage/Contents/ContentsItem.jsx +226 -278
  194. package/src/components/manage/Contents/ContentsItem.test.jsx +10 -6
  195. package/src/components/manage/Contents/ContentsPropertiesModal.test.jsx +1 -5
  196. package/src/components/manage/Contents/ContentsRenameModal.test.jsx +1 -5
  197. package/src/components/manage/Contents/ContentsTagsModal.test.jsx +1 -5
  198. package/src/components/manage/Contents/ContentsWorkflowModal.test.jsx +1 -5
  199. package/src/components/manage/Contents/DropZoneContent.jsx +339 -0
  200. package/src/components/manage/Contents/__mocks__/index.tsx +2 -18
  201. package/src/components/manage/Controlpanels/AddonsControlpanel.jsx +7 -0
  202. package/src/components/manage/Controlpanels/AddonsControlpanel.test.jsx +7 -4
  203. package/src/components/manage/Controlpanels/Aliases.test.jsx +8 -9
  204. package/src/components/manage/Controlpanels/BlockType.tsx +165 -0
  205. package/src/components/manage/Controlpanels/BlockTypes.tsx +145 -0
  206. package/src/components/manage/Controlpanels/ContentType.jsx +131 -222
  207. package/src/components/manage/Controlpanels/ContentType.test.jsx +13 -14
  208. package/src/components/manage/Controlpanels/ContentTypeLayout.test.jsx +12 -9
  209. package/src/components/manage/Controlpanels/ContentTypeSchema.jsx +1 -1
  210. package/src/components/manage/Controlpanels/ContentTypes.jsx +9 -2
  211. package/src/components/manage/Controlpanels/ContentTypes.test.jsx +7 -4
  212. package/src/components/manage/Controlpanels/Controlpanel.jsx +122 -218
  213. package/src/components/manage/Controlpanels/Controlpanel.test.jsx +8 -33
  214. package/src/components/manage/Controlpanels/Controlpanels.jsx +28 -5
  215. package/src/components/manage/Controlpanels/Controlpanels.test.jsx +23 -8
  216. package/src/components/manage/Controlpanels/DatabaseInformation.jsx +9 -0
  217. package/src/components/manage/Controlpanels/Groups/GroupsControlpanel.test.jsx +7 -4
  218. package/src/components/manage/Controlpanels/ModerateComments.jsx +8 -0
  219. package/src/components/manage/Controlpanels/ModerateComments.test.jsx +7 -4
  220. package/src/components/manage/Controlpanels/Relations/Relations.jsx +1 -1
  221. package/src/components/manage/Controlpanels/Rules/AddRule.test.jsx +8 -9
  222. package/src/components/manage/Controlpanels/Rules/ConfigureRule.test.jsx +9 -6
  223. package/src/components/manage/Controlpanels/Rules/EditRule.test.jsx +8 -9
  224. package/src/components/manage/Controlpanels/Rules/Rules.test.jsx +7 -4
  225. package/src/components/manage/Controlpanels/UndoControlpanel.test.jsx +8 -9
  226. package/src/components/manage/Controlpanels/Users/UserGroupMembershipControlPanel.test.jsx +10 -4
  227. package/src/components/manage/Controlpanels/Users/UsersControlpanel.jsx +628 -631
  228. package/src/components/manage/Controlpanels/Users/UsersControlpanel.ssr.test.jsx +624 -0
  229. package/src/components/manage/Controlpanels/Users/UsersControlpanel.test.jsx +70 -10
  230. package/src/components/manage/Controlpanels/VersionOverview.jsx +19 -6
  231. package/src/components/manage/Delete/Delete.test.jsx +13 -8
  232. package/src/components/manage/Diff/Diff.jsx +201 -298
  233. package/src/components/manage/Diff/Diff.test.jsx +8 -10
  234. package/src/components/manage/Diff/DiffField.test.jsx +1 -6
  235. package/src/components/manage/Display/Display.test.jsx +2 -11
  236. package/src/components/manage/Edit/Edit.test.jsx +12 -11
  237. package/src/components/manage/Form/BlockDataForm.test.jsx +1 -5
  238. package/src/components/manage/Form/Field.jsx +1 -69
  239. package/src/components/manage/Form/Form.jsx +17 -4
  240. package/src/components/manage/Form/Form.test.jsx +130 -5
  241. package/src/components/manage/Form/InlineForm.test.jsx +1 -5
  242. package/src/components/manage/Form/ModalForm.jsx +175 -97
  243. package/src/components/manage/Form/ModalForm.test.jsx +27 -5
  244. package/src/components/manage/Form/__mocks__/index.tsx +9 -27
  245. package/src/components/manage/History/History.jsx +209 -300
  246. package/src/components/manage/History/History.test.jsx +20 -9
  247. package/src/components/manage/LinksToItem/LinksToItem.test.jsx +7 -4
  248. package/src/components/manage/Multilingual/CompareLanguages.jsx +6 -6
  249. package/src/components/manage/Multilingual/CreateTranslation.jsx +16 -13
  250. package/src/components/manage/Multilingual/ManageTranslations.jsx +5 -5
  251. package/src/components/manage/Multilingual/ManageTranslations.test.jsx +15 -12
  252. package/src/components/manage/Multilingual/TranslationObject.jsx +11 -8
  253. package/src/components/manage/Preferences/ChangePassword.test.jsx +8 -9
  254. package/src/components/manage/Preferences/PersonalPreferences.jsx +8 -5
  255. package/src/components/manage/Preferences/PersonalPreferences.test.jsx +10 -23
  256. package/src/components/manage/Rules/Rules.test.jsx +5 -2
  257. package/src/components/manage/Sharing/Sharing.jsx +21 -15
  258. package/src/components/manage/Sharing/Sharing.test.jsx +9 -6
  259. package/src/components/manage/Sidebar/ObjectBrowser.jsx +10 -0
  260. package/src/components/manage/Sidebar/ObjectBrowserBody.jsx +25 -5
  261. package/src/components/manage/Sidebar/ObjectBrowserBody.test.jsx +52 -0
  262. package/src/components/manage/Sidebar/Sidebar.jsx +2 -0
  263. package/src/components/manage/Sidebar/Sidebar.test.jsx +4 -1
  264. package/src/components/manage/Sidebar/SidebarPortal.test.tsx +42 -0
  265. package/src/components/manage/Sidebar/SidebarPortal.tsx +48 -0
  266. package/src/components/manage/TemplateChooser/TemplateChooser.test.jsx +1 -0
  267. package/src/components/manage/Toast/Toast.jsx +32 -0
  268. package/src/components/manage/Toast/Toast.test.jsx +9 -5
  269. package/src/components/manage/Toolbar/PersonalTools.test.jsx +15 -0
  270. package/src/components/manage/Toolbar/Toolbar.jsx +109 -12
  271. package/src/components/manage/Toolbar/Toolbar.test.jsx +15 -10
  272. package/src/components/manage/Toolbar/Types.crash.test.jsx +48 -0
  273. package/src/components/manage/Toolbar/Types.jsx +6 -4
  274. package/src/components/manage/UniversalLink/UniversalLink.test.jsx +16 -0
  275. package/src/components/manage/UniversalLink/UniversalLink.tsx +1 -0
  276. package/src/components/manage/Widgets/AlignWidget.stories.jsx +9 -0
  277. package/src/components/manage/Widgets/AlignWidget.test.tsx +95 -0
  278. package/src/components/manage/Widgets/{AlignWidget.jsx → AlignWidget.tsx} +23 -7
  279. package/src/components/manage/Widgets/ArrayWidget.jsx +111 -88
  280. package/src/components/manage/Widgets/ArrayWidget.test.jsx +1 -12
  281. package/src/components/manage/Widgets/BlockAlignment.stories.tsx +104 -0
  282. package/src/components/manage/Widgets/BlockAlignment.test.tsx +104 -0
  283. package/src/components/manage/Widgets/BlockAlignment.tsx +88 -0
  284. package/src/components/manage/Widgets/BlockWidth.stories.tsx +69 -0
  285. package/src/components/manage/Widgets/BlockWidth.test.tsx +62 -0
  286. package/src/components/manage/Widgets/BlockWidth.tsx +101 -0
  287. package/src/components/manage/Widgets/ButtonsWidget.stories.jsx +61 -0
  288. package/src/components/manage/Widgets/ButtonsWidget.test.tsx +138 -0
  289. package/src/components/manage/Widgets/ButtonsWidget.tsx +195 -0
  290. package/src/components/manage/Widgets/CheckboxGroupWidget.test.jsx +1 -6
  291. package/src/components/manage/Widgets/DatetimeWidget.jsx +98 -54
  292. package/src/components/manage/Widgets/DatetimeWidget.test.jsx +56 -6
  293. package/src/components/manage/Widgets/FileWidget.jsx +7 -0
  294. package/src/components/manage/Widgets/FormFieldWrapper.jsx +143 -163
  295. package/src/components/manage/Widgets/ImageWidget.jsx +18 -5
  296. package/src/components/manage/Widgets/ObjectBrowserWidget.jsx +6 -0
  297. package/src/components/manage/Widgets/ObjectListWidget.test.jsx +2 -11
  298. package/src/components/manage/Widgets/ObjectWidget.test.jsx +1 -5
  299. package/src/components/manage/Widgets/QueryWidget.jsx +137 -9
  300. package/src/components/manage/Widgets/QuerystringWidget.test.jsx +3 -1
  301. package/src/components/manage/Widgets/RadioGroupWidget.test.jsx +1 -6
  302. package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.test.jsx +1 -6
  303. package/src/components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthIndexField.jsx +56 -50
  304. package/src/components/manage/Widgets/RegistryImageWidget.jsx +1 -1
  305. package/src/components/manage/Widgets/RegistryImageWidget.test.jsx +1 -0
  306. package/src/components/manage/Widgets/SchemaWidget.test.jsx +1 -6
  307. package/src/components/manage/Widgets/SchemaWidgetFieldset.test.jsx +1 -6
  308. package/src/components/manage/Widgets/SelectAutoComplete.test.jsx +1 -6
  309. package/src/components/manage/Widgets/SelectStyling.jsx +52 -20
  310. package/src/components/manage/Widgets/SelectWidget.test.jsx +1 -6
  311. package/src/components/manage/Widgets/Size.stories.tsx +69 -0
  312. package/src/components/manage/Widgets/Size.test.tsx +59 -0
  313. package/src/components/manage/Widgets/Size.tsx +78 -0
  314. package/src/components/manage/Widgets/TextWidget.jsx +4 -0
  315. package/src/components/manage/Widgets/TimeWidget.test.jsx +1 -6
  316. package/src/components/manage/Widgets/TokenWidget.jsx +142 -186
  317. package/src/components/manage/Widgets/TokenWidget.test.jsx +1 -6
  318. package/src/components/manage/Widgets/UrlWidget.jsx +47 -18
  319. package/src/components/manage/Widgets/VocabularyTermsWidget.test.jsx +2 -11
  320. package/src/components/manage/Widgets/__mocks__/index.tsx +33 -51
  321. package/src/components/manage/Widgets/index.tsx +21 -0
  322. package/src/components/manage/Workflow/Workflow.test.jsx +2 -11
  323. package/src/components/theme/AlternateHrefLangs/AlternateHrefLangs.jsx +1 -0
  324. package/src/components/theme/AlternateHrefLangs/AlternateHrefLangs.test.jsx +30 -0
  325. package/src/components/theme/App/App.jsx +5 -1
  326. package/src/components/theme/App/App.test.jsx +13 -10
  327. package/src/components/theme/Comments/CommentEditModal.test.jsx +1 -5
  328. package/src/components/theme/Comments/Comments.test.jsx +2 -11
  329. package/src/components/theme/ConnectionRefused/ConnectionRefused.jsx +3 -2
  330. package/src/components/theme/ContactForm/ContactForm.test.jsx +14 -13
  331. package/src/components/theme/Image/Image.jsx +14 -5
  332. package/src/components/theme/Image/Image.test.jsx +247 -146
  333. package/src/components/theme/InjectPloneComponentsCSS/InjectPloneComponentsCSS.tsx +7 -0
  334. package/src/components/theme/LanguageSelector/LanguageSelector.tsx +3 -3
  335. package/src/components/theme/MultilingualRedirector/MultilingualRedirector.jsx +42 -12
  336. package/src/components/theme/MultilingualRedirector/MultilingualRedirector.test.jsx +6 -3
  337. package/src/components/theme/PasswordReset/PasswordReset.jsx +108 -191
  338. package/src/components/theme/PasswordReset/RequestPasswordReset.test.jsx +1 -5
  339. package/src/components/theme/Register/Register.test.jsx +1 -5
  340. package/src/components/theme/Search/Search.jsx +230 -327
  341. package/src/components/theme/Search/Search.test.jsx +14 -14
  342. package/src/components/theme/Sitemap/Sitemap.jsx +22 -30
  343. package/src/components/theme/Sitemap/Sitemap.stories.jsx +82 -0
  344. package/src/components/theme/Sitemap/Sitemap.test.jsx +18 -0
  345. package/src/components/theme/SlotRenderer/SlotRenderer.tsx +12 -6
  346. package/src/components/theme/Unauthorized/Unauthorized.jsx +27 -24
  347. package/src/components/theme/Unauthorized/Unauthorized.test.jsx +31 -2
  348. package/src/components/theme/VideoEmbed/VideoEmbed.jsx +100 -0
  349. package/src/components/theme/View/EventDatesInfo.test.jsx +1 -6
  350. package/src/components/theme/View/EventView.stories.jsx +89 -0
  351. package/src/components/theme/View/EventView.test.jsx +1 -6
  352. package/src/components/theme/View/FileView.stories.jsx +50 -0
  353. package/src/components/theme/View/ImageView.jsx +2 -1
  354. package/src/components/theme/View/ImageView.test.jsx +3 -0
  355. package/src/components/theme/View/LinkView.stories.jsx +57 -0
  356. package/src/components/theme/View/ListingView.stories.jsx +70 -0
  357. package/src/components/theme/View/NewsItemView.stories.jsx +58 -0
  358. package/src/components/theme/View/RenderBlocks.jsx +8 -10
  359. package/src/components/theme/View/RenderBlocks.stories.jsx +112 -0
  360. package/src/components/theme/View/RenderBlocks.test.jsx +14 -4
  361. package/src/components/theme/View/SummaryView.stories.jsx +71 -0
  362. package/src/components/theme/View/TabularView.stories.jsx +66 -0
  363. package/src/components/theme/View/View.jsx +8 -1
  364. package/src/components/theme/View/View.test.jsx +37 -24
  365. package/src/components/theme/Widgets/DateWidget.jsx +4 -5
  366. package/src/components/theme/Widgets/DatetimeWidget.jsx +4 -5
  367. package/src/components/theme/Widgets/ImageWidget.test.jsx +31 -11
  368. package/src/components/theme/Widgets/RichTextWidget.jsx +1 -1
  369. package/src/config/Blocks.jsx +3 -0
  370. package/src/config/ControlPanels.js +2 -0
  371. package/src/config/Loadables.jsx +1 -5
  372. package/src/config/Widgets.jsx +7 -0
  373. package/src/config/index.js +10 -1
  374. package/src/config/slots.js +19 -0
  375. package/src/config/validation.ts +8 -0
  376. package/src/constants/ActionTypes.js +1 -0
  377. package/src/express-middleware/devproxy.js +3 -1
  378. package/src/express-middleware/files.js +1 -0
  379. package/src/express-middleware/files.test.js +59 -0
  380. package/src/express-middleware/images.js +1 -0
  381. package/src/express-middleware/images.test.js +50 -0
  382. package/src/helpers/Api/Api.js +2 -2
  383. package/src/helpers/AuthToken/AuthToken.js +1 -6
  384. package/src/helpers/Blocks/Blocks.js +113 -28
  385. package/src/helpers/Blocks/Blocks.test.js +100 -0
  386. package/src/helpers/Content/Content.js +23 -0
  387. package/src/helpers/Content/Content.test.js +39 -0
  388. package/src/helpers/Extensions/withBlockSchemaEnhancer.jsx +4 -1
  389. package/src/helpers/FormValidation/FormValidation.test.js +31 -0
  390. package/src/helpers/FormValidation/validators.ts +52 -6
  391. package/src/helpers/I18n/I18n.test.ts +44 -0
  392. package/src/helpers/I18n/I18n.ts +31 -0
  393. package/src/helpers/Loadable/__mocks__/Loadable.jsx +7 -22
  394. package/src/helpers/MessageLabels/MessageLabels.js +5 -0
  395. package/src/helpers/Robots/Robots.js +1 -1
  396. package/src/helpers/Robots/Robots.test.js +34 -0
  397. package/src/helpers/Url/Url.js +1 -0
  398. package/src/helpers/Utils/Date.js +26 -1
  399. package/src/helpers/Utils/Date.test.js +237 -0
  400. package/src/helpers/Utils/Utils.jsx +17 -0
  401. package/src/helpers/Utils/Utils.test.jsx +39 -0
  402. package/src/helpers/Utils/withSaveAsDraft.jsx +33 -9
  403. package/src/helpers/index.js +1 -0
  404. package/src/hooks/user/useUser.js +1 -1
  405. package/src/internalChecks.test.ts +11 -0
  406. package/src/middleware/api.js +14 -5
  407. package/src/reducers/blockTypes/blockTypes.js +38 -0
  408. package/src/reducers/content/content.js +3 -18
  409. package/src/reducers/diff/diff.js +5 -1
  410. package/src/reducers/diff/diff.test.js +60 -4
  411. package/src/reducers/index.js +2 -0
  412. package/src/reducers/querystring/querystring.js +8 -1
  413. package/src/reducers/users/users.js +1 -1
  414. package/src/routes.js +10 -0
  415. package/src/server.jsx +14 -6
  416. package/src/start-client.jsx +21 -3
  417. package/test-addons-loader.js +3 -0
  418. package/test-setup-globals.js +56 -2
  419. package/theme/themes/default/elements/segment.variables +9 -16
  420. package/theme/themes/default/globals/site.variables +3 -3
  421. package/theme/themes/pastanaga/collections/form.overrides +22 -1
  422. package/theme/themes/pastanaga/elements/button.overrides +30 -3
  423. package/theme/themes/pastanaga/elements/segment.variables +1 -4
  424. package/theme/themes/pastanaga/extras/block-types.less +17 -0
  425. package/theme/themes/pastanaga/extras/contents.less +63 -4
  426. package/theme/themes/pastanaga/extras/main.less +16 -4
  427. package/theme/themes/pastanaga/extras/toolbar.less +10 -5
  428. package/theme/themes/pastanaga/extras/videoembed.less +22 -0
  429. package/theme/themes/pastanaga/extras/widgets.less +79 -0
  430. package/theme/themes/pastanaga/globals/site.variables +0 -3
  431. package/tsconfig.declarations.json +1 -1
  432. package/tsconfig.json +1 -1
  433. package/types/actions/blockTypes/blockTypes.d.ts +7 -0
  434. package/types/components/index.d.ts +1 -1
  435. package/types/components/manage/Blocks/Block/Order/Item.test.d.ts +1 -0
  436. package/types/components/manage/Blocks/Block/Order/utilities.d.ts +2 -1
  437. package/types/components/manage/Blocks/Grid/context.d.ts +1 -0
  438. package/types/components/manage/Blocks/Maps/Body.d.ts +9 -0
  439. package/types/components/manage/Blocks/Maps/View.d.ts +1 -1
  440. package/types/components/manage/Blocks/Teaser/utils.d.ts +5 -0
  441. package/types/components/manage/Blocks/Video/Body.d.ts +4 -2
  442. package/types/components/manage/Blocks/Video/schema.d.ts +4 -0
  443. package/types/components/manage/Contents/Contents.d.ts +1 -1
  444. package/types/components/manage/Contents/ContentsIndexHeader.d.ts +6 -11
  445. package/types/components/manage/Contents/ContentsItem.d.ts +3 -10
  446. package/types/components/manage/Contents/DropZoneContent.d.ts +2 -0
  447. package/types/components/manage/Contents/__mocks__/index.d.ts +2 -2
  448. package/types/components/manage/Controlpanels/BlockType.d.ts +7 -0
  449. package/types/components/manage/Controlpanels/BlockTypes.d.ts +7 -0
  450. package/types/components/manage/Controlpanels/ContentType.d.ts +2 -2
  451. package/types/components/manage/Controlpanels/Controlpanel.d.ts +2 -5
  452. package/types/components/manage/Controlpanels/Relations/RelationsMatrix.d.ts +1 -1
  453. package/types/components/manage/Controlpanels/Users/UsersControlpanel.ssr.test.d.ts +1 -0
  454. package/types/components/manage/Controlpanels/VersionOverview.d.ts +2 -1
  455. package/types/components/manage/Controlpanels/index.d.ts +3 -2
  456. package/types/components/manage/Diff/Diff.d.ts +7 -2
  457. package/types/components/manage/Form/__mocks__/index.d.ts +8 -8
  458. package/types/components/manage/Multilingual/ManageTranslations.d.ts +1 -1
  459. package/types/components/manage/Sidebar/ObjectBrowser.d.ts +1 -1
  460. package/types/components/manage/Sidebar/ObjectBrowserBody.test.d.ts +1 -0
  461. package/types/components/manage/Sidebar/SidebarPortal.d.ts +7 -15
  462. package/types/components/manage/Toolbar/Types.crash.test.d.ts +1 -0
  463. package/types/components/manage/Widgets/AlignWidget.d.ts +8 -10
  464. package/types/components/manage/Widgets/AlignWidget.stories.d.ts +1 -0
  465. package/types/components/manage/Widgets/BlockAlignment.d.ts +7 -0
  466. package/types/components/manage/Widgets/BlockAlignment.stories.d.ts +8 -0
  467. package/types/components/manage/Widgets/BlockWidth.d.ts +7 -0
  468. package/types/components/manage/Widgets/BlockWidth.stories.d.ts +6 -0
  469. package/types/components/manage/Widgets/ButtonsWidget.d.ts +48 -1
  470. package/types/components/manage/Widgets/ButtonsWidget.stories.d.ts +3 -0
  471. package/types/components/manage/Widgets/FormFieldWrapper.d.ts +28 -5
  472. package/types/components/manage/Widgets/ImageWidget.d.ts +1 -1
  473. package/types/components/manage/Widgets/InternalUrlWidget.d.ts +1 -1
  474. package/types/components/manage/Widgets/ObjectBrowserWidget.d.ts +2 -0
  475. package/types/components/manage/Widgets/QueryWidget.d.ts +5 -2
  476. package/types/components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthIndexField.d.ts +22 -5
  477. package/types/components/manage/Widgets/SelectStyling.d.ts +1 -0
  478. package/types/components/manage/Widgets/Size.d.ts +7 -0
  479. package/types/components/manage/Widgets/Size.stories.d.ts +6 -0
  480. package/types/components/manage/Widgets/UrlWidget.d.ts +1 -1
  481. package/types/components/manage/Widgets/__mocks__/index.d.ts +33 -33
  482. package/types/components/manage/Widgets/index.d.ts +11 -6
  483. package/types/components/theme/ConnectionRefused/ConnectionRefused.d.ts +2 -2
  484. package/types/components/theme/InjectPloneComponentsCSS/InjectPloneComponentsCSS.d.ts +3 -0
  485. package/types/components/theme/PasswordReset/PasswordReset.d.ts +6 -2
  486. package/types/components/theme/Search/Search.d.ts +1 -1
  487. package/types/components/theme/Sitemap/Sitemap.stories.d.ts +13 -0
  488. package/types/components/theme/SlotRenderer/SlotRenderer.d.ts +4 -5
  489. package/types/components/theme/Unauthorized/Unauthorized.d.ts +2 -2
  490. package/types/components/theme/VideoEmbed/VideoEmbed.d.ts +2 -0
  491. package/types/components/theme/View/EventView.stories.d.ts +19 -0
  492. package/types/components/theme/View/FileView.stories.d.ts +18 -0
  493. package/types/components/theme/View/LinkView.stories.d.ts +18 -0
  494. package/types/components/theme/View/ListingView.stories.d.ts +24 -0
  495. package/types/components/theme/View/NewsItemView.stories.d.ts +23 -0
  496. package/types/components/theme/View/RenderBlocks.stories.d.ts +23 -0
  497. package/types/components/theme/View/SummaryView.stories.d.ts +23 -0
  498. package/types/components/theme/View/TabularView.stories.d.ts +23 -0
  499. package/types/config/ControlPanels.d.ts +1 -0
  500. package/types/config/Views.d.ts +1 -1
  501. package/types/config/Widgets.d.ts +6 -0
  502. package/types/config/slots.d.ts +7 -0
  503. package/types/constants/ActionTypes.d.ts +1 -0
  504. package/types/helpers/Blocks/Blocks.d.ts +4 -0
  505. package/types/helpers/Content/Content.d.ts +7 -0
  506. package/types/helpers/Extensions/withBlockSchemaEnhancer.d.ts +4 -5
  507. package/types/helpers/FormValidation/validators.d.ts +18 -1
  508. package/types/helpers/I18n/I18n.d.ts +20 -0
  509. package/types/helpers/Loadable/__mocks__/Loadable.d.ts +2 -2
  510. package/types/helpers/MessageLabels/MessageLabels.d.ts +100 -94
  511. package/types/helpers/Utils/Utils.d.ts +1 -0
  512. package/types/helpers/index.d.ts +1 -0
  513. package/types/reducers/blockTypes/blockTypes.d.ts +16 -0
  514. package/types/reducers/index.d.ts +2 -0
  515. package/types/routes.d.ts +7 -5
  516. package/vitest.config.mjs +84 -42
  517. package/webpack-plugins/webpack-less-plugin.js +1 -1
  518. package/webpack-plugins/webpack-scss-plugin.js +172 -0
  519. package/jest-addons-loader.js +0 -3
  520. package/jest-extender-plugin.js +0 -39
  521. package/jest-setup-afterenv.js +0 -2
  522. package/jest-svgsystem-transform.js +0 -10
  523. package/patches/patchit.sh +0 -2
  524. package/patches/razzle-jest.patch +0 -10
  525. package/src/components/manage/Contents/__mocks__/index.vitest.tsx +0 -5
  526. package/src/components/manage/Form/__mocks__/index.vitest.tsx +0 -73
  527. package/src/components/manage/Sidebar/SidebarPortal.jsx +0 -47
  528. package/src/components/manage/Sidebar/SidebarPortal.test.jsx +0 -26
  529. package/src/components/manage/Widgets/AlignWidget.test.jsx +0 -59
  530. package/src/components/manage/Widgets/ButtonsWidget.jsx +0 -41
  531. package/src/components/manage/Widgets/ButtonsWidget.test.jsx +0 -70
  532. package/src/components/manage/Widgets/__mocks__/index.vitest.tsx +0 -41
  533. package/src/helpers/Loadable/__mocks__/Loadable.vitest.jsx +0 -39
  534. package/test-setup-globals-vitest.js +0 -46
  535. package/theme/themes/pastanaga/extras/utils.less +0 -63
@@ -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}
@@ -3,6 +3,7 @@ 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
+ import { CookiesProvider } from 'react-cookie';
6
7
  import config from '@plone/volto/registry';
7
8
 
8
9
  import ManageTranslations from './ManageTranslations';
@@ -41,18 +42,20 @@ describe('ManageTranslations', () => {
41
42
  });
42
43
  const { container } = render(
43
44
  <Provider store={store}>
44
- <MemoryRouter>
45
- <ManageTranslations
46
- location={{
47
- pathname: '/blog-post',
48
- state: {
49
- language: 'es',
50
- translationOf: '/en/page-en',
51
- },
52
- }}
53
- />
54
- <div id="toolbar"></div>
55
- </MemoryRouter>
45
+ <CookiesProvider>
46
+ <MemoryRouter>
47
+ <ManageTranslations
48
+ location={{
49
+ pathname: '/blog-post',
50
+ state: {
51
+ language: 'es',
52
+ translationOf: '/en/page-en',
53
+ },
54
+ }}
55
+ />
56
+ <div id="toolbar"></div>
57
+ </MemoryRouter>
58
+ </CookiesProvider>
56
59
  </Provider>,
57
60
  );
58
61
 
@@ -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}
@@ -4,16 +4,13 @@ import { Provider } from 'react-intl-redux';
4
4
  import configureStore from 'redux-mock-store';
5
5
  import jwt from 'jsonwebtoken';
6
6
  import { MemoryRouter } from 'react-router-dom';
7
+ import { CookiesProvider } from 'react-cookie';
7
8
 
8
9
  import ChangePassword from './ChangePassword';
9
10
 
10
11
  const mockStore = configureStore();
11
12
 
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
+ vi.mock('@plone/volto/components/manage/Form');
17
14
 
18
15
  vi.mock('../Toolbar/Toolbar', () => ({
19
16
  default: vi.fn(() => <div id="Portal" />),
@@ -44,10 +41,12 @@ describe('ChangePassword', () => {
44
41
  });
45
42
  const { container } = render(
46
43
  <Provider store={store}>
47
- <MemoryRouter>
48
- <ChangePassword location={{ pathname: '/blog' }} />
49
- <div id="toolbar"></div>
50
- </MemoryRouter>
44
+ <CookiesProvider>
45
+ <MemoryRouter>
46
+ <ChangePassword location={{ pathname: '/blog' }} />
47
+ <div id="toolbar"></div>
48
+ </MemoryRouter>
49
+ </CookiesProvider>
51
50
  </Provider>,
52
51
  );
53
52
 
@@ -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();
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import { Provider } from 'react-intl-redux';
3
3
  import configureStore from 'redux-mock-store';
4
4
  import { MemoryRouter } from 'react-router-dom';
5
+ import { CookiesProvider } from 'react-cookie';
5
6
  import { render } from '@testing-library/react';
6
7
 
7
8
  import PersonalPreferences from './PersonalPreferences';
@@ -12,23 +13,7 @@ vi.mock('../Toolbar/Toolbar', () => ({
12
13
  default: vi.fn(() => <div id="Portal" />),
13
14
  }));
14
15
 
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
- });
16
+ vi.mock('@plone/volto/components/manage/Form');
32
17
 
33
18
  describe('PersonalPreferences', () => {
34
19
  it('renders a personal preferences component', () => {
@@ -53,12 +38,14 @@ describe('PersonalPreferences', () => {
53
38
  });
54
39
  const { container } = render(
55
40
  <Provider store={store}>
56
- <MemoryRouter>
57
- <PersonalPreferences
58
- location={{ pathname: '/blog' }}
59
- closeMenu={() => {}}
60
- />
61
- </MemoryRouter>
41
+ <CookiesProvider>
42
+ <MemoryRouter>
43
+ <PersonalPreferences
44
+ location={{ pathname: '/blog' }}
45
+ closeMenu={() => {}}
46
+ />
47
+ </MemoryRouter>
48
+ </CookiesProvider>
62
49
  </Provider>,
63
50
  );
64
51
  expect(container).toMatchSnapshot();
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { render } from '@testing-library/react';
3
3
  import { Provider } from 'react-intl-redux';
4
+ import { CookiesProvider } from 'react-cookie';
4
5
  import configureMockStore from 'redux-mock-store';
5
6
  import thunk from 'redux-thunk';
6
7
 
@@ -69,8 +70,10 @@ describe('Rules', () => {
69
70
  });
70
71
  const { container } = render(
71
72
  <Provider store={store}>
72
- <Rules location={{ pathname: '/blog/rules' }} />
73
- <div id="toolbar"></div>
73
+ <CookiesProvider>
74
+ <Rules location={{ pathname: '/blog/rules' }} />
75
+ <div id="toolbar"></div>
76
+ </CookiesProvider>
74
77
  </Provider>,
75
78
  );
76
79
 
@@ -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>
@@ -4,6 +4,7 @@ import configureStore from 'redux-mock-store';
4
4
  import { Provider } from 'react-intl-redux';
5
5
  import jwt from 'jsonwebtoken';
6
6
  import { MemoryRouter } from 'react-router-dom';
7
+ import { CookiesProvider } from 'react-cookie';
7
8
  import { PluggablesProvider } from '@plone/volto/components/manage/Pluggable';
8
9
 
9
10
  import Sharing from './Sharing';
@@ -60,12 +61,14 @@ describe('Sharing', () => {
60
61
 
61
62
  const { container } = render(
62
63
  <Provider store={store}>
63
- <PluggablesProvider>
64
- <MemoryRouter>
65
- <Sharing location={{ pathname: '/blog' }} />
66
- <div id="toolbar"></div>
67
- </MemoryRouter>
68
- </PluggablesProvider>
64
+ <CookiesProvider>
65
+ <PluggablesProvider>
66
+ <MemoryRouter>
67
+ <Sharing location={{ pathname: '/blog' }} />
68
+ <div id="toolbar"></div>
69
+ </MemoryRouter>
70
+ </PluggablesProvider>
71
+ </CookiesProvider>
69
72
  </Provider>,
70
73
  );
71
74
 
@@ -58,6 +58,8 @@ const withObjectBrowser = (WrappedComponent) =>
58
58
  selectableTypes,
59
59
  maximumSelectionSize,
60
60
  currentPath,
61
+ initialPath,
62
+ onlyFolderishSelectable,
61
63
  } = {}) =>
62
64
  this.setState(() => ({
63
65
  isObjectBrowserOpen: true,
@@ -70,6 +72,8 @@ const withObjectBrowser = (WrappedComponent) =>
70
72
  selectableTypes,
71
73
  maximumSelectionSize,
72
74
  currentPath,
75
+ initialPath,
76
+ onlyFolderishSelectable,
73
77
  }));
74
78
 
75
79
  closeObjectBrowser = () => this.setState({ isObjectBrowserOpen: false });
@@ -80,6 +84,10 @@ const withObjectBrowser = (WrappedComponent) =>
80
84
  this.props.pathname ||
81
85
  this.props.location?.pathname;
82
86
 
87
+ let initialPath = this.state?.initialPath
88
+ ? getBaseUrl(this.state.initialPath)
89
+ : null;
90
+
83
91
  return (
84
92
  <>
85
93
  <WrappedComponent
@@ -103,6 +111,7 @@ const withObjectBrowser = (WrappedComponent) =>
103
111
  : this.props.data
104
112
  }
105
113
  contextURL={getBaseUrl(contextURL)}
114
+ initialPath={initialPath}
106
115
  closeObjectBrowser={this.closeObjectBrowser}
107
116
  mode={this.state.mode}
108
117
  onSelectItem={this.state.onSelectItem}
@@ -110,6 +119,7 @@ const withObjectBrowser = (WrappedComponent) =>
110
119
  searchableTypes={this.state.searchableTypes}
111
120
  selectableTypes={this.state.selectableTypes}
112
121
  maximumSelectionSize={this.state.maximumSelectionSize}
122
+ onlyFolderishSelectable={this.state.onlyFolderishSelectable}
113
123
  />
114
124
  </SidebarPopup>
115
125
  </>
@@ -84,8 +84,10 @@ class ObjectBrowserBody extends Component {
84
84
  onSelectItem: PropTypes.func,
85
85
  dataName: PropTypes.string,
86
86
  maximumSelectionSize: PropTypes.number,
87
+ initialPath: PropTypes.string,
87
88
  contextURL: PropTypes.string,
88
89
  searchableTypes: PropTypes.arrayOf(PropTypes.string),
90
+ onlyFolderishSelectable: PropTypes.bool,
89
91
  };
90
92
 
91
93
  /**
@@ -101,6 +103,7 @@ class ObjectBrowserBody extends Component {
101
103
  selectableTypes: [],
102
104
  searchableTypes: null,
103
105
  maximumSelectionSize: null,
106
+ onlyFolderishSelectable: false,
104
107
  };
105
108
 
106
109
  /**
@@ -111,18 +114,21 @@ class ObjectBrowserBody extends Component {
111
114
  */
112
115
  constructor(props) {
113
116
  super(props);
117
+ const defaultMultiplePath = props.initialPath || '/';
114
118
  this.state = {
115
119
  currentFolder:
116
- this.props.mode === 'multiple' ? '/' : this.props.contextURL || '/',
120
+ this.props.mode === 'multiple'
121
+ ? defaultMultiplePath
122
+ : this.props.contextURL || '/',
117
123
  currentImageFolder:
118
124
  this.props.mode === 'multiple'
119
- ? '/'
125
+ ? defaultMultiplePath
120
126
  : this.props.mode === 'image' && this.props.data?.url
121
127
  ? getParentURL(this.props.data.url)
122
128
  : '/',
123
129
  currentLinkFolder:
124
130
  this.props.mode === 'multiple'
125
- ? '/'
131
+ ? defaultMultiplePath
126
132
  : this.props.mode === 'link' && this.props.data?.href
127
133
  ? getParentURL(this.props.data.href)
128
134
  : '/',
@@ -142,10 +148,14 @@ class ObjectBrowserBody extends Component {
142
148
  showSearchInput: false,
143
149
  // In image mode, the searchable types default to the image types which
144
150
  // can be overridden with the property if specified.
151
+ // If selectableTypes are passed, the searchableTypes are the selectableTypes
145
152
  searchableTypes:
146
153
  this.props.mode === 'image'
147
154
  ? this.props.searchableTypes || config.settings.imageObjects
148
- : this.props.searchableTypes,
155
+ : [
156
+ ...(this.props.searchableTypes ?? []),
157
+ ...(this.props.selectableTypes ?? []),
158
+ ],
149
159
  view: this.props.mode === 'image' ? 'icons' : 'list',
150
160
  };
151
161
  this.searchInputRef = React.createRef();
@@ -329,7 +339,17 @@ class ObjectBrowserBody extends Component {
329
339
  };
330
340
 
331
341
  isSelectable = (item) => {
332
- const { maximumSelectionSize, data, mode, selectableTypes } = this.props;
342
+ const {
343
+ maximumSelectionSize,
344
+ data,
345
+ mode,
346
+ selectableTypes,
347
+ onlyFolderishSelectable,
348
+ } = this.props;
349
+
350
+ if (onlyFolderishSelectable && !item.is_folderish) {
351
+ return false;
352
+ }
333
353
  if (
334
354
  maximumSelectionSize &&
335
355
  data &&
@@ -0,0 +1,52 @@
1
+ import React from 'react';
2
+ import { render } from '@testing-library/react';
3
+ import configureStore from 'redux-mock-store';
4
+ import { Provider } from 'react-intl-redux';
5
+ import ObjectBrowserBody from './ObjectBrowserBody';
6
+
7
+ const mockStore = configureStore();
8
+
9
+ const baseState = {
10
+ search: { subrequests: {} },
11
+ intl: { locale: 'en', messages: {} },
12
+ };
13
+
14
+ const baseProps = {
15
+ block: 'test-block',
16
+ data: {},
17
+ closeObjectBrowser: () => {},
18
+ onChangeBlock: () => {},
19
+ };
20
+
21
+ const getInitialSearchPath = (actions) => {
22
+ const action = actions.find((a) => a.type === 'SEARCH_CONTENT');
23
+ return action?.request?.path?.split('/@search')[0];
24
+ };
25
+
26
+ describe('ObjectBrowserBody', () => {
27
+ it('uses initialPath as the default folder when mode=multiple', () => {
28
+ const store = mockStore(baseState);
29
+ render(
30
+ <Provider store={store}>
31
+ <ObjectBrowserBody
32
+ {...baseProps}
33
+ mode="multiple"
34
+ initialPath="/company/team"
35
+ />
36
+ </Provider>,
37
+ );
38
+
39
+ expect(getInitialSearchPath(store.getActions())).toBe('/company/team');
40
+ });
41
+
42
+ it('defaults to root when mode=multiple and initialPath is not provided', () => {
43
+ const store = mockStore(baseState);
44
+ render(
45
+ <Provider store={store}>
46
+ <ObjectBrowserBody {...baseProps} mode="multiple" />
47
+ </Provider>,
48
+ );
49
+
50
+ expect(getInitialSearchPath(store.getActions())).toBe('/');
51
+ });
52
+ });
@@ -155,6 +155,7 @@ const Sidebar = (props) => {
155
155
  key: 'documentTab',
156
156
  as: 'button',
157
157
  className: 'ui button',
158
+ type: 'button',
158
159
  content: type || intl.formatMessage(messages.document),
159
160
  },
160
161
  pane: (
@@ -170,6 +171,7 @@ const Sidebar = (props) => {
170
171
  key: 'blockTab',
171
172
  as: 'button',
172
173
  className: 'ui button',
174
+ type: 'button',
173
175
  content: intl.formatMessage(messages.block),
174
176
  },
175
177
  pane: (
@@ -2,6 +2,7 @@ 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
+ import { CookiesProvider } from 'react-cookie';
5
6
 
6
7
  import Sidebar from './Sidebar';
7
8
 
@@ -22,7 +23,9 @@ test('renders a sidebar component', () => {
22
23
  });
23
24
  const component = renderer.create(
24
25
  <Provider store={store}>
25
- <Sidebar />
26
+ <CookiesProvider>
27
+ <Sidebar />
28
+ </CookiesProvider>
26
29
  </Provider>,
27
30
  );
28
31
  const json = component.toJSON();