@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
@@ -10,11 +10,14 @@ function getDisplayName(WrappedComponent) {
10
10
  * A HOC that injects querystring metadata information from the backend.
11
11
  *
12
12
  */
13
- export default (WrappedComponent) => {
13
+ export default function withQueryString(WrappedComponent) {
14
14
  function WithQueryString(props) {
15
15
  const dispatch = useDispatch();
16
16
 
17
17
  const qs = useSelector((state) => state.querystring);
18
+ // This showed up after updating eslint-plugin-react-hooks
19
+ // TODO: fix it properly
20
+ // eslint-disable-next-line react-hooks/exhaustive-deps
18
21
  const indexes = qs?.indexes || {};
19
22
 
20
23
  React.useEffect(() => {
@@ -29,4 +32,4 @@ export default (WrappedComponent) => {
29
32
  WrappedComponent,
30
33
  )})`;
31
34
  return WithQueryString;
32
- };
35
+ }
@@ -5,6 +5,8 @@ import { useLocation, useHistory } from 'react-router-dom';
5
5
 
6
6
  import { resolveExtension } from '@plone/volto/helpers/Extensions/withBlockExtensions';
7
7
  import config from '@plone/volto/registry';
8
+ import { usePrevious } from '@plone/volto/helpers';
9
+ import { isEqual } from 'lodash';
8
10
 
9
11
  function getDisplayName(WrappedComponent) {
10
12
  return WrappedComponent.displayName || WrappedComponent.name || 'Component';
@@ -27,9 +29,8 @@ const PAQO = 'plone.app.querystring.operation';
27
29
  *
28
30
  */
29
31
  function getInitialState(data, facets, urlSearchText, id) {
30
- const {
31
- types: facetWidgetTypes,
32
- } = config.blocks.blocksConfig.search.extensions.facetWidgets;
32
+ const { types: facetWidgetTypes } =
33
+ config.blocks.blocksConfig.search.extensions.facetWidgets;
33
34
  const facetSettings = data?.facets || [];
34
35
 
35
36
  return {
@@ -85,9 +86,8 @@ function normalizeState({
85
86
  sortOrder,
86
87
  facetSettings, // data.facets extracted from block data
87
88
  }) {
88
- const {
89
- types: facetWidgetTypes,
90
- } = config.blocks.blocksConfig.search.extensions.facetWidgets;
89
+ const { types: facetWidgetTypes } =
90
+ config.blocks.blocksConfig.search.extensions.facetWidgets;
91
91
 
92
92
  const params = {
93
93
  query: [
@@ -148,12 +148,16 @@ const getSearchFields = (searchData) => {
148
148
  };
149
149
 
150
150
  /**
151
- * A HOC that will mirror the search block state to a hash location
151
+ * A hook that will mirror the search block state to a hash location
152
152
  */
153
153
  const useHashState = () => {
154
154
  const location = useLocation();
155
155
  const history = useHistory();
156
156
 
157
+ /**
158
+ * Required to maintain parameter compatibility.
159
+ With this we will maintain support for receiving hash (#) and search (?) type parameters.
160
+ */
157
161
  const oldState = React.useMemo(() => {
158
162
  return {
159
163
  ...qs.parse(location.search),
@@ -169,7 +173,7 @@ const useHashState = () => {
169
173
 
170
174
  const setSearchData = React.useCallback(
171
175
  (searchData) => {
172
- const newParams = qs.parse(location.hash);
176
+ const newParams = qs.parse(location.search);
173
177
 
174
178
  let changed = false;
175
179
 
@@ -186,11 +190,11 @@ const useHashState = () => {
186
190
 
187
191
  if (changed) {
188
192
  history.push({
189
- hash: qs.stringify(newParams),
193
+ search: qs.stringify(newParams),
190
194
  });
191
195
  }
192
196
  },
193
- [history, oldState, location.hash],
197
+ [history, oldState, location.search],
194
198
  );
195
199
 
196
200
  return [current, setSearchData];
@@ -234,6 +238,8 @@ const withSearch = (options) => (WrappedComponent) => {
234
238
  editable,
235
239
  );
236
240
 
241
+ // TODO: Improve the hook dependencies out of the scope of https://github.com/plone/volto/pull/4662
242
+ // eslint-disable-next-line react-hooks/exhaustive-deps
237
243
  const urlQuery = locationSearchData.query
238
244
  ? deserializeQuery(locationSearchData.query)
239
245
  : [];
@@ -244,40 +250,57 @@ const withSearch = (options) => (WrappedComponent) => {
244
250
 
245
251
  // TODO: refactor, should use only useLocationStateManager()!!!
246
252
  const [searchText, setSearchText] = React.useState(urlSearchText);
253
+ // TODO: Improve the hook dependencies out of the scope of https://github.com/plone/volto/pull/4662
254
+ // eslint-disable-next-line react-hooks/exhaustive-deps
247
255
  const configuredFacets =
248
256
  data.facets?.map((facet) => facet?.field?.value) || [];
249
257
  const multiFacets = data.facets
250
258
  ?.filter((facet) => facet?.multiple)
251
259
  .map((facet) => facet?.field?.value);
252
- const [facets, setFacets] = React.useState(
253
- Object.assign(
254
- {},
255
- ...urlQuery.map(({ i, v }) => ({ [i]: v })), // TODO: the 'o' should be kept. This would be a major refactoring of the facets
256
-
257
- // support for simple filters like ?Subject=something
258
- // TODO: since the move to hash params this is no longer working.
259
- // We'd have to treat the location.search and manage it just like the
260
- // hash, to support it. We can read it, but we'd have to reset it as
261
- // well, so at that point what's the difference to the hash?
262
- ...configuredFacets.map((f) =>
263
- locationSearchData[f]
264
- ? {
265
- [f]:
266
- multiFacets.indexOf(f) > -1
267
- ? [locationSearchData[f]]
268
- : locationSearchData[f],
269
- }
270
- : {},
271
- ),
272
- ),
273
- );
260
+ const [facets, setFacets] = React.useState({});
261
+ const previousUrlQuery = usePrevious(urlQuery);
262
+
263
+ React.useEffect(() => {
264
+ if (!isEqual(urlQuery, previousUrlQuery)) {
265
+ setFacets(
266
+ Object.assign(
267
+ {},
268
+ ...urlQuery.map(({ i, v }) => ({ [i]: v })), // TODO: the 'o' should be kept. This would be a major refactoring of the facets
269
+
270
+ // support for simple filters like ?Subject=something
271
+ // TODO: since the move to hash params this is no longer working.
272
+ // We'd have to treat the location.search and manage it just like the
273
+ // hash, to support it. We can read it, but we'd have to reset it as
274
+ // well, so at that point what's the difference to the hash?
275
+ ...configuredFacets.map((f) =>
276
+ locationSearchData[f]
277
+ ? {
278
+ [f]:
279
+ multiFacets.indexOf(f) > -1
280
+ ? [locationSearchData[f]]
281
+ : locationSearchData[f],
282
+ }
283
+ : {},
284
+ ),
285
+ ),
286
+ );
287
+ }
288
+ }, [
289
+ urlQuery,
290
+ configuredFacets,
291
+ locationSearchData,
292
+ multiFacets,
293
+ previousUrlQuery,
294
+ ]);
274
295
 
275
296
  const [sortOn, setSortOn] = React.useState(data?.query?.sort_on);
276
297
  const [sortOrder, setSortOrder] = React.useState(data?.query?.sort_order);
277
298
 
278
- const [searchData, setSearchData] = React.useState(
279
- getInitialState(data, facets, urlSearchText, id),
280
- );
299
+ const [searchData, setSearchData] = React.useState({});
300
+
301
+ React.useEffect(() => {
302
+ setSearchData(getInitialState(data, facets, urlSearchText, id));
303
+ }, [facets, data, urlSearchText, id]);
281
304
 
282
305
  const timeoutRef = React.useRef();
283
306
  const facetSettings = data?.facets;
@@ -297,7 +320,7 @@ const withSearch = (options) => (WrappedComponent) => {
297
320
  id,
298
321
  query: data.query || {},
299
322
  facets: toSearchFacets || facets,
300
- searchText: toSearchText || searchText,
323
+ searchText: toSearchText ? toSearchText.trim() : '',
301
324
  sortOn: toSortOn || sortOn,
302
325
  sortOrder: toSortOrder || sortOrder,
303
326
  facetSettings,
@@ -325,6 +348,16 @@ const withSearch = (options) => (WrappedComponent) => {
325
348
  ],
326
349
  );
327
350
 
351
+ const removeSearchQuery = () => {
352
+ searchData.query = searchData.query.reduce(
353
+ // Remove SearchableText from query
354
+ (acc, kvp) => (kvp.i === 'SearchableText' ? acc : [...acc, kvp]),
355
+ [],
356
+ );
357
+ setSearchData(searchData);
358
+ setLocationSearchData(getSearchFields(searchData));
359
+ };
360
+
328
361
  const querystringResults = useSelector(
329
362
  (state) => state.querystringsearch.subrequests,
330
363
  );
@@ -343,6 +376,7 @@ const withSearch = (options) => (WrappedComponent) => {
343
376
  sortOrder={sortOrder}
344
377
  searchedText={urlSearchText}
345
378
  searchText={searchText}
379
+ removeSearchQuery={removeSearchQuery}
346
380
  setSearchText={setSearchText}
347
381
  onTriggerSearch={onTriggerSearch}
348
382
  totalItems={totalItems}
@@ -11,6 +11,7 @@ import { Grid, Segment } from 'semantic-ui-react';
11
11
  import { Button } from 'semantic-ui-react';
12
12
  import { flushSync } from 'react-dom';
13
13
  import { defineMessages, useIntl } from 'react-intl';
14
+ import cx from 'classnames';
14
15
 
15
16
  const messages = defineMessages({
16
17
  searchButtonText: {
@@ -19,11 +20,22 @@ const messages = defineMessages({
19
20
  },
20
21
  });
21
22
 
22
- const FacetWrapper = ({ children }) => (
23
- <Segment basic className="facet">
24
- {children}
25
- </Segment>
26
- );
23
+ const FacetWrapper = ({ children, facetSettings = {}, visible }) => {
24
+ const { advanced, field = {} } = facetSettings;
25
+
26
+ return (
27
+ <Segment
28
+ basic
29
+ className={cx('facet', {
30
+ [`facet-index-${field.value}`]: !!field.value,
31
+ 'advanced-facet': advanced,
32
+ 'advanced-facet-hidden': !visible,
33
+ })}
34
+ >
35
+ {children}
36
+ </Segment>
37
+ );
38
+ };
27
39
 
28
40
  const LeftColumnFacets = (props) => {
29
41
  const {
@@ -11,6 +11,7 @@ import { Grid, Segment } from 'semantic-ui-react';
11
11
  import { Button } from 'semantic-ui-react';
12
12
  import { flushSync } from 'react-dom';
13
13
  import { defineMessages, useIntl } from 'react-intl';
14
+ import cx from 'classnames';
14
15
 
15
16
  const messages = defineMessages({
16
17
  searchButtonText: {
@@ -19,11 +20,22 @@ const messages = defineMessages({
19
20
  },
20
21
  });
21
22
 
22
- const FacetWrapper = ({ children }) => (
23
- <Segment basic className="facet">
24
- {children}
25
- </Segment>
26
- );
23
+ const FacetWrapper = ({ children, facetSettings = {}, visible }) => {
24
+ const { advanced, field = {} } = facetSettings;
25
+
26
+ return (
27
+ <Segment
28
+ basic
29
+ className={cx('facet', {
30
+ [`facet-index-${field.value}`]: !!field.value,
31
+ 'advanced-facet': advanced,
32
+ 'advanced-facet-hidden': !visible,
33
+ })}
34
+ >
35
+ {children}
36
+ </Segment>
37
+ );
38
+ };
27
39
 
28
40
  const RightColumnFacets = (props) => {
29
41
  const {
@@ -11,6 +11,7 @@ import {
11
11
  SortOn,
12
12
  ViewSwitcher,
13
13
  } from '../components';
14
+ import cx from 'classnames';
14
15
 
15
16
  const messages = defineMessages({
16
17
  searchButtonText: {
@@ -19,11 +20,24 @@ const messages = defineMessages({
19
20
  },
20
21
  });
21
22
 
22
- const FacetWrapper = ({ children }) => (
23
- <Grid.Column mobile={12} tablet={4} computer={3}>
24
- {children}
25
- </Grid.Column>
26
- );
23
+ const FacetWrapper = ({ children, facetSettings = {}, visible }) => {
24
+ const { advanced, field = {} } = facetSettings;
25
+
26
+ return (
27
+ <Grid.Column
28
+ mobile={12}
29
+ tablet={4}
30
+ computer={3}
31
+ className={cx('facet', {
32
+ [`facet-index-${field.value}`]: !!field.value,
33
+ 'advanced-facet': advanced,
34
+ 'advanced-facet-hidden': !visible,
35
+ })}
36
+ >
37
+ {children}
38
+ </Grid.Column>
39
+ );
40
+ };
27
41
 
28
42
  const TopSideFacets = (props) => {
29
43
  const {
@@ -117,6 +131,7 @@ const TopSideFacets = (props) => {
117
131
  <ViewSwitcher {...props} />
118
132
  )}
119
133
  </div>
134
+
120
135
  {data.facets?.length > 0 && (
121
136
  <div className="facets">
122
137
  {data.facetsTitle && <h3>{data.facetsTitle}</h3>}
@@ -136,6 +151,7 @@ const TopSideFacets = (props) => {
136
151
  </Grid>
137
152
  </div>
138
153
  )}
154
+
139
155
  <SearchDetails
140
156
  text={searchedText}
141
157
  total={totalItems}
@@ -37,8 +37,7 @@ const messages = defineMessages({
37
37
  defaultMessage: 'Show search button?',
38
38
  },
39
39
  showSearchButtonDescription: {
40
- id:
41
- 'The button presence disables the live search, the query is issued when you press ENTER',
40
+ id: 'The button presence disables the live search, the query is issued when you press ENTER',
42
41
  defaultMessage:
43
42
  'The button presence disables the live search, the query is issued when you press ENTER',
44
43
  },
@@ -83,11 +82,19 @@ const messages = defineMessages({
83
82
  defaultMessage: 'Hide facet?',
84
83
  },
85
84
  hideFacetDescription: {
86
- id:
87
- 'Hidden facets will still filter the results if proper parameters are passed in URLs',
85
+ id: 'Hidden facets will still filter the results if proper parameters are passed in URLs',
88
86
  defaultMessage:
89
87
  'Hidden facets will still filter the results if proper parameters are passed in URLs',
90
88
  },
89
+ advancedFacetTitle: {
90
+ id: 'Advanced facet?',
91
+ defaultMessage: 'Advanced facet?',
92
+ },
93
+ advancedFacetDescription: {
94
+ id: 'Advanced facets are initially hidden and displayed on demand',
95
+ defaultMessage:
96
+ 'Advanced facets are initially hidden and displayed on demand',
97
+ },
91
98
  facetWidget: {
92
99
  id: 'Facet widget',
93
100
  defaultMessage: 'Facet widget',
@@ -131,7 +138,7 @@ const FacetSchema = ({ intl }) => ({
131
138
  {
132
139
  id: 'default',
133
140
  title: 'Default',
134
- fields: ['title', 'field', 'type', 'hidden'],
141
+ fields: ['title', 'field', 'type', 'hidden', 'advanced'],
135
142
  },
136
143
  ],
137
144
  properties: {
@@ -170,17 +177,25 @@ const FacetSchema = ({ intl }) => ({
170
177
  default: false,
171
178
  description: intl.formatMessage(messages.hideFacetDescription),
172
179
  },
180
+ advanced: {
181
+ type: 'boolean',
182
+ title: intl.formatMessage(messages.advancedFacetTitle),
183
+ default: false,
184
+ description: intl.formatMessage(messages.advancedFacetDescription),
185
+ },
173
186
  type: {
174
187
  title: intl.formatMessage(messages.facetWidget),
175
- choices: config.blocks.blocksConfig.search.extensions.facetWidgets.types.map(
176
- ({ id, title }) => [
177
- id,
178
- `${intl.formatMessage({ id: id, defaultMessage: title })}`,
179
- ],
180
- ),
181
- defaultValue: config.blocks.blocksConfig.search.extensions.facetWidgets.types.find(
182
- ({ isDefault }) => isDefault,
183
- ).id,
188
+ choices:
189
+ config.blocks.blocksConfig.search.extensions.facetWidgets.types.map(
190
+ ({ id, title }) => [
191
+ id,
192
+ `${intl.formatMessage({ id: id, defaultMessage: title })}`,
193
+ ],
194
+ ),
195
+ defaultValue:
196
+ config.blocks.blocksConfig.search.extensions.facetWidgets.types.find(
197
+ ({ isDefault }) => isDefault,
198
+ ).id,
184
199
  },
185
200
  },
186
201
  required: ['field'],
@@ -157,9 +157,8 @@ class CellComponent extends Component {
157
157
  const selectionState = this.state.editorState.getSelection();
158
158
  const anchorKey = selectionState.getAnchorKey();
159
159
  const currentContent = this.state.editorState.getCurrentContent();
160
- const currentContentBlock = currentContent.getBlockForKey(
161
- anchorKey,
162
- );
160
+ const currentContentBlock =
161
+ currentContent.getBlockForKey(anchorKey);
163
162
  const blockType = currentContentBlock.getType();
164
163
  if (!includes(this.draftConfig.listBlockTypes, blockType)) {
165
164
  this.props.onSelectBlock(
@@ -24,7 +24,6 @@ const TeaserBody = (props) => {
24
24
  TeaserBody.propTypes = {
25
25
  data: PropTypes.objectOf(PropTypes.any).isRequired,
26
26
  isEditMode: PropTypes.bool,
27
- variation: PropTypes.string,
28
27
  };
29
28
 
30
29
  export default TeaserBody;
@@ -3,8 +3,7 @@ import PropTypes from 'prop-types';
3
3
  import { Message } from 'semantic-ui-react';
4
4
  import { defineMessages, useIntl } from 'react-intl';
5
5
  import imageBlockSVG from '@plone/volto/components/manage/Blocks/Image/block-image.svg';
6
- import { flattenToAppURL, isInternalURL } from '@plone/volto/helpers';
7
- import { getTeaserImageURL } from './utils';
6
+ import { isInternalURL } from '@plone/volto/helpers';
8
7
  import { MaybeWrap } from '@plone/volto/components';
9
8
  import { UniversalLink } from '@plone/volto/components';
10
9
  import cx from 'classnames';
@@ -18,20 +17,14 @@ const messages = defineMessages({
18
17
  },
19
18
  });
20
19
 
21
- const DefaultImage = (props) => <img {...props} alt={props.alt || ''} />;
22
-
23
20
  const TeaserDefaultTemplate = (props) => {
24
21
  const { className, data, isEditMode } = props;
25
22
  const intl = useIntl();
26
23
  const href = data.href?.[0];
27
24
  const image = data.preview_image?.[0];
28
- const align = data?.styles?.align;
29
25
 
30
- const hasImageComponent = config.getComponent('Image').component;
31
- const Image = config.getComponent('Image').component || DefaultImage;
26
+ const Image = config.getComponent('Image').component;
32
27
  const { openExternalLinkInNewTab } = config.settings;
33
- const defaultImageSrc =
34
- href && flattenToAppURL(getTeaserImageURL({ href, image, align }));
35
28
 
36
29
  return (
37
30
  <div className={cx('block teaser', className)}>
@@ -60,9 +53,11 @@ const TeaserDefaultTemplate = (props) => {
60
53
  {(href.hasPreviewImage || href.image_field || image) && (
61
54
  <div className="image-wrapper">
62
55
  <Image
63
- src={hasImageComponent ? href : defaultImageSrc}
56
+ item={image || href}
57
+ imageField={image ? image.image_field : href.image_field}
64
58
  alt=""
65
59
  loading="lazy"
60
+ responsive={true}
66
61
  />
67
62
  </div>
68
63
  )}
@@ -101,3 +101,8 @@ export const TeaserSchema = ({ intl }) => {
101
101
 
102
102
  return schema;
103
103
  };
104
+
105
+ export const gridTeaserDisableStylingSchema = ({ schema, formData, intl }) => {
106
+ schema.fieldsets = schema.fieldsets.filter((item) => item.id !== 'styling');
107
+ return schema;
108
+ };
@@ -275,9 +275,8 @@ export class EditComponent extends Component {
275
275
  const selectionState = this.state.editorState.getSelection();
276
276
  const anchorKey = selectionState.getAnchorKey();
277
277
  const currentContent = this.state.editorState.getCurrentContent();
278
- const currentContentBlock = currentContent.getBlockForKey(
279
- anchorKey,
280
- );
278
+ const currentContentBlock =
279
+ currentContent.getBlockForKey(anchorKey);
281
280
  const blockType = currentContentBlock.getType();
282
281
  if (!includes(this.draftConfig.listBlockTypes, blockType)) {
283
282
  this.props.onSelectBlock(
@@ -1,16 +1,3 @@
1
- /**
2
- * View title/description block.
3
- * @module volto-slate/blocks/Title/TitleBlockView
4
- */
5
-
6
- import React from 'react';
7
- import PropTypes from 'prop-types';
8
-
9
- /**
10
- * View title block component.
11
- * @class View
12
- * @extends Component
13
- */
14
1
  const TitleBlockView = ({ properties, metadata }) => {
15
2
  return (
16
3
  <h1 className="documentFirstHeading">
@@ -19,14 +6,4 @@ const TitleBlockView = ({ properties, metadata }) => {
19
6
  );
20
7
  };
21
8
 
22
- /**
23
- * Property types.
24
- * @property {Object} propTypes Property types.
25
- * @static
26
- */
27
- TitleBlockView.propTypes = {
28
- properties: PropTypes.objectOf(PropTypes.any).isRequired,
29
- metadata: PropTypes.objectOf(PropTypes.any),
30
- };
31
-
32
9
  export default TitleBlockView;
@@ -1,10 +1,25 @@
1
1
  import React from 'react';
2
2
  import renderer from 'react-test-renderer';
3
+ import configureStore from 'redux-mock-store';
4
+ import { Provider } from 'react-intl-redux';
5
+ import { MemoryRouter } from 'react-router-dom';
3
6
  import View from './View';
4
7
 
8
+ const mockStore = configureStore();
9
+
5
10
  test('renders a view title component', () => {
11
+ const store = mockStore({
12
+ intl: {
13
+ locale: 'en',
14
+ messages: {},
15
+ },
16
+ });
6
17
  const component = renderer.create(
7
- <View properties={{ title: 'My Title' }} />,
18
+ <Provider store={store}>
19
+ <MemoryRouter>
20
+ <View properties={{ title: 'My Title' }} id="a123" />
21
+ </MemoryRouter>
22
+ </Provider>,
8
23
  );
9
24
  const json = component.toJSON();
10
25
  expect(json).toMatchSnapshot();
@@ -1,8 +1,37 @@
1
- const TableOfContentsSchema = ({ data }) => {
1
+ import { defineMessages } from 'react-intl';
2
+
3
+ const messages = defineMessages({
4
+ toc: {
5
+ id: 'toc',
6
+ defaultMessage: 'Table of Contents',
7
+ },
8
+ Title: {
9
+ id: 'Title',
10
+ defaultMessage: 'Title',
11
+ },
12
+ HideTitle: {
13
+ id: 'Hide title',
14
+ defaultMessage: 'Hide title',
15
+ },
16
+ Entries: {
17
+ id: 'Entries',
18
+ defaultMessage: 'Entries',
19
+ },
20
+ Ordered: {
21
+ id: 'Ordered',
22
+ defaultMessage: 'Ordered',
23
+ },
24
+ Sticky: {
25
+ id: 'Sticky',
26
+ defaultMessage: 'Sticky',
27
+ },
28
+ });
29
+
30
+ const TableOfContentsSchema = ({ data, intl }) => {
2
31
  const { variation = 'default' } = data;
3
32
 
4
33
  return {
5
- title: 'Table of Contents',
34
+ title: intl.formatMessage(messages.toc),
6
35
  fieldsets: [
7
36
  {
8
37
  id: 'default',
@@ -10,21 +39,21 @@ const TableOfContentsSchema = ({ data }) => {
10
39
  fields: [
11
40
  'title',
12
41
  'hide_title',
13
- ...(variation === 'default' ? ['ordered'] : []),
42
+ ...(variation === 'default' ? ['ordered'] : ['sticky']),
14
43
  'levels',
15
44
  ],
16
45
  },
17
46
  ],
18
47
  properties: {
19
48
  title: {
20
- title: 'Block title',
49
+ title: intl.formatMessage(messages.Title),
21
50
  },
22
51
  hide_title: {
23
- title: 'Hide title',
52
+ title: intl.formatMessage(messages.HideTitle),
24
53
  type: 'boolean',
25
54
  },
26
55
  levels: {
27
- title: 'Entries',
56
+ title: intl.formatMessage(messages.Entries),
28
57
  isMulti: true,
29
58
  choices: [
30
59
  ['h1', 'h1'],
@@ -36,7 +65,11 @@ const TableOfContentsSchema = ({ data }) => {
36
65
  ],
37
66
  },
38
67
  ordered: {
39
- title: 'Ordered',
68
+ title: intl.formatMessage(messages.Ordered),
69
+ type: 'boolean',
70
+ },
71
+ sticky: {
72
+ title: intl.formatMessage(messages.Sticky),
40
73
  type: 'boolean',
41
74
  },
42
75
  },