@plone/volto 19.0.0-alpha.2 → 19.0.0-alpha.20

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 (366) hide show
  1. package/.eslintignore +1 -0
  2. package/.eslintrc +37 -3
  3. package/CHANGELOG.md +338 -1
  4. package/README.md +20 -16
  5. package/babel.js +1 -3
  6. package/cypress/docker/prefixed-rules.yml +26 -0
  7. package/cypress/docker/prefixed.yml +24 -0
  8. package/cypress/support/commands.js +12 -6
  9. package/cypress/support/guillotina.js +1 -0
  10. package/cypress.config.js +1 -0
  11. package/global-test-setup.js +1 -2
  12. package/locales/af.json +1 -0
  13. package/locales/ar.json +1 -0
  14. package/locales/bg.json +1 -0
  15. package/locales/bn.json +1 -0
  16. package/locales/ca/LC_MESSAGES/volto.po +124 -17
  17. package/locales/ca.json +1 -1
  18. package/locales/cs.json +1 -0
  19. package/locales/cy.json +1 -0
  20. package/locales/da.json +1 -0
  21. package/locales/de/LC_MESSAGES/volto.po +135 -28
  22. package/locales/de.json +1 -1
  23. package/locales/el.json +1 -0
  24. package/locales/en/LC_MESSAGES/volto.po +125 -18
  25. package/locales/en.json +1 -1
  26. package/locales/en_AU.json +1 -0
  27. package/locales/en_GB.json +1 -0
  28. package/locales/eo.json +1 -0
  29. package/locales/es/LC_MESSAGES/volto.po +125 -18
  30. package/locales/es.json +1 -1
  31. package/locales/et.json +1 -0
  32. package/locales/eu/LC_MESSAGES/volto.po +124 -17
  33. package/locales/eu.json +1 -1
  34. package/locales/fa.json +1 -0
  35. package/locales/fi/LC_MESSAGES/volto.po +124 -17
  36. package/locales/fi.json +1 -1
  37. package/locales/fr/LC_MESSAGES/volto.po +125 -18
  38. package/locales/fr.json +1 -1
  39. package/locales/fu.json +1 -0
  40. package/locales/gl.json +1 -0
  41. package/locales/he.json +1 -0
  42. package/locales/hi/LC_MESSAGES/volto.po +128 -21
  43. package/locales/hi.json +1 -1
  44. package/locales/hr.json +1 -0
  45. package/locales/hu.json +1 -0
  46. package/locales/hy.json +1 -0
  47. package/locales/id.json +1 -0
  48. package/locales/it/LC_MESSAGES/volto.po +129 -22
  49. package/locales/it.json +1 -1
  50. package/locales/ja/LC_MESSAGES/volto.po +124 -17
  51. package/locales/ja.json +1 -1
  52. package/locales/ka.json +1 -0
  53. package/locales/kn.json +1 -0
  54. package/locales/ko.json +1 -0
  55. package/locales/lt.json +1 -0
  56. package/locales/lv.json +1 -0
  57. package/locales/mi.json +1 -0
  58. package/locales/mk.json +1 -0
  59. package/locales/my.json +1 -0
  60. package/locales/nb_NO.json +1 -0
  61. package/locales/nl/LC_MESSAGES/volto.po +128 -21
  62. package/locales/nl.json +1 -1
  63. package/locales/nn.json +1 -0
  64. package/locales/pl.json +1 -0
  65. package/locales/pt/LC_MESSAGES/volto.po +124 -17
  66. package/locales/pt.json +1 -1
  67. package/locales/pt_BR/LC_MESSAGES/volto.po +147 -40
  68. package/locales/pt_BR.json +1 -1
  69. package/locales/rm.json +1 -0
  70. package/locales/ro/LC_MESSAGES/volto.po +128 -21
  71. package/locales/ro.json +1 -1
  72. package/locales/ru/LC_MESSAGES/volto.po +128 -21
  73. package/locales/ru.json +1 -1
  74. package/locales/sk.json +1 -0
  75. package/locales/sl.json +1 -0
  76. package/locales/sm.json +1 -0
  77. package/locales/sq.json +1 -0
  78. package/locales/sr.json +1 -0
  79. package/locales/sr@cyrl.json +1 -0
  80. package/locales/sr@latn.json +1 -0
  81. package/locales/sv.json +1 -1
  82. package/locales/ta.json +1 -0
  83. package/locales/te.json +1 -0
  84. package/locales/th.json +1 -0
  85. package/locales/to.json +1 -0
  86. package/locales/tr.json +1 -0
  87. package/locales/uk.json +1 -0
  88. package/locales/vi.json +1 -0
  89. package/locales/volto.pot +125 -18
  90. package/locales/zh_CN/LC_MESSAGES/volto.po +124 -17
  91. package/locales/zh_CN.json +1 -1
  92. package/locales/zh_Hant.json +1 -0
  93. package/locales/zh_Hant_HK.json +1 -0
  94. package/package.json +43 -100
  95. package/razzle.config.js +21 -21
  96. package/src/actions/content/content.js +0 -1
  97. package/src/actions/controlpanels/controlpanels.js +13 -7
  98. package/src/actions/controlpanels/controlpanels.test.js +11 -5
  99. package/src/actions/users/users.js +2 -2
  100. package/src/components/manage/Actions/Actions.test.jsx +1 -5
  101. package/src/components/manage/Add/Add.jsx +5 -6
  102. package/src/components/manage/BlockChooser/BlockChooser.jsx +1 -0
  103. package/src/components/manage/Blocks/Block/BlocksForm.test.jsx +1 -5
  104. package/src/components/manage/Blocks/Block/Edit.jsx +1 -0
  105. package/src/components/manage/Blocks/Block/EditBlockWrapper.jsx +9 -4
  106. package/src/components/manage/Blocks/Block/Settings.test.jsx +1 -5
  107. package/src/components/manage/Blocks/HTML/Edit.test.jsx +1 -5
  108. package/src/components/manage/Blocks/Image/Edit.jsx +5 -1
  109. package/src/components/manage/Blocks/Image/ImageSidebar.test.jsx +1 -5
  110. package/src/components/manage/Blocks/LeadImage/Edit.jsx +2 -2
  111. package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.jsx +1 -1
  112. package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.test.jsx +1 -5
  113. package/src/components/manage/Blocks/Listing/ImageGallery.jsx +6 -4
  114. package/src/components/manage/Blocks/Maps/Edit.jsx +2 -1
  115. package/src/components/manage/Blocks/Maps/MapsSidebar.test.jsx +1 -5
  116. package/src/components/manage/Blocks/Search/SearchBlockView.jsx +21 -4
  117. package/src/components/manage/Blocks/Search/components/DateRangeFacet.test.jsx +1 -6
  118. package/src/components/manage/Blocks/Search/components/SelectFacet.test.jsx +1 -6
  119. package/src/components/manage/Blocks/Teaser/Data.jsx +21 -7
  120. package/src/components/manage/Blocks/Teaser/DefaultBody.jsx +1 -1
  121. package/src/components/manage/Blocks/Teaser/schema.js +8 -3
  122. package/src/components/manage/Blocks/Video/Edit.jsx +2 -1
  123. package/src/components/manage/Blocks/Video/VideoSidebar.test.jsx +1 -5
  124. package/src/components/manage/Contents/Contents.jsx +689 -654
  125. package/src/components/manage/Contents/Contents.test.jsx +8 -5
  126. package/src/components/manage/Contents/ContentsBreadcrumbs.Multilingual.test.jsx +18 -5
  127. package/src/components/manage/Contents/ContentsBreadcrumbs.jsx +20 -26
  128. package/src/components/manage/Contents/ContentsBreadcrumbs.test.jsx +14 -0
  129. package/src/components/manage/Contents/ContentsDeleteModal.jsx +258 -206
  130. package/src/components/manage/Contents/ContentsDeleteModal.stories.jsx +26 -8
  131. package/src/components/manage/Contents/ContentsItem.jsx +10 -2
  132. package/src/components/manage/Contents/ContentsPropertiesModal.test.jsx +1 -5
  133. package/src/components/manage/Contents/ContentsRenameModal.test.jsx +1 -5
  134. package/src/components/manage/Contents/ContentsTagsModal.test.jsx +1 -5
  135. package/src/components/manage/Contents/ContentsUploadModal.test.jsx +13 -22
  136. package/src/components/manage/Contents/ContentsWorkflowModal.test.jsx +1 -5
  137. package/src/components/manage/Contents/DropZoneContent.jsx +323 -0
  138. package/src/components/manage/Contents/__mocks__/index.tsx +2 -18
  139. package/src/components/manage/Controlpanels/Aliases.test.jsx +1 -5
  140. package/src/components/manage/Controlpanels/ContentType.jsx +1 -1
  141. package/src/components/manage/Controlpanels/ContentType.test.jsx +1 -5
  142. package/src/components/manage/Controlpanels/Groups/GroupsControlpanel.jsx +3 -2
  143. package/src/components/manage/Controlpanels/Relations/Relations.jsx +1 -1
  144. package/src/components/manage/Controlpanels/Rules/AddRule.test.jsx +1 -5
  145. package/src/components/manage/Controlpanels/Rules/EditRule.test.jsx +1 -5
  146. package/src/components/manage/Controlpanels/UndoControlpanel.test.jsx +1 -5
  147. package/src/components/manage/Controlpanels/Users/RenderUsers.jsx +156 -175
  148. package/src/components/manage/Controlpanels/Users/UsersControlpanel.jsx +575 -630
  149. package/src/components/manage/Controlpanels/Users/UsersControlpanel.test.jsx +4 -3
  150. package/src/components/manage/Diff/Diff.test.jsx +1 -6
  151. package/src/components/manage/Diff/DiffField.test.jsx +1 -6
  152. package/src/components/manage/Display/Display.test.jsx +2 -11
  153. package/src/components/manage/Edit/Edit.jsx +2 -3
  154. package/src/components/manage/Edit/Edit.test.jsx +1 -5
  155. package/src/components/manage/Form/BlockDataForm.test.jsx +1 -5
  156. package/src/components/manage/Form/Form.test.jsx +1 -5
  157. package/src/components/manage/Form/InlineForm.jsx +2 -2
  158. package/src/components/manage/Form/InlineForm.test.jsx +1 -5
  159. package/src/components/manage/Form/ModalForm.jsx +12 -10
  160. package/src/components/manage/Form/ModalForm.test.jsx +27 -5
  161. package/src/components/manage/Form/__mocks__/index.tsx +9 -27
  162. package/src/components/manage/Multilingual/CompareLanguages.jsx +2 -5
  163. package/src/components/manage/Multilingual/CreateTranslation.jsx +8 -8
  164. package/src/components/manage/Multilingual/ManageTranslations.jsx +4 -2
  165. package/src/components/manage/Multilingual/ManageTranslations.test.jsx +5 -1
  166. package/src/components/manage/Multilingual/TranslationObject.jsx +1 -1
  167. package/src/components/manage/Preferences/ChangePassword.test.jsx +1 -5
  168. package/src/components/manage/Preferences/PersonalPreferences.test.jsx +1 -17
  169. package/src/components/manage/Sidebar/ObjectBrowser.jsx +3 -0
  170. package/src/components/manage/Sidebar/ObjectBrowserBody.jsx +13 -1
  171. package/src/components/manage/Sidebar/ObjectBrowserNav.jsx +2 -1
  172. package/src/components/manage/Sidebar/SidebarPortal.test.tsx +42 -0
  173. package/src/components/manage/Sidebar/SidebarPortal.tsx +48 -0
  174. package/src/components/manage/TemplateChooser/TemplateChooser.jsx +2 -1
  175. package/src/components/manage/Toolbar/More.jsx +4 -1
  176. package/src/components/manage/Toolbar/More.test.jsx +3 -0
  177. package/src/components/manage/Toolbar/PersonalTools.jsx +2 -1
  178. package/src/components/manage/Toolbar/Toolbar.jsx +3 -4
  179. package/src/components/manage/Toolbar/Types.jsx +7 -7
  180. package/src/components/manage/UniversalLink/UniversalLink.tsx +1 -0
  181. package/src/components/manage/Widgets/AlignWidget.stories.jsx +9 -0
  182. package/src/components/manage/Widgets/AlignWidget.test.tsx +95 -0
  183. package/src/components/manage/Widgets/{AlignWidget.jsx → AlignWidget.tsx} +23 -7
  184. package/src/components/manage/Widgets/ArrayWidget.test.jsx +1 -6
  185. package/src/components/manage/Widgets/BlockAlignment.stories.tsx +104 -0
  186. package/src/components/manage/Widgets/BlockAlignment.test.tsx +104 -0
  187. package/src/components/manage/Widgets/BlockAlignment.tsx +88 -0
  188. package/src/components/manage/Widgets/BlockWidth.stories.tsx +69 -0
  189. package/src/components/manage/Widgets/BlockWidth.test.tsx +62 -0
  190. package/src/components/manage/Widgets/BlockWidth.tsx +101 -0
  191. package/src/components/manage/Widgets/ButtonsWidget.stories.jsx +61 -0
  192. package/src/components/manage/Widgets/ButtonsWidget.test.tsx +138 -0
  193. package/src/components/manage/Widgets/ButtonsWidget.tsx +176 -0
  194. package/src/components/manage/Widgets/CheckboxGroupWidget.test.jsx +1 -6
  195. package/src/components/manage/Widgets/DatetimeWidget.jsx +16 -1
  196. package/src/components/manage/Widgets/DatetimeWidget.test.jsx +1 -6
  197. package/src/components/manage/Widgets/FileWidget.jsx +14 -8
  198. package/src/components/manage/Widgets/FormFieldWrapper.jsx +146 -168
  199. package/src/components/manage/Widgets/ImageWidget.jsx +171 -38
  200. package/src/components/manage/Widgets/InternalUrlWidget.jsx +2 -0
  201. package/src/components/manage/Widgets/ObjectBrowserWidget.jsx +8 -0
  202. package/src/components/manage/Widgets/ObjectListWidget.test.jsx +2 -11
  203. package/src/components/manage/Widgets/ObjectWidget.test.jsx +1 -5
  204. package/src/components/manage/Widgets/QueryWidget.jsx +137 -9
  205. package/src/components/manage/Widgets/RadioGroupWidget.test.jsx +1 -6
  206. package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.test.jsx +1 -6
  207. package/src/components/manage/Widgets/RegistryImageWidget.test.jsx +3 -2
  208. package/src/components/manage/Widgets/SchemaWidget.test.jsx +1 -6
  209. package/src/components/manage/Widgets/SchemaWidgetFieldset.test.jsx +1 -6
  210. package/src/components/manage/Widgets/SelectAutoComplete.jsx +29 -12
  211. package/src/components/manage/Widgets/SelectAutoComplete.test.jsx +1 -6
  212. package/src/components/manage/Widgets/SelectWidget.test.jsx +1 -6
  213. package/src/components/manage/Widgets/Size.stories.tsx +69 -0
  214. package/src/components/manage/Widgets/Size.test.tsx +59 -0
  215. package/src/components/manage/Widgets/Size.tsx +78 -0
  216. package/src/components/manage/Widgets/TimeWidget.test.jsx +1 -6
  217. package/src/components/manage/Widgets/TokenWidget.test.jsx +1 -6
  218. package/src/components/manage/Widgets/UrlWidget.jsx +2 -0
  219. package/src/components/manage/Widgets/VocabularyTermsWidget.test.jsx +2 -11
  220. package/src/components/manage/Widgets/__mocks__/index.tsx +33 -51
  221. package/src/components/manage/Widgets/index.tsx +21 -0
  222. package/src/components/manage/Workflow/Workflow.test.jsx +2 -11
  223. package/src/components/theme/AlternateHrefLangs/AlternateHrefLangs.jsx +1 -3
  224. package/src/components/theme/AlternateHrefLangs/AlternateHrefLangs.test.jsx +0 -4
  225. package/src/components/theme/App/App.jsx +5 -1
  226. package/src/components/theme/App/App.test.jsx +1 -0
  227. package/src/components/theme/Avatar/Avatar.jsx +2 -1
  228. package/src/components/theme/Comments/CommentEditModal.test.jsx +1 -5
  229. package/src/components/theme/Comments/Comments.test.jsx +2 -11
  230. package/src/components/theme/ContactForm/ContactForm.test.jsx +1 -5
  231. package/src/components/theme/FormattedDate/FormattedDate.stories.jsx +20 -2
  232. package/src/components/theme/Image/Image.jsx +11 -8
  233. package/src/components/theme/InjectPloneComponentsCSS/InjectPloneComponentsCSS.tsx +7 -0
  234. package/src/components/theme/LanguageSelector/{LanguageSelector.test.jsx → LanguageSelector.test.tsx} +6 -6
  235. package/src/components/theme/LanguageSelector/LanguageSelector.tsx +89 -0
  236. package/src/components/theme/Logo/Logo.Multilingual.test.jsx +0 -5
  237. package/src/components/theme/MultilingualRedirector/MultilingualRedirector.jsx +10 -14
  238. package/src/components/theme/MultilingualRedirector/MultilingualRedirector.test.jsx +3 -5
  239. package/src/components/theme/Navigation/NavItem.jsx +1 -5
  240. package/src/components/theme/Navigation/Navigation.Multilingual.test.jsx +0 -5
  241. package/src/components/theme/NotFound/NotFound.jsx +5 -2
  242. package/src/components/theme/NotFound/NotFound.test.jsx +3 -0
  243. package/src/components/theme/PasswordReset/RequestPasswordReset.test.jsx +1 -5
  244. package/src/components/theme/PreviewImage/PreviewImage.jsx +1 -1
  245. package/src/components/theme/Register/Register.test.jsx +1 -5
  246. package/src/components/theme/RequestTimeout/RequestTimeout.jsx +1 -1
  247. package/src/components/theme/Sitemap/Sitemap.jsx +6 -5
  248. package/src/components/theme/Sitemap/Sitemap.test.jsx +0 -1
  249. package/src/components/theme/Unauthorized/Unauthorized.jsx +5 -2
  250. package/src/components/theme/View/EventDatesInfo.test.jsx +1 -6
  251. package/src/components/theme/View/EventView.test.jsx +1 -6
  252. package/src/components/theme/View/FileView.jsx +9 -1
  253. package/src/components/theme/View/View.jsx +8 -1
  254. package/src/components/theme/Widgets/ImageWidget.jsx +2 -1
  255. package/src/config/ControlPanels.js +1 -0
  256. package/src/config/Widgets.jsx +7 -0
  257. package/src/config/index.js +18 -25
  258. package/src/config/server.js +0 -2
  259. package/src/config/slots.js +19 -0
  260. package/src/express-middleware/devproxy.js +20 -5
  261. package/src/helpers/Api/APIResourceWithAuth.js +8 -3
  262. package/src/helpers/Api/Api.js +7 -4
  263. package/src/helpers/AsyncConnect/ssr.js +4 -1
  264. package/src/helpers/Content/Content.js +23 -0
  265. package/src/helpers/Content/Content.test.js +39 -0
  266. package/src/helpers/Content/withClientSideContent.jsx +35 -0
  267. package/src/helpers/Extensions/withBlockSchemaEnhancer.jsx +4 -1
  268. package/src/helpers/Html/Html.jsx +13 -7
  269. package/src/helpers/LanguageMap/LanguageMap.js +115 -8
  270. package/src/helpers/Loadable/__mocks__/Loadable.jsx +7 -22
  271. package/src/helpers/MessageLabels/MessageLabels.js +5 -0
  272. package/src/helpers/Sitemap/Sitemap.js +4 -4
  273. package/src/helpers/Url/Url.js +33 -2
  274. package/src/helpers/Url/Url.test.js +62 -0
  275. package/src/hooks/user/useUser.js +1 -1
  276. package/src/internalChecks.test.ts +11 -0
  277. package/src/middleware/Api.test.js +4 -0
  278. package/src/middleware/api.js +82 -28
  279. package/src/middleware/storeProtectLoadUtils.test.js +3 -3
  280. package/src/reducers/content/content.js +3 -18
  281. package/src/reducers/diff/diff.js +5 -1
  282. package/src/reducers/diff/diff.test.js +60 -4
  283. package/src/reducers/querystring/querystring.js +8 -1
  284. package/src/routes.js +4 -2
  285. package/src/server.jsx +45 -14
  286. package/src/start-client.jsx +9 -6
  287. package/src/start-server.js +9 -3
  288. package/test-addons-loader.js +3 -0
  289. package/test-setup-config.jsx +0 -2
  290. package/test-setup-globals.js +30 -2
  291. package/theme/themes/pastanaga/extras/blocks.less +26 -0
  292. package/theme/themes/pastanaga/extras/contents.less +80 -5
  293. package/theme/themes/pastanaga/extras/main.less +17 -2
  294. package/theme/themes/pastanaga/extras/widgets.less +79 -0
  295. package/tsconfig.declarations.json +1 -1
  296. package/tsconfig.json +4 -5
  297. package/types/components/manage/Blocks/Teaser/schema.d.ts +1 -0
  298. package/types/components/manage/Contents/DropZoneContent.d.ts +2 -0
  299. package/types/components/manage/Contents/__mocks__/index.d.ts +2 -2
  300. package/types/components/manage/Controlpanels/Relations/RelationsMatrix.d.ts +1 -1
  301. package/types/components/manage/Controlpanels/Users/RenderUsers.d.ts +18 -2
  302. package/types/components/manage/Controlpanels/Users/UsersControlpanel.d.ts +6 -2
  303. package/types/components/manage/Controlpanels/index.d.ts +2 -2
  304. package/types/components/manage/Form/__mocks__/index.d.ts +8 -8
  305. package/types/components/manage/Multilingual/ManageTranslations.d.ts +1 -1
  306. package/types/components/manage/Sidebar/ObjectBrowser.d.ts +1 -1
  307. package/types/components/manage/Sidebar/SidebarPortal.d.ts +7 -15
  308. package/types/components/manage/Widgets/AlignWidget.d.ts +8 -10
  309. package/types/components/manage/Widgets/AlignWidget.stories.d.ts +1 -0
  310. package/types/components/manage/Widgets/BlockAlignment.d.ts +7 -0
  311. package/types/components/manage/Widgets/BlockAlignment.stories.d.ts +8 -0
  312. package/types/components/manage/Widgets/BlockWidth.d.ts +7 -0
  313. package/types/components/manage/Widgets/BlockWidth.stories.d.ts +6 -0
  314. package/types/components/manage/Widgets/ButtonsWidget.d.ts +48 -1
  315. package/types/components/manage/Widgets/ButtonsWidget.stories.d.ts +3 -0
  316. package/types/components/manage/Widgets/FormFieldWrapper.d.ts +28 -5
  317. package/types/components/manage/Widgets/ImageWidget.d.ts +41 -1
  318. package/types/components/manage/Widgets/InternalUrlWidget.d.ts +1 -1
  319. package/types/components/manage/Widgets/ObjectBrowserWidget.d.ts +2 -0
  320. package/types/components/manage/Widgets/QueryWidget.d.ts +5 -2
  321. package/types/components/manage/Widgets/RecurrenceWidget/Utils.d.ts +12 -18
  322. package/types/components/manage/Widgets/Size.d.ts +7 -0
  323. package/types/components/manage/Widgets/Size.stories.d.ts +6 -0
  324. package/types/components/manage/Widgets/UrlWidget.d.ts +1 -1
  325. package/types/components/manage/Widgets/__mocks__/index.d.ts +33 -33
  326. package/types/components/manage/Widgets/index.d.ts +11 -6
  327. package/types/components/theme/FormattedDate/FormattedDate.stories.d.ts +1 -1
  328. package/types/components/theme/InjectPloneComponentsCSS/InjectPloneComponentsCSS.d.ts +3 -0
  329. package/types/components/theme/LanguageSelector/LanguageSelector.d.ts +3 -10
  330. package/types/components/theme/Unauthorized/Unauthorized.d.ts +2 -2
  331. package/types/config/Widgets.d.ts +6 -0
  332. package/types/config/slots.d.ts +7 -0
  333. package/types/helpers/Content/Content.d.ts +7 -0
  334. package/types/helpers/Content/withClientSideContent.d.ts +1 -0
  335. package/types/helpers/Extensions/withBlockSchemaEnhancer.d.ts +4 -5
  336. package/types/helpers/Helmet/Helmet.d.ts +1 -1
  337. package/types/helpers/LanguageMap/LanguageMap.d.ts +428 -4
  338. package/types/helpers/Loadable/__mocks__/Loadable.d.ts +2 -2
  339. package/types/helpers/MessageLabels/MessageLabels.d.ts +68 -62
  340. package/types/helpers/Url/Url.d.ts +14 -0
  341. package/types/helpers/Url/bulkFlattenToAppURL.d.ts +5 -0
  342. package/types/middleware/api.d.ts +6 -9
  343. package/types/reducers/index.d.ts +1 -0
  344. package/types/start-client.d.ts +0 -1
  345. package/vitest.config.mjs +4 -4
  346. package/webpack-plugins/webpack-scss-plugin.js +172 -0
  347. package/jest-addons-loader.js +0 -3
  348. package/jest-extender-plugin.js +0 -39
  349. package/jest-setup-afterenv.js +0 -2
  350. package/jest-svgsystem-transform.js +0 -10
  351. package/package-why.json +0 -34
  352. package/patches/patchit.sh +0 -2
  353. package/patches/razzle-jest.patch +0 -10
  354. package/src/actions/content/content.multilingual.test.js +0 -17
  355. package/src/components/manage/Contents/__mocks__/index.vitest.tsx +0 -5
  356. package/src/components/manage/Form/__mocks__/index.vitest.tsx +0 -73
  357. package/src/components/manage/Sidebar/SidebarPortal.jsx +0 -47
  358. package/src/components/manage/Sidebar/SidebarPortal.test.jsx +0 -26
  359. package/src/components/manage/Widgets/AlignWidget.test.jsx +0 -59
  360. package/src/components/manage/Widgets/ButtonsWidget.jsx +0 -41
  361. package/src/components/manage/Widgets/ButtonsWidget.test.jsx +0 -70
  362. package/src/components/manage/Widgets/__mocks__/index.vitest.tsx +0 -41
  363. package/src/components/theme/LanguageSelector/LanguageSelector.jsx +0 -77
  364. package/src/helpers/Loadable/__mocks__/Loadable.vitest.jsx +0 -39
  365. package/test-setup-globals-vitest.js +0 -46
  366. package/theme/themes/pastanaga/extras/utils.less +0 -63
