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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (367) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc +37 -0
  3. package/CHANGELOG.md +274 -2
  4. package/README.md +3 -6
  5. package/cypress/docker/prefixed-rules.yml +26 -0
  6. package/cypress/docker/prefixed.yml +24 -0
  7. package/cypress/support/commands.js +12 -6
  8. package/cypress/support/guillotina.js +1 -0
  9. package/cypress.config.js +1 -0
  10. package/locales/af.json +1 -0
  11. package/locales/ar.json +1 -0
  12. package/locales/bg.json +1 -0
  13. package/locales/bn.json +1 -0
  14. package/locales/ca/LC_MESSAGES/volto.po +96 -17
  15. package/locales/ca.json +1 -1
  16. package/locales/cs.json +1 -0
  17. package/locales/cy.json +1 -0
  18. package/locales/da.json +1 -0
  19. package/locales/de/LC_MESSAGES/volto.po +104 -25
  20. package/locales/de.json +1 -1
  21. package/locales/el.json +1 -0
  22. package/locales/en/LC_MESSAGES/volto.po +97 -18
  23. package/locales/en.json +1 -1
  24. package/locales/en_AU.json +1 -0
  25. package/locales/en_GB.json +1 -0
  26. package/locales/eo.json +1 -0
  27. package/locales/es/LC_MESSAGES/volto.po +97 -18
  28. package/locales/es.json +1 -1
  29. package/locales/et.json +1 -0
  30. package/locales/eu/LC_MESSAGES/volto.po +96 -17
  31. package/locales/eu.json +1 -1
  32. package/locales/fa.json +1 -0
  33. package/locales/fi/LC_MESSAGES/volto.po +96 -17
  34. package/locales/fi.json +1 -1
  35. package/locales/fr/LC_MESSAGES/volto.po +97 -18
  36. package/locales/fr.json +1 -1
  37. package/locales/fu.json +1 -0
  38. package/locales/gl.json +1 -0
  39. package/locales/he.json +1 -0
  40. package/locales/hi/LC_MESSAGES/volto.po +100 -21
  41. package/locales/hi.json +1 -1
  42. package/locales/hr.json +1 -0
  43. package/locales/hu.json +1 -0
  44. package/locales/hy.json +1 -0
  45. package/locales/id.json +1 -0
  46. package/locales/it/LC_MESSAGES/volto.po +101 -22
  47. package/locales/it.json +1 -1
  48. package/locales/ja/LC_MESSAGES/volto.po +96 -17
  49. package/locales/ja.json +1 -1
  50. package/locales/ka.json +1 -0
  51. package/locales/kn.json +1 -0
  52. package/locales/ko.json +1 -0
  53. package/locales/lt.json +1 -0
  54. package/locales/lv.json +1 -0
  55. package/locales/mi.json +1 -0
  56. package/locales/mk.json +1 -0
  57. package/locales/my.json +1 -0
  58. package/locales/nb_NO.json +1 -0
  59. package/locales/nl/LC_MESSAGES/volto.po +100 -21
  60. package/locales/nl.json +1 -1
  61. package/locales/nn.json +1 -0
  62. package/locales/pl.json +1 -0
  63. package/locales/pt/LC_MESSAGES/volto.po +96 -17
  64. package/locales/pt.json +1 -1
  65. package/locales/pt_BR/LC_MESSAGES/volto.po +116 -37
  66. package/locales/pt_BR.json +1 -1
  67. package/locales/rm.json +1 -0
  68. package/locales/ro/LC_MESSAGES/volto.po +100 -21
  69. package/locales/ro.json +1 -1
  70. package/locales/ru/LC_MESSAGES/volto.po +100 -21
  71. package/locales/ru.json +1 -1
  72. package/locales/sk.json +1 -0
  73. package/locales/sl.json +1 -0
  74. package/locales/sm.json +1 -0
  75. package/locales/sq.json +1 -0
  76. package/locales/sr.json +1 -0
  77. package/locales/sr@cyrl.json +1 -0
  78. package/locales/sr@latn.json +1 -0
  79. package/locales/sv.json +1 -1
  80. package/locales/ta.json +1 -0
  81. package/locales/te.json +1 -0
  82. package/locales/th.json +1 -0
  83. package/locales/to.json +1 -0
  84. package/locales/tr.json +1 -0
  85. package/locales/uk.json +1 -0
  86. package/locales/vi.json +1 -0
  87. package/locales/volto.pot +97 -18
  88. package/locales/zh_CN/LC_MESSAGES/volto.po +96 -17
  89. package/locales/zh_CN.json +1 -1
  90. package/locales/zh_Hant.json +1 -0
  91. package/locales/zh_Hant_HK.json +1 -0
  92. package/package.json +36 -27
  93. package/razzle.config.js +16 -0
  94. package/src/actions/actions/actions.test.js +3 -3
  95. package/src/actions/addons/addons.test.js +15 -12
  96. package/src/actions/aliases/aliases.test.js +1 -1
  97. package/src/actions/content/content.js +0 -1
  98. package/src/actions/controlpanels/controlpanels.js +13 -7
  99. package/src/actions/controlpanels/controlpanels.test.js +11 -5
  100. package/src/actions/querystring/querystring.test.js +2 -2
  101. package/src/actions/types/types.test.js +1 -1
  102. package/src/actions/users/users.js +2 -2
  103. package/src/components/manage/Actions/Actions.test.jsx +5 -1
  104. package/src/components/manage/Add/Add.jsx +27 -26
  105. package/src/components/manage/Add/Add.test.jsx +6 -3
  106. package/src/components/manage/Aliases/Aliases.test.jsx +7 -7
  107. package/src/components/manage/Blocks/Block/BlocksForm.jsx +1 -0
  108. package/src/components/manage/Blocks/Block/BlocksForm.test.jsx +48 -16
  109. package/src/components/manage/Blocks/Block/Edit.jsx +3 -1
  110. package/src/components/manage/Blocks/Block/EditBlockWrapper.jsx +9 -4
  111. package/src/components/manage/Blocks/Block/Settings.test.jsx +5 -1
  112. package/src/components/manage/Blocks/Block/StyleWrapper.jsx +11 -3
  113. package/src/components/manage/Blocks/Description/View.test.jsx +1 -1
  114. package/src/components/manage/Blocks/HTML/Edit.test.jsx +12 -5
  115. package/src/components/manage/Blocks/HTML/View.test.jsx +1 -1
  116. package/src/components/manage/Blocks/Image/Edit.jsx +5 -1
  117. package/src/components/manage/Blocks/Image/ImageSidebar.test.jsx +6 -2
  118. package/src/components/manage/Blocks/LeadImage/Edit.jsx +2 -2
  119. package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.jsx +1 -1
  120. package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.test.jsx +8 -1
  121. package/src/components/manage/Blocks/Listing/ImageGallery.jsx +6 -4
  122. package/src/components/manage/Blocks/Listing/View.test.jsx +3 -1
  123. package/src/components/manage/Blocks/Maps/Edit.jsx +2 -1
  124. package/src/components/manage/Blocks/Maps/MapsSidebar.test.jsx +5 -1
  125. package/src/components/manage/Blocks/Search/SearchBlockView.jsx +21 -4
  126. package/src/components/manage/Blocks/Search/components/DateRangeFacet.test.jsx +13 -7
  127. package/src/components/manage/Blocks/Search/components/SelectFacet.test.jsx +12 -6
  128. package/src/components/manage/Blocks/Teaser/Data.jsx +21 -7
  129. package/src/components/manage/Blocks/Teaser/DefaultBody.jsx +1 -1
  130. package/src/components/manage/Blocks/Teaser/schema.js +8 -3
  131. package/src/components/manage/Blocks/Title/Edit.jsx +8 -2
  132. package/src/components/manage/Blocks/ToC/variations/DefaultTocRenderer.test.jsx +11 -1
  133. package/src/components/manage/Blocks/Video/Edit.jsx +2 -1
  134. package/src/components/manage/Blocks/Video/VideoSidebar.test.jsx +5 -1
  135. package/src/components/manage/ConditionalLink/ConditionalLink.test.tsx +109 -0
  136. package/src/components/manage/ConditionalLink/ConditionalLink.tsx +36 -0
  137. package/src/components/manage/Contents/Contents.jsx +23 -2
  138. package/src/components/manage/Contents/Contents.test.jsx +36 -13
  139. package/src/components/manage/Contents/ContentsBreadcrumbs.Multilingual.test.jsx +18 -5
  140. package/src/components/manage/Contents/ContentsBreadcrumbs.jsx +20 -26
  141. package/src/components/manage/Contents/ContentsBreadcrumbs.test.jsx +14 -0
  142. package/src/components/manage/Contents/ContentsDeleteModal.jsx +258 -206
  143. package/src/components/manage/Contents/ContentsDeleteModal.stories.jsx +26 -8
  144. package/src/components/manage/Contents/ContentsItem.jsx +10 -2
  145. package/src/components/manage/Contents/ContentsPropertiesModal.test.jsx +5 -1
  146. package/src/components/manage/Contents/ContentsRenameModal.test.jsx +5 -1
  147. package/src/components/manage/Contents/ContentsTagsModal.test.jsx +5 -1
  148. package/src/components/manage/Contents/ContentsUploadModal.test.jsx +13 -22
  149. package/src/components/manage/Contents/ContentsWorkflowModal.test.jsx +5 -1
  150. package/src/components/manage/Contents/__mocks__/index.tsx +16 -0
  151. package/src/components/manage/Contents/__mocks__/index.vitest.tsx +5 -0
  152. package/src/components/manage/Controlpanels/AddonsControlpanel.test.jsx +28 -3
  153. package/src/components/manage/Controlpanels/Aliases.test.jsx +35 -3
  154. package/src/components/manage/Controlpanels/ContentType.jsx +1 -1
  155. package/src/components/manage/Controlpanels/ContentType.test.jsx +29 -3
  156. package/src/components/manage/Controlpanels/ContentTypeLayout.test.jsx +4 -2
  157. package/src/components/manage/Controlpanels/ContentTypes.test.jsx +25 -2
  158. package/src/components/manage/Controlpanels/Controlpanel.test.jsx +37 -6
  159. package/src/components/manage/Controlpanels/Controlpanels.test.jsx +47 -3
  160. package/src/components/manage/Controlpanels/Groups/GroupsControlpanel.jsx +3 -2
  161. package/src/components/manage/Controlpanels/Groups/GroupsControlpanel.test.jsx +15 -9
  162. package/src/components/manage/Controlpanels/ModerateComments.test.jsx +31 -5
  163. package/src/components/manage/Controlpanels/Rules/AddRule.test.jsx +13 -4
  164. package/src/components/manage/Controlpanels/Rules/ConfigureRule.test.jsx +9 -5
  165. package/src/components/manage/Controlpanels/Rules/EditRule.test.jsx +12 -4
  166. package/src/components/manage/Controlpanels/Rules/Rules.test.jsx +7 -3
  167. package/src/components/manage/Controlpanels/UndoControlpanel.test.jsx +33 -4
  168. package/src/components/manage/Controlpanels/Users/RenderUsers.jsx +156 -175
  169. package/src/components/manage/Controlpanels/Users/UserGroupMembershipControlPanel.test.jsx +3 -1
  170. package/src/components/manage/Controlpanels/Users/UsersControlpanel.jsx +575 -630
  171. package/src/components/manage/Controlpanels/Users/UsersControlpanel.test.jsx +16 -9
  172. package/src/components/manage/Delete/Delete.test.jsx +45 -4
  173. package/src/components/manage/Diff/Diff.test.jsx +15 -6
  174. package/src/components/manage/Diff/DiffField.test.jsx +12 -6
  175. package/src/components/manage/Display/Display.test.jsx +17 -6
  176. package/src/components/manage/Edit/Edit.jsx +2 -3
  177. package/src/components/manage/Edit/Edit.test.jsx +11 -3
  178. package/src/components/manage/Form/BlockDataForm.test.jsx +5 -1
  179. package/src/components/manage/Form/Form.jsx +32 -0
  180. package/src/components/manage/Form/Form.test.jsx +27 -19
  181. package/src/components/manage/Form/InlineForm.jsx +2 -2
  182. package/src/components/manage/Form/InlineForm.test.jsx +5 -1
  183. package/src/components/manage/Form/ModalForm.test.jsx +5 -1
  184. package/src/components/manage/Form/__mocks__/index.tsx +17 -0
  185. package/src/components/manage/Form/__mocks__/index.vitest.tsx +73 -0
  186. package/src/components/manage/History/History.test.jsx +3 -1
  187. package/src/components/manage/LinksToItem/LinksToItem.test.jsx +6 -4
  188. package/src/components/manage/MaybeWrap/MaybeWrap.tsx +15 -0
  189. package/src/components/manage/Multilingual/CompareLanguages.jsx +2 -5
  190. package/src/components/manage/Multilingual/CreateTranslation.jsx +8 -8
  191. package/src/components/manage/Multilingual/ManageTranslations.jsx +4 -2
  192. package/src/components/manage/Multilingual/ManageTranslations.test.jsx +8 -3
  193. package/src/components/manage/Multilingual/TranslationObject.jsx +1 -1
  194. package/src/components/manage/Preferences/ChangePassword.test.jsx +9 -2
  195. package/src/components/manage/Preferences/PersonalInformation.test.jsx +3 -1
  196. package/src/components/manage/Preferences/PersonalPreferences.test.jsx +20 -7
  197. package/src/components/manage/Rules/Rules.test.jsx +6 -3
  198. package/src/components/manage/Sharing/Sharing.test.jsx +3 -1
  199. package/src/components/manage/Sidebar/ObjectBrowserNav.jsx +2 -1
  200. package/src/components/manage/Sidebar/ObjectBrowserNav.test.jsx +3 -3
  201. package/src/components/manage/Sidebar/SidebarPortal.test.tsx +42 -0
  202. package/src/components/manage/Sidebar/SidebarPortal.tsx +48 -0
  203. package/src/components/manage/TemplateChooser/TemplateChooser.jsx +2 -1
  204. package/src/components/manage/Toolbar/More.jsx +4 -1
  205. package/src/components/manage/Toolbar/More.test.jsx +9 -7
  206. package/src/components/manage/Toolbar/PersonalTools.jsx +2 -1
  207. package/src/components/manage/Toolbar/Toolbar.jsx +3 -4
  208. package/src/components/manage/Toolbar/Types.jsx +7 -7
  209. package/src/components/manage/UniversalLink/UniversalLink.test.jsx +196 -14
  210. package/src/components/manage/UniversalLink/UniversalLink.tsx +215 -0
  211. package/src/components/manage/Widgets/ArrayWidget.test.jsx +22 -5
  212. package/src/components/manage/Widgets/CheckboxGroupWidget.test.jsx +12 -5
  213. package/src/components/manage/Widgets/DatetimeWidget.jsx +5 -0
  214. package/src/components/manage/Widgets/DatetimeWidget.test.jsx +21 -6
  215. package/src/components/manage/Widgets/FileWidget.jsx +14 -8
  216. package/src/components/manage/Widgets/ImageWidget.jsx +176 -40
  217. package/src/components/manage/Widgets/InternalUrlWidget.jsx +2 -0
  218. package/src/components/manage/Widgets/NumberWidget.test.jsx +8 -7
  219. package/src/components/manage/Widgets/ObjectBrowserWidget.jsx +3 -0
  220. package/src/components/manage/Widgets/ObjectListWidget.jsx +11 -1
  221. package/src/components/manage/Widgets/ObjectListWidget.test.jsx +18 -8
  222. package/src/components/manage/Widgets/ObjectWidget.test.jsx +5 -1
  223. package/src/components/manage/Widgets/RadioGroupWidget.test.jsx +12 -5
  224. package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.test.jsx +12 -6
  225. package/src/components/manage/Widgets/RegistryImageWidget.test.jsx +44 -41
  226. package/src/components/manage/Widgets/SchemaWidget.test.jsx +12 -5
  227. package/src/components/manage/Widgets/SchemaWidgetFieldset.test.jsx +12 -5
  228. package/src/components/manage/Widgets/SelectAutoComplete.jsx +29 -12
  229. package/src/components/manage/Widgets/SelectAutoComplete.test.jsx +12 -6
  230. package/src/components/manage/Widgets/SelectWidget.jsx +3 -1
  231. package/src/components/manage/Widgets/SelectWidget.test.jsx +12 -6
  232. package/src/components/manage/Widgets/TimeWidget.test.jsx +13 -5
  233. package/src/components/manage/Widgets/TokenWidget.test.jsx +12 -6
  234. package/src/components/manage/Widgets/UrlWidget.jsx +2 -0
  235. package/src/components/manage/Widgets/VocabularyTermsWidget.test.jsx +18 -9
  236. package/src/components/manage/Widgets/__mocks__/index.tsx +16 -0
  237. package/src/components/manage/Widgets/__mocks__/index.vitest.tsx +41 -0
  238. package/src/components/manage/Workflow/Workflow.test.jsx +17 -7
  239. package/src/components/theme/AlternateHrefLangs/AlternateHrefLangs.jsx +1 -3
  240. package/src/components/theme/AlternateHrefLangs/AlternateHrefLangs.test.jsx +0 -4
  241. package/src/components/theme/App/App.jsx +3 -1
  242. package/src/components/theme/App/App.test.jsx +22 -17
  243. package/src/components/theme/AppExtras/AppExtras.test.jsx +6 -6
  244. package/src/components/theme/Avatar/Avatar.jsx +2 -1
  245. package/src/components/theme/Comments/CommentEditModal.test.jsx +5 -1
  246. package/src/components/theme/Comments/Comments.test.jsx +29 -12
  247. package/src/components/theme/ContactForm/ContactForm.test.jsx +8 -4
  248. package/src/components/theme/FormattedDate/FormattedDate.stories.jsx +20 -2
  249. package/src/components/theme/Header/Header.test.jsx +19 -13
  250. package/src/components/theme/Image/Image.jsx +11 -8
  251. package/src/components/theme/LanguageSelector/{LanguageSelector.test.jsx → LanguageSelector.test.tsx} +6 -6
  252. package/src/components/theme/LanguageSelector/LanguageSelector.tsx +89 -0
  253. package/src/components/theme/Logo/Logo.Multilingual.test.jsx +0 -5
  254. package/src/components/theme/Logout/Logout.test.jsx +1 -1
  255. package/src/components/theme/MultilingualRedirector/MultilingualRedirector.jsx +8 -12
  256. package/src/components/theme/MultilingualRedirector/MultilingualRedirector.test.jsx +3 -5
  257. package/src/components/theme/Navigation/NavItem.jsx +1 -5
  258. package/src/components/theme/Navigation/Navigation.Multilingual.test.jsx +0 -5
  259. package/src/components/theme/NotFound/NotFound.jsx +5 -2
  260. package/src/components/theme/NotFound/NotFound.test.jsx +3 -0
  261. package/src/components/theme/PasswordReset/PasswordReset.test.jsx +10 -1
  262. package/src/components/theme/PasswordReset/RequestPasswordReset.test.jsx +5 -1
  263. package/src/components/theme/PreviewImage/PreviewImage.jsx +1 -1
  264. package/src/components/theme/Register/Register.test.jsx +5 -1
  265. package/src/components/theme/RequestTimeout/RequestTimeout.jsx +1 -1
  266. package/src/components/theme/Search/Search.test.jsx +6 -4
  267. package/src/components/theme/Sitemap/Sitemap.jsx +6 -5
  268. package/src/components/theme/Sitemap/Sitemap.test.jsx +0 -1
  269. package/src/components/theme/TsTest/TsTest.test.tsx +0 -1
  270. package/src/components/theme/View/EventDatesInfo.test.jsx +12 -5
  271. package/src/components/theme/View/EventView.test.jsx +12 -5
  272. package/src/components/theme/View/FileView.jsx +9 -1
  273. package/src/components/theme/View/ListingView.test.jsx +2 -0
  274. package/src/components/theme/View/SummaryView.test.jsx +10 -0
  275. package/src/components/theme/View/TabularView.test.jsx +1 -0
  276. package/src/components/theme/View/View.jsx +1 -1
  277. package/src/components/theme/View/View.test.jsx +42 -23
  278. package/src/components/theme/Widgets/ImageWidget.jsx +2 -1
  279. package/src/config/ControlPanels.js +1 -0
  280. package/src/config/index.js +18 -25
  281. package/src/config/server.js +0 -2
  282. package/src/express-middleware/devproxy.js +20 -5
  283. package/src/helpers/Api/APIResourceWithAuth.js +8 -3
  284. package/src/helpers/Api/Api.js +7 -4
  285. package/src/helpers/Api/Api.plone.rest.test.js +11 -9
  286. package/src/helpers/Api/Api.test.js +11 -14
  287. package/src/helpers/AsyncConnect/AsyncConnect.test.jsx +145 -189
  288. package/src/helpers/AsyncConnect/ssr.js +4 -1
  289. package/src/helpers/AuthToken/AuthToken.test.js +60 -22
  290. package/src/helpers/Blocks/Blocks.test.js +1 -1
  291. package/src/helpers/Content/Content.js +23 -0
  292. package/src/helpers/Content/Content.test.js +39 -0
  293. package/src/helpers/Content/withClientSideContent.jsx +35 -0
  294. package/src/helpers/Extensions/withBlockSchemaEnhancer.jsx +4 -1
  295. package/src/helpers/Html/Html.jsx +13 -7
  296. package/src/helpers/Html/Html.test.jsx +32 -28
  297. package/src/helpers/LanguageMap/LanguageMap.js +115 -8
  298. package/src/helpers/Loadable/__mocks__/Loadable.jsx +16 -1
  299. package/src/helpers/Loadable/__mocks__/Loadable.vitest.jsx +39 -0
  300. package/src/helpers/MessageLabels/MessageLabels.js +5 -0
  301. package/src/helpers/Sitemap/Sitemap.js +4 -4
  302. package/src/helpers/Url/Url.js +32 -2
  303. package/src/helpers/Url/Url.test.js +62 -0
  304. package/src/helpers/Utils/withSaveAsDraft.jsx +241 -0
  305. package/src/hooks/user/useUser.js +1 -1
  306. package/src/middleware/Api.test.js +51 -0
  307. package/src/middleware/api.js +78 -29
  308. package/src/middleware/storeProtectLoadUtils.test.js +93 -81
  309. package/src/reducers/content/content.js +3 -18
  310. package/src/reducers/diff/diff.js +5 -1
  311. package/src/reducers/diff/diff.test.js +60 -4
  312. package/src/routes.js +4 -2
  313. package/src/server.jsx +45 -14
  314. package/src/start-client.jsx +9 -6
  315. package/src/start-server.js +9 -3
  316. package/test-setup-config.jsx +0 -2
  317. package/test-setup-globals-vitest.js +46 -0
  318. package/theme/themes/pastanaga/collections/table.overrides +9 -0
  319. package/theme/themes/pastanaga/extras/blocks.less +26 -0
  320. package/theme/themes/pastanaga/extras/contents.less +17 -5
  321. package/theme/themes/pastanaga/extras/main.less +32 -2
  322. package/tsconfig.declarations.json +12 -1
  323. package/tsconfig.json +5 -5
  324. package/types/components/manage/Blocks/Teaser/schema.d.ts +1 -0
  325. package/types/components/manage/ConditionalLink/ConditionalLink.d.ts +11 -15
  326. package/types/components/manage/Contents/__mocks__/index.vitest.d.ts +2 -0
  327. package/types/components/manage/Controlpanels/Users/RenderUsers.d.ts +18 -2
  328. package/types/components/manage/Controlpanels/Users/UsersControlpanel.d.ts +6 -2
  329. package/types/components/manage/Controlpanels/index.d.ts +2 -2
  330. package/types/components/manage/Form/__mocks__/index.vitest.d.ts +8 -0
  331. package/types/components/manage/MaybeWrap/MaybeWrap.d.ts +7 -5
  332. package/types/components/manage/Sidebar/SidebarPortal.d.ts +7 -15
  333. package/types/components/manage/UniversalLink/UniversalLink.d.ts +54 -20
  334. package/types/components/manage/Widgets/ImageWidget.d.ts +41 -1
  335. package/types/components/manage/Widgets/RecurrenceWidget/Utils.d.ts +12 -18
  336. package/types/components/manage/Widgets/__mocks__/index.vitest.d.ts +33 -0
  337. package/types/components/theme/FormattedDate/FormattedDate.stories.d.ts +1 -1
  338. package/types/components/theme/LanguageSelector/LanguageSelector.d.ts +3 -10
  339. package/types/helpers/Content/Content.d.ts +7 -0
  340. package/types/helpers/Content/withClientSideContent.d.ts +1 -0
  341. package/types/helpers/Extensions/withBlockSchemaEnhancer.d.ts +4 -5
  342. package/types/helpers/Helmet/Helmet.d.ts +1 -1
  343. package/types/helpers/LanguageMap/LanguageMap.d.ts +428 -4
  344. package/types/helpers/Loadable/__mocks__/Loadable.vitest.d.ts +3 -0
  345. package/types/helpers/MessageLabels/MessageLabels.d.ts +68 -62
  346. package/types/helpers/Url/Url.d.ts +14 -0
  347. package/types/helpers/Url/bulkFlattenToAppURL.d.ts +5 -0
  348. package/types/helpers/Utils/withSaveAsDraft.d.ts +1 -0
  349. package/types/middleware/api.d.ts +6 -9
  350. package/types/react-router-hash-link.d.ts +12 -0
  351. package/types/reducers/index.d.ts +1 -0
  352. package/types/routes.d.ts +4 -0
  353. package/types/server.d.ts +1 -1
  354. package/types/start-client.d.ts +0 -1
  355. package/vite-plugins/svg.mjs +81 -0
  356. package/vitest.config.mjs +77 -0
  357. package/package-why.json +0 -34
  358. package/src/actions/content/content.multilingual.test.js +0 -17
  359. package/src/components/manage/ConditionalLink/ConditionalLink.jsx +0 -27
  360. package/src/components/manage/ConditionalLink/ConditionalLink.test.jsx +0 -30
  361. package/src/components/manage/MaybeWrap/MaybeWrap.jsx +0 -9
  362. package/src/components/manage/Sidebar/SidebarPortal.jsx +0 -47
  363. package/src/components/manage/Sidebar/SidebarPortal.test.jsx +0 -26
  364. package/src/components/manage/UniversalLink/UniversalLink.jsx +0 -154
  365. package/src/components/manage/Widgets/FileWidget.test.jsx +0 -91
  366. package/src/components/theme/LanguageSelector/LanguageSelector.jsx +0 -77
  367. package/theme/themes/pastanaga/extras/utils.less +0 -63
