@plone/volto 17.0.0-alpha.9 → 17.0.1

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 +774 -5
  3. package/CONTRIBUTING.md +5 -1
  4. package/README.md +12 -9
  5. package/RELEASING.md +5 -5
  6. package/addon-registry.js +10 -1
  7. package/create-addons-loader.js +1 -1
  8. package/cypress/support/commands.js +70 -14
  9. package/cypress/support/e2e.js +1 -2
  10. package/cypress/support/volto-slate.js +4 -5
  11. package/cypress.config.js +1 -0
  12. package/docker-compose.yml +1 -1
  13. package/locales/ca/LC_MESSAGES/volto.po +281 -53
  14. package/locales/ca.json +1 -1
  15. package/locales/de/LC_MESSAGES/volto.po +289 -61
  16. package/locales/de.json +1 -1
  17. package/locales/en/LC_MESSAGES/volto.po +279 -51
  18. package/locales/en.json +1 -1
  19. package/locales/es/LC_MESSAGES/volto.po +318 -90
  20. package/locales/es.json +1 -1
  21. package/locales/eu/LC_MESSAGES/volto.po +280 -52
  22. package/locales/eu.json +1 -1
  23. package/locales/fi/LC_MESSAGES/volto.po +280 -52
  24. package/locales/fi.json +1 -1
  25. package/locales/fr/LC_MESSAGES/volto.po +281 -53
  26. package/locales/fr.json +1 -1
  27. package/locales/it/LC_MESSAGES/volto.po +474 -246
  28. package/locales/it.json +1 -1
  29. package/locales/ja/LC_MESSAGES/volto.po +280 -52
  30. package/locales/ja.json +1 -1
  31. package/locales/nl/LC_MESSAGES/volto.po +281 -53
  32. package/locales/nl.json +1 -1
  33. package/locales/pt/LC_MESSAGES/volto.po +281 -53
  34. package/locales/pt.json +1 -1
  35. package/locales/pt_BR/LC_MESSAGES/volto.po +314 -86
  36. package/locales/pt_BR.json +1 -1
  37. package/locales/ro/LC_MESSAGES/volto.po +281 -53
  38. package/locales/ro.json +1 -1
  39. package/locales/volto.pot +284 -52
  40. package/locales/zh_CN/LC_MESSAGES/volto.po +281 -53
  41. package/locales/zh_CN.json +1 -1
  42. package/package.json +44 -34
  43. package/packages/volto-slate/package.json +1 -1
  44. package/packages/volto-slate/src/actions/index.js +1 -1
  45. package/packages/volto-slate/src/blocks/Table/TableBlockEdit.jsx +21 -212
  46. package/packages/volto-slate/src/blocks/Table/schema.js +122 -0
  47. package/packages/volto-slate/src/blocks/Text/DefaultTextBlockEditor.jsx +8 -3
  48. package/packages/volto-slate/src/blocks/Text/TextBlockView.jsx +21 -16
  49. package/packages/volto-slate/src/blocks/Text/extensions/withDeserializers.js +3 -1
  50. package/packages/volto-slate/src/blocks/Text/index.js +10 -7
  51. package/packages/volto-slate/src/editor/config.jsx +5 -4
  52. package/packages/volto-slate/src/editor/index.js +4 -4
  53. package/packages/volto-slate/src/editor/less/slate.less +28 -0
  54. package/packages/volto-slate/src/editor/plugins/Link/render.jsx +5 -6
  55. package/packages/volto-slate/src/editor/plugins/StyleMenu/StyleMenu.jsx +14 -4
  56. package/packages/volto-slate/src/editor/plugins/StyleMenu/utils.js +14 -5
  57. package/packages/volto-slate/src/editor/render.jsx +77 -8
  58. package/packages/volto-slate/src/editor/ui/SlateContextToolbar.jsx +2 -2
  59. package/packages/volto-slate/src/editor/ui/index.js +15 -15
  60. package/packages/volto-slate/src/index.js +2 -2
  61. package/packages/volto-slate/src/utils/blocks.js +7 -0
  62. package/packages/volto-slate/src/widgets/RichTextWidget.jsx +15 -8
  63. package/razzle.config.js +4 -6
  64. package/src/actions/index.js +4 -0
  65. package/src/actions/navroot/navroot.js +16 -0
  66. package/src/actions/navroot/navroot.test.js +15 -0
  67. package/src/actions/relations/rebuild.js +7 -7
  68. package/src/actions/relations/relations.js +17 -0
  69. package/src/actions/site/site.js +16 -0
  70. package/src/actions/site/site.test.js +15 -0
  71. package/src/actions/userSession/userSession.js +17 -1
  72. package/src/components/index.js +194 -192
  73. package/src/components/manage/Actions/Actions.jsx +133 -243
  74. package/src/components/manage/Add/Add.jsx +7 -8
  75. package/src/components/manage/AnchorPlugin/index.jsx +2 -2
  76. package/src/components/manage/AnchorPlugin/utils/EditorUtils.js +3 -1
  77. package/src/components/manage/Blocks/Block/BlocksForm.jsx +19 -2
  78. package/src/components/manage/Blocks/Block/Edit.jsx +1 -1
  79. package/src/components/manage/Blocks/Block/Settings.jsx +2 -0
  80. package/src/components/manage/Blocks/Block/Settings.test.jsx +92 -0
  81. package/src/components/manage/Blocks/Block/Style.jsx +2 -2
  82. package/src/components/manage/Blocks/Container/Data.jsx +32 -0
  83. package/src/components/manage/Blocks/Container/Edit.jsx +177 -0
  84. package/src/components/manage/Blocks/Container/EditBlockWrapper.jsx +121 -0
  85. package/src/components/manage/Blocks/Container/NewBlockAddButton.jsx +84 -0
  86. package/src/components/manage/Blocks/Container/SimpleContainerToolbar.jsx +54 -0
  87. package/src/components/manage/Blocks/Grid/Edit.jsx +47 -0
  88. package/src/components/manage/Blocks/Grid/View.jsx +43 -0
  89. package/src/components/manage/Blocks/Grid/adapter.js +14 -0
  90. package/src/components/manage/Blocks/Grid/grid-1.svg +6 -0
  91. package/src/components/manage/Blocks/Grid/grid-2.svg +9 -0
  92. package/src/components/manage/Blocks/Grid/grid-3.svg +10 -0
  93. package/src/components/manage/Blocks/Grid/grid-4.svg +11 -0
  94. package/src/components/manage/Blocks/Grid/schema.js +35 -0
  95. package/src/components/manage/Blocks/Grid/templates.js +47 -0
  96. package/src/components/manage/Blocks/HTML/Edit.jsx +8 -8
  97. package/src/components/manage/Blocks/HeroImageLeft/Edit.jsx +36 -26
  98. package/src/components/manage/Blocks/Image/Edit.jsx +51 -12
  99. package/src/components/manage/Blocks/Image/Edit.test.jsx +2 -0
  100. package/src/components/manage/Blocks/Image/ImageSidebar.jsx +66 -16
  101. package/src/components/manage/Blocks/Image/View.jsx +26 -5
  102. package/src/components/manage/Blocks/Image/View.test.jsx +20 -0
  103. package/src/components/manage/Blocks/Image/schema.js +17 -10
  104. package/src/components/manage/Blocks/Image/utils.js +14 -0
  105. package/src/components/manage/Blocks/LeadImage/Edit.jsx +32 -10
  106. package/src/components/manage/Blocks/LeadImage/Edit.test.jsx +11 -1
  107. package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.jsx +28 -9
  108. package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.test.jsx +8 -2
  109. package/src/components/manage/Blocks/LeadImage/View.jsx +50 -38
  110. package/src/components/manage/Blocks/LeadImage/View.test.jsx +11 -1
  111. package/src/components/manage/Blocks/Listing/DefaultTemplate.jsx +18 -3
  112. package/src/components/manage/Blocks/Listing/ListingBody.jsx +32 -8
  113. package/src/components/manage/Blocks/Listing/ListingBody.test.jsx +20 -0
  114. package/src/components/manage/Blocks/Listing/SummaryTemplate.jsx +1 -1
  115. package/src/components/manage/Blocks/Listing/getAsyncData.js +3 -5
  116. package/src/components/manage/Blocks/Listing/withQuerystringResults.jsx +27 -17
  117. package/src/components/manage/Blocks/Maps/Edit.jsx +135 -209
  118. package/src/components/manage/Blocks/Maps/Edit.test.jsx +1 -2
  119. package/src/components/manage/Blocks/Maps/View.test.jsx +1 -2
  120. package/src/components/manage/Blocks/Search/SearchBlockView.jsx +3 -2
  121. package/src/components/manage/Blocks/Search/components/Facets.jsx +66 -7
  122. package/src/components/manage/Blocks/Search/components/FilterList.jsx +4 -6
  123. package/src/components/manage/Blocks/Search/components/SearchInput.jsx +9 -2
  124. package/src/components/manage/Blocks/Search/components/SelectFacet.jsx +2 -9
  125. package/src/components/manage/Blocks/Search/components/index.js +13 -13
  126. package/src/components/manage/Blocks/Search/hocs/index.js +2 -2
  127. package/src/components/manage/Blocks/Search/hocs/withQueryString.jsx +5 -2
  128. package/src/components/manage/Blocks/Search/hocs/withSearch.jsx +70 -36
  129. package/src/components/manage/Blocks/Search/layout/LeftColumnFacets.jsx +17 -5
  130. package/src/components/manage/Blocks/Search/layout/RightColumnFacets.jsx +17 -5
  131. package/src/components/manage/Blocks/Search/layout/TopSideFacets.jsx +21 -5
  132. package/src/components/manage/Blocks/Search/schema.js +29 -14
  133. package/src/components/manage/Blocks/Table/Cell.jsx +2 -3
  134. package/src/components/manage/Blocks/Teaser/Body.jsx +0 -1
  135. package/src/components/manage/Blocks/Teaser/DefaultBody.jsx +5 -10
  136. package/src/components/manage/Blocks/Teaser/schema.js +5 -0
  137. package/src/components/manage/Blocks/Text/Edit.jsx +2 -3
  138. package/src/components/manage/Blocks/Title/View.jsx +0 -23
  139. package/src/components/manage/Blocks/Title/View.test.jsx +16 -1
  140. package/src/components/manage/Blocks/ToC/Schema.jsx +40 -7
  141. package/src/components/manage/Blocks/ToC/View.jsx +84 -14
  142. package/src/components/manage/Blocks/ToC/variations/DefaultTocRenderer.jsx +8 -3
  143. package/src/components/manage/Blocks/ToC/variations/DefaultTocRenderer.test.jsx +44 -0
  144. package/src/components/manage/Blocks/ToC/variations/HorizontalMenu.jsx +149 -10
  145. package/src/components/manage/Blocks/ToC/variations/index.js +3 -1
  146. package/src/components/manage/Blocks/Video/View.test.jsx +1 -1
  147. package/src/components/manage/Contents/Contents.jsx +285 -114
  148. package/src/components/manage/Contents/ContentsPropertiesModal.jsx +90 -166
  149. package/src/components/manage/Contents/ContentsRenameModal.jsx +88 -139
  150. package/src/components/manage/Contents/ContentsRenameModal.stories.jsx +61 -0
  151. package/src/components/manage/Contents/ContentsTagsModal.jsx +83 -130
  152. package/src/components/manage/Contents/ContentsTagsModal.stories.jsx +68 -0
  153. package/src/components/manage/Contents/ContentsUploadModal.jsx +11 -7
  154. package/src/components/manage/Contents/ContentsWorkflowModal.jsx +87 -154
  155. package/src/components/manage/Controlpanels/Aliases.jsx +4 -12
  156. package/src/components/manage/Controlpanels/Groups/GroupsControlpanel.jsx +65 -38
  157. package/src/components/manage/Controlpanels/Groups/RenderGroups.jsx +2 -2
  158. package/src/components/manage/Controlpanels/Relations/BrokenRelations.jsx +38 -13
  159. package/src/components/manage/Controlpanels/Relations/Relations.jsx +5 -5
  160. package/src/components/manage/Controlpanels/Relations/RelationsListing.jsx +8 -7
  161. package/src/components/manage/Controlpanels/Relations/RelationsMatrix.jsx +68 -68
  162. package/src/components/manage/Controlpanels/Rules/AddRule.jsx +3 -10
  163. package/src/components/manage/Controlpanels/Rules/EditRule.jsx +1 -1
  164. package/src/components/manage/Controlpanels/UndoControlpanel.jsx +6 -9
  165. package/src/components/manage/Controlpanels/Users/RenderUsers.jsx +97 -7
  166. package/src/components/manage/Controlpanels/Users/UsersControlpanel.jsx +127 -99
  167. package/src/components/manage/Delete/Delete.jsx +96 -171
  168. package/src/components/manage/Diff/DiffField.jsx +25 -1
  169. package/src/components/manage/DragDropList/DragDropList.jsx +18 -13
  170. package/src/components/manage/Form/BlockDataForm.jsx +3 -2
  171. package/src/components/manage/Form/BlockDataForm.test.jsx +51 -17
  172. package/src/components/manage/Form/Form.jsx +7 -6
  173. package/src/components/manage/Form/InlineForm.test.jsx +16 -14
  174. package/src/components/manage/History/History.jsx +11 -1
  175. package/src/components/manage/LinksToItem/LinksToItem.jsx +209 -0
  176. package/src/components/manage/LinksToItem/LinksToItem.test.jsx +100 -0
  177. package/src/components/manage/LockingToastsFactory/LockingToastsFactory.jsx +1 -2
  178. package/src/components/manage/Messages/Messages.jsx +32 -99
  179. package/src/components/manage/Messages/Messages.test.jsx +0 -1
  180. package/src/components/manage/Preferences/ChangePassword.jsx +2 -2
  181. package/src/components/manage/Sharing/Sharing.jsx +80 -22
  182. package/src/components/manage/Sidebar/AlignBlock.jsx +1 -1
  183. package/src/components/manage/Sidebar/Sidebar.jsx +139 -220
  184. package/src/components/manage/TemplateChooser/TemplateChooser.jsx +38 -0
  185. package/src/components/manage/TemplateChooser/TemplateChooser.test.jsx +34 -0
  186. package/src/components/manage/TemplateChooser/template.svg +10 -0
  187. package/src/components/manage/Toast/Toast.jsx +1 -1
  188. package/src/components/manage/Toolbar/More.jsx +17 -2
  189. package/src/components/manage/Toolbar/PersonalTools.jsx +97 -155
  190. package/src/components/manage/Toolbar/Toolbar.jsx +2 -2
  191. package/src/components/manage/UniversalLink/UniversalLink.jsx +6 -12
  192. package/src/components/manage/UniversalLink/UniversalLink.test.jsx +37 -0
  193. package/src/components/manage/Widgets/AlignWidget.jsx +2 -4
  194. package/src/components/manage/Widgets/ArrayWidget.jsx +3 -1
  195. package/src/components/manage/Widgets/ArrayWidget.test.jsx +45 -1
  196. package/src/components/manage/Widgets/ColorPickerWidget.jsx +6 -1
  197. package/src/components/manage/Widgets/ColorPickerWidget.test.jsx +9 -7
  198. package/src/components/manage/Widgets/DatetimeWidget.jsx +2 -8
  199. package/src/components/manage/Widgets/FileWidget.jsx +2 -1
  200. package/src/components/manage/Widgets/FormFieldWrapper.jsx +1 -1
  201. package/src/components/manage/Widgets/IdWidget.jsx +1 -2
  202. package/src/components/manage/Widgets/ObjectBrowserWidget.jsx +2 -9
  203. package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.jsx +3 -10
  204. package/src/components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthIndexField.jsx +4 -4
  205. package/src/components/manage/Widgets/RegistryImageWidget.jsx +210 -0
  206. package/src/components/manage/Widgets/RegistryImageWidget.test.jsx +91 -0
  207. package/src/components/manage/Widgets/SchemaWidget.jsx +6 -9
  208. package/src/components/manage/Widgets/SelectUtils.js +1 -1
  209. package/src/components/manage/Widgets/SelectWidget.jsx +15 -1
  210. package/src/components/manage/Widgets/SelectWidget.test.jsx +45 -1
  211. package/src/components/manage/Widgets/WysiwygWidget.jsx +2 -9
  212. package/src/components/manage/Workflow/Workflow.jsx +75 -184
  213. package/src/components/theme/Anontools/Anontools.jsx +44 -72
  214. package/src/components/theme/Anontools/Anontools.stories.jsx +16 -6
  215. package/src/components/theme/Anontools/Anontools.test.jsx +16 -2
  216. package/src/components/theme/Breadcrumbs/Breadcrumbs.jsx +52 -99
  217. package/src/components/theme/Breadcrumbs/Breadcrumbs.stories.jsx +14 -13
  218. package/src/components/theme/Comments/Comment.stories.jsx +84 -0
  219. package/src/components/theme/Comments/CommentEditModal.jsx +63 -115
  220. package/src/components/theme/Comments/Comments.jsx +268 -380
  221. package/src/components/theme/Component/Component.jsx +1 -1
  222. package/src/components/theme/ContactForm/ContactForm.jsx +108 -192
  223. package/src/components/theme/ContactForm/ContactForm.stories.jsx +1 -1
  224. package/src/components/theme/ContactForm/ContactForm.test.jsx +2 -3
  225. package/src/components/theme/ContentMetadataTags/ContentMetadataTags.jsx +41 -3
  226. package/src/components/theme/Error/ServerError.jsx +29 -0
  227. package/src/components/theme/Header/Header.jsx +37 -63
  228. package/src/components/theme/Header/Header.test.jsx +18 -0
  229. package/src/components/theme/Image/Image.jsx +96 -0
  230. package/src/components/theme/Image/Image.test.jsx +125 -0
  231. package/src/components/theme/Login/Login.jsx +160 -243
  232. package/src/components/theme/Logo/Logo.Multilingual.test.jsx +131 -1
  233. package/src/components/theme/Logo/Logo.jsx +35 -27
  234. package/src/components/theme/Logo/Logo.test.jsx +135 -1
  235. package/src/components/theme/Logout/Logout.jsx +36 -83
  236. package/src/components/theme/Navigation/Navigation.jsx +86 -171
  237. package/src/components/theme/PasswordReset/PasswordReset.jsx +7 -5
  238. package/src/components/theme/PasswordReset/RequestPasswordReset.jsx +95 -170
  239. package/src/components/theme/PreviewImage/PreviewImage.jsx +31 -15
  240. package/src/components/theme/PreviewImage/PreviewImage.test.js +53 -13
  241. package/src/components/theme/Register/Register.jsx +2 -4
  242. package/src/components/theme/Search/SearchTags.jsx +30 -60
  243. package/src/components/theme/SearchWidget/SearchWidget.jsx +49 -97
  244. package/src/components/theme/SearchWidget/SearchWidget.test.jsx +8 -0
  245. package/src/components/theme/Sitemap/Sitemap.jsx +24 -13
  246. package/src/components/theme/Sitemap/Sitemap.test.jsx +23 -2
  247. package/src/components/theme/TsTest/TsTest.test.tsx +11 -0
  248. package/src/components/theme/TsTest/TsTest.tsx +15 -0
  249. package/src/components/theme/View/AlbumView.jsx +21 -16
  250. package/src/components/theme/View/EventView.jsx +36 -25
  251. package/src/components/theme/View/FileView.jsx +23 -18
  252. package/src/components/theme/View/ImageView.jsx +40 -32
  253. package/src/components/theme/View/ImageView.test.jsx +4 -0
  254. package/src/components/theme/View/LinkView.jsx +53 -78
  255. package/src/components/theme/View/ListingView.jsx +36 -28
  256. package/src/components/theme/View/NewsItemView.jsx +16 -17
  257. package/src/components/theme/View/RenderBlocks.jsx +56 -27
  258. package/src/components/theme/View/RenderEmptyBlock.jsx +5 -0
  259. package/src/components/theme/View/SummaryView.jsx +49 -39
  260. package/src/components/theme/View/TabularView.jsx +59 -53
  261. package/src/components/theme/View/View.jsx +2 -0
  262. package/src/components/theme/Widgets/ImageWidget.stories.jsx +1 -2
  263. package/src/config/Blocks.jsx +46 -0
  264. package/src/config/Components.jsx +3 -1
  265. package/src/config/ControlPanels.js +0 -1
  266. package/src/config/Loadables.jsx +1 -1
  267. package/src/config/NonContentRoutes.jsx +1 -0
  268. package/src/config/RichTextEditor/Blocks.jsx +4 -5
  269. package/src/config/RichTextEditor/FromHTML.jsx +2 -2
  270. package/src/config/RichTextEditor/Plugins.jsx +2 -3
  271. package/src/config/RichTextEditor/Styles.jsx +1 -1
  272. package/src/config/RichTextEditor/ToHTML.jsx +12 -10
  273. package/src/config/RichTextEditor/index.js +2 -3
  274. package/src/config/Views.jsx +6 -4
  275. package/src/config/Widgets.jsx +3 -0
  276. package/src/config/index.js +36 -2
  277. package/src/config/server.js +2 -0
  278. package/src/constants/ActionTypes.js +4 -0
  279. package/src/constants/Indexes.js +3 -1
  280. package/src/express-middleware/devproxy.js +1 -1
  281. package/src/express-middleware/files.js +11 -9
  282. package/src/express-middleware/images.js +12 -5
  283. package/src/express-middleware/ok.js +16 -0
  284. package/src/express-middleware/robotstxt.js +1 -1
  285. package/src/express-middleware/sitemap.js +1 -1
  286. package/src/express-middleware/static.js +3 -3
  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 +6 -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
