@plone/volto 19.0.0-alpha.8 → 19.0.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 (540) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc +26 -15
  3. package/AGENTS.md +47 -0
  4. package/CHANGELOG.md +536 -9
  5. package/README.md +22 -19
  6. package/babel.js +1 -9
  7. package/cypress/docker/prefixed-rules.yml +26 -0
  8. package/cypress/docker/prefixed.yml +24 -0
  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 +5516 -0
  13. package/locales/af.json +1 -1
  14. package/locales/ar/LC_MESSAGES/volto.po +5516 -0
  15. package/locales/ar.json +1 -1
  16. package/locales/bg/LC_MESSAGES/volto.po +5516 -0
  17. package/locales/bg.json +1 -1
  18. package/locales/bn/LC_MESSAGES/volto.po +5516 -0
  19. package/locales/bn.json +1 -1
  20. package/locales/ca/LC_MESSAGES/volto.po +547 -355
  21. package/locales/ca.json +1 -1
  22. package/locales/cs/LC_MESSAGES/volto.po +5516 -0
  23. package/locales/cs.json +1 -1
  24. package/locales/cy/LC_MESSAGES/volto.po +5516 -0
  25. package/locales/cy.json +1 -1
  26. package/locales/da/LC_MESSAGES/volto.po +5516 -0
  27. package/locales/da.json +1 -1
  28. package/locales/de/LC_MESSAGES/volto.po +218 -25
  29. package/locales/de.json +1 -1
  30. package/locales/el/LC_MESSAGES/volto.po +5516 -0
  31. package/locales/el.json +1 -1
  32. package/locales/en/LC_MESSAGES/volto.po +207 -11
  33. package/locales/en.json +1 -1
  34. package/locales/en_AU/LC_MESSAGES/volto.po +5516 -0
  35. package/locales/en_AU.json +1 -1
  36. package/locales/en_GB/LC_MESSAGES/volto.po +5516 -0
  37. package/locales/en_GB.json +1 -1
  38. package/locales/eo/LC_MESSAGES/volto.po +5516 -0
  39. package/locales/eo.json +1 -1
  40. package/locales/es/LC_MESSAGES/volto.po +332 -141
  41. package/locales/es.json +1 -1
  42. package/locales/et/LC_MESSAGES/volto.po +5516 -0
  43. package/locales/et.json +1 -1
  44. package/locales/eu/LC_MESSAGES/volto.po +409 -218
  45. package/locales/eu.json +1 -1
  46. package/locales/fa/LC_MESSAGES/volto.po +5516 -0
  47. package/locales/fa.json +1 -1
  48. package/locales/fi/LC_MESSAGES/volto.po +208 -16
  49. package/locales/fi.json +1 -1
  50. package/locales/fr/LC_MESSAGES/volto.po +365 -174
  51. package/locales/fr.json +1 -1
  52. package/locales/fu/LC_MESSAGES/volto.po +5516 -0
  53. package/locales/fu.json +1 -1
  54. package/locales/gl/LC_MESSAGES/volto.po +5516 -0
  55. package/locales/gl.json +1 -1
  56. package/locales/he/LC_MESSAGES/volto.po +5516 -0
  57. package/locales/he.json +1 -1
  58. package/locales/hi/LC_MESSAGES/volto.po +216 -19
  59. package/locales/hi.json +1 -1
  60. package/locales/hr/LC_MESSAGES/volto.po +5516 -0
  61. package/locales/hr.json +1 -1
  62. package/locales/hu/LC_MESSAGES/volto.po +5516 -0
  63. package/locales/hu.json +1 -1
  64. package/locales/hy/LC_MESSAGES/volto.po +5516 -0
  65. package/locales/hy.json +1 -1
  66. package/locales/id/LC_MESSAGES/volto.po +5516 -0
  67. package/locales/id.json +1 -1
  68. package/locales/it/LC_MESSAGES/volto.po +232 -35
  69. package/locales/it.json +1 -1
  70. package/locales/ja/LC_MESSAGES/volto.po +250 -57
  71. package/locales/ja.json +1 -1
  72. package/locales/ka/LC_MESSAGES/volto.po +5516 -0
  73. package/locales/ka.json +1 -1
  74. package/locales/kn/LC_MESSAGES/volto.po +5516 -0
  75. package/locales/kn.json +1 -1
  76. package/locales/ko/LC_MESSAGES/volto.po +5516 -0
  77. package/locales/ko.json +1 -1
  78. package/locales/lt/LC_MESSAGES/volto.po +5516 -0
  79. package/locales/lt.json +1 -1
  80. package/locales/lv/LC_MESSAGES/volto.po +5516 -0
  81. package/locales/lv.json +1 -1
  82. package/locales/mi/LC_MESSAGES/volto.po +5516 -0
  83. package/locales/mi.json +1 -1
  84. package/locales/mk/LC_MESSAGES/volto.po +5516 -0
  85. package/locales/mk.json +1 -1
  86. package/locales/my/LC_MESSAGES/volto.po +5516 -0
  87. package/locales/my.json +1 -1
  88. package/locales/nb_NO/LC_MESSAGES/volto.po +5516 -0
  89. package/locales/nb_NO.json +1 -1
  90. package/locales/nl/LC_MESSAGES/volto.po +260 -67
  91. package/locales/nl.json +1 -1
  92. package/locales/nn/LC_MESSAGES/volto.po +5516 -0
  93. package/locales/nn.json +1 -1
  94. package/locales/pl/LC_MESSAGES/volto.po +5516 -0
  95. package/locales/pl.json +1 -1
  96. package/locales/pt/LC_MESSAGES/volto.po +859 -667
  97. package/locales/pt.json +1 -1
  98. package/locales/pt_BR/LC_MESSAGES/volto.po +212 -21
  99. package/locales/pt_BR.json +1 -1
  100. package/locales/rm/LC_MESSAGES/volto.po +5516 -0
  101. package/locales/rm.json +1 -1
  102. package/locales/ro/LC_MESSAGES/volto.po +244 -53
  103. package/locales/ro.json +1 -1
  104. package/locales/ru/LC_MESSAGES/volto.po +207 -15
  105. package/locales/ru.json +1 -1
  106. package/locales/sk/LC_MESSAGES/volto.po +5516 -0
  107. package/locales/sk.json +1 -1
  108. package/locales/sl/LC_MESSAGES/volto.po +5516 -0
  109. package/locales/sl.json +1 -1
  110. package/locales/sm/LC_MESSAGES/volto.po +5516 -0
  111. package/locales/sm.json +1 -1
  112. package/locales/sq/LC_MESSAGES/volto.po +5516 -0
  113. package/locales/sq.json +1 -1
  114. package/locales/sr/LC_MESSAGES/volto.po +5516 -0
  115. package/locales/sr.json +1 -1
  116. package/locales/sr@cyrl/LC_MESSAGES/volto.po +5516 -0
  117. package/locales/sr@cyrl.json +1 -1
  118. package/locales/sr@latn/LC_MESSAGES/volto.po +5516 -0
  119. package/locales/sr@latn.json +1 -1
  120. package/locales/sv/LC_MESSAGES/volto.po +5516 -0
  121. package/locales/sv.json +1 -1
  122. package/locales/ta/LC_MESSAGES/volto.po +5516 -0
  123. package/locales/ta.json +1 -1
  124. package/locales/te/LC_MESSAGES/volto.po +5516 -0
  125. package/locales/te.json +1 -1
  126. package/locales/th/LC_MESSAGES/volto.po +5516 -0
  127. package/locales/th.json +1 -1
  128. package/locales/to/LC_MESSAGES/volto.po +5516 -0
  129. package/locales/to.json +1 -1
  130. package/locales/tr/LC_MESSAGES/volto.po +5516 -0
  131. package/locales/tr.json +1 -1
  132. package/locales/uk/LC_MESSAGES/volto.po +5516 -0
  133. package/locales/uk.json +1 -1
  134. package/locales/vi/LC_MESSAGES/volto.po +5516 -0
  135. package/locales/vi.json +1 -1
  136. package/locales/volto.pot +201 -10
  137. package/locales/zh_CN/LC_MESSAGES/volto.po +207 -15
  138. package/locales/zh_CN.json +1 -1
  139. package/locales/zh_Hant/LC_MESSAGES/volto.po +5516 -0
  140. package/locales/zh_Hant.json +1 -1
  141. package/locales/zh_Hant_HK/LC_MESSAGES/volto.po +5516 -0
  142. package/locales/zh_Hant_HK.json +1 -1
  143. package/package.json +71 -148
  144. package/razzle.config.js +32 -25
  145. package/src/actions/blockTypes/blockTypes.ts +24 -0
  146. package/src/actions/controlpanels/controlpanels.js +7 -12
  147. package/src/actions/controlpanels/controlpanels.test.js +2 -3
  148. package/src/components/manage/Actions/Actions.test.jsx +1 -5
  149. package/src/components/manage/Add/Add.jsx +15 -10
  150. package/src/components/manage/Add/Add.test.jsx +10 -3
  151. package/src/components/manage/Aliases/Aliases.test.jsx +5 -2
  152. package/src/components/manage/BlockChooser/BlockChooser.jsx +8 -10
  153. package/src/components/manage/Blocks/Block/BlocksForm.jsx +10 -7
  154. package/src/components/manage/Blocks/Block/BlocksForm.test.jsx +3 -14
  155. package/src/components/manage/Blocks/Block/Edit.jsx +19 -10
  156. package/src/components/manage/Blocks/Block/Order/Item.jsx +33 -14
  157. package/src/components/manage/Blocks/Block/Order/Item.test.jsx +90 -0
  158. package/src/components/manage/Blocks/Block/Order/Order.jsx +116 -67
  159. package/src/components/manage/Blocks/Block/Order/utilities.js +28 -11
  160. package/src/components/manage/Blocks/Block/Settings.test.jsx +1 -5
  161. package/src/components/manage/Blocks/Grid/View.jsx +14 -11
  162. package/src/components/manage/Blocks/Grid/context.js +3 -0
  163. package/src/components/manage/Blocks/HTML/Edit.test.jsx +1 -5
  164. package/src/components/manage/Blocks/Image/ImageSidebar.test.jsx +2 -5
  165. package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.test.jsx +2 -5
  166. package/src/components/manage/Blocks/Listing/Edit.jsx +1 -0
  167. package/src/components/manage/Blocks/Listing/ImageGallery.jsx +6 -4
  168. package/src/components/manage/Blocks/Listing/ListingBody.jsx +4 -0
  169. package/src/components/manage/Blocks/Maps/MapsSidebar.test.jsx +1 -5
  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 +6 -5
  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/Delete/Delete.test.jsx +13 -8
  231. package/src/components/manage/Diff/Diff.jsx +201 -298
  232. package/src/components/manage/Diff/Diff.test.jsx +8 -10
  233. package/src/components/manage/Diff/DiffField.test.jsx +1 -6
  234. package/src/components/manage/Display/Display.test.jsx +2 -11
  235. package/src/components/manage/Edit/Edit.test.jsx +12 -11
  236. package/src/components/manage/Form/BlockDataForm.test.jsx +1 -5
  237. package/src/components/manage/Form/Field.jsx +1 -69
  238. package/src/components/manage/Form/Form.jsx +17 -4
  239. package/src/components/manage/Form/Form.test.jsx +130 -5
  240. package/src/components/manage/Form/InlineForm.test.jsx +1 -5
  241. package/src/components/manage/Form/ModalForm.jsx +175 -97
  242. package/src/components/manage/Form/ModalForm.test.jsx +27 -5
  243. package/src/components/manage/Form/__mocks__/index.tsx +9 -27
  244. package/src/components/manage/History/History.test.jsx +15 -8
  245. package/src/components/manage/LinksToItem/LinksToItem.test.jsx +7 -4
  246. package/src/components/manage/Multilingual/CompareLanguages.jsx +6 -6
  247. package/src/components/manage/Multilingual/CreateTranslation.jsx +16 -13
  248. package/src/components/manage/Multilingual/ManageTranslations.jsx +5 -5
  249. package/src/components/manage/Multilingual/ManageTranslations.test.jsx +15 -12
  250. package/src/components/manage/Multilingual/TranslationObject.jsx +11 -8
  251. package/src/components/manage/Preferences/ChangePassword.test.jsx +8 -9
  252. package/src/components/manage/Preferences/PersonalPreferences.jsx +8 -5
  253. package/src/components/manage/Preferences/PersonalPreferences.test.jsx +10 -23
  254. package/src/components/manage/Rules/Rules.test.jsx +5 -2
  255. package/src/components/manage/Sharing/Sharing.jsx +21 -15
  256. package/src/components/manage/Sharing/Sharing.test.jsx +9 -6
  257. package/src/components/manage/Sidebar/ObjectBrowser.jsx +10 -0
  258. package/src/components/manage/Sidebar/ObjectBrowserBody.jsx +25 -5
  259. package/src/components/manage/Sidebar/ObjectBrowserBody.test.jsx +52 -0
  260. package/src/components/manage/Sidebar/Sidebar.jsx +2 -0
  261. package/src/components/manage/Sidebar/Sidebar.test.jsx +4 -1
  262. package/src/components/manage/Sidebar/SidebarPortal.test.tsx +42 -0
  263. package/src/components/manage/Sidebar/SidebarPortal.tsx +48 -0
  264. package/src/components/manage/TemplateChooser/TemplateChooser.test.jsx +1 -0
  265. package/src/components/manage/Toast/Toast.jsx +32 -0
  266. package/src/components/manage/Toast/Toast.test.jsx +9 -5
  267. package/src/components/manage/Toolbar/PersonalTools.test.jsx +15 -0
  268. package/src/components/manage/Toolbar/Toolbar.jsx +103 -11
  269. package/src/components/manage/Toolbar/Toolbar.test.jsx +15 -10
  270. package/src/components/manage/Toolbar/Types.crash.test.jsx +48 -0
  271. package/src/components/manage/Toolbar/Types.jsx +6 -4
  272. package/src/components/manage/UniversalLink/UniversalLink.test.jsx +16 -0
  273. package/src/components/manage/UniversalLink/UniversalLink.tsx +1 -0
  274. package/src/components/manage/Widgets/AlignWidget.stories.jsx +9 -0
  275. package/src/components/manage/Widgets/AlignWidget.test.tsx +95 -0
  276. package/src/components/manage/Widgets/{AlignWidget.jsx → AlignWidget.tsx} +23 -7
  277. package/src/components/manage/Widgets/ArrayWidget.jsx +111 -88
  278. package/src/components/manage/Widgets/ArrayWidget.test.jsx +1 -12
  279. package/src/components/manage/Widgets/BlockAlignment.stories.tsx +104 -0
  280. package/src/components/manage/Widgets/BlockAlignment.test.tsx +104 -0
  281. package/src/components/manage/Widgets/BlockAlignment.tsx +88 -0
  282. package/src/components/manage/Widgets/BlockWidth.stories.tsx +69 -0
  283. package/src/components/manage/Widgets/BlockWidth.test.tsx +62 -0
  284. package/src/components/manage/Widgets/BlockWidth.tsx +101 -0
  285. package/src/components/manage/Widgets/ButtonsWidget.stories.jsx +61 -0
  286. package/src/components/manage/Widgets/ButtonsWidget.test.tsx +138 -0
  287. package/src/components/manage/Widgets/ButtonsWidget.tsx +195 -0
  288. package/src/components/manage/Widgets/CheckboxGroupWidget.test.jsx +1 -6
  289. package/src/components/manage/Widgets/DatetimeWidget.jsx +98 -54
  290. package/src/components/manage/Widgets/DatetimeWidget.test.jsx +56 -6
  291. package/src/components/manage/Widgets/FileWidget.jsx +7 -0
  292. package/src/components/manage/Widgets/FormFieldWrapper.jsx +143 -163
  293. package/src/components/manage/Widgets/ImageWidget.jsx +18 -5
  294. package/src/components/manage/Widgets/ObjectBrowserWidget.jsx +6 -0
  295. package/src/components/manage/Widgets/ObjectListWidget.test.jsx +2 -11
  296. package/src/components/manage/Widgets/ObjectWidget.test.jsx +1 -5
  297. package/src/components/manage/Widgets/QueryWidget.jsx +137 -9
  298. package/src/components/manage/Widgets/QuerystringWidget.test.jsx +3 -1
  299. package/src/components/manage/Widgets/RadioGroupWidget.test.jsx +1 -6
  300. package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.test.jsx +1 -6
  301. package/src/components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthIndexField.jsx +56 -50
  302. package/src/components/manage/Widgets/RegistryImageWidget.jsx +1 -1
  303. package/src/components/manage/Widgets/RegistryImageWidget.test.jsx +1 -0
  304. package/src/components/manage/Widgets/SchemaWidget.test.jsx +1 -6
  305. package/src/components/manage/Widgets/SchemaWidgetFieldset.test.jsx +1 -6
  306. package/src/components/manage/Widgets/SelectAutoComplete.test.jsx +1 -6
  307. package/src/components/manage/Widgets/SelectStyling.jsx +52 -20
  308. package/src/components/manage/Widgets/SelectWidget.test.jsx +1 -6
  309. package/src/components/manage/Widgets/Size.stories.tsx +69 -0
  310. package/src/components/manage/Widgets/Size.test.tsx +59 -0
  311. package/src/components/manage/Widgets/Size.tsx +78 -0
  312. package/src/components/manage/Widgets/TextWidget.jsx +4 -0
  313. package/src/components/manage/Widgets/TimeWidget.test.jsx +1 -6
  314. package/src/components/manage/Widgets/TokenWidget.jsx +142 -186
  315. package/src/components/manage/Widgets/TokenWidget.test.jsx +1 -6
  316. package/src/components/manage/Widgets/UrlWidget.jsx +47 -18
  317. package/src/components/manage/Widgets/VocabularyTermsWidget.test.jsx +2 -11
  318. package/src/components/manage/Widgets/__mocks__/index.tsx +33 -51
  319. package/src/components/manage/Widgets/index.tsx +21 -0
  320. package/src/components/manage/Workflow/Workflow.test.jsx +2 -11
  321. package/src/components/theme/AlternateHrefLangs/AlternateHrefLangs.jsx +1 -0
  322. package/src/components/theme/AlternateHrefLangs/AlternateHrefLangs.test.jsx +30 -0
  323. package/src/components/theme/App/App.jsx +5 -1
  324. package/src/components/theme/App/App.test.jsx +13 -10
  325. package/src/components/theme/Comments/CommentEditModal.test.jsx +1 -5
  326. package/src/components/theme/Comments/Comments.test.jsx +2 -11
  327. package/src/components/theme/ConnectionRefused/ConnectionRefused.jsx +3 -2
  328. package/src/components/theme/ContactForm/ContactForm.test.jsx +14 -13
  329. package/src/components/theme/Image/Image.jsx +25 -13
  330. package/src/components/theme/Image/Image.test.jsx +247 -146
  331. package/src/components/theme/InjectPloneComponentsCSS/InjectPloneComponentsCSS.tsx +7 -0
  332. package/src/components/theme/LanguageSelector/LanguageSelector.tsx +3 -3
  333. package/src/components/theme/MultilingualRedirector/MultilingualRedirector.jsx +42 -12
  334. package/src/components/theme/MultilingualRedirector/MultilingualRedirector.test.jsx +6 -3
  335. package/src/components/theme/PasswordReset/PasswordReset.jsx +108 -191
  336. package/src/components/theme/PasswordReset/RequestPasswordReset.test.jsx +1 -5
  337. package/src/components/theme/Register/Register.test.jsx +1 -5
  338. package/src/components/theme/RequestTimeout/RequestTimeout.jsx +1 -1
  339. package/src/components/theme/Search/Search.jsx +230 -327
  340. package/src/components/theme/Search/Search.test.jsx +14 -14
  341. package/src/components/theme/Sitemap/Sitemap.jsx +22 -30
  342. package/src/components/theme/Sitemap/Sitemap.stories.jsx +82 -0
  343. package/src/components/theme/Sitemap/Sitemap.test.jsx +18 -0
  344. package/src/components/theme/SlotRenderer/SlotRenderer.tsx +12 -6
  345. package/src/components/theme/Unauthorized/Unauthorized.jsx +27 -24
  346. package/src/components/theme/Unauthorized/Unauthorized.test.jsx +31 -2
  347. package/src/components/theme/VideoEmbed/VideoEmbed.jsx +100 -0
  348. package/src/components/theme/View/EventDatesInfo.test.jsx +1 -6
  349. package/src/components/theme/View/EventView.stories.jsx +89 -0
  350. package/src/components/theme/View/EventView.test.jsx +1 -6
  351. package/src/components/theme/View/FileView.stories.jsx +50 -0
  352. package/src/components/theme/View/ImageView.jsx +2 -1
  353. package/src/components/theme/View/ImageView.test.jsx +3 -0
  354. package/src/components/theme/View/LinkView.stories.jsx +57 -0
  355. package/src/components/theme/View/ListingView.stories.jsx +70 -0
  356. package/src/components/theme/View/NewsItemView.stories.jsx +58 -0
  357. package/src/components/theme/View/RenderBlocks.jsx +8 -10
  358. package/src/components/theme/View/RenderBlocks.stories.jsx +112 -0
  359. package/src/components/theme/View/RenderBlocks.test.jsx +14 -4
  360. package/src/components/theme/View/SummaryView.stories.jsx +71 -0
  361. package/src/components/theme/View/TabularView.stories.jsx +66 -0
  362. package/src/components/theme/View/View.jsx +8 -1
  363. package/src/components/theme/View/View.test.jsx +37 -24
  364. package/src/components/theme/Widgets/DateWidget.jsx +4 -5
  365. package/src/components/theme/Widgets/DatetimeWidget.jsx +4 -5
  366. package/src/components/theme/Widgets/ImageWidget.test.jsx +31 -11
  367. package/src/components/theme/Widgets/RichTextWidget.jsx +1 -1
  368. package/src/config/Blocks.jsx +3 -0
  369. package/src/config/ControlPanels.js +2 -0
  370. package/src/config/Loadables.jsx +1 -5
  371. package/src/config/Widgets.jsx +7 -0
  372. package/src/config/index.js +22 -11
  373. package/src/config/server.js +0 -2
  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 +16 -4
  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/APIResourceWithAuth.js +8 -3
  383. package/src/helpers/Api/Api.js +9 -6
  384. package/src/helpers/AsyncConnect/ssr.js +4 -1
  385. package/src/helpers/AuthToken/AuthToken.js +1 -6
  386. package/src/helpers/Blocks/Blocks.js +113 -28
  387. package/src/helpers/Blocks/Blocks.test.js +100 -0
  388. package/src/helpers/Content/Content.js +23 -0
  389. package/src/helpers/Content/Content.test.js +39 -0
  390. package/src/helpers/Extensions/withBlockSchemaEnhancer.jsx +4 -1
  391. package/src/helpers/FormValidation/FormValidation.test.js +31 -0
  392. package/src/helpers/FormValidation/validators.ts +52 -6
  393. package/src/helpers/Html/Html.jsx +13 -4
  394. package/src/helpers/I18n/I18n.test.ts +44 -0
  395. package/src/helpers/I18n/I18n.ts +31 -0
  396. package/src/helpers/Loadable/__mocks__/Loadable.jsx +7 -22
  397. package/src/helpers/MessageLabels/MessageLabels.js +5 -0
  398. package/src/helpers/Robots/Robots.js +1 -1
  399. package/src/helpers/Robots/Robots.test.js +34 -0
  400. package/src/helpers/Sitemap/Sitemap.js +4 -4
  401. package/src/helpers/Url/Url.js +33 -2
  402. package/src/helpers/Url/Url.test.js +62 -0
  403. package/src/helpers/Utils/Date.js +26 -1
  404. package/src/helpers/Utils/Date.test.js +237 -0
  405. package/src/helpers/Utils/Utils.jsx +17 -0
  406. package/src/helpers/Utils/Utils.test.jsx +39 -0
  407. package/src/helpers/Utils/withSaveAsDraft.jsx +33 -9
  408. package/src/helpers/index.js +1 -0
  409. package/src/hooks/user/useUser.js +1 -1
  410. package/src/internalChecks.test.ts +11 -0
  411. package/src/middleware/api.js +14 -5
  412. package/src/reducers/blockTypes/blockTypes.js +38 -0
  413. package/src/reducers/content/content.js +3 -18
  414. package/src/reducers/diff/diff.js +5 -1
  415. package/src/reducers/diff/diff.test.js +60 -4
  416. package/src/reducers/index.js +2 -0
  417. package/src/reducers/querystring/querystring.js +8 -1
  418. package/src/reducers/users/users.js +1 -1
  419. package/src/routes.js +10 -0
  420. package/src/server.jsx +54 -14
  421. package/src/start-client.jsx +30 -5
  422. package/src/start-server.js +9 -3
  423. package/test-addons-loader.js +3 -0
  424. package/test-setup-globals.js +56 -2
  425. package/theme/themes/default/elements/segment.variables +9 -16
  426. package/theme/themes/default/globals/site.variables +3 -3
  427. package/theme/themes/pastanaga/collections/form.overrides +22 -1
  428. package/theme/themes/pastanaga/elements/button.overrides +30 -3
  429. package/theme/themes/pastanaga/elements/segment.variables +1 -4
  430. package/theme/themes/pastanaga/extras/block-types.less +17 -0
  431. package/theme/themes/pastanaga/extras/contents.less +63 -4
  432. package/theme/themes/pastanaga/extras/main.less +16 -4
  433. package/theme/themes/pastanaga/extras/toolbar.less +10 -5
  434. package/theme/themes/pastanaga/extras/videoembed.less +22 -0
  435. package/theme/themes/pastanaga/extras/widgets.less +79 -0
  436. package/theme/themes/pastanaga/globals/site.variables +0 -3
  437. package/tsconfig.declarations.json +1 -1
  438. package/tsconfig.json +1 -1
  439. package/types/actions/blockTypes/blockTypes.d.ts +7 -0
  440. package/types/components/index.d.ts +1 -1
  441. package/types/components/manage/Blocks/Block/Order/Item.test.d.ts +1 -0
  442. package/types/components/manage/Blocks/Block/Order/utilities.d.ts +2 -1
  443. package/types/components/manage/Blocks/Grid/context.d.ts +1 -0
  444. package/types/components/manage/Blocks/Teaser/utils.d.ts +5 -0
  445. package/types/components/manage/Blocks/Video/Body.d.ts +4 -2
  446. package/types/components/manage/Blocks/Video/schema.d.ts +4 -0
  447. package/types/components/manage/Contents/Contents.d.ts +1 -1
  448. package/types/components/manage/Contents/ContentsIndexHeader.d.ts +6 -11
  449. package/types/components/manage/Contents/ContentsItem.d.ts +3 -10
  450. package/types/components/manage/Contents/DropZoneContent.d.ts +2 -0
  451. package/types/components/manage/Contents/__mocks__/index.d.ts +2 -2
  452. package/types/components/manage/Controlpanels/BlockType.d.ts +7 -0
  453. package/types/components/manage/Controlpanels/BlockTypes.d.ts +7 -0
  454. package/types/components/manage/Controlpanels/ContentType.d.ts +2 -2
  455. package/types/components/manage/Controlpanels/Controlpanel.d.ts +2 -5
  456. package/types/components/manage/Controlpanels/Relations/RelationsMatrix.d.ts +1 -1
  457. package/types/components/manage/Controlpanels/Users/UsersControlpanel.ssr.test.d.ts +1 -0
  458. package/types/components/manage/Controlpanels/index.d.ts +2 -2
  459. package/types/components/manage/Diff/Diff.d.ts +7 -2
  460. package/types/components/manage/Form/__mocks__/index.d.ts +8 -8
  461. package/types/components/manage/Multilingual/ManageTranslations.d.ts +1 -1
  462. package/types/components/manage/Sidebar/ObjectBrowser.d.ts +1 -1
  463. package/types/components/manage/Sidebar/ObjectBrowserBody.test.d.ts +1 -0
  464. package/types/components/manage/Sidebar/SidebarPortal.d.ts +7 -15
  465. package/types/components/manage/Toolbar/Types.crash.test.d.ts +1 -0
  466. package/types/components/manage/Widgets/AlignWidget.d.ts +8 -10
  467. package/types/components/manage/Widgets/AlignWidget.stories.d.ts +1 -0
  468. package/types/components/manage/Widgets/BlockAlignment.d.ts +7 -0
  469. package/types/components/manage/Widgets/BlockAlignment.stories.d.ts +8 -0
  470. package/types/components/manage/Widgets/BlockWidth.d.ts +7 -0
  471. package/types/components/manage/Widgets/BlockWidth.stories.d.ts +6 -0
  472. package/types/components/manage/Widgets/ButtonsWidget.d.ts +48 -1
  473. package/types/components/manage/Widgets/ButtonsWidget.stories.d.ts +3 -0
  474. package/types/components/manage/Widgets/FormFieldWrapper.d.ts +28 -5
  475. package/types/components/manage/Widgets/ImageWidget.d.ts +1 -1
  476. package/types/components/manage/Widgets/InternalUrlWidget.d.ts +1 -1
  477. package/types/components/manage/Widgets/ObjectBrowserWidget.d.ts +2 -0
  478. package/types/components/manage/Widgets/QueryWidget.d.ts +5 -2
  479. package/types/components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthIndexField.d.ts +22 -5
  480. package/types/components/manage/Widgets/SelectStyling.d.ts +1 -0
  481. package/types/components/manage/Widgets/Size.d.ts +7 -0
  482. package/types/components/manage/Widgets/Size.stories.d.ts +6 -0
  483. package/types/components/manage/Widgets/UrlWidget.d.ts +1 -1
  484. package/types/components/manage/Widgets/__mocks__/index.d.ts +33 -33
  485. package/types/components/manage/Widgets/index.d.ts +11 -6
  486. package/types/components/theme/ConnectionRefused/ConnectionRefused.d.ts +2 -2
  487. package/types/components/theme/InjectPloneComponentsCSS/InjectPloneComponentsCSS.d.ts +3 -0
  488. package/types/components/theme/PasswordReset/PasswordReset.d.ts +6 -2
  489. package/types/components/theme/Search/Search.d.ts +1 -1
  490. package/types/components/theme/Sitemap/Sitemap.stories.d.ts +13 -0
  491. package/types/components/theme/SlotRenderer/SlotRenderer.d.ts +4 -5
  492. package/types/components/theme/Unauthorized/Unauthorized.d.ts +2 -2
  493. package/types/components/theme/VideoEmbed/VideoEmbed.d.ts +2 -0
  494. package/types/components/theme/View/EventView.stories.d.ts +19 -0
  495. package/types/components/theme/View/FileView.stories.d.ts +18 -0
  496. package/types/components/theme/View/LinkView.stories.d.ts +18 -0
  497. package/types/components/theme/View/ListingView.stories.d.ts +24 -0
  498. package/types/components/theme/View/NewsItemView.stories.d.ts +23 -0
  499. package/types/components/theme/View/RenderBlocks.stories.d.ts +23 -0
  500. package/types/components/theme/View/SummaryView.stories.d.ts +23 -0
  501. package/types/components/theme/View/TabularView.stories.d.ts +23 -0
  502. package/types/config/ControlPanels.d.ts +1 -0
  503. package/types/config/Views.d.ts +1 -1
  504. package/types/config/Widgets.d.ts +6 -0
  505. package/types/config/slots.d.ts +7 -0
  506. package/types/constants/ActionTypes.d.ts +1 -0
  507. package/types/helpers/Blocks/Blocks.d.ts +4 -0
  508. package/types/helpers/Content/Content.d.ts +7 -0
  509. package/types/helpers/Extensions/withBlockSchemaEnhancer.d.ts +4 -5
  510. package/types/helpers/FormValidation/validators.d.ts +18 -1
  511. package/types/helpers/I18n/I18n.d.ts +20 -0
  512. package/types/helpers/Loadable/__mocks__/Loadable.d.ts +2 -2
  513. package/types/helpers/MessageLabels/MessageLabels.d.ts +100 -94
  514. package/types/helpers/Url/Url.d.ts +14 -0
  515. package/types/helpers/Utils/Utils.d.ts +1 -0
  516. package/types/helpers/index.d.ts +1 -0
  517. package/types/reducers/blockTypes/blockTypes.d.ts +16 -0
  518. package/types/reducers/index.d.ts +2 -0
  519. package/types/routes.d.ts +7 -5
  520. package/types/start-client.d.ts +0 -1
  521. package/vitest.config.mjs +84 -42
  522. package/webpack-plugins/webpack-less-plugin.js +1 -1
  523. package/webpack-plugins/webpack-scss-plugin.js +172 -0
  524. package/jest-addons-loader.js +0 -3
  525. package/jest-extender-plugin.js +0 -39
  526. package/jest-setup-afterenv.js +0 -2
  527. package/jest-svgsystem-transform.js +0 -10
  528. package/patches/patchit.sh +0 -2
  529. package/patches/razzle-jest.patch +0 -10
  530. package/src/components/manage/Contents/__mocks__/index.vitest.tsx +0 -5
  531. package/src/components/manage/Form/__mocks__/index.vitest.tsx +0 -73
  532. package/src/components/manage/Sidebar/SidebarPortal.jsx +0 -47
  533. package/src/components/manage/Sidebar/SidebarPortal.test.jsx +0 -26
  534. package/src/components/manage/Widgets/AlignWidget.test.jsx +0 -59
  535. package/src/components/manage/Widgets/ButtonsWidget.jsx +0 -41
  536. package/src/components/manage/Widgets/ButtonsWidget.test.jsx +0 -70
  537. package/src/components/manage/Widgets/__mocks__/index.vitest.tsx +0 -41
  538. package/src/helpers/Loadable/__mocks__/Loadable.vitest.jsx +0 -39
  539. package/test-setup-globals-vitest.js +0 -46
  540. package/theme/themes/pastanaga/extras/utils.less +0 -63