@@ -35,6 +35,9 @@ import {
35
35
  RecurrenceWidget,
36
36
  RadioGroupWidget,
37
37
  CheckboxGroupWidget,
38
+ Size,
39
+ BlockAlignment,
40
+ BlockWidth,
38
41
  } from '@plone/volto/components/manage/Widgets';
39
42
 
40
43
  import ArrayViewWidget from '@plone/volto/components/theme/Widgets/ArrayWidget';
@@ -102,6 +105,10 @@ export const widgetMapping = {
102
105
  hidden: HiddenWidget,
103
106
  radio_group: RadioGroupWidget,
104
107
  checkbox_group: CheckboxGroupWidget,
108
+ // SemanticUI Free widgets
109
+ blockAlignment: BlockAlignment,
110
+ blockWidth: BlockWidth,
111
+ size: Size,
105
112
  },
106
113
  vocabulary: {
107
114
  'plone.app.vocabularies.Catalog': ObjectBrowserWidget,
@@ -25,13 +25,11 @@ import { installDefaultBlocks } from './Blocks';
25
25
  import { getSiteAsyncPropExtender } from '@plone/volto/helpers/Site';
26
26
  import { registerValidators } from './validation';
27
27
 
28
+ import languages from '@plone/volto/constants/Languages.cjs';
29
+
28
30
  const host = process.env.HOST || 'localhost';
29
31
  const port = process.env.PORT || '3000';
30
32
 
31
- const apiPath =
32
- process.env.RAZZLE_API_PATH ||
33
- (__DEVELOPMENT__ ? `http://${host}:${port}` : '');
34
-
35
33
  const getServerURL = (url) => {
36
34
  if (!url) return;
37
35
  const apiPathURL = parseUrl(url);
@@ -44,12 +42,14 @@ const getServerURL = (url) => {
44
42
  // if RAZZLE_PUBLIC_URL is present, use it
45
43
  // if in DEV, use the host/port combination by default
46
44
  // if in PROD, assume it's RAZZLE_API_PATH server name (no /api or alikes) or fallback
47
- // to DEV settings if RAZZLE_API_PATH is not present
45
+ // to DEV settings if RAZZLE_API_PATH is not present.
46
+ // Finally, add the subpath, if there is one.
48
47
  const publicURL =
49
- process.env.RAZZLE_PUBLIC_URL ||
50
- (__DEVELOPMENT__
51
- ? `http://${host}:${port}`
52
- : getServerURL(process.env.RAZZLE_API_PATH) || `http://${host}:${port}`);
48
+ (process.env.RAZZLE_PUBLIC_URL ||
49
+ (__DEVELOPMENT__
50
+ ? `http://${host}:${port}`
51
+ : getServerURL(process.env.RAZZLE_API_PATH) ||
52
+ `http://${host}:${port}`)) + (process.env.RAZZLE_SUBPATH_PREFIX || '');
53
53
 
54
54
  const serverConfig =
55
55
  typeof __SERVER__ !== 'undefined' && __SERVER__
@@ -63,7 +63,10 @@ let config = {
63
63
  // The URL Volto is going to be served (see sensible defaults above)
64
64
  publicURL,
65
65
  okRoute: '/ok',
66
- apiPath,
66
+ // Base URL for API requests from the browser.
67
+ // If not explicitly set, use the publicURL (seamless mode) --
68
+ // but in that case it will be updated in server.jsx for each request.
69
+ apiPath: process.env.RAZZLE_API_PATH || publicURL,
67
70
  apiExpanders: [
68
71
  // Added here for documentation purposes, added at the end because it
69
72
  // depends on a value of this object.
@@ -97,6 +100,7 @@ let config = {
97
100
  // apiPath: process.env.RAZZLE_API_PATH || 'http://localhost:8081/db/web', // for guillotina
98
101
  actions_raising_api_errors: ['GET_CONTENT', 'UPDATE_CONTENT'],
99
102
  internalApiPath: process.env.RAZZLE_INTERNAL_API_PATH || undefined,
103
+ subpathPrefix: process.env.RAZZLE_SUBPATH_PREFIX || '',
100
104
  websockets: process.env.RAZZLE_WEBSOCKETS || false,
101
105
  // TODO: legacyTraverse to be removed when the use of the legacy traverse is deprecated.
102
106
  legacyTraverse: process.env.RAZZLE_LEGACY_TRAVERSE || false,
@@ -111,9 +115,7 @@ let config = {
111
115
  openExternalLinkInNewTab: false,
112
116
  notSupportedBrowsers: ['ie'],
113
117
  defaultPageSize: 25,
114
- isMultilingual: false,
115
- supportedLanguages: ['en'],
116
- defaultLanguage: process.env.SITE_DEFAULT_LANGUAGE || 'en',
118
+ supportedLanguages: Object.keys(languages),
117
119
  navDepth: 1,
118
120
  expressMiddleware: serverConfig.expressMiddleware, // BBB
119
121
  defaultBlockType: 'slate',
@@ -141,7 +143,7 @@ let config = {
141
143
  serverConfig,
142
144
  storeExtenders: [],
143
145
  showTags: true,
144
- showRelatedItems: false,
146
+ showRelatedItems: true,
145
147
  controlpanels: [],
146
148
  controlPanelsIcons,
147
149
  filterControlPanels,
@@ -198,7 +200,8 @@ config.settings.apiExpanders = [
198
200
  ...config.settings.apiExpanders,
199
201
  {
200
202
  match: '',
201
- GET_CONTENT: ['breadcrumbs', 'actions', 'types', 'navroot'],
203
+ GET_CONTENT: ['breadcrumbs', 'actions', 'types', 'navroot', 'translations'],
204
+ // Note: translations is removed in the API middleware if the site is not multilingual.
202
205
  },
203
206
  {
204
207
  match: '',
@@ -232,16 +235,6 @@ Object.entries(slots).forEach(([slotName, components]) => {
232
235
  });
233
236
  });
234
237
 
235
- // Make sure that process.env.SITE_DEFAULT_LANGUAGE is set in availableLanguages
236
- if (
237
- process.env.SITE_DEFAULT_LANGUAGE &&
238
- !config.settings.supportedLanguages.includes(
239
- process.env.SITE_DEFAULT_LANGUAGE,
240
- )
241
- ) {
242
- config.settings.supportedLanguages.push(process.env.SITE_DEFAULT_LANGUAGE);
243
- }
244
-
245
238
  registerValidators(ConfigRegistry);
246
239
  installDefaultComponents(ConfigRegistry);
247
240
  installDefaultWidgets(ConfigRegistry);
@@ -1,7 +1,6 @@
1
1
  import imagesMiddleware from '@plone/volto/express-middleware/images';
2
2
  import filesMiddleware from '@plone/volto/express-middleware/files';
3
3
  import robotstxtMiddleware from '@plone/volto/express-middleware/robotstxt';
4
- import okMiddleware from '@plone/volto/express-middleware/ok';
5
4
  import sitemapMiddleware from '@plone/volto/express-middleware/sitemap';
6
5
  import staticsMiddleware from '@plone/volto/express-middleware/static';
7
6
  import devProxyMiddleware from '@plone/volto/express-middleware/devproxy';
@@ -12,7 +11,6 @@ const settings = {
12
11
  filesMiddleware(),
13
12
  imagesMiddleware(),
14
13
  robotstxtMiddleware(),
15
- okMiddleware(),
16
14
  sitemapMiddleware(),
17
15
  staticsMiddleware(),
18
16
  ],
@@ -1,7 +1,26 @@
1
+ import loadable from '@loadable/component';
1
2
  import RelatedItems from '@plone/volto/components/theme/RelatedItems/RelatedItems';
2
3
  import Tags from '@plone/volto/components/theme/Tags/Tags';
4
+ import { isCmsUi } from '@plone/volto/helpers/Url/Url';
5
+
6
+ const InjectPloneComponentsCSS = loadable(
7
+ () =>
8
+ import(
9
+ '@plone/volto/components/theme/InjectPloneComponentsCSS/InjectPloneComponentsCSS'
10
+ ),
11
+ { fallback: null },
12
+ );
13
+
14
+ const onlyCMSUI = ({ location }) => isCmsUi(location?.pathname);
3
15
 
4
16
  const slots = {
17
+ aboveApp: [
18
+ {
19
+ name: 'plone-components-css',
20
+ component: InjectPloneComponentsCSS,
21
+ predicates: [onlyCMSUI],
22
+ },
23
+ ],
5
24
  belowContent: [
6
25
  {
7
26
  name: 'tags',
@@ -10,8 +10,16 @@ import querystring from 'querystring';
10
10
  import { parse as parseUrl } from 'url';
11
11
 
12
12
  const filter = function (pathname, req) {
13
- // This is the proxy to the API in case the accept header is 'application/json'
14
- return config.settings.devProxyToApiPath && pathname.startsWith('/++api++');
13
+ // Check if pathname is defined, there are some corner cases that pathname is null
14
+ if (pathname) {
15
+ // This is the proxy to the API in case the accept header is 'application/json'
16
+ return (
17
+ config.settings.devProxyToApiPath &&
18
+ pathname.startsWith(`${config.settings.subpathPrefix}/++api++`)
19
+ );
20
+ } else {
21
+ return false;
22
+ }
15
23
  };
16
24
 
17
25
  let _env = null;
@@ -73,17 +81,24 @@ export default function devProxyMiddleware() {
73
81
  },
74
82
  pathRewrite: (path, req) => {
75
83
  const { apiPathURL, instancePath } = getEnv();
84
+ const vhSubpath = config.settings.subpathPrefix
85
+ ? config.settings.subpathPrefix
86
+ .split('/')
87
+ .filter(Boolean)
88
+ .map((part) => '/_vh_' + part)
89
+ .join('')
90
+ : '';
76
91
  const target =
77
92
  config.settings.proxyRewriteTarget ||
78
93
  `/VirtualHostBase/${apiPathURL.protocol.slice(0, -1)}/${
79
94
  apiPathURL.hostname
80
- }:${apiPathURL.port}${instancePath}/++api++/VirtualHostRoot`;
95
+ }:${apiPathURL.port}${instancePath}/++api++/VirtualHostRoot${vhSubpath}`;
81
96
 
82
- return `${target}${path.replace('/++api++', '')}`;
97
+ return `${target}${path.replace(`${config.settings.subpathPrefix}/++api++`, '')}`;
83
98
  },
99
+ changeOrigin: true,
84
100
  logLevel: process.env.DEBUG_HPM ? 'debug' : 'silent',
85
101
  ...(process.env.RAZZLE_DEV_PROXY_INSECURE && {
86
- changeOrigin: true,
87
102
  secure: false,
88
103
  }),
89
104
  });
@@ -6,6 +6,7 @@
6
6
  import superagent from 'superagent';
7
7
  import config from '@plone/volto/registry';
8
8
  import { addHeadersFactory } from '@plone/volto/helpers/Proxy/Proxy';
9
+ import { stripSubpathPrefix } from '@plone/volto/helpers/Url/Url';
9
10
 
10
11
  /**
11
12
  * Get a resource image/file with authenticated (if token exist) API headers
@@ -16,9 +17,9 @@ import { addHeadersFactory } from '@plone/volto/helpers/Proxy/Proxy';
16
17
  export const getAPIResourceWithAuth = (req) =>
17
18
  new Promise((resolve, reject) => {
18
19
  const { settings } = config;
19
- const APISUFIX = settings.legacyTraverse ? '' : '/++api++';
20
-
20
+ const apiSuffix = settings.legacyTraverse ? '' : '/++api++';
21
21
  let apiPath = '';
22
+
22
23
  if (settings.internalApiPath && __SERVER__) {
23
24
  apiPath = settings.internalApiPath;
24
25
  } else if (__DEVELOPMENT__ && settings.devProxyToApiPath) {
@@ -26,8 +27,12 @@ export const getAPIResourceWithAuth = (req) =>
26
27
  } else {
27
28
  apiPath = settings.apiPath;
28
29
  }
30
+
31
+ //strip subpath if any
32
+ const contentPath = stripSubpathPrefix(req.path);
33
+
29
34
  const request = superagent
30
- .get(`${apiPath}${__DEVELOPMENT__ ? '' : APISUFIX}${req.path}`)
35
+ .get(`${apiPath}${__DEVELOPMENT__ ? '' : apiSuffix}${contentPath}`)
31
36
  .maxResponseSize(settings.maxResponseSize)
32
37
  .responseType('blob');
33
38
  const authToken = req.universalCookies.get('auth_token');
@@ -7,7 +7,10 @@ import superagent from 'superagent';
7
7
  import Cookies from 'universal-cookie';
8
8
  import config from '@plone/volto/registry';
9
9
  import { addHeadersFactory } from '@plone/volto/helpers/Proxy/Proxy';
10
- import { stripQuerystring } from '@plone/volto/helpers/Url/Url';
10
+ import {
11
+ stripQuerystring,
12
+ stripSubpathPrefix,
13
+ } from '@plone/volto/helpers/Url/Url';
11
14
 
12
15
  const methods = ['get', 'post', 'put', 'patch', 'del'];
13
16
 
@@ -19,11 +22,10 @@ const methods = ['get', 'post', 'put', 'patch', 'del'];
19
22
  */
20
23
  export function formatUrl(path) {
21
24
  const { settings } = config;
22
- const APISUFIX = settings.legacyTraverse ? '' : '/++api++';
25
+ const apiSuffix = settings.legacyTraverse ? '' : '/++api++';
23
26
 
24
27
  if (path.startsWith('http://') || path.startsWith('https://')) return path;
25
28
 
26
- const adjustedPath = path[0] !== '/' ? `/${path}` : path;
27
29
  let apiPath = '';
28
30
  if (settings.internalApiPath && __SERVER__) {
29
31
  apiPath = settings.internalApiPath;
@@ -31,7 +33,8 @@ export function formatUrl(path) {
31
33
  apiPath = settings.apiPath;
32
34
  }
33
35
 
34
- return `${apiPath}${APISUFIX}${adjustedPath}`;
36
+ const contentPath = stripSubpathPrefix(path[0] !== '/' ? `/${path}` : path);
37
+ return `${apiPath}${apiSuffix}${contentPath}`;
35
38
  }
36
39
 
37
40
  /**
@@ -1,6 +1,7 @@
1
1
  import { matchRoutes } from 'react-router-config';
2
2
  import { mapSeries, isPromise } from './utils';
3
3
  import { endGlobalLoad } from '@plone/volto/actions/asyncConnect/asyncConnect';
4
+ import { stripSubpathPrefix } from '@plone/volto/helpers/Url/Url';
4
5
 
5
6
  export function filterComponents(branch) {
6
7
  return branch.reduce((result, { route, match }) => {
@@ -18,7 +19,9 @@ export function loadAsyncConnect({
18
19
  filter = () => true,
19
20
  ...rest
20
21
  }) {
21
- const layered = filterComponents(matchRoutes(routes, location.pathname));
22
+ const layered = filterComponents(
23
+ matchRoutes(routes, stripSubpathPrefix(location.pathname)),
24
+ );
22
25
 
23
26
  if (layered.length === 0) {
24
27
  return Promise.resolve();
@@ -11,6 +11,7 @@ import keys from 'lodash/keys';
11
11
  import endsWith from 'lodash/endsWith';
12
12
  import find from 'lodash/find';
13
13
  import config from '@plone/volto/registry';
14
+ import omit from 'lodash/omit';
14
15
 
15
16
  /**
16
17
  * Nest content.
@@ -85,3 +86,25 @@ export function getLanguageIndependentFields(schema) {
85
86
  properties[field]['multilingual_options']?.['language_independent'],
86
87
  );
87
88
  }
89
+
90
+ /**
91
+ * Flattens static behaviors into the parent object with dot-notation keys.
92
+ * @function flattenStaticBehaviors
93
+ * @param {Object} result The result object containing static behaviors.
94
+ * @returns {Object} Result object with flattened static behaviors.
95
+ */
96
+ export function flattenStaticBehaviors(result) {
97
+ if (!result['@static_behaviors']) {
98
+ return result;
99
+ }
100
+
101
+ let flattened = Object.assign({}, result);
102
+ map(result['@static_behaviors'], (behavior) => {
103
+ flattened = {
104
+ ...omit(flattened, behavior),
105
+ ...mapKeys(flattened[behavior], (value, key) => `${behavior}.${key}`),
106
+ };
107
+ });
108
+
109
+ return flattened;
110
+ }
@@ -2,6 +2,7 @@ import {
2
2
  nestContent,
3
3
  getContentIcon,
4
4
  getLanguageIndependentFields,
5
+ flattenStaticBehaviors,
5
6
  } from './Content';
6
7
  import contentExistingSVG from '@plone/volto/icons/content-existing.svg';
7
8
  import linkSVG from '@plone/volto/icons/link.svg';
@@ -96,4 +97,42 @@ describe('Content', () => {
96
97
  expect(getLanguageIndependentFields(schema)).toStrictEqual(['lif']);
97
98
  });
98
99
  });
100
+
101
+ describe('flattenStaticBehaviors', () => {
102
+ it('returns object unchanged when no @static_behaviors', () => {
103
+ const input = {
104
+ title: 'Example',
105
+ creator: 'admin',
106
+ };
107
+ expect(flattenStaticBehaviors(input)).toEqual(input);
108
+ });
109
+
110
+ it('flattens static behaviors into dot-notation keys', () => {
111
+ const input = {
112
+ title: 'Example',
113
+ '@static_behaviors': [
114
+ 'guillotina_cms.interfaces.blocks.IBlocks',
115
+ 'guillotina_cms.interfaces.dublin_core.IDublinCore',
116
+ ],
117
+ 'guillotina_cms.interfaces.blocks.IBlocks': {
118
+ blocks: 'blocks',
119
+ blocks_layout: 'blocks_layout',
120
+ },
121
+ 'guillotina_cms.interfaces.dublin_core.IDublinCore': {
122
+ creator: 'creator',
123
+ },
124
+ };
125
+ expect(flattenStaticBehaviors(input)).toEqual({
126
+ title: 'Example',
127
+ '@static_behaviors': [
128
+ 'guillotina_cms.interfaces.blocks.IBlocks',
129
+ 'guillotina_cms.interfaces.dublin_core.IDublinCore',
130
+ ],
131
+ 'guillotina_cms.interfaces.blocks.IBlocks.blocks': 'blocks',
132
+ 'guillotina_cms.interfaces.blocks.IBlocks.blocks_layout':
133
+ 'blocks_layout',
134
+ 'guillotina_cms.interfaces.dublin_core.IDublinCore.creator': 'creator',
135
+ });
136
+ });
137
+ });
99
138
  });
@@ -0,0 +1,35 @@
1
+ /*
2
+ This is a HOC for use with the volto Edit component.
3
+ It makes sure that we fetch the content from the API on the client side
4
+ when the Edit component is mounted, if there is an internalApiPath
5
+ that is different from the public API path. Otherwise we might end up
6
+ saving backend API paths back to the server.
7
+
8
+ It's admittedly a bit of a workaround.
9
+ Ideally the volto SSR should produce correct URLs
10
+ so that we don't have to do this on the client side.
11
+ But, that requires refactoring that won't happen quickly...
12
+ */
13
+
14
+ import { useEffect } from 'react';
15
+ import { useDispatch, useSelector } from 'react-redux';
16
+ import hoistNonReactStatics from 'hoist-non-react-statics';
17
+ import config from '@plone/volto/registry';
18
+ import { getContent } from '@plone/volto/actions/content/content';
19
+
20
+ export default function withClientSideContent(WrappedComponent) {
21
+ function WithClientSideContent(props) {
22
+ const { internalApiPath } = config.settings;
23
+ const dispatch = useDispatch();
24
+ const content = useSelector((state) => state.content);
25
+ const id = content.data?.['@id'];
26
+ useEffect(() => {
27
+ if (internalApiPath && id?.startsWith(internalApiPath)) {
28
+ dispatch(getContent(id.substring(internalApiPath.length)));
29
+ }
30
+ }, [internalApiPath, dispatch, id]);
31
+ return <WrappedComponent {...props} />;
32
+ }
33
+
34
+ return hoistNonReactStatics(WithClientSideContent, WrappedComponent);
35
+ }
@@ -305,8 +305,11 @@ export const EMPTY_STYLES_SCHEMA = {
305
305
 
306
306
  /**
307
307
  * Adds the `styles` field and 'styling' fieldset in a given schema
308
+ * @param {object} params Helper params
309
+ * @param {import('@plone/types').JSONSchema} params.schema Schema to enhance
310
+ * @param {import('react-intl').IntlShape} params.intl intl helper for translations
308
311
  */
309
- export const addStyling = ({ schema, formData, intl }) => {
312
+ export const addStyling = ({ schema, intl }) => {
310
313
  if (isEmpty(find(schema.fieldsets, { id: 'styling' }))) {
311
314
  schema.fieldsets.push({
312
315
  id: 'styling',
@@ -9,6 +9,7 @@ import Helmet from '@plone/volto/helpers/Helmet/Helmet';
9
9
  import serialize from 'serialize-javascript';
10
10
  import join from 'lodash/join';
11
11
  import BodyClass from '@plone/volto/helpers/BodyClass/BodyClass';
12
+ import { addSubpathPrefix } from '@plone/volto/helpers/Url/Url';
12
13
  import { runtimeConfig } from '@plone/volto/runtime_config';
13
14
  import config from '@plone/volto/registry';
14
15
 
@@ -122,21 +123,26 @@ class Html extends Component {
122
123
  ...(publicURL && {
123
124
  publicURL,
124
125
  }),
125
- ...(process.env.SITE_DEFAULT_LANGUAGE && {
126
- defaultLanguage: process.env.SITE_DEFAULT_LANGUAGE,
127
- }),
128
126
  })};`,
129
127
  }}
130
128
  />
131
129
 
132
- <link rel="icon" href="/favicon.ico" sizes="any" />
133
- <link rel="icon" href="/icon.svg" type="image/svg+xml" />
130
+ <link
131
+ rel="icon"
132
+ href={addSubpathPrefix('/favicon.ico')}
133
+ sizes="any"
134
+ />
135
+ <link
136
+ rel="icon"
137
+ href={addSubpathPrefix('/icon.svg')}
138
+ type="image/svg+xml"
139
+ />
134
140
  <link
135
141
  rel="apple-touch-icon"
136
142
  sizes="180x180"
137
- href="/apple-touch-icon.png"
143
+ href={addSubpathPrefix('/apple-touch-icon.png')}
138
144
  />
139
- <link rel="manifest" href="/site.webmanifest" />
145
+ <link rel="manifest" href={addSubpathPrefix('/site.webmanifest')} />
140
146
  <meta name="generator" content="Plone 6 - https://plone.org" />
141
147
  <meta name="viewport" content="width=device-width, initial-scale=1" />
142
148
  <meta name="mobile-web-app-capable" content="yes" />