@@ -1,7 +1,7 @@
1
1
  import registry from '@plone/volto/registry';
2
2
 
3
3
  /**
4
- * A component that can autommatically look up its implementation from the
4
+ * A component that can automatically look up its implementation from the
5
5
  * registry based on the provided component `componentName`
6
6
  */
7
7
  const Component = ({ componentName, dependencies, ...rest }) => {
@@ -1,22 +1,15 @@
1
- /**
2
- * Contact Form container.
3
- * @module components/theme/ContactForm/ContactForm
4
- */
5
-
6
- import React, { Component } from 'react';
7
- import PropTypes from 'prop-types';
8
- import { Helmet } from '@plone/volto/helpers';
9
- import { connect } from 'react-redux';
10
- import { compose } from 'redux';
1
+ import { useCallback, useEffect } from 'react';
11
2
  import { Portal } from 'react-portal';
12
3
  import { Container, Message, Icon } from 'semantic-ui-react';
13
- import { defineMessages, injectIntl } from 'react-intl';
14
- import { Link, withRouter } from 'react-router-dom';
4
+ import { defineMessages, useIntl } from 'react-intl';
5
+ import { Link, useHistory, useLocation } from 'react-router-dom';
15
6
  import { toast } from 'react-toastify';
16
7
 
17
- import { Form, Toolbar, Toast } from '@plone/volto/components';
18
8
  import { emailNotification } from '@plone/volto/actions';
19
- import { getBaseUrl } from '@plone/volto/helpers';
9
+ import { useDispatch, useSelector } from 'react-redux';
10
+ import { Form, Toolbar, Toast } from '@plone/volto/components';
11
+ import { getBaseUrl, Helmet, usePrevious } from '@plone/volto/helpers';
12
+ import { useClient } from '@plone/volto/hooks';
20
13
 
21
14
  const messages = defineMessages({
22
15
  send: {
@@ -65,195 +58,118 @@ const messages = defineMessages({
65
58
  },
66
59
  });
67
60
 
68
- /**
69
- * ContactForm class.
70
- * @class ContactForm
71
- * @extends Component
72
- */
73
- export class ContactFormComponent extends Component {
74
- /**
75
- * Property types.
76
- * @property {Object} propTypes Property types.
77
- * @static
78
- */
79
- static propTypes = {
80
- emailNotification: PropTypes.func.isRequired,
81
- error: PropTypes.shape({
82
- message: PropTypes.string,
83
- }),
84
- loading: PropTypes.bool,
85
- loaded: PropTypes.bool,
86
- pathname: PropTypes.string.isRequired,
87
- };
61
+ const useEmailNotification = () => {
62
+ const loading = useSelector((state) => state.emailNotification.loading);
63
+ const loaded = useSelector((state) => state.emailNotification.loaded);
64
+ const error = useSelector((state) => state.emailNotification.error);
88
65
 
89
- /**
90
- * Default properties.
91
- * @property {Object} defaultProps Default properties.
92
- * @static
93
- */
94
- static defaultProps = {
95
- error: null,
96
- loading: null,
97
- loaded: null,
98
- };
66
+ return { loading, loaded, error };
67
+ };
68
+
69
+ const ContactFormComponent = () => {
70
+ const history = useHistory();
71
+ const { pathname } = useLocation();
72
+ const dispatch = useDispatch();
73
+ const intl = useIntl();
74
+ const isClient = useClient();
99
75
 
100
- /**
101
- * Constructor
102
- * @method constructor
103
- * @param {Object} props Component properties
104
- * @constructs WysiwygEditor
105
- */
106
- constructor(props) {
107
- super(props);
108
- this.onSubmit = this.onSubmit.bind(this);
109
- this.onCancel = this.onCancel.bind(this);
110
- this.state = { isClient: false };
111
- }
76
+ const { loaded, loading, error } = useEmailNotification();
112
77
 
113
- /**
114
- * Component will receive props
115
- * @method componentWillReceiveProps
116
- * @param {Object} nextProps Next properties
117
- * @returns {undefined}
118
- */
119
- UNSAFE_componentWillReceiveProps(nextProps) {
120
- if (this.props.loading && nextProps.loaded) {
78
+ const prevloading = usePrevious(loading);
79
+
80
+ useEffect(() => {
81
+ if (prevloading && loaded) {
121
82
  toast.success(
122
83
  <Toast
123
84
  success
124
- title={this.props.intl.formatMessage(messages.success)}
125
- content={this.props.intl.formatMessage(messages.messageSent)}
85
+ title={intl.formatMessage(messages.success)}
86
+ content={intl.formatMessage(messages.messageSent)}
126
87
  />,
127
88
  );
128
89
  }
129
- }
90
+ }, [intl, loaded, prevloading]);
130
91
 
131
- /**
132
- * Component did mount
133
- * @method componentDidMount
134
- * @returns {undefined}
135
- */
136
- componentDidMount() {
137
- this.setState({ isClient: true });
138
- }
92
+ const onSubmit = (data) => {
93
+ const { from, message, name, subject } = data;
94
+ dispatch(emailNotification(from, message, name, subject));
95
+ };
139
96
 
140
- /**
141
- * On submit handler
142
- * @method onSubmit
143
- * @param {Object} data Data object.
144
- * @returns {undefined}
145
- */
146
- onSubmit(data) {
147
- this.props.emailNotification(
148
- data.from,
149
- data.message,
150
- data.name,
151
- data.subject,
152
- );
153
- }
97
+ const onCancel = useCallback(() => {
98
+ history.goBack();
99
+ }, [history]);
154
100
 
155
- /**
156
- * Cancel handler
157
- * @method onCancel
158
- * @returns {undefined}
159
- */
160
- onCancel() {
161
- this.props.history.goBack();
162
- }
163
- /**
164
- * Render method.
165
- * @method render
166
- * @returns {string} Markup for the component.
167
- */
168
- render() {
169
- return (
170
- <div id="contact-form">
171
- <Container id="view">
172
- <Helmet title={this.props.intl.formatMessage(messages.contactForm)} />
173
- {this.props.error && (
174
- <Message
175
- icon="warning"
176
- negative
177
- attached
178
- header={this.props.intl.formatMessage(messages.error)}
179
- content={this.props.error.message}
180
- />
181
- )}
182
- <Form
183
- onSubmit={this.onSubmit}
184
- onCancel={this.onCancel}
185
- formData={{ blocksLayoutFieldname: {} }}
186
- submitLabel={this.props.intl.formatMessage(messages.send)}
187
- resetAfterSubmit
188
- title={this.props.intl.formatMessage(messages.contactForm)}
189
- loading={this.props.loading}
190
- schema={{
191
- fieldsets: [
192
- {
193
- fields: ['name', 'from', 'subject', 'message'],
194
- id: 'default',
195
- title: this.props.intl.formatMessage(messages.default),
196
- },
197
- ],
198
- properties: {
199
- name: {
200
- title: this.props.intl.formatMessage(messages.name),
201
- type: 'string',
202
- },
203
- from: {
204
- title: this.props.intl.formatMessage(messages.from),
205
- type: 'email',
206
- },
207
- subject: {
208
- title: this.props.intl.formatMessage(messages.subject),
209
- type: 'string',
210
- },
211
- message: {
212
- title: this.props.intl.formatMessage(messages.message),
213
- type: 'string',
214
- widget: 'textarea',
215
- },
216
- },
217
- required: ['from', 'message'],
218
- }}
101
+ return (
102
+ <div id="contact-form">
103
+ <Container id="view">
104
+ <Helmet title={intl.formatMessage(messages.contactForm)} />
105
+ {error && (
106
+ <Message
107
+ icon="warning"
108
+ negative
109
+ attached
110
+ header={intl.formatMessage(messages.error)}
111
+ content={error.message}
219
112
  />
220
- {this.state.isClient && (
221
- <Portal node={document.getElementById('toolbar')}>
222
- <Toolbar
223
- pathname={this.props.pathname}
224
- hideDefaultViewButtons
225
- inner={
226
- <Link
227
- to={`${getBaseUrl(this.props.pathname)}`}
228
- className="item"
229
- >
230
- <Icon
231
- name="arrow left"
232
- size="big"
233
- color="blue"
234
- title={this.props.intl.formatMessage(messages.back)}
235
- />
236
- </Link>
237
- }
238
- />
239
- </Portal>
240
- )}
241
- </Container>
242
- </div>
243
- );
244
- }
245
- }
113
+ )}
114
+ <Form
115
+ onSubmit={onSubmit}
116
+ onCancel={onCancel}
117
+ formData={{ blocksLayoutFieldname: {} }}
118
+ submitLabel={intl.formatMessage(messages.send)}
119
+ resetAfterSubmit
120
+ title={intl.formatMessage(messages.contactForm)}
121
+ loading={loading}
122
+ schema={{
123
+ fieldsets: [
124
+ {
125
+ fields: ['name', 'from', 'subject', 'message'],
126
+ id: 'default',
127
+ title: intl.formatMessage(messages.default),
128
+ },
129
+ ],
130
+ properties: {
131
+ name: {
132
+ title: intl.formatMessage(messages.name),
133
+ type: 'string',
134
+ },
135
+ from: {
136
+ title: intl.formatMessage(messages.from),
137
+ type: 'email',
138
+ },
139
+ subject: {
140
+ title: intl.formatMessage(messages.subject),
141
+ type: 'string',
142
+ },
143
+ message: {
144
+ title: intl.formatMessage(messages.message),
145
+ type: 'string',
146
+ widget: 'textarea',
147
+ },
148
+ },
149
+ required: ['from', 'message'],
150
+ }}
151
+ />
152
+ {isClient && (
153
+ <Portal node={document.getElementById('toolbar')}>
154
+ <Toolbar
155
+ pathname={pathname}
156
+ hideDefaultViewButtons
157
+ inner={
158
+ <Link to={`${getBaseUrl(pathname)}`} className="item">
159
+ <Icon
160
+ name="arrow left"
161
+ size="big"
162
+ color="blue"
163
+ title={intl.formatMessage(messages.back)}
164
+ />
165
+ </Link>
166
+ }
167
+ />
168
+ </Portal>
169
+ )}
170
+ </Container>
171
+ </div>
172
+ );
173
+ };
246
174
 
247
- export default compose(
248
- withRouter,
249
- injectIntl,
250
- connect(
251
- (state, props) => ({
252
- loading: state.emailNotification.loading,
253
- loaded: state.emailNotification.loaded,
254
- error: state.emailNotification.error,
255
- pathname: props.location.pathname,
256
- }),
257
- { emailNotification },
258
- ),
259
- )(ContactFormComponent);
175
+ export default ContactFormComponent;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { ContactFormComponent } from './ContactForm';
2
+ import ContactFormComponent from './ContactForm';
3
3
  import { injectIntl } from 'react-intl';
4
4
  import { RealStoreWrapper as Wrapper } from '@plone/volto/storybook';
5
5
 
@@ -10,7 +10,6 @@ jest.mock('react-portal', () => ({
10
10
  }));
11
11
 
12
12
  const mockStore = configureStore();
13
-
14
13
  describe('Contact form', () => {
15
14
  it('renders a contact form', () => {
16
15
  const store = mockStore({
@@ -29,7 +28,7 @@ describe('Contact form', () => {
29
28
  const component = renderer.create(
30
29
  <Provider store={store}>
31
30
  <MemoryRouter>
32
- <ContactForm location={{ pathname: '/blog' }} />
31
+ <ContactForm />
33
32
  </MemoryRouter>
34
33
  </Provider>,
35
34
  );
@@ -56,7 +55,7 @@ describe('Contact form', () => {
56
55
  const component = renderer.create(
57
56
  <Provider store={store}>
58
57
  <MemoryRouter>
59
- <ContactForm location={{ pathname: '/' }} />
58
+ <ContactForm />
60
59
  </MemoryRouter>
61
60
  </Provider>,
62
61
  );
@@ -1,6 +1,13 @@
1
- import React from 'react';
2
- import { toPublicURL, Helmet } from '@plone/volto/helpers';
1
+ import React, { useEffect } from 'react';
2
+ import {
3
+ toPublicURL,
4
+ Helmet,
5
+ hasApiExpander,
6
+ getBaseUrl,
7
+ } from '@plone/volto/helpers';
8
+ import { getNavroot } from '@plone/volto/actions';
3
9
  import config from '@plone/volto/registry';
10
+ import { useDispatch, useSelector } from 'react-redux';
4
11
 
5
12
  const ContentMetadataTags = (props) => {
6
13
  const {
@@ -14,6 +21,17 @@ const ContentMetadataTags = (props) => {
14
21
  description,
15
22
  } = props.content;
16
23
 
24
+ const dispatch = useDispatch();
25
+ const pathname = useSelector((state) => state.router.location.pathname);
26
+ const navroot = useSelector((state) => state.navroot?.data?.navroot);
27
+ const site = useSelector((state) => state.site?.data);
28
+
29
+ useEffect(() => {
30
+ if (pathname && !hasApiExpander('navroot', getBaseUrl(pathname))) {
31
+ dispatch(getNavroot(getBaseUrl(pathname)));
32
+ }
33
+ }, [dispatch, pathname]);
34
+
17
35
  const getContentImageInfo = () => {
18
36
  const { contentMetadataTagsImageField } = config.settings;
19
37
  const image = props.content[contentMetadataTagsImageField];
@@ -45,10 +63,30 @@ const ContentMetadataTags = (props) => {
45
63
 
46
64
  const contentImageInfo = getContentImageInfo();
47
65
 
66
+ const getTitle = () => {
67
+ const includeSiteTitle =
68
+ config?.settings?.siteTitleFormat?.includeSiteTitle || false;
69
+ const titleAndSiteTitleSeparator =
70
+ config?.settings?.titleAndSiteTitleSeparator || '-';
71
+ const navRootTitle = navroot?.title;
72
+ const siteRootTitle = site?.['plone.site_title'];
73
+ const titlePart = navRootTitle || siteRootTitle;
74
+
75
+ if (includeSiteTitle && titlePart && titlePart !== title) {
76
+ return seo_title || `${title} ${titleAndSiteTitleSeparator} ${titlePart}`;
77
+ } else {
78
+ return seo_title || title;
79
+ }
80
+ };
81
+
48
82
  return (
49
83
  <>
50
84
  <Helmet>
51
- <title>{(seo_title || title)?.replace(/\u00AD/g, '')}</title>
85
+ <title>{getTitle()?.replace(/\u00AD/g, '')}</title>
86
+ <link
87
+ rel="canonical"
88
+ href={seo_canonical_url || toPublicURL(props.content['@id'])}
89
+ />
52
90
  <meta name="description" content={seo_description || description} />
53
91
  <meta
54
92
  property="og:title"
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @module components/theme/Error/ServerError
3
+ */
4
+
5
+ import React from 'react';
6
+ import { FormattedMessage } from 'react-intl';
7
+ import { Container } from 'semantic-ui-react';
8
+ import { withServerErrorCode } from '@plone/volto/helpers/Utils/Utils';
9
+
10
+ /**
11
+ * server error
12
+ * @function ServerError
13
+ * @returns {string} Markup of the server error page.
14
+ */
15
+ const ServerError = () => (
16
+ <Container className="view-wrapper">
17
+ <h1>
18
+ <FormattedMessage id="Server Error" defaultMessage="Server Error" />
19
+ </h1>
20
+ <p className="description">
21
+ <FormattedMessage
22
+ id="We apologize for the inconvenience, but there was an unexpected error on the server."
23
+ defaultMessage="We apologize for the inconvenience, but there was an unexpected error on the server."
24
+ />
25
+ </p>
26
+ </Container>
27
+ );
28
+
29
+ export default withServerErrorCode(500)(ServerError);
@@ -1,12 +1,6 @@
1
- /**
2
- * Header component.
3
- * @module components/theme/Header/Header
4
- */
5
-
6
- import React, { Component } from 'react';
7
1
  import { Container, Segment } from 'semantic-ui-react';
8
2
  import PropTypes from 'prop-types';
9
- import { connect } from 'react-redux';
3
+ import { useSelector, shallowEqual } from 'react-redux';
10
4
 
11
5
  import {
12
6
  Anontools,
@@ -16,65 +10,45 @@ import {
16
10
  SearchWidget,
17
11
  } from '@plone/volto/components';
18
12
 
19
- /**
20
- * Header component class.
21
- * @class Header
22
- * @extends Component
23
- */
24
- class Header extends Component {
25
- /**
26
- * Property types.
27
- * @property {Object} propTypes Property types.
28
- * @static
29
- */
30
- static propTypes = {
31
- token: PropTypes.string,
32
- pathname: PropTypes.string.isRequired,
33
- };
34
-
35
- /**
36
- * Default properties.
37
- * @property {Object} defaultProps Default properties.
38
- * @static
39
- */
40
- static defaultProps = {
41
- token: null,
42
- };
13
+ const Header = ({ pathname }) => {
14
+ const token = useSelector((state) => state.userSession.token, shallowEqual);
43
15
 
44
- /**
45
- * Render method.
46
- * @method render
47
- * @returns {string} Markup for the component.
48
- */
49
- render() {
50
- return (
51
- <Segment basic className="header-wrapper" role="banner">
52
- <Container>
53
- <div className="header">
54
- <div className="logo-nav-wrapper">
55
- <div className="logo">
56
- <Logo />
57
- </div>
58
- <Navigation pathname={this.props.pathname} />
16
+ return (
17
+ <Segment basic className="header-wrapper" role="banner">
18
+ <Container>
19
+ <div className="header">
20
+ <div className="logo-nav-wrapper">
21
+ <div className="logo">
22
+ <Logo />
59
23
  </div>
60
- <div className="tools-search-wrapper">
61
- <LanguageSelector />
62
- {!this.props.token && (
63
- <div className="tools">
64
- <Anontools />
65
- </div>
66
- )}
67
- <div className="search">
68
- <SearchWidget />
24
+ <Navigation pathname={pathname} />
25
+ </div>
26
+ <div className="tools-search-wrapper">
27
+ <LanguageSelector />
28
+ {!token && (
29
+ <div className="tools">
30
+ <Anontools />
69
31
  </div>
32
+ )}
33
+ <div className="search">
34
+ <SearchWidget />
70
35
  </div>
71
36
  </div>
72
- </Container>
73
- </Segment>
74
- );
75
- }
76
- }
37
+ </div>
38
+ </Container>
39
+ </Segment>
40
+ );
41
+ };
42
+
43
+ export default Header;
44
+
45
+ Header.propTypes = {
46
+ token: PropTypes.string,
47
+ pathname: PropTypes.string.isRequired,
48
+ content: PropTypes.objectOf(PropTypes.any),
49
+ };
77
50
 
78
- export default connect((state) => ({
79
- token: state.userSession.token,
80
- }))(Header);
51
+ Header.defaultProps = {
52
+ token: null,
53
+ content: null,
54
+ };
@@ -39,4 +39,22 @@ describe('Header', () => {
39
39
  const json = component.toJSON();
40
40
  expect(json).toMatchSnapshot();
41
41
  });
42
+
43
+ it('renders a header component - auth', () => {
44
+ const store = mockStore({
45
+ userSession: { token: '1234567890' },
46
+ intl: {
47
+ locale: 'en',
48
+ messages: {},
49
+ },
50
+ });
51
+
52
+ const component = renderer.create(
53
+ <Provider store={store}>
54
+ <Header pathname="/blog" />
55
+ </Provider>,
56
+ );
57
+ const json = component.toJSON();
58
+ expect(json).toMatchSnapshot();
59
+ });
42
60
  });