@@ -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();
@@ -0,0 +1,42 @@
1
+ import React from 'react';
2
+ import { cleanup, render, screen } from '@testing-library/react';
3
+
4
+ import SidebarPortal from './SidebarPortal';
5
+
6
+ describe('SidebarPortal', () => {
7
+ let portalRoot: HTMLDivElement | null;
8
+
9
+ beforeEach(() => {
10
+ portalRoot = document.createElement('div');
11
+ portalRoot.setAttribute('id', 'sidebar-properties');
12
+ document.body.appendChild(portalRoot);
13
+ });
14
+
15
+ afterEach(() => {
16
+ cleanup();
17
+ portalRoot?.remove();
18
+ portalRoot = null;
19
+ });
20
+
21
+ test('renders the sidebar portal when the block is selected', async () => {
22
+ render(
23
+ <SidebarPortal selected={true}>
24
+ <p>Tested!</p>
25
+ </SidebarPortal>,
26
+ );
27
+
28
+ expect(await screen.findByText('Tested!')).toBeInTheDocument();
29
+ });
30
+
31
+ test('does not render the sidebar portal when the block is not selected', () => {
32
+ render(
33
+ <SidebarPortal selected={false}>
34
+ <p>Tested, but you should not see this!</p>
35
+ </SidebarPortal>,
36
+ );
37
+
38
+ expect(
39
+ screen.queryByText('Tested, but you should not see this!'),
40
+ ).not.toBeInTheDocument();
41
+ });
42
+ });
@@ -0,0 +1,48 @@
1
+ import React from 'react';
2
+ import { createPortal } from 'react-dom';
3
+
4
+ type SidebarPortalProps = {
5
+ children?: React.ReactNode;
6
+ selected: boolean;
7
+ tab?: string;
8
+ };
9
+
10
+ const SidebarPortal = ({
11
+ children,
12
+ selected,
13
+ tab = 'sidebar-properties',
14
+ }: SidebarPortalProps) => {
15
+ const [isClient, setIsClient] = React.useState(false);
16
+
17
+ React.useEffect(() => setIsClient(true), []);
18
+
19
+ if (!isClient || !selected) {
20
+ return null;
21
+ }
22
+
23
+ const target = document.getElementById(tab);
24
+
25
+ if (!target) {
26
+ return null;
27
+ }
28
+
29
+ return createPortal(
30
+ <div role="form" style={{ height: '100%' }}>
31
+ <div
32
+ style={{ height: '100%' }}
33
+ role="presentation"
34
+ onClick={(e) => {
35
+ e.stopPropagation();
36
+ }}
37
+ onKeyDown={(e) => {
38
+ e.stopPropagation();
39
+ }}
40
+ >
41
+ {children}
42
+ </div>
43
+ </div>,
44
+ target,
45
+ );
46
+ };
47
+
48
+ export default SidebarPortal;
@@ -13,6 +13,7 @@ test('renders a TemplateChooser component', () => {
13
13
  locale: 'en',
14
14
  messages: { templateid: 'Template default translation' },
15
15
  },
16
+ site: { data: { 'plone.image_scales': { preview: {}, listing: {} } } },
16
17
  });
17
18
 
18
19
  const component = renderer.create(