@plone/volto 17.0.0-alpha.8 → 17.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 (365) hide show
  1. package/.eslintrc +26 -3
  2. package/CHANGELOG.md +488 -5
  3. package/CONTRIBUTING.md +5 -1
  4. package/README.md +12 -9
  5. package/addon-registry.js +10 -1
  6. package/create-addons-loader.js +1 -1
  7. package/cypress/support/commands.js +70 -14
  8. package/cypress/support/e2e.js +1 -2
  9. package/cypress/support/volto-slate.js +4 -5
  10. package/cypress.config.js +1 -0
  11. package/docker-compose.yml +1 -1
  12. package/locales/ca/LC_MESSAGES/volto.po +276 -53
  13. package/locales/ca.json +1 -1
  14. package/locales/de/LC_MESSAGES/volto.po +284 -61
  15. package/locales/de.json +1 -1
  16. package/locales/en/LC_MESSAGES/volto.po +274 -51
  17. package/locales/en.json +1 -1
  18. package/locales/es/LC_MESSAGES/volto.po +313 -90
  19. package/locales/es.json +1 -1
  20. package/locales/eu/LC_MESSAGES/volto.po +275 -52
  21. package/locales/eu.json +1 -1
  22. package/locales/fi/LC_MESSAGES/volto.po +275 -52
  23. package/locales/fi.json +1 -1
  24. package/locales/fr/LC_MESSAGES/volto.po +276 -53
  25. package/locales/fr.json +1 -1
  26. package/locales/it/LC_MESSAGES/volto.po +469 -246
  27. package/locales/it.json +1 -1
  28. package/locales/ja/LC_MESSAGES/volto.po +275 -52
  29. package/locales/ja.json +1 -1
  30. package/locales/nl/LC_MESSAGES/volto.po +276 -53
  31. package/locales/nl.json +1 -1
  32. package/locales/pt/LC_MESSAGES/volto.po +276 -53
  33. package/locales/pt.json +1 -1
  34. package/locales/pt_BR/LC_MESSAGES/volto.po +309 -86
  35. package/locales/pt_BR.json +1 -1
  36. package/locales/ro/LC_MESSAGES/volto.po +276 -53
  37. package/locales/ro.json +1 -1
  38. package/locales/volto.pot +279 -52
  39. package/locales/zh_CN/LC_MESSAGES/volto.po +276 -53
  40. package/locales/zh_CN.json +1 -1
  41. package/package.json +44 -34
  42. package/packages/volto-slate/package.json +1 -1
  43. package/packages/volto-slate/src/actions/index.js +1 -1
  44. package/packages/volto-slate/src/blocks/Table/TableBlockEdit.jsx +21 -212
  45. package/packages/volto-slate/src/blocks/Table/schema.js +122 -0
  46. package/packages/volto-slate/src/blocks/Text/DefaultTextBlockEditor.jsx +8 -3
  47. package/packages/volto-slate/src/blocks/Text/TextBlockView.jsx +21 -16
  48. package/packages/volto-slate/src/blocks/Text/extensions/withDeserializers.js +3 -1
  49. package/packages/volto-slate/src/blocks/Text/index.js +10 -7
  50. package/packages/volto-slate/src/editor/config.jsx +5 -4
  51. package/packages/volto-slate/src/editor/index.js +4 -4
  52. package/packages/volto-slate/src/editor/less/slate.less +28 -0
  53. package/packages/volto-slate/src/editor/plugins/Link/render.jsx +5 -6
  54. package/packages/volto-slate/src/editor/plugins/StyleMenu/StyleMenu.jsx +14 -4
  55. package/packages/volto-slate/src/editor/plugins/StyleMenu/utils.js +14 -5
  56. package/packages/volto-slate/src/editor/render.jsx +77 -8
  57. package/packages/volto-slate/src/editor/ui/SlateContextToolbar.jsx +2 -2
  58. package/packages/volto-slate/src/editor/ui/index.js +15 -15
  59. package/packages/volto-slate/src/index.js +2 -2
  60. package/packages/volto-slate/src/utils/blocks.js +7 -0
  61. package/packages/volto-slate/src/widgets/RichTextWidget.jsx +15 -8
  62. package/razzle.config.js +4 -6
  63. package/src/actions/index.js +4 -0
  64. package/src/actions/navroot/navroot.js +16 -0
  65. package/src/actions/navroot/navroot.test.js +15 -0
  66. package/src/actions/relations/rebuild.js +7 -7
  67. package/src/actions/relations/relations.js +17 -0
  68. package/src/actions/site/site.js +16 -0
  69. package/src/actions/site/site.test.js +15 -0
  70. package/src/actions/userSession/userSession.js +17 -1
  71. package/src/components/index.js +194 -192
  72. package/src/components/manage/Actions/Actions.jsx +133 -243
  73. package/src/components/manage/Add/Add.jsx +7 -8
  74. package/src/components/manage/AnchorPlugin/index.jsx +2 -2
  75. package/src/components/manage/AnchorPlugin/utils/EditorUtils.js +3 -1
  76. package/src/components/manage/Blocks/Block/BlocksForm.jsx +19 -2
  77. package/src/components/manage/Blocks/Block/Edit.jsx +1 -1
  78. package/src/components/manage/Blocks/Block/Settings.jsx +2 -0
  79. package/src/components/manage/Blocks/Block/Settings.test.jsx +92 -0
  80. package/src/components/manage/Blocks/Block/Style.jsx +2 -2
  81. package/src/components/manage/Blocks/Container/Data.jsx +32 -0
  82. package/src/components/manage/Blocks/Container/Edit.jsx +177 -0
  83. package/src/components/manage/Blocks/Container/EditBlockWrapper.jsx +121 -0
  84. package/src/components/manage/Blocks/Container/NewBlockAddButton.jsx +84 -0
  85. package/src/components/manage/Blocks/Container/SimpleContainerToolbar.jsx +54 -0
  86. package/src/components/manage/Blocks/Grid/Edit.jsx +47 -0
  87. package/src/components/manage/Blocks/Grid/View.jsx +43 -0
  88. package/src/components/manage/Blocks/Grid/adapter.js +14 -0
  89. package/src/components/manage/Blocks/Grid/grid-1.svg +6 -0
  90. package/src/components/manage/Blocks/Grid/grid-2.svg +9 -0
  91. package/src/components/manage/Blocks/Grid/grid-3.svg +10 -0
  92. package/src/components/manage/Blocks/Grid/grid-4.svg +11 -0
  93. package/src/components/manage/Blocks/Grid/schema.js +35 -0
  94. package/src/components/manage/Blocks/Grid/templates.js +47 -0
  95. package/src/components/manage/Blocks/HTML/Edit.jsx +8 -8
  96. package/src/components/manage/Blocks/HeroImageLeft/Edit.jsx +36 -26
  97. package/src/components/manage/Blocks/Image/Edit.jsx +51 -12
  98. package/src/components/manage/Blocks/Image/Edit.test.jsx +2 -0
  99. package/src/components/manage/Blocks/Image/ImageSidebar.jsx +66 -16
  100. package/src/components/manage/Blocks/Image/View.jsx +26 -5
  101. package/src/components/manage/Blocks/Image/View.test.jsx +20 -0
  102. package/src/components/manage/Blocks/Image/schema.js +17 -10
  103. package/src/components/manage/Blocks/Image/utils.js +14 -0
  104. package/src/components/manage/Blocks/LeadImage/Edit.jsx +32 -10
  105. package/src/components/manage/Blocks/LeadImage/Edit.test.jsx +11 -1
  106. package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.jsx +28 -9
  107. package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.test.jsx +8 -2
  108. package/src/components/manage/Blocks/LeadImage/View.jsx +50 -38
  109. package/src/components/manage/Blocks/LeadImage/View.test.jsx +11 -1
  110. package/src/components/manage/Blocks/Listing/DefaultTemplate.jsx +18 -3
  111. package/src/components/manage/Blocks/Listing/ListingBody.jsx +32 -8
  112. package/src/components/manage/Blocks/Listing/ListingBody.test.jsx +20 -0
  113. package/src/components/manage/Blocks/Listing/SummaryTemplate.jsx +1 -1
  114. package/src/components/manage/Blocks/Listing/getAsyncData.js +3 -5
  115. package/src/components/manage/Blocks/Listing/withQuerystringResults.jsx +27 -17
  116. package/src/components/manage/Blocks/Maps/Edit.jsx +135 -209
  117. package/src/components/manage/Blocks/Maps/Edit.test.jsx +1 -2
  118. package/src/components/manage/Blocks/Maps/View.test.jsx +1 -2
  119. package/src/components/manage/Blocks/Search/SearchBlockView.jsx +3 -2
  120. package/src/components/manage/Blocks/Search/components/Facets.jsx +66 -7
  121. package/src/components/manage/Blocks/Search/components/FilterList.jsx +4 -6
  122. package/src/components/manage/Blocks/Search/components/SearchInput.jsx +9 -2
  123. package/src/components/manage/Blocks/Search/components/SelectFacet.jsx +2 -9
  124. package/src/components/manage/Blocks/Search/components/index.js +13 -13
  125. package/src/components/manage/Blocks/Search/hocs/index.js +2 -2
  126. package/src/components/manage/Blocks/Search/hocs/withQueryString.jsx +5 -2
  127. package/src/components/manage/Blocks/Search/hocs/withSearch.jsx +70 -36
  128. package/src/components/manage/Blocks/Search/layout/LeftColumnFacets.jsx +17 -5
  129. package/src/components/manage/Blocks/Search/layout/RightColumnFacets.jsx +17 -5
  130. package/src/components/manage/Blocks/Search/layout/TopSideFacets.jsx +21 -5
  131. package/src/components/manage/Blocks/Search/schema.js +29 -14
  132. package/src/components/manage/Blocks/Table/Cell.jsx +2 -3
  133. package/src/components/manage/Blocks/Teaser/Body.jsx +0 -1
  134. package/src/components/manage/Blocks/Teaser/DefaultBody.jsx +5 -10
  135. package/src/components/manage/Blocks/Teaser/schema.js +5 -0
  136. package/src/components/manage/Blocks/Text/Edit.jsx +2 -3
  137. package/src/components/manage/Blocks/Title/View.jsx +0 -23
  138. package/src/components/manage/Blocks/Title/View.test.jsx +16 -1
  139. package/src/components/manage/Blocks/ToC/Schema.jsx +40 -7
  140. package/src/components/manage/Blocks/ToC/View.jsx +84 -14
  141. package/src/components/manage/Blocks/ToC/variations/DefaultTocRenderer.jsx +8 -3
  142. package/src/components/manage/Blocks/ToC/variations/DefaultTocRenderer.test.jsx +44 -0
  143. package/src/components/manage/Blocks/ToC/variations/HorizontalMenu.jsx +149 -10
  144. package/src/components/manage/Blocks/ToC/variations/index.js +3 -1
  145. package/src/components/manage/Contents/Contents.jsx +285 -114
  146. package/src/components/manage/Contents/ContentsPropertiesModal.jsx +90 -166
  147. package/src/components/manage/Contents/ContentsRenameModal.jsx +88 -139
  148. package/src/components/manage/Contents/ContentsRenameModal.stories.jsx +61 -0
  149. package/src/components/manage/Contents/ContentsTagsModal.jsx +83 -130
  150. package/src/components/manage/Contents/ContentsTagsModal.stories.jsx +68 -0
  151. package/src/components/manage/Contents/ContentsUploadModal.jsx +11 -7
  152. package/src/components/manage/Contents/ContentsWorkflowModal.jsx +87 -154
  153. package/src/components/manage/Controlpanels/Aliases.jsx +4 -12
  154. package/src/components/manage/Controlpanels/Groups/GroupsControlpanel.jsx +65 -38
  155. package/src/components/manage/Controlpanels/Groups/RenderGroups.jsx +2 -2
  156. package/src/components/manage/Controlpanels/Relations/BrokenRelations.jsx +38 -13
  157. package/src/components/manage/Controlpanels/Relations/Relations.jsx +5 -5
  158. package/src/components/manage/Controlpanels/Relations/RelationsListing.jsx +8 -7
  159. package/src/components/manage/Controlpanels/Relations/RelationsMatrix.jsx +68 -68
  160. package/src/components/manage/Controlpanels/Rules/AddRule.jsx +3 -10
  161. package/src/components/manage/Controlpanels/Rules/EditRule.jsx +1 -1
  162. package/src/components/manage/Controlpanels/UndoControlpanel.jsx +6 -9
  163. package/src/components/manage/Controlpanels/Users/RenderUsers.jsx +97 -7
  164. package/src/components/manage/Controlpanels/Users/UsersControlpanel.jsx +127 -99
  165. package/src/components/manage/Delete/Delete.jsx +96 -171
  166. package/src/components/manage/Diff/DiffField.jsx +25 -1
  167. package/src/components/manage/DragDropList/DragDropList.jsx +18 -13
  168. package/src/components/manage/Form/BlockDataForm.jsx +3 -2
  169. package/src/components/manage/Form/BlockDataForm.test.jsx +51 -17
  170. package/src/components/manage/Form/Form.jsx +7 -6
  171. package/src/components/manage/Form/InlineForm.test.jsx +16 -14
  172. package/src/components/manage/History/History.jsx +11 -1
  173. package/src/components/manage/LinksToItem/LinksToItem.jsx +209 -0
  174. package/src/components/manage/LinksToItem/LinksToItem.test.jsx +100 -0
  175. package/src/components/manage/LockingToastsFactory/LockingToastsFactory.jsx +1 -2
  176. package/src/components/manage/Messages/Messages.jsx +32 -99
  177. package/src/components/manage/Messages/Messages.test.jsx +0 -1
  178. package/src/components/manage/Preferences/ChangePassword.jsx +2 -2
  179. package/src/components/manage/Sharing/Sharing.jsx +62 -22
  180. package/src/components/manage/Sidebar/AlignBlock.jsx +1 -1
  181. package/src/components/manage/Sidebar/Sidebar.jsx +139 -220
  182. package/src/components/manage/TemplateChooser/TemplateChooser.jsx +38 -0
  183. package/src/components/manage/TemplateChooser/TemplateChooser.test.jsx +34 -0
  184. package/src/components/manage/TemplateChooser/template.svg +10 -0
  185. package/src/components/manage/Toast/Toast.jsx +1 -1
  186. package/src/components/manage/Toolbar/More.jsx +17 -2
  187. package/src/components/manage/Toolbar/PersonalTools.jsx +97 -155
  188. package/src/components/manage/Toolbar/Toolbar.jsx +2 -2
  189. package/src/components/manage/UniversalLink/UniversalLink.jsx +6 -12
  190. package/src/components/manage/UniversalLink/UniversalLink.test.jsx +37 -0
  191. package/src/components/manage/Widgets/AlignWidget.jsx +2 -4
  192. package/src/components/manage/Widgets/ArrayWidget.jsx +3 -1
  193. package/src/components/manage/Widgets/ArrayWidget.test.jsx +45 -1
  194. package/src/components/manage/Widgets/ColorPickerWidget.jsx +6 -1
  195. package/src/components/manage/Widgets/ColorPickerWidget.test.jsx +9 -7
  196. package/src/components/manage/Widgets/DatetimeWidget.jsx +2 -8
  197. package/src/components/manage/Widgets/FileWidget.jsx +2 -1
  198. package/src/components/manage/Widgets/FormFieldWrapper.jsx +1 -1
  199. package/src/components/manage/Widgets/IdWidget.jsx +1 -2
  200. package/src/components/manage/Widgets/ObjectBrowserWidget.jsx +2 -9
  201. package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.jsx +3 -10
  202. package/src/components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthIndexField.jsx +4 -4
  203. package/src/components/manage/Widgets/RegistryImageWidget.jsx +210 -0
  204. package/src/components/manage/Widgets/RegistryImageWidget.test.jsx +91 -0
  205. package/src/components/manage/Widgets/SchemaWidget.jsx +6 -9
  206. package/src/components/manage/Widgets/SelectUtils.js +1 -1
  207. package/src/components/manage/Widgets/SelectWidget.jsx +15 -1
  208. package/src/components/manage/Widgets/SelectWidget.test.jsx +45 -1
  209. package/src/components/manage/Widgets/WysiwygWidget.jsx +2 -9
  210. package/src/components/manage/Workflow/Workflow.jsx +75 -184
  211. package/src/components/theme/Anontools/Anontools.jsx +44 -72
  212. package/src/components/theme/Anontools/Anontools.stories.jsx +16 -6
  213. package/src/components/theme/Anontools/Anontools.test.jsx +16 -2
  214. package/src/components/theme/Breadcrumbs/Breadcrumbs.jsx +52 -99
  215. package/src/components/theme/Breadcrumbs/Breadcrumbs.stories.jsx +14 -13
  216. package/src/components/theme/Comments/Comment.stories.jsx +84 -0
  217. package/src/components/theme/Comments/CommentEditModal.jsx +63 -115
  218. package/src/components/theme/Comments/Comments.jsx +268 -380
  219. package/src/components/theme/Component/Component.jsx +1 -1
  220. package/src/components/theme/ContactForm/ContactForm.jsx +108 -192
  221. package/src/components/theme/ContactForm/ContactForm.stories.jsx +1 -1
  222. package/src/components/theme/ContactForm/ContactForm.test.jsx +2 -3
  223. package/src/components/theme/ContentMetadataTags/ContentMetadataTags.jsx +41 -3
  224. package/src/components/theme/Error/ServerError.jsx +29 -0
  225. package/src/components/theme/Header/Header.jsx +37 -63
  226. package/src/components/theme/Header/Header.test.jsx +18 -0
  227. package/src/components/theme/Image/Image.jsx +96 -0
  228. package/src/components/theme/Image/Image.test.jsx +125 -0
  229. package/src/components/theme/Login/Login.jsx +160 -243
  230. package/src/components/theme/Logo/Logo.Multilingual.test.jsx +131 -1
  231. package/src/components/theme/Logo/Logo.jsx +35 -27
  232. package/src/components/theme/Logo/Logo.test.jsx +135 -1
  233. package/src/components/theme/Logout/Logout.jsx +36 -83
  234. package/src/components/theme/Navigation/Navigation.jsx +86 -171
  235. package/src/components/theme/NotFound/NotFound.jsx +55 -41
  236. package/src/components/theme/PasswordReset/PasswordReset.jsx +7 -5
  237. package/src/components/theme/PasswordReset/RequestPasswordReset.jsx +95 -170
  238. package/src/components/theme/PreviewImage/PreviewImage.jsx +31 -15
  239. package/src/components/theme/PreviewImage/PreviewImage.test.js +53 -13
  240. package/src/components/theme/Register/Register.jsx +2 -4
  241. package/src/components/theme/Search/SearchTags.jsx +30 -60
  242. package/src/components/theme/SearchWidget/SearchWidget.jsx +49 -97
  243. package/src/components/theme/SearchWidget/SearchWidget.test.jsx +8 -0
  244. package/src/components/theme/Sitemap/Sitemap.jsx +24 -13
  245. package/src/components/theme/Sitemap/Sitemap.test.jsx +23 -2
  246. package/src/components/theme/TsTest/TsTest.test.tsx +11 -0
  247. package/src/components/theme/TsTest/TsTest.tsx +15 -0
  248. package/src/components/theme/View/AlbumView.jsx +21 -16
  249. package/src/components/theme/View/EventView.jsx +36 -25
  250. package/src/components/theme/View/FileView.jsx +23 -18
  251. package/src/components/theme/View/ImageView.jsx +40 -32
  252. package/src/components/theme/View/ImageView.test.jsx +4 -0
  253. package/src/components/theme/View/LinkView.jsx +53 -78
  254. package/src/components/theme/View/ListingView.jsx +36 -28
  255. package/src/components/theme/View/NewsItemView.jsx +16 -17
  256. package/src/components/theme/View/RenderBlocks.jsx +56 -21
  257. package/src/components/theme/View/RenderEmptyBlock.jsx +5 -0
  258. package/src/components/theme/View/SummaryView.jsx +49 -39
  259. package/src/components/theme/View/TabularView.jsx +59 -53
  260. package/src/components/theme/View/View.jsx +2 -0
  261. package/src/components/theme/Widgets/ImageWidget.stories.jsx +1 -2
  262. package/src/config/Blocks.jsx +46 -0
  263. package/src/config/Components.jsx +3 -1
  264. package/src/config/ControlPanels.js +0 -1
  265. package/src/config/Loadables.jsx +1 -1
  266. package/src/config/NonContentRoutes.jsx +1 -0
  267. package/src/config/RichTextEditor/Blocks.jsx +4 -5
  268. package/src/config/RichTextEditor/FromHTML.jsx +2 -2
  269. package/src/config/RichTextEditor/Plugins.jsx +2 -3
  270. package/src/config/RichTextEditor/Styles.jsx +1 -1
  271. package/src/config/RichTextEditor/ToHTML.jsx +12 -10
  272. package/src/config/RichTextEditor/index.js +2 -3
  273. package/src/config/Views.jsx +6 -4
  274. package/src/config/Widgets.jsx +3 -0
  275. package/src/config/index.js +36 -2
  276. package/src/config/server.js +2 -0
  277. package/src/constants/ActionTypes.js +4 -0
  278. package/src/constants/Indexes.js +3 -1
  279. package/src/express-middleware/devproxy.js +1 -1
  280. package/src/express-middleware/files.js +11 -9
  281. package/src/express-middleware/images.js +12 -5
  282. package/src/express-middleware/ok.js +16 -0
  283. package/src/express-middleware/robotstxt.js +1 -1
  284. package/src/express-middleware/sitemap.js +1 -1
  285. package/src/express-middleware/static.js +3 -3
  286. package/src/helpers/Api/Api.js +1 -1
  287. package/src/helpers/Blocks/Blocks.js +52 -6
  288. package/src/helpers/Blocks/Blocks.test.js +92 -13
  289. package/src/helpers/Extensions/index.js +2 -1
  290. package/src/helpers/Extensions/withBlockSchemaEnhancer.js +63 -61
  291. package/src/helpers/Extensions/withBlockSchemaEnhancer.test.js +145 -0
  292. package/src/helpers/FormValidation/FormValidation.js +37 -7
  293. package/src/helpers/FormValidation/FormValidation.test.js +32 -0
  294. package/src/helpers/Html/Html.jsx +2 -8
  295. package/src/helpers/Loadable/__mocks__/Loadable.js +18 -18
  296. package/src/helpers/MessageLabels/MessageLabels.js +39 -4
  297. package/src/helpers/ScrollToTop/ScrollToTop.jsx +5 -3
  298. package/src/helpers/Site/index.js +21 -0
  299. package/src/helpers/Url/Url.js +22 -1
  300. package/src/helpers/Url/Url.test.js +41 -0
  301. package/src/helpers/Utils/UseDetectClickOutside.stories.jsx +190 -0
  302. package/src/helpers/Utils/Utils.js +35 -0
  303. package/src/helpers/Utils/Utils.test.js +13 -0
  304. package/src/helpers/Utils/usePagination.js +67 -14
  305. package/src/helpers/Utils/usePagination.test.js +115 -0
  306. package/src/helpers/index.js +15 -8
  307. package/src/hooks/client/useClient.js +11 -0
  308. package/src/hooks/clipboard/useClipboard.js +26 -0
  309. package/src/hooks/index.js +2 -0
  310. package/src/icons/grid-block.svg +11 -0
  311. package/src/middleware/api.js +203 -173
  312. package/src/middleware/blacklistRoutes.js +25 -22
  313. package/src/middleware/index.js +2 -2
  314. package/src/middleware/storeProtectLoadUtils.js +61 -62
  315. package/src/middleware/storeProtectLoadUtils.test.js +47 -43
  316. package/src/reducers/actions/actions.js +7 -5
  317. package/src/reducers/actions/actions.test.js +70 -0
  318. package/src/reducers/content/content.test.js +4 -4
  319. package/src/reducers/index.js +4 -0
  320. package/src/reducers/navigation/navigation.js +5 -5
  321. package/src/reducers/navigation/navigation.test.js +30 -0
  322. package/src/reducers/navroot/navroot.js +79 -0
  323. package/src/reducers/navroot/navroot.test.js +110 -0
  324. package/src/reducers/relations/relations.js +74 -46
  325. package/src/reducers/site/site.js +51 -0
  326. package/src/reducers/site/site.test.js +67 -0
  327. package/src/reducers/userSession/userSession.js +15 -1
  328. package/src/registry.js +2 -2
  329. package/src/routes.js +9 -0
  330. package/src/server.jsx +9 -0
  331. package/src/start-server.js +2 -2
  332. package/src/storybook.jsx +24 -38
  333. package/test-setup-config.js +11 -1
  334. package/theme/themes/pastanaga/collections/form.overrides +46 -0
  335. package/theme/themes/pastanaga/collections/menu.overrides +3 -2
  336. package/theme/themes/pastanaga/elements/container.overrides +5 -2
  337. package/theme/themes/pastanaga/elements/input.overrides +11 -1
  338. package/theme/themes/pastanaga/elements/label.overrides +10 -0
  339. package/theme/themes/pastanaga/elements/step.overrides +2 -1
  340. package/theme/themes/pastanaga/extras/blocks.less +25 -15
  341. package/theme/themes/pastanaga/extras/color-picker-widget.less +1 -1
  342. package/theme/themes/pastanaga/extras/contents.less +6 -1
  343. package/theme/themes/pastanaga/extras/draftjs.less +4 -4
  344. package/theme/themes/pastanaga/extras/grid.less +427 -0
  345. package/theme/themes/pastanaga/extras/login.less +3 -0
  346. package/theme/themes/pastanaga/extras/main.less +14 -7
  347. package/theme/themes/pastanaga/extras/react-dates-overrides.less +4 -2
  348. package/theme/themes/pastanaga/extras/search.less +7 -1
  349. package/theme/themes/pastanaga/extras/sidebar.less +5 -4
  350. package/theme/themes/pastanaga/extras/time-picker-overrides.less +5 -3
  351. package/theme/themes/pastanaga/extras/toc.less +29 -0
  352. package/theme/themes/pastanaga/extras/toolbar.less +6 -2
  353. package/theme/themes/pastanaga/extras/userscontrolpanel.less +17 -9
  354. package/theme/themes/pastanaga/extras/widgets.less +1 -1
  355. package/theme/themes/pastanaga/modules/rating.overrides +2 -1
  356. package/theme/themes/pastanaga-cms-ui/elements/container.overrides +2 -1
  357. package/theme/themes/pastanaga-cms-ui/extras/cms-ui.elements.container.less +6 -2
  358. package/theme/themes/pastanaga-cms-ui/extras/cms-ui.site.less +2 -2
  359. package/tsconfig.json +33 -0
  360. package/webpack-plugins/webpack-less-plugin.js +19 -0
  361. package/.yarn/install-state.gz +0 -0
  362. package/.yarn/releases/yarn-3.2.3.cjs +0 -783
  363. package/src/components/manage/Blocks/Teaser/utils.js +0 -44
  364. package/src/components/manage/Blocks/Teaser/utils.test.jsx +0 -229
  365. package/src/components/theme/Header/Header.md +0 -27