@@ -6,7 +6,11 @@ import { MemoryRouter } from 'react-router-dom';
6
6
 
7
7
  import Register from './Register';
8
8
 
9
- jest.mock('@plone/volto/components/manage/Form');
9
+ vi.mock('@plone/volto/components/manage/Form', async () => {
10
+ return await import(
11
+ '@plone/volto/components/manage/Form/__mocks__/index.vitest.tsx'
12
+ );
13
+ });
10
14
 
11
15
  const mockStore = configureStore();
12
16
 
@@ -29,7 +29,7 @@ const RequestTimeout = () => (
29
29
  <h1 style={{ textAlign: 'center', lineHeight: '40px' }}>
30
30
  <FormattedMessage
31
31
  id="No connection to the server"
32
- defaultMessage="There is no connection to the server, due to a timeout o no network connection."
32
+ defaultMessage="There is no connection to the server, due to a timeout or no network connection."
33
33
  />
34
34
  <br />
35
35
  <a href={config.settings.apiPath}>{config.settings.apiPath}</a>
@@ -8,11 +8,13 @@ import { __test__ as Search } from './Search';
8
8
 
9
9
  const mockStore = configureStore();
10
10
 
11
- jest.mock('../../manage/Toolbar/Toolbar', () =>
12
- jest.fn(() => <div id="Portal" />),
13
- );
11
+ vi.mock('../../manage/Toolbar/Toolbar', () => ({
12
+ default: vi.fn(() => <div id="Portal" />),
13
+ }));
14
14
 
15
- jest.mock('./SearchTags', () => jest.fn(() => <div id="search-tags" />));
15
+ vi.mock('./SearchTags', () => ({
16
+ default: vi.fn(() => <div id="search-tags" />),
17
+ }));
16
18
 
17
19
  describe('Search', () => {
18
20
  it('renders an empty search component', () => {
@@ -36,14 +36,14 @@ function Sitemap(props) {
36
36
  location: { pathname },
37
37
  lang,
38
38
  getNavigation,
39
+ isMultilingual,
39
40
  } = props;
40
41
 
41
42
  useEffect(() => {
42
- const { settings } = config;
43
- const language = settings.isMultilingual ? `${toBackendLang(lang)}` : null;
43
+ const language = isMultilingual ? `${toBackendLang(lang)}` : null;
44
44
  const path = getSitemapPath(pathname, language);
45
45
  getNavigation(path, 4);
46
- }, [pathname, lang, getNavigation]);
46
+ }, [pathname, lang, getNavigation, isMultilingual]);
47
47
 
48
48
  const renderItems = (items) => {
49
49
  return (
@@ -100,6 +100,7 @@ export default compose(
100
100
  (state) => ({
101
101
  items: state.navigation.items,
102
102
  lang: state.intl.locale,
103
+ isMultilingual: state.site.data.features?.multilingual,
103
104
  }),
104
105
  { getNavigation },
105
106
  ),
@@ -108,10 +109,10 @@ export default compose(
108
109
  key: 'navigation',
109
110
  promise: ({ location, store: { dispatch, getState } }) => {
110
111
  if (!__SERVER__) return;
111
- const { settings } = config;
112
+ const state = getState();
112
113
  const path = getSitemapPath(
113
114
  location.pathname,
114
- settings.isMultilingual
115
+ state.site.data.features?.multilingual
115
116
  ? toBackendLang(getState().intl.locale)
116
117
  : null,
117
118
  );
@@ -58,7 +58,6 @@ describe('Sitemap', () => {
58
58
 
59
59
  describe('Sitemap in a multilingual site', () => {
60
60
  beforeEach(() => {
61
- config.settings.isMultilingual = true;
62
61
  config.settings.supportedLanguages = ['en', 'es'];
63
62
  });
64
63
  it('renders a sitemap component', () => {
@@ -1,6 +1,5 @@
1
1
  import renderer from 'react-test-renderer';
2
2
  import TsTest from './TsTest';
3
- import { expect } from '@jest/globals';
4
3
 
5
4
  describe('Ts test component', () => {
6
5
  test('Renders', () => {
@@ -5,11 +5,18 @@ import { When } from './EventDatesInfo';
5
5
  import configureStore from 'redux-mock-store';
6
6
  const mockStore = configureStore();
7
7
 
8
- jest.mock('@plone/volto/helpers/Loadable/Loadable');
9
- beforeAll(
10
- async () =>
11
- await require('@plone/volto/helpers/Loadable/Loadable').__setLoadables(),
12
- );
8
+ vi.mock('@plone/volto/helpers/Loadable/Loadable', async () => {
9
+ return await import(
10
+ '@plone/volto/helpers/Loadable/__mocks__/Loadable.vitest.jsx'
11
+ );
12
+ });
13
+
14
+ beforeAll(async () => {
15
+ const { __setLoadables } = await import(
16
+ '@plone/volto/helpers/Loadable/Loadable'
17
+ );
18
+ await __setLoadables();
19
+ });
13
20
 
14
21
  const store = mockStore({
15
22
  intl: {
@@ -14,11 +14,18 @@ const store = mockStore({
14
14
  },
15
15
  });
16
16
 
17
- jest.mock('@plone/volto/helpers/Loadable/Loadable');
18
- beforeAll(
19
- async () =>
20
- await require('@plone/volto/helpers/Loadable/Loadable').__setLoadables(),
21
- );
17
+ vi.mock('@plone/volto/helpers/Loadable/Loadable', async () => {
18
+ return await import(
19
+ '@plone/volto/helpers/Loadable/__mocks__/Loadable.vitest.jsx'
20
+ );
21
+ });
22
+
23
+ beforeAll(async () => {
24
+ const { __setLoadables } = await import(
25
+ '@plone/volto/helpers/Loadable/Loadable'
26
+ );
27
+ await __setLoadables();
28
+ });
22
29
 
23
30
  const { settings } = config;
24
31
 
@@ -7,6 +7,7 @@ import React from 'react';
7
7
  import PropTypes from 'prop-types';
8
8
  import { Container as SemanticContainer } from 'semantic-ui-react';
9
9
  import { flattenToAppURL } from '@plone/volto/helpers/Url/Url';
10
+ import { FormattedMessage } from 'react-intl';
10
11
  import config from '@plone/volto/registry';
11
12
 
12
13
  /**
@@ -30,7 +31,14 @@ const FileView = ({ content }) => {
30
31
  )}
31
32
  {content.file?.download && (
32
33
  <a href={flattenToAppURL(content.file.download)}>
33
- {content.file.filename}
34
+ {content.file.filename ? (
35
+ content.file.filename
36
+ ) : (
37
+ <FormattedMessage
38
+ id="Download file"
39
+ defaultMessage="Download file"
40
+ />
41
+ )}
34
42
  </a>
35
43
  )}
36
44
  </Container>
@@ -29,12 +29,14 @@ describe('ListingView', () => {
29
29
  description: 'My item description',
30
30
  url: '/item',
31
31
  '@type': 'Document',
32
+ '@id': 'item1',
32
33
  },
33
34
  {
34
35
  title: 'Second item',
35
36
  description: 'My second item description',
36
37
  url: '/item2',
37
38
  '@type': 'Document',
39
+ '@id': 'item2',
38
40
  },
39
41
  ],
40
42
  }}
@@ -7,6 +7,16 @@ import { MemoryRouter } from 'react-router-dom';
7
7
  import SummaryView from './SummaryView';
8
8
 
9
9
  const mockStore = configureStore();
10
+ vi.mock('@plone/volto/components/manage/UniversalLink/UniversalLink', () => ({
11
+ default: vi.fn(({ item, ...props }) => {
12
+ // Ensure @id is always present
13
+ const safeItem = {
14
+ ...item,
15
+ '@id': item['@id'] || item.url || '/default-link',
16
+ };
17
+ return <div data-testid="universal-link">{safeItem.title}</div>;
18
+ }),
19
+ }));
10
20
 
11
21
  describe('TabularView', () => {
12
22
  it('renders a summary view component', () => {
@@ -28,6 +28,7 @@ describe('TabularView', () => {
28
28
  title: 'My item',
29
29
  description: 'My item description',
30
30
  url: '/item',
31
+ '@id': '/item',
31
32
  },
32
33
  ],
33
34
  }}
@@ -246,7 +246,7 @@ class View extends Component {
246
246
  />
247
247
  <SlotRenderer name="aboveContent" content={this.props.content} />
248
248
  <RenderedView
249
- key={this.props.content['@id']}
249
+ key={flattenToAppURL(this.props.content['@id'])}
250
250
  content={this.props.content}
251
251
  location={this.props.location}
252
252
  token={this.props.token}
@@ -26,18 +26,25 @@ global.__SERVER__ = true; // eslint-disable-line no-underscore-dangle
26
26
 
27
27
  const mockStore = configureStore();
28
28
 
29
- jest.mock('../../manage/Toolbar/Toolbar', () =>
30
- jest.fn(() => <div id="Portal" />),
31
- );
29
+ vi.mock('../../manage/Toolbar/Toolbar', () => ({
30
+ default: vi.fn(() => <div id="Portal" />),
31
+ }));
32
32
 
33
- jest.mock('../Comments/Comments', () => jest.fn(() => <div id="Comments" />));
34
- jest.mock('../Tags/Tags', () => jest.fn(() => <div id="Tags" />));
35
- jest.mock('../SlotRenderer/SlotRenderer', () =>
36
- jest.fn(() => <div id="SlotRenderer" />),
37
- );
38
- jest.mock('../ContentMetadataTags/ContentMetadataTags', () =>
39
- jest.fn(() => <div id="ContentMetadataTags" />),
40
- );
33
+ vi.mock('../Comments/Comments', () => ({
34
+ default: vi.fn(() => <div id="Comments" />),
35
+ }));
36
+
37
+ vi.mock('../Tags/Tags', () => ({
38
+ default: vi.fn(() => <div id="Tags" />),
39
+ }));
40
+
41
+ vi.mock('../SlotRenderer/SlotRenderer', () => ({
42
+ default: vi.fn(() => <div id="SlotRenderer" />),
43
+ }));
44
+
45
+ vi.mock('../ContentMetadataTags/ContentMetadataTags', () => ({
46
+ default: vi.fn(() => <div id="ContentMetadataTags" />),
47
+ }));
41
48
 
42
49
  const actions = {
43
50
  document_actions: [],
@@ -151,8 +158,10 @@ describe('View', () => {
151
158
  });
152
159
  const { container } = render(
153
160
  <Provider store={store}>
154
- <View location={{ pathname: '/test' }} />
155
- <div id="toolbar"></div>
161
+ <>
162
+ <View location={{ pathname: '/test' }} />
163
+ <div id="toolbar"></div>
164
+ </>
156
165
  </Provider>,
157
166
  );
158
167
 
@@ -172,8 +181,10 @@ describe('View', () => {
172
181
  });
173
182
  const { container } = render(
174
183
  <Provider store={store}>
175
- <View location={{ pathname: '/test' }} />
176
- <div id="toolbar"></div>
184
+ <>
185
+ <View location={{ pathname: '/test' }} />
186
+ <div id="toolbar"></div>
187
+ </>
177
188
  </Provider>,
178
189
  );
179
190
 
@@ -193,8 +204,10 @@ describe('View', () => {
193
204
  });
194
205
  const { container } = render(
195
206
  <Provider store={store}>
196
- <View location={{ pathname: '/test' }} />
197
- <div id="toolbar"></div>
207
+ <>
208
+ <View location={{ pathname: '/test' }} />
209
+ <div id="toolbar"></div>
210
+ </>
198
211
  </Provider>,
199
212
  );
200
213
 
@@ -214,8 +227,10 @@ describe('View', () => {
214
227
  });
215
228
  const { container } = render(
216
229
  <Provider store={store}>
217
- <View location={{ pathname: '/test' }} />
218
- <div id="toolbar"></div>
230
+ <>
231
+ <View location={{ pathname: '/test' }} />
232
+ <div id="toolbar"></div>
233
+ </>
219
234
  </Provider>,
220
235
  );
221
236
 
@@ -243,16 +258,20 @@ describe('View', () => {
243
258
  });
244
259
  const { rerender } = render(
245
260
  <Provider store={store}>
246
- <View location={{ pathname: '/a' }} />
247
- <div id="toolbar"></div>
261
+ <>
262
+ <View location={{ pathname: '/test' }} />
263
+ <div id="toolbar"></div>
264
+ </>
248
265
  </Provider>,
249
266
  );
250
267
  expect(instanceCount).toBe(1);
251
268
  store.getState().content.data['@id'] = '/b';
252
269
  rerender(
253
270
  <Provider store={store}>
254
- <View location={{ pathname: '/b' }} />
255
- <div id="toolbar"></div>
271
+ <>
272
+ <View location={{ pathname: '/test' }} />
273
+ <div id="toolbar"></div>
274
+ </>
256
275
  </Provider>,
257
276
  );
258
277
  expect(instanceCount).toBe(2);
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import cx from 'classnames';
3
3
  import { flattenToAppURL } from '@plone/volto/helpers/Url/Url';
4
+ import Image from '@plone/volto/components/theme/Image/Image';
4
5
 
5
6
  const niceBytes = (bytes) => {
6
7
  bytes = Number(bytes);
@@ -18,7 +19,7 @@ const niceBytes = (bytes) => {
18
19
  const ImageWidget = ({ value, className }) =>
19
20
  value ? (
20
21
  <span className={cx(className, 'image', 'widget')}>
21
- <img
22
+ <Image
22
23
  src={
23
24
  value.data
24
25
  ? `data:${value['content-type']};base64,${value.data}`
@@ -77,6 +77,7 @@ export const unwantedControlPanelsFields = {
77
77
  'exposeDCMetaTags',
78
78
  'enable_sitemap',
79
79
  'webstats_js',
80
+ 'webstats_head_js',
80
81
  ],
81
82
  editing: ['available_editors', 'default_editor', 'ext_editor'],
82
83
  imaging: [
@@ -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
  ],
@@ -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,15 +1,17 @@
1
1
  import config from '@plone/volto/registry';
2
2
  import Api from './Api';
3
3
 
4
- jest.mock('superagent', () => ({
5
- get: jest.fn((url) => ({
6
- url,
7
- query: jest.fn(),
8
- set: jest.fn(),
9
- type: jest.fn(),
10
- send: jest.fn(),
11
- end: jest.fn(),
12
- })),
4
+ vi.mock('superagent', () => ({
5
+ default: {
6
+ get: vi.fn((url) => ({
7
+ url,
8
+ query: vi.fn(),
9
+ set: vi.fn(),
10
+ type: vi.fn(),
11
+ send: vi.fn(),
12
+ end: vi.fn(),
13
+ })),
14
+ },
13
15
  }));
14
16
 
15
17
  beforeAll(() => {