@@ -67,7 +67,15 @@ export function addExpandersToPath(path, type, isAnonymous) {
67
67
 
68
68
  const querystringFromConfig = apiExpanders
69
69
  .filter((expand) => matchPath(url, expand.match) && expand[type])
70
- .reduce((acc, expand) => ({ ...acc, ...expand?.['querystring'] }), {});
70
+ .reduce((acc, expand) => {
71
+ let querystring = expand?.['querystring'];
72
+ // The querystring accepts being a function to be able to take other
73
+ // config parameters
74
+ if (typeof querystring === 'function') {
75
+ querystring = querystring(config);
76
+ }
77
+ return { ...acc, ...querystring };
78
+ }, {});
71
79
 
72
80
  const queryMerge = { ...query, ...querystringFromConfig };
73
81
 
@@ -117,52 +125,76 @@ function sendOnSocket(request) {
117
125
  * @param {Object} api Api object.
118
126
  * @returns {Promise} Action promise.
119
127
  */
120
- const apiMiddlewareFactory = (api) => ({ dispatch, getState }) => (next) => (
121
- action,
122
- ) => {
123
- const { settings } = config;
128
+ const apiMiddlewareFactory =
129
+ (api) =>
130
+ ({ dispatch, getState }) =>
131
+ (next) =>
132
+ (action) => {
133
+ const { settings } = config;
124
134
 
125
- const isAnonymous = !getState().userSession.token;
135
+ const token = getState().userSession.token;
136
+ let isAnonymous = true;
137
+ if (token) {
138
+ const tokenExpiration = jwtDecode(token).exp;
139
+ const currentTime = new Date().getTime() / 1000;
140
+ isAnonymous = !token || currentTime > tokenExpiration;
141
+ }
126
142
 
127
- if (typeof action === 'function') {
128
- return action(dispatch, getState);
129
- }
143
+ if (typeof action === 'function') {
144
+ return action(dispatch, getState);
145
+ }
130
146
 
131
- const { request, type, mode = 'parallel', ...rest } = action;
132
- const { subrequest } = action; // We want subrequest remains in `...rest` above
147
+ const { request, type, mode = 'parallel', ...rest } = action;
148
+ const { subrequest } = action; // We want subrequest remains in `...rest` above
133
149
 
134
- let actionPromise;
150
+ let actionPromise;
135
151
 
136
- if (!request) {
137
- return next(action);
138
- }
152
+ if (!request) {
153
+ return next(action);
154
+ }
139
155
 
140
- next({ ...rest, type: `${type}_PENDING` });
156
+ next({ ...rest, type: `${type}_PENDING` });
141
157
 
142
- if (socket) {
143
- actionPromise = Array.isArray(request)
144
- ? Promise.all(
145
- request.map((item) =>
146
- sendOnSocket({
147
- ...item,
148
- path: addExpandersToPath(item.path, type, isAnonymous),
149
- id: type,
150
- }),
151
- ),
152
- )
153
- : sendOnSocket({
154
- ...request,
155
- path: addExpandersToPath(request.path, type, isAnonymous),
156
- id: type,
157
- });
158
- } else {
159
- actionPromise = Array.isArray(request)
160
- ? mode === 'serial'
161
- ? request.reduce((prevPromise, item) => {
162
- return prevPromise.then((acc) => {
163
- return api[item.op](
164
- addExpandersToPath(item.path, type, isAnonymous),
165
- {
158
+ if (socket) {
159
+ actionPromise = Array.isArray(request)
160
+ ? Promise.all(
161
+ request.map((item) =>
162
+ sendOnSocket({
163
+ ...item,
164
+ path: addExpandersToPath(item.path, type, isAnonymous),
165
+ id: type,
166
+ }),
167
+ ),
168
+ )
169
+ : sendOnSocket({
170
+ ...request,
171
+ path: addExpandersToPath(request.path, type, isAnonymous),
172
+ id: type,
173
+ });
174
+ } else {
175
+ actionPromise = Array.isArray(request)
176
+ ? mode === 'serial'
177
+ ? request.reduce((prevPromise, item) => {
178
+ return prevPromise.then((acc) => {
179
+ return api[item.op](
180
+ addExpandersToPath(item.path, type, isAnonymous),
181
+ {
182
+ data: item.data,
183
+ type: item.type,
184
+ headers: item.headers,
185
+ params: request.params,
186
+ checkUrl: settings.actions_raising_api_errors.includes(
187
+ action.type,
188
+ ),
189
+ },
190
+ ).then((reqres) => {
191
+ return [...acc, reqres];
192
+ });
193
+ });
194
+ }, Promise.resolve([]))
195
+ : Promise.all(
196
+ request.map((item) =>
197
+ api[item.op](addExpandersToPath(item.path, type, isAnonymous), {
166
198
  data: item.data,
167
199
  type: item.type,
168
200
  headers: item.headers,
@@ -170,164 +202,162 @@ const apiMiddlewareFactory = (api) => ({ dispatch, getState }) => (next) => (
170
202
  checkUrl: settings.actions_raising_api_errors.includes(
171
203
  action.type,
172
204
  ),
173
- },
174
- ).then((reqres) => {
175
- return [...acc, reqres];
176
- });
177
- });
178
- }, Promise.resolve([]))
179
- : Promise.all(
180
- request.map((item) =>
181
- api[item.op](addExpandersToPath(item.path, type, isAnonymous), {
182
- data: item.data,
183
- type: item.type,
184
- headers: item.headers,
185
- params: request.params,
186
- checkUrl: settings.actions_raising_api_errors.includes(
187
- action.type,
188
- ),
189
- }),
190
- ),
191
- )
192
- : api[request.op](addExpandersToPath(request.path, type, isAnonymous), {
193
- data: request.data,
194
- type: request.type,
195
- headers: request.headers,
196
- params: request.params,
197
- checkUrl: settings.actions_raising_api_errors.includes(action.type),
198
- });
199
- actionPromise.then(
200
- (result) => {
201
- const { settings } = config;
202
- if (getState().apierror.connectionRefused) {
203
- next({
204
- ...rest,
205
- type: RESET_APIERROR,
205
+ }),
206
+ ),
207
+ )
208
+ : api[request.op](addExpandersToPath(request.path, type, isAnonymous), {
209
+ data: request.data,
210
+ type: request.type,
211
+ headers: request.headers,
212
+ params: request.params,
213
+ checkUrl: settings.actions_raising_api_errors.includes(action.type),
206
214
  });
207
- }
208
- if (type === GET_CONTENT) {
209
- const lang = result?.language?.token;
210
- if (
211
- lang &&
212
- getState().intl.locale !== toReactIntlLang(lang) &&
213
- !subrequest &&
214
- config.settings.supportedLanguages.includes(lang)
215
- ) {
216
- const langFileName = toGettextLang(lang);
217
- import('~/../locales/' + langFileName + '.json').then((locale) => {
218
- dispatch(changeLanguage(lang, locale.default));
215
+ actionPromise.then(
216
+ (result) => {
217
+ const { settings } = config;
218
+ if (getState().apierror.connectionRefused) {
219
+ next({
220
+ ...rest,
221
+ type: RESET_APIERROR,
219
222
  });
220
223
  }
221
- }
222
- if (type === LOGIN && settings.websockets) {
223
- const cookies = new Cookies();
224
- cookies.set(
225
- 'auth_token',
226
- result.token,
227
- getCookieOptions({
228
- expires: new Date(jwtDecode(result.token).exp * 1000),
229
- }),
230
- );
231
- api.get('/@wstoken').then((res) => {
232
- socket = new WebSocket(
233
- `${settings.apiPath.replace('http', 'ws')}/@ws?ws_token=${
234
- res.token
235
- }`,
224
+ if (type === GET_CONTENT) {
225
+ const lang = result?.language?.token;
226
+ if (
227
+ lang &&
228
+ getState().intl.locale !== toReactIntlLang(lang) &&
229
+ !subrequest &&
230
+ config.settings.supportedLanguages.includes(lang)
231
+ ) {
232
+ const langFileName = toGettextLang(lang);
233
+ import('~/../locales/' + langFileName + '.json').then(
234
+ (locale) => {
235
+ dispatch(changeLanguage(lang, locale.default));
236
+ },
237
+ );
238
+ }
239
+ }
240
+ if (type === LOGIN && settings.websockets) {
241
+ const cookies = new Cookies();
242
+ cookies.set(
243
+ 'auth_token',
244
+ result.token,
245
+ getCookieOptions({
246
+ expires: new Date(jwtDecode(result.token).exp * 1000),
247
+ }),
236
248
  );
237
- socket.onmessage = (message) => {
238
- const packet = JSON.parse(message.data);
239
- if (packet.error) {
240
- dispatch({
241
- type: `${packet.id}_FAIL`,
242
- error: packet.error,
243
- });
244
- } else {
245
- dispatch({
246
- type: `${packet.id}_SUCCESS`,
247
- result: JSON.parse(packet.data),
248
- });
249
- }
250
- };
251
- });
252
- }
253
- return next({ ...rest, result, type: `${type}_SUCCESS` });
254
- },
255
- (error) => {
256
- // Only SRR can set ECONNREFUSED
257
- if (error.code === 'ECONNREFUSED') {
258
- next({
259
- ...rest,
260
- error,
261
- statusCode: error.code,
262
- connectionRefused: true,
263
- type: SET_APIERROR,
264
- });
265
- }
266
-
267
- // Response error is marked crossDomain if CORS error happen
268
- else if (error.crossDomain) {
269
- next({
270
- ...rest,
271
- error,
272
- statusCode: 'CORSERROR',
273
- connectionRefused: false,
274
- type: SET_APIERROR,
275
- });
276
- }
277
-
278
- // Check for actions who can raise api errors
279
- if (settings.actions_raising_api_errors.includes(action.type)) {
280
- // Gateway timeout
281
- if (error?.response?.statusCode === 504) {
282
- next({
283
- ...rest,
284
- error,
285
- statusCode: error.code,
286
- connectionRefused: true,
287
- type: SET_APIERROR,
249
+ api.get('/@wstoken').then((res) => {
250
+ socket = new WebSocket(
251
+ `${settings.apiPath.replace('http', 'ws')}/@ws?ws_token=${
252
+ res.token
253
+ }`,
254
+ );
255
+ socket.onmessage = (message) => {
256
+ const packet = JSON.parse(message.data);
257
+ if (packet.error) {
258
+ dispatch({
259
+ type: `${packet.id}_FAIL`,
260
+ error: packet.error,
261
+ });
262
+ } else {
263
+ dispatch({
264
+ type: `${packet.id}_SUCCESS`,
265
+ result: JSON.parse(packet.data),
266
+ });
267
+ }
268
+ };
288
269
  });
289
270
  }
290
-
291
- // Redirect
292
- else if (error?.code === 301) {
271
+ try {
272
+ return next({ ...rest, result, type: `${type}_SUCCESS` });
273
+ } catch (error) {
274
+ // There was an exception while processing reducers or downstream middleware.
293
275
  next({
294
276
  ...rest,
295
- error,
296
- statusCode: error.code,
297
- connectionRefused: false,
298
- type: SET_APIERROR,
277
+ error: { status: 500, error },
278
+ type: `${type}_FAIL`,
299
279
  });
280
+ // Rethrow the original exception on the client side only,
281
+ // so it doesn't fall through to express on the server.
282
+ if (__CLIENT__) throw error;
300
283
  }
301
-
302
- // Redirect
303
- else if (error?.code === 408) {
284
+ },
285
+ (error) => {
286
+ // Only SSR can set ECONNREFUSED
287
+ if (error.code === 'ECONNREFUSED') {
304
288
  next({
305
289
  ...rest,
306
290
  error,
307
291
  statusCode: error.code,
308
- connectionRefused: false,
292
+ connectionRefused: true,
309
293
  type: SET_APIERROR,
310
294
  });
311
295
  }
312
296
 
313
- // Unauthorized
314
- else if (error?.response?.statusCode === 401) {
297
+ // Response error is marked crossDomain if CORS error happen
298
+ else if (error.crossDomain) {
315
299
  next({
316
300
  ...rest,
317
301
  error,
318
- statusCode: error.response,
319
- message: error.response.body.message,
302
+ statusCode: 'CORSERROR',
320
303
  connectionRefused: false,
321
304
  type: SET_APIERROR,
322
305
  });
323
306
  }
324
- }
325
- return next({ ...rest, error, type: `${type}_FAIL` });
326
- },
327
- );
328
- }
329
307
 
330
- return actionPromise;
331
- };
308
+ // Check for actions who can raise api errors
309
+ if (settings.actions_raising_api_errors.includes(action.type)) {
310
+ // Gateway timeout
311
+ if (error?.response?.statusCode === 504) {
312
+ next({
313
+ ...rest,
314
+ error,
315
+ statusCode: error.code,
316
+ connectionRefused: true,
317
+ type: SET_APIERROR,
318
+ });
319
+ }
320
+
321
+ // Redirect
322
+ else if (error?.code === 301) {
323
+ next({
324
+ ...rest,
325
+ error,
326
+ statusCode: error.code,
327
+ connectionRefused: false,
328
+ type: SET_APIERROR,
329
+ });
330
+ }
331
+
332
+ // Redirect
333
+ else if (error?.code === 408) {
334
+ next({
335
+ ...rest,
336
+ error,
337
+ statusCode: error.code,
338
+ connectionRefused: false,
339
+ type: SET_APIERROR,
340
+ });
341
+ }
342
+
343
+ // Unauthorized
344
+ else if (error?.response?.statusCode === 401) {
345
+ next({
346
+ ...rest,
347
+ error,
348
+ statusCode: error.response,
349
+ message: error.response.body.message,
350
+ connectionRefused: false,
351
+ type: SET_APIERROR,
352
+ });
353
+ }
354
+ }
355
+ return next({ ...rest, error, type: `${type}_FAIL` });
356
+ },
357
+ );
358
+ }
359
+
360
+ return actionPromise;
361
+ };
332
362
 
333
363
  export default apiMiddlewareFactory;
@@ -1,31 +1,34 @@
1
1
  import config from '@plone/volto/registry';
2
2
  import { matchPath } from 'react-router';
3
3
 
4
- const blacklistRoutes = ({ dispatch, getState }) => (next) => (action) => {
5
- if (typeof action === 'function') {
6
- return next(action);
7
- }
4
+ const blacklistRoutes =
5
+ ({ dispatch, getState }) =>
6
+ (next) =>
7
+ (action) => {
8
+ if (typeof action === 'function') {
9
+ return next(action);
10
+ }
8
11
 
9
- switch (action.type) {
10
- case '@@router/LOCATION_CHANGE':
11
- const { pathname } = action.payload.location;
12
- const { externalRoutes = [] } = config.settings;
12
+ switch (action.type) {
13
+ case '@@router/LOCATION_CHANGE':
14
+ const { pathname } = action.payload.location;
15
+ const { externalRoutes = [] } = config.settings;
13
16
 
14
- const route = externalRoutes.find((route) =>
15
- matchPath(pathname, route.match),
16
- );
17
+ const route = externalRoutes.find((route) =>
18
+ matchPath(pathname, route.match),
19
+ );
17
20
 
18
- if (!route) {
21
+ if (!route) {
22
+ return next(action);
23
+ } else {
24
+ window.location.replace(
25
+ route.url ? route.url(action.payload) : pathname,
26
+ );
27
+ }
28
+ break;
29
+ default:
19
30
  return next(action);
20
- } else {
21
- window.location.replace(
22
- route.url ? route.url(action.payload) : pathname,
23
- );
24
- }
25
- break;
26
- default:
27
- return next(action);
28
- }
29
- };
31
+ }
32
+ };
30
33
 
31
34
  export default blacklistRoutes;
@@ -4,8 +4,8 @@
4
4
  * @example import { api } from 'middleware';
5
5
  */
6
6
 
7
- export api from '@plone/volto/middleware/api';
8
- export blacklistRoutes from './blacklistRoutes';
7
+ export { default as api } from '@plone/volto/middleware/api';
8
+ export { default as blacklistRoutes } from './blacklistRoutes';
9
9
  export {
10
10
  protectLoadStart,
11
11
  protectLoadEnd,
@@ -21,42 +21,43 @@ const RESET_CONTENT = 'RESET_CONTENT';
21
21
  // such a reset when navigating between two content routes.
22
22
  // ---
23
23
 
24
- export const protectLoadStart = ({ dispatch, getState }) => (next) => (
25
- action,
26
- ) => {
27
- if (typeof action === 'function') {
28
- return next(action);
29
- }
30
- switch (action.type) {
31
- case LOCATION_CHANGE:
32
- const { location } = action.payload;
33
- const { pathname: path } = location;
34
- const currentPath = getState().router.location.pathname;
35
- const result = next(action);
36
- if (isCmsUi(path)) {
37
- // Next path: isCmsUI, Non Content. There is no
38
- // loading here, so skip counting altogether.
39
- // Will update the delayed location constantly.
40
- dispatch({
41
- type: PROTECT_SKIPPED,
42
- location,
43
- });
44
- } else {
45
- dispatch({
46
- type: PROTECT_START,
47
- location,
48
- // Only reset before the fetch, if we depart from
49
- // a not isCmsUi, Content pass. However, reset will
50
- // not occur if moving between two content paths,
51
- // only the postponed location will be booked.
52
- resetBeforeFetch: isCmsUi(currentPath),
53
- });
54
- }
55
- return result;
56
- default:
24
+ export const protectLoadStart =
25
+ ({ dispatch, getState }) =>
26
+ (next) =>
27
+ (action) => {
28
+ if (typeof action === 'function') {
57
29
  return next(action);
58
- }
59
- };
30
+ }
31
+ switch (action.type) {
32
+ case LOCATION_CHANGE:
33
+ const { location } = action.payload;
34
+ const { pathname: path } = location;
35
+ const currentPath = getState().router.location.pathname;
36
+ const result = next(action);
37
+ if (isCmsUi(path)) {
38
+ // Next path: isCmsUI, Non Content. There is no
39
+ // loading here, so skip counting altogether.
40
+ // Will update the delayed location constantly.
41
+ dispatch({
42
+ type: PROTECT_SKIPPED,
43
+ location,
44
+ });
45
+ } else {
46
+ dispatch({
47
+ type: PROTECT_START,
48
+ location,
49
+ // Only reset before the fetch, if we depart from
50
+ // a not isCmsUi, Content pass. However, reset will
51
+ // not occur if moving between two content paths,
52
+ // only the postponed location will be booked.
53
+ resetBeforeFetch: isCmsUi(currentPath),
54
+ });
55
+ }
56
+ return result;
57
+ default:
58
+ return next(action);
59
+ }
60
+ };
60
61
 
61
62
  // Note that there is a bit of heuristics here. We assume that every action
62
63
  // like this is beginning/ending an action. If this logic fails then the counting
@@ -70,34 +71,32 @@ const mapActions = {
70
71
  [GET_CONTENT_PENDING]: RESET_CONTENT,
71
72
  };
72
73
 
73
- export const protectLoadEnd = ({ dispatch, getState }) => (next) => (
74
- action,
75
- ) => {
76
- if (typeof action === 'function') {
77
- return next(action);
78
- }
79
- const {
80
- isCounting,
81
- resetBeforeFetch,
82
- requestCount,
83
- } = getState().loadProtector;
84
- if (resetBeforeFetch) {
85
- const type = mapActions[action.type];
86
- if (type) {
87
- dispatch({ type });
74
+ export const protectLoadEnd =
75
+ ({ dispatch, getState }) =>
76
+ (next) =>
77
+ (action) => {
78
+ if (typeof action === 'function') {
79
+ return next(action);
88
80
  }
89
- }
90
- if (isCounting && requestCount === 1 && isResponseAction(action)) {
91
- setTimeout(
92
- () =>
93
- dispatch({
94
- type: PROTECT_END,
95
- }),
96
- 0,
97
- );
98
- }
99
- return next(action);
100
- };
81
+ const { isCounting, resetBeforeFetch, requestCount } =
82
+ getState().loadProtector;
83
+ if (resetBeforeFetch) {
84
+ const type = mapActions[action.type];
85
+ if (type) {
86
+ dispatch({ type });
87
+ }
88
+ }
89
+ if (isCounting && requestCount === 1 && isResponseAction(action)) {
90
+ setTimeout(
91
+ () =>
92
+ dispatch({
93
+ type: PROTECT_END,
94
+ }),
95
+ 0,
96
+ );
97
+ }
98
+ return next(action);
99
+ };
101
100
 
102
101
  export function loadProtector(state = {}, action = {}) {
103
102
  switch (action.type) {