@plone/volto 17.0.0-alpha.2 → 17.0.0-alpha.21

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 (318) hide show
  1. package/.yarn/install-state.gz +0 -0
  2. package/CHANGELOG.md +549 -15
  3. package/CONTRIBUTING.md +1 -1
  4. package/README.md +11 -14
  5. package/addon-registry.js +34 -0
  6. package/create-theme-addons-loader.js +79 -0
  7. package/cypress/support/commands.js +58 -5
  8. package/cypress/support/e2e.js +1 -2
  9. package/cypress/support/volto-slate.js +4 -5
  10. package/docker-compose.yml +1 -1
  11. package/locales/ca/LC_MESSAGES/volto.po +282 -7
  12. package/locales/ca.json +1 -1
  13. package/locales/de/LC_MESSAGES/volto.po +301 -26
  14. package/locales/de.json +1 -1
  15. package/locales/en/LC_MESSAGES/volto.po +281 -6
  16. package/locales/en.json +1 -1
  17. package/locales/es/LC_MESSAGES/volto.po +291 -16
  18. package/locales/es.json +1 -1
  19. package/locales/eu/LC_MESSAGES/volto.po +282 -7
  20. package/locales/eu.json +1 -1
  21. package/locales/fi/LC_MESSAGES/volto.po +4891 -0
  22. package/locales/fi.json +1 -1
  23. package/locales/fr/LC_MESSAGES/volto.po +282 -7
  24. package/locales/fr.json +1 -1
  25. package/locales/it/LC_MESSAGES/volto.po +284 -9
  26. package/locales/it.json +1 -1
  27. package/locales/ja/LC_MESSAGES/volto.po +282 -7
  28. package/locales/ja.json +1 -1
  29. package/locales/nl/LC_MESSAGES/volto.po +937 -650
  30. package/locales/nl.json +1 -1
  31. package/locales/pt/LC_MESSAGES/volto.po +282 -7
  32. package/locales/pt.json +1 -1
  33. package/locales/pt_BR/LC_MESSAGES/volto.po +291 -16
  34. package/locales/pt_BR.json +1 -1
  35. package/locales/ro/LC_MESSAGES/volto.po +282 -7
  36. package/locales/ro.json +1 -1
  37. package/locales/volto.pot +282 -7
  38. package/locales/zh_CN/LC_MESSAGES/volto.po +282 -7
  39. package/locales/zh_CN.json +1 -1
  40. package/package.json +8 -6
  41. package/packages/volto-slate/build/messages/src/blocks/Table/TableBlockEdit.json +1 -1
  42. package/packages/volto-slate/build/messages/src/blocks/Text/DefaultTextBlockEditor.json +1 -1
  43. package/packages/volto-slate/build/messages/src/blocks/Text/DetachedTextBlockEditor.json +1 -1
  44. package/packages/volto-slate/build/messages/src/blocks/Text/SlashMenu.json +1 -1
  45. package/packages/volto-slate/build/messages/src/editor/plugins/AdvancedLink/index.json +1 -1
  46. package/packages/volto-slate/build/messages/src/editor/plugins/Link/index.json +1 -1
  47. package/packages/volto-slate/build/messages/src/editor/plugins/Table/index.json +1 -1
  48. package/packages/volto-slate/build/messages/src/elementEditor/messages.json +1 -1
  49. package/packages/volto-slate/build/messages/src/widgets/HtmlSlateWidget.json +1 -1
  50. package/packages/volto-slate/build/messages/src/widgets/RichTextWidgetView.json +1 -1
  51. package/packages/volto-slate/package.json +1 -1
  52. package/packages/volto-slate/src/actions/index.js +1 -1
  53. package/packages/volto-slate/src/blocks/Table/TableBlockEdit.jsx +21 -212
  54. package/packages/volto-slate/src/blocks/Table/schema.js +122 -0
  55. package/packages/volto-slate/src/blocks/Text/DefaultTextBlockEditor.jsx +8 -3
  56. package/packages/volto-slate/src/blocks/Text/SlashMenu.jsx +4 -3
  57. package/packages/volto-slate/src/blocks/Text/TextBlockView.jsx +20 -16
  58. package/packages/volto-slate/src/blocks/Text/extensions/withDeserializers.js +3 -1
  59. package/packages/volto-slate/src/blocks/Text/index.js +10 -2
  60. package/packages/volto-slate/src/editor/config.jsx +5 -4
  61. package/packages/volto-slate/src/editor/deserialize.js +0 -1
  62. package/packages/volto-slate/src/editor/index.js +4 -4
  63. package/packages/volto-slate/src/editor/less/slate.less +28 -0
  64. package/packages/volto-slate/src/editor/plugins/StyleMenu/StyleMenu.jsx +14 -4
  65. package/packages/volto-slate/src/editor/plugins/StyleMenu/utils.js +14 -5
  66. package/packages/volto-slate/src/editor/render.jsx +68 -8
  67. package/packages/volto-slate/src/editor/ui/SlateContextToolbar.jsx +2 -2
  68. package/packages/volto-slate/src/editor/ui/index.js +15 -15
  69. package/packages/volto-slate/src/index.js +2 -2
  70. package/packages/volto-slate/src/utils/blocks.js +7 -0
  71. package/packages/volto-slate/src/widgets/RichTextWidget.jsx +15 -8
  72. package/razzle.config.js +28 -0
  73. package/src/actions/index.js +6 -0
  74. package/src/actions/language/language.js +9 -8
  75. package/src/actions/querystringsearch/querystringsearch.js +20 -14
  76. package/src/actions/relations/rebuild.js +25 -0
  77. package/src/actions/relations/relations.js +86 -0
  78. package/src/actions/relations/relations.test.js +15 -0
  79. package/src/components/index.js +3 -0
  80. package/src/components/manage/Add/Add.jsx +2 -2
  81. package/src/components/manage/AnchorPlugin/index.jsx +2 -2
  82. package/src/components/manage/AnchorPlugin/utils/EditorUtils.js +3 -1
  83. package/src/components/manage/BlockChooser/BlockChooser.jsx +14 -5
  84. package/src/components/manage/BlockChooser/BlockChooser.test.jsx +5 -0
  85. package/src/components/manage/Blocks/Block/BlocksForm.jsx +19 -2
  86. package/src/components/manage/Blocks/Block/Edit.jsx +1 -1
  87. package/src/components/manage/Blocks/Block/Style.jsx +2 -2
  88. package/src/components/manage/Blocks/Container/Data.jsx +32 -0
  89. package/src/components/manage/Blocks/Container/Edit.jsx +174 -0
  90. package/src/components/manage/Blocks/Container/EditBlockWrapper.jsx +120 -0
  91. package/src/components/manage/Blocks/Container/NewBlockAddButton.jsx +84 -0
  92. package/src/components/manage/Blocks/Container/SimpleContainerToolbar.jsx +54 -0
  93. package/src/components/manage/Blocks/Grid/Edit.jsx +33 -0
  94. package/src/components/manage/Blocks/Grid/View.jsx +43 -0
  95. package/src/components/manage/Blocks/Grid/adapter.js +14 -0
  96. package/src/components/manage/Blocks/Grid/grid-1.svg +6 -0
  97. package/src/components/manage/Blocks/Grid/grid-2.svg +9 -0
  98. package/src/components/manage/Blocks/Grid/grid-3.svg +10 -0
  99. package/src/components/manage/Blocks/Grid/grid-4.svg +11 -0
  100. package/src/components/manage/Blocks/Grid/schema.js +35 -0
  101. package/src/components/manage/Blocks/Grid/templates.js +47 -0
  102. package/src/components/manage/Blocks/HeroImageLeft/Edit.jsx +6 -1
  103. package/src/components/manage/Blocks/Image/Edit.jsx +51 -12
  104. package/src/components/manage/Blocks/Image/Edit.test.jsx +2 -0
  105. package/src/components/manage/Blocks/Image/ImageSidebar.jsx +66 -16
  106. package/src/components/manage/Blocks/Image/View.jsx +25 -5
  107. package/src/components/manage/Blocks/Image/View.test.jsx +20 -0
  108. package/src/components/manage/Blocks/Image/schema.js +12 -9
  109. package/src/components/manage/Blocks/Image/utils.js +14 -0
  110. package/src/components/manage/Blocks/LeadImage/Edit.jsx +32 -10
  111. package/src/components/manage/Blocks/LeadImage/Edit.test.jsx +11 -1
  112. package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.jsx +28 -9
  113. package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.test.jsx +8 -2
  114. package/src/components/manage/Blocks/LeadImage/View.jsx +50 -38
  115. package/src/components/manage/Blocks/LeadImage/View.test.jsx +11 -1
  116. package/src/components/manage/Blocks/Listing/DefaultTemplate.jsx +18 -3
  117. package/src/components/manage/Blocks/Listing/Edit.jsx +0 -14
  118. package/src/components/manage/Blocks/Listing/ListingBody.jsx +30 -8
  119. package/src/components/manage/Blocks/Listing/ListingBody.test.jsx +20 -0
  120. package/src/components/manage/Blocks/Listing/SummaryTemplate.jsx +1 -1
  121. package/src/components/manage/Blocks/Listing/getAsyncData.js +9 -3
  122. package/src/components/manage/Blocks/Listing/withQuerystringResults.jsx +26 -18
  123. package/src/components/manage/Blocks/Search/SearchBlockEdit.jsx +5 -4
  124. package/src/components/manage/Blocks/Search/SearchBlockView.jsx +2 -1
  125. package/src/components/manage/Blocks/Search/components/DateRangeFacet.jsx +4 -1
  126. package/src/components/manage/Blocks/Search/components/Facets.jsx +64 -4
  127. package/src/components/manage/Blocks/Search/components/SearchInput.jsx +9 -2
  128. package/src/components/manage/Blocks/Search/components/index.js +13 -13
  129. package/src/components/manage/Blocks/Search/hocs/index.js +2 -2
  130. package/src/components/manage/Blocks/Search/hocs/withQueryString.jsx +2 -2
  131. package/src/components/manage/Blocks/Search/hocs/withSearch.jsx +43 -15
  132. package/src/components/manage/Blocks/Search/layout/LeftColumnFacets.jsx +17 -5
  133. package/src/components/manage/Blocks/Search/layout/RightColumnFacets.jsx +17 -5
  134. package/src/components/manage/Blocks/Search/layout/TopSideFacets.jsx +21 -5
  135. package/src/components/manage/Blocks/Search/schema.js +16 -1
  136. package/src/components/manage/Blocks/Teaser/Body.jsx +0 -1
  137. package/src/components/manage/Blocks/Teaser/DefaultBody.jsx +5 -10
  138. package/src/components/manage/Blocks/Teaser/schema.js +5 -0
  139. package/src/components/manage/Blocks/Title/View.jsx +15 -5
  140. package/src/components/manage/Blocks/Title/View.test.jsx +16 -1
  141. package/src/components/manage/Blocks/ToC/Schema.jsx +5 -1
  142. package/src/components/manage/Blocks/ToC/View.jsx +8 -1
  143. package/src/components/manage/Blocks/ToC/variations/DefaultTocRenderer.jsx +17 -4
  144. package/src/components/manage/Blocks/ToC/variations/HorizontalMenu.jsx +148 -10
  145. package/src/components/manage/Blocks/ToC/variations/index.js +3 -1
  146. package/src/components/manage/Contents/Contents.jsx +47 -32
  147. package/src/components/manage/Contents/ContentsItem.jsx +6 -0
  148. package/src/components/manage/Contents/ContentsUploadModal.jsx +10 -5
  149. package/src/components/manage/Controlpanels/AddonsControlpanel.jsx +3 -3
  150. package/src/components/manage/Controlpanels/Controlpanels.jsx +199 -224
  151. package/src/components/manage/Controlpanels/Controlpanels.test.jsx +46 -7
  152. package/src/components/manage/Controlpanels/Relations/BrokenRelations.jsx +66 -0
  153. package/src/components/manage/Controlpanels/Relations/Relations.jsx +114 -0
  154. package/src/components/manage/Controlpanels/Relations/RelationsListing.jsx +479 -0
  155. package/src/components/manage/Controlpanels/Relations/RelationsMatrix.jsx +531 -0
  156. package/src/components/manage/Controlpanels/Users/UserGroupMembershipControlPanel.jsx +3 -3
  157. package/src/components/manage/Controlpanels/Users/UserGroupMembershipListing.jsx +51 -82
  158. package/src/components/manage/Controlpanels/Users/UserGroupMembershipMatrix.jsx +79 -75
  159. package/src/components/manage/DragDropList/DragDropList.jsx +18 -13
  160. package/src/components/manage/Form/Form.jsx +5 -3
  161. package/src/components/manage/Form/InlineForm.jsx +39 -9
  162. package/src/components/manage/Form/InlineFormState.js +8 -0
  163. package/src/components/manage/History/History.jsx +11 -1
  164. package/src/components/manage/LinksToItem/LinksToItem.jsx +209 -0
  165. package/src/components/manage/LinksToItem/LinksToItem.test.jsx +97 -0
  166. package/src/components/manage/Multilingual/CreateTranslation.jsx +2 -2
  167. package/src/components/manage/Multilingual/TranslationObject.jsx +4 -3
  168. package/src/components/manage/Preferences/ChangePassword.jsx +2 -2
  169. package/src/components/manage/Preferences/PersonalPreferences.jsx +2 -2
  170. package/src/components/manage/Sharing/Sharing.jsx +5 -1
  171. package/src/components/manage/Sidebar/AlignBlock.jsx +1 -1
  172. package/src/components/manage/TemplateChooser/TemplateChooser.jsx +38 -0
  173. package/src/components/manage/TemplateChooser/TemplateChooser.test.jsx +34 -0
  174. package/src/components/manage/TemplateChooser/template.svg +10 -0
  175. package/src/components/manage/Toast/Toast.jsx +2 -2
  176. package/src/components/manage/Toolbar/More.jsx +15 -0
  177. package/src/components/manage/Toolbar/Types.jsx +2 -2
  178. package/src/components/manage/UniversalLink/UniversalLink.jsx +2 -6
  179. package/src/components/manage/UniversalLink/UniversalLink.test.jsx +36 -0
  180. package/src/components/manage/Widgets/ColorPickerWidget.jsx +6 -1
  181. package/src/components/manage/Widgets/DatetimeWidget.jsx +9 -5
  182. package/src/components/manage/Widgets/FileWidget.jsx +2 -1
  183. package/src/components/manage/Widgets/ObjectListWidget.jsx +3 -8
  184. package/src/components/manage/Widgets/RecurrenceWidget/ByDayField.jsx +2 -1
  185. package/src/components/manage/Widgets/RecurrenceWidget/MonthOfTheYearField.jsx +2 -1
  186. package/src/components/manage/Widgets/RecurrenceWidget/Occurences.jsx +2 -1
  187. package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.jsx +8 -3
  188. package/src/components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthField.jsx +2 -1
  189. package/src/components/manage/Widgets/SelectUtils.js +1 -1
  190. package/src/components/manage/Widgets/SelectWidget.jsx +1 -1
  191. package/src/components/theme/Anontools/Anontools.jsx +44 -72
  192. package/src/components/theme/Anontools/Anontools.stories.jsx +16 -6
  193. package/src/components/theme/Anontools/Anontools.test.jsx +16 -2
  194. package/src/components/theme/Breadcrumbs/Breadcrumbs.jsx +52 -99
  195. package/src/components/theme/Breadcrumbs/Breadcrumbs.stories.jsx +14 -13
  196. package/src/components/theme/Comments/CommentEditModal.jsx +63 -115
  197. package/src/components/theme/Component/Component.jsx +1 -1
  198. package/src/components/theme/ContactForm/ContactForm.jsx +108 -192
  199. package/src/components/theme/ContactForm/ContactForm.stories.jsx +1 -1
  200. package/src/components/theme/ContactForm/ContactForm.test.jsx +2 -3
  201. package/src/components/theme/Footer/Footer.jsx +2 -13
  202. package/src/components/theme/Header/Header.jsx +37 -63
  203. package/src/components/theme/Header/Header.test.jsx +18 -0
  204. package/src/components/theme/Icon/Icon.jsx +2 -2
  205. package/src/components/theme/Image/Image.jsx +96 -0
  206. package/src/components/theme/Image/Image.test.jsx +125 -0
  207. package/src/components/theme/LanguageSelector/LanguageSelector.js +8 -3
  208. package/src/components/theme/Login/Login.jsx +1 -0
  209. package/src/components/theme/Logo/Logo.jsx +4 -1
  210. package/src/components/theme/MultilingualRedirector/MultilingualRedirector.jsx +2 -2
  211. package/src/components/theme/Navigation/NavItem.jsx +4 -2
  212. package/src/components/theme/NotFound/NotFound.jsx +55 -41
  213. package/src/components/theme/PasswordReset/PasswordReset.jsx +7 -4
  214. package/src/components/theme/PasswordReset/RequestPasswordReset.jsx +1 -1
  215. package/src/components/theme/PreviewImage/PreviewImage.jsx +25 -14
  216. package/src/components/theme/PreviewImage/PreviewImage.test.js +39 -16
  217. package/src/components/theme/SearchWidget/SearchWidget.jsx +38 -98
  218. package/src/components/theme/Sitemap/Sitemap.jsx +5 -3
  219. package/src/components/theme/View/AlbumView.jsx +20 -16
  220. package/src/components/theme/View/DefaultView.jsx +1 -1
  221. package/src/components/theme/View/EventDatesInfo.jsx +2 -1
  222. package/src/components/theme/View/EventView.jsx +36 -25
  223. package/src/components/theme/View/FileView.jsx +23 -18
  224. package/src/components/theme/View/ImageView.jsx +40 -32
  225. package/src/components/theme/View/ImageView.test.jsx +4 -0
  226. package/src/components/theme/View/LinkView.jsx +53 -78
  227. package/src/components/theme/View/ListingView.jsx +36 -28
  228. package/src/components/theme/View/NewsItemView.jsx +16 -17
  229. package/src/components/theme/View/RenderBlocks.jsx +56 -21
  230. package/src/components/theme/View/RenderEmptyBlock.jsx +5 -0
  231. package/src/components/theme/View/SummaryView.jsx +49 -39
  232. package/src/components/theme/View/TabularView.jsx +59 -53
  233. package/src/components/theme/Widgets/DateWidget.jsx +2 -1
  234. package/src/components/theme/Widgets/DatetimeWidget.jsx +2 -1
  235. package/src/components/theme/Widgets/RelationsWidget.jsx +13 -11
  236. package/src/config/Blocks.jsx +46 -0
  237. package/src/config/Components.jsx +2 -1
  238. package/src/config/ControlPanels.js +2 -0
  239. package/src/config/NonContentRoutes.jsx +1 -0
  240. package/src/config/RichTextEditor/Blocks.jsx +2 -2
  241. package/src/config/RichTextEditor/FromHTML.jsx +2 -2
  242. package/src/config/RichTextEditor/Styles.jsx +1 -1
  243. package/src/config/Widgets.jsx +2 -0
  244. package/src/config/index.js +24 -0
  245. package/src/config/server.js +2 -0
  246. package/src/constants/ActionTypes.js +4 -0
  247. package/src/constants/Indexes.js +3 -1
  248. package/src/constants/Languages.js +8 -4
  249. package/src/express-middleware/devproxy.js +1 -1
  250. package/src/express-middleware/files.js +3 -3
  251. package/src/express-middleware/images.js +4 -4
  252. package/src/express-middleware/ok.js +16 -0
  253. package/src/express-middleware/robotstxt.js +1 -1
  254. package/src/express-middleware/sitemap.js +37 -5
  255. package/src/express-middleware/static.js +3 -3
  256. package/src/helpers/Api/Api.js +1 -1
  257. package/src/helpers/Blocks/Blocks.js +48 -0
  258. package/src/helpers/Blocks/Blocks.test.js +79 -0
  259. package/src/helpers/Extensions/index.js +2 -1
  260. package/src/helpers/Extensions/withBlockSchemaEnhancer.js +15 -11
  261. package/src/helpers/Extensions/withBlockSchemaEnhancer.test.js +145 -0
  262. package/src/helpers/FormValidation/FormValidation.js +40 -2
  263. package/src/helpers/FormValidation/FormValidation.test.js +73 -0
  264. package/src/helpers/Html/Html.jsx +3 -1
  265. package/src/helpers/Html/Html.test.jsx +5 -0
  266. package/src/helpers/MessageLabels/MessageLabels.js +80 -0
  267. package/src/helpers/Robots/Robots.js +24 -6
  268. package/src/helpers/ScrollToTop/ScrollToTop.jsx +5 -3
  269. package/src/helpers/Sitemap/Sitemap.js +44 -2
  270. package/src/helpers/Url/Url.js +49 -7
  271. package/src/helpers/Url/Url.test.js +67 -0
  272. package/src/helpers/Utils/UseDetectClickOutside.stories.jsx +191 -0
  273. package/src/helpers/Utils/Utils.js +63 -13
  274. package/src/helpers/Utils/Utils.test.js +4 -4
  275. package/src/helpers/Utils/usePagination.js +67 -14
  276. package/src/helpers/Utils/usePagination.test.js +115 -0
  277. package/src/helpers/index.js +20 -10
  278. package/src/hooks/client/useClient.js +11 -0
  279. package/src/hooks/clipboard/useClipboard.js +26 -0
  280. package/src/hooks/index.js +2 -0
  281. package/src/icons/grid-block.svg +11 -0
  282. package/src/middleware/Api.test.js +54 -0
  283. package/src/middleware/api.js +24 -6
  284. package/src/middleware/index.js +2 -2
  285. package/src/reducers/actions/actions.js +8 -6
  286. package/src/reducers/actions/actions.test.js +70 -0
  287. package/src/reducers/breadcrumbs/breadcrumbs.js +1 -1
  288. package/src/reducers/index.js +2 -0
  289. package/src/reducers/navigation/navigation.js +1 -1
  290. package/src/reducers/relations/relations.js +173 -0
  291. package/src/reducers/types/types.js +1 -1
  292. package/src/routes.js +14 -0
  293. package/src/server.jsx +28 -23
  294. package/src/start-server.js +2 -2
  295. package/test-setup-config.js +11 -1
  296. package/theme/themes/pastanaga/extras/blocks.less +5 -1
  297. package/theme/themes/pastanaga/extras/contents.less +1 -0
  298. package/theme/themes/pastanaga/extras/grid.less +426 -0
  299. package/theme/themes/pastanaga/extras/main.less +8 -1
  300. package/theme/themes/pastanaga/extras/search.less +6 -0
  301. package/theme/themes/pastanaga/extras/sidebar.less +4 -0
  302. package/theme/themes/pastanaga/extras/toc.less +29 -0
  303. package/theme/themes/pastanaga/extras/userscontrolpanel.less +99 -76
  304. package/.changelog.draft +0 -31
  305. package/.editorconfig +0 -36
  306. package/.storybook/main.js +0 -127
  307. package/.storybook/manager.js +0 -15
  308. package/.storybook/preview.js +0 -21
  309. package/.storybook/static/previewImage.svg +0 -48
  310. package/.yarnrc.yml +0 -5
  311. package/jsdoc.json +0 -16
  312. package/netlify.toml +0 -5
  313. package/pyvenv.cfg +0 -3
  314. package/share/man/man1/ttx.1 +0 -225
  315. package/src/components/manage/Blocks/Teaser/utils.js +0 -44
  316. package/src/components/manage/Blocks/Teaser/utils.test.jsx +0 -229
  317. package/src/components/theme/Header/Header.md +0 -27
  318. package/towncrier.toml +0 -33
@@ -8,15 +8,27 @@ import PropTypes from 'prop-types';
8
8
  import { map } from 'lodash';
9
9
  import { List } from 'semantic-ui-react';
10
10
  import { FormattedMessage, injectIntl } from 'react-intl';
11
+ import { useHistory } from 'react-router-dom';
11
12
  import AnchorLink from 'react-anchor-link-smooth-scroll';
13
+ import Slugger from 'github-slugger';
12
14
 
13
- const RenderListItems = ({ items, data }) => {
15
+ const RenderListItems = ({ items, data, history }) => {
14
16
  return map(items, (item) => {
15
- const { id, level, title } = item;
17
+ const { id, level, title, override_toc, plaintext } = item;
18
+ const slug = override_toc
19
+ ? Slugger.slug(plaintext)
20
+ : Slugger.slug(title) || id;
16
21
  return (
17
22
  item && (
18
23
  <List.Item key={id} className={`item headline-${level}`} as="li">
19
- <AnchorLink href={`#${id}`}>{title}</AnchorLink>
24
+ <AnchorLink
25
+ href={`#${slug}`}
26
+ onClick={(e) => {
27
+ history.push({ hash: slug });
28
+ }}
29
+ >
30
+ {title}
31
+ </AnchorLink>
20
32
  {item.items?.length > 0 && (
21
33
  <List
22
34
  ordered={data.ordered}
@@ -38,6 +50,7 @@ const RenderListItems = ({ items, data }) => {
38
50
  * @extends Component
39
51
  */
40
52
  const View = ({ data, tocEntries }) => {
53
+ const history = useHistory();
41
54
  return (
42
55
  <>
43
56
  {data.title && !data.hide_title ? (
@@ -57,7 +70,7 @@ const View = ({ data, tocEntries }) => {
57
70
  bulleted={!data.ordered}
58
71
  as={data.ordered ? 'ol' : 'ul'}
59
72
  >
60
- <RenderListItems items={tocEntries} data={data} />
73
+ <RenderListItems items={tocEntries} data={data} history={history} />
61
74
  </List>
62
75
  </>
63
76
  );
@@ -1,23 +1,22 @@
1
- /**
2
- * View toc block.
3
- * @module components/manage/Blocks/ToC/View
4
- */
5
-
6
- import React from 'react';
1
+ import React, { useEffect, useState } from 'react';
7
2
  import PropTypes from 'prop-types';
8
3
  import { map } from 'lodash';
9
- import { Menu } from 'semantic-ui-react';
4
+ import { Menu, Dropdown } from 'semantic-ui-react';
10
5
  import { FormattedMessage, injectIntl } from 'react-intl';
11
6
  import AnchorLink from 'react-anchor-link-smooth-scroll';
7
+ import Slugger from 'github-slugger';
12
8
 
13
9
  const RenderMenuItems = ({ items }) => {
14
10
  return map(items, (item) => {
15
- const { id, level, title } = item;
11
+ const { id, level, title, override_toc, plaintext } = item;
12
+ const slug = override_toc
13
+ ? Slugger.slug(plaintext)
14
+ : Slugger.slug(title) || id;
16
15
  return (
17
16
  item && (
18
17
  <React.Fragment key={id}>
19
18
  <Menu.Item className={`headline-${level}`}>
20
- <AnchorLink href={`#${id}`}>{title}</AnchorLink>
19
+ <AnchorLink href={`#${slug}`}>{title}</AnchorLink>
21
20
  </Menu.Item>
22
21
  {item.items?.length > 0 && <RenderMenuItems items={item.items} />}
23
22
  </React.Fragment>
@@ -32,6 +31,131 @@ const RenderMenuItems = ({ items }) => {
32
31
  * @extends Component
33
32
  */
34
33
  const View = ({ data, tocEntries }) => {
34
+ const [isDropdownOpen, setIsDropdownOpen] = useState(false);
35
+ // When the page is resized to prevent items from the TOC from going out of the viewport,
36
+ // a dropdown menu is added containing all the items that don't fit.
37
+ const handleResize = () => {
38
+ const menuElement = document.querySelector('.responsive-menu');
39
+ const containerWidth = menuElement.offsetWidth;
40
+
41
+ // Get all divs that contain the items from the TOC, except the dropdown button
42
+ const nested = document.querySelectorAll(
43
+ '.responsive-menu .item:not(.dropdown)',
44
+ );
45
+ const nestedArray = Object.values(nested);
46
+ const middle = Math.ceil(nestedArray.length / 2);
47
+ const firstHalfNested = nestedArray.slice(0, middle);
48
+ const secondHalfNested = nestedArray.slice(middle);
49
+
50
+ const dropdown = document.querySelector('.dropdown');
51
+ const dropdownWidth = dropdown.offsetWidth;
52
+
53
+ const firstHalfNestedHiddenItems = [];
54
+
55
+ // Add a 'hidden' class for the items that should be in the dropdown
56
+ firstHalfNested.forEach((item) => {
57
+ const itemOffsetLeft = item.offsetLeft;
58
+ const itemOffsetWidth = item.offsetWidth;
59
+ if (itemOffsetLeft + itemOffsetWidth > containerWidth - dropdownWidth) {
60
+ item.classList.add('hidden');
61
+ firstHalfNestedHiddenItems.push(item);
62
+ } else {
63
+ item.classList.remove('hidden');
64
+ }
65
+ });
66
+
67
+ secondHalfNested.forEach((item) => item.classList.add('hidden-dropdown'));
68
+
69
+ const diff = firstHalfNested.length - firstHalfNestedHiddenItems.length;
70
+ const secondHalfNestedShownItems = secondHalfNested.slice(diff);
71
+ secondHalfNestedShownItems.forEach((item) =>
72
+ item.classList.remove('hidden-dropdown'),
73
+ );
74
+
75
+ // If there are elements that should be displayed in the dropdown, show the dropdown button
76
+ if (secondHalfNestedShownItems.length > 0)
77
+ dropdown.classList.remove('hidden-dropdown');
78
+ else {
79
+ dropdown.classList.add('hidden-dropdown');
80
+ }
81
+ };
82
+
83
+ const handleDropdownKeyDown = (event) => {
84
+ const dropdownMenu = document.querySelector('.menu.transition');
85
+ if (event.key === 'ArrowDown' && isDropdownOpen) {
86
+ event.preventDefault();
87
+ const menuItems = dropdownMenu.querySelectorAll(
88
+ '.item:not(.hidden-dropdown)',
89
+ );
90
+ const focusedItem = dropdownMenu.querySelector('.item.focused');
91
+ const focusedIndex = Array.from(menuItems).indexOf(focusedItem);
92
+
93
+ if (focusedIndex === -1) {
94
+ // No item is currently focused, so focus the first item
95
+ menuItems[0].classList.add('focused');
96
+ } else if (focusedIndex === menuItems.length - 1) {
97
+ // Remove focus from the currently focused item and close the dropdown
98
+ focusedItem.classList.remove('focused');
99
+ setIsDropdownOpen(false);
100
+
101
+ // Focus the next element on the page
102
+ const nextElement = dropdownMenu.nextElementSibling;
103
+ if (nextElement) {
104
+ nextElement.focus();
105
+ }
106
+ } else {
107
+ // Remove focus from the currently focused item
108
+ focusedItem.classList.remove('focused');
109
+
110
+ // Focus the next item or wrap around to the first item
111
+ const nextIndex = (focusedIndex + 1) % menuItems.length;
112
+ menuItems[nextIndex].classList.add('focused');
113
+ }
114
+ } else if (event.key === 'Enter' && isDropdownOpen) {
115
+ const focusedItem = dropdownMenu.querySelector('.item.focused');
116
+ if (focusedItem) {
117
+ focusedItem.querySelector('a').click();
118
+ focusedItem.classList.remove('focused');
119
+ }
120
+ } else if (event.key === 'Tab') {
121
+ const focusedItem = dropdownMenu.querySelector('.item.focused');
122
+ if (focusedItem) {
123
+ focusedItem.classList.remove('focused');
124
+ }
125
+ }
126
+ };
127
+
128
+ useEffect(() => {
129
+ if (data.sticky) {
130
+ const toc = document.querySelector('.horizontalMenu');
131
+ const tocPos = toc ? toc.offsetTop : 0;
132
+
133
+ const handleScroll = () => {
134
+ let scrollPos = window.scrollY;
135
+ if (scrollPos > tocPos && toc) {
136
+ toc.classList.add('sticky-toc');
137
+ } else if (scrollPos <= tocPos && toc) {
138
+ toc.classList.remove('sticky-toc');
139
+ }
140
+ };
141
+
142
+ window.addEventListener('scroll', handleScroll);
143
+
144
+ return () => {
145
+ window.removeEventListener('scroll', handleScroll);
146
+ };
147
+ }
148
+ }, [data.sticky]);
149
+
150
+ useEffect(() => {
151
+ handleResize();
152
+ window.addEventListener('resize', handleResize);
153
+
154
+ return () => {
155
+ window.removeEventListener('resize', handleResize);
156
+ };
157
+ });
158
+
35
159
  return (
36
160
  <>
37
161
  {data.title && !data.hide_title ? (
@@ -46,8 +170,22 @@ const View = ({ data, tocEntries }) => {
46
170
  ) : (
47
171
  ''
48
172
  )}
49
- <Menu>
173
+ <Menu className="responsive-menu">
50
174
  <RenderMenuItems items={tocEntries} />
175
+ <Dropdown
176
+ item
177
+ text="More"
178
+ className="hidden-dropdown"
179
+ open={isDropdownOpen}
180
+ onOpen={() => setIsDropdownOpen(true)}
181
+ onClose={() => setIsDropdownOpen(false)}
182
+ tabIndex={0}
183
+ onKeyDown={handleDropdownKeyDown}
184
+ >
185
+ <Dropdown.Menu>
186
+ <RenderMenuItems items={tocEntries} />
187
+ </Dropdown.Menu>
188
+ </Dropdown>
51
189
  </Menu>
52
190
  </>
53
191
  );
@@ -1,7 +1,7 @@
1
1
  import DefaultTocRenderer from './DefaultTocRenderer';
2
2
  import HorizontalMenu from './HorizontalMenu';
3
3
 
4
- export default [
4
+ const ToCVariations = [
5
5
  {
6
6
  id: 'default',
7
7
  title: 'Listing (default)',
@@ -14,3 +14,5 @@ export default [
14
14
  view: HorizontalMenu,
15
15
  },
16
16
  ];
17
+
18
+ export default ToCVariations;
@@ -12,7 +12,7 @@ import { Link } from 'react-router-dom';
12
12
  import {
13
13
  Button,
14
14
  Confirm,
15
- Container,
15
+ Container as SemanticContainer,
16
16
  Divider,
17
17
  Dropdown,
18
18
  Menu,
@@ -70,6 +70,7 @@ import {
70
70
 
71
71
  import { Helmet, getBaseUrl } from '@plone/volto/helpers';
72
72
  import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
73
+ import config from '@plone/volto/registry';
73
74
 
74
75
  import backSVG from '@plone/volto/icons/back.svg';
75
76
  import cutSVG from '@plone/volto/icons/cut.svg';
@@ -449,7 +450,7 @@ class Contents extends Component {
449
450
  sort_on: this.props.sort?.on || 'getObjPositionInParent',
450
451
  sort_order: this.props.sort?.order || 'ascending',
451
452
  isClient: false,
452
- linkIntegrityBreakages: '',
453
+ linkIntegrityBreakages: [],
453
454
  };
454
455
  this.filterTimeout = null;
455
456
  }
@@ -796,18 +797,20 @@ class Contents extends Component {
796
797
  */
797
798
  onMoveToTop(event, { value }) {
798
799
  const id = this.state.items[value]['@id'];
799
- value = this.state.currentPage * this.state.pageSize + value;
800
- this.props.orderContent(
801
- getBaseUrl(this.props.pathname),
802
- id.replace(/^.*\//, ''),
803
- -value,
804
- );
805
- this.setState(
806
- {
807
- currentPage: 0,
808
- },
809
- () => this.fetchContents(),
810
- );
800
+ this.props
801
+ .orderContent(
802
+ getBaseUrl(this.props.pathname),
803
+ id.replace(/^.*\//, ''),
804
+ 'top',
805
+ )
806
+ .then(() => {
807
+ this.setState(
808
+ {
809
+ currentPage: 0,
810
+ },
811
+ () => this.fetchContents(),
812
+ );
813
+ });
811
814
  }
812
815
 
813
816
  /**
@@ -818,18 +821,21 @@ class Contents extends Component {
818
821
  * @returns {undefined}
819
822
  */
820
823
  onMoveToBottom(event, { value }) {
821
- this.onOrderItem(
822
- this.state.items[value]['@id'],
823
- value,
824
- this.state.items.length - 1 - value,
825
- false,
826
- );
827
- this.onOrderItem(
828
- this.state.items[value]['@id'],
829
- value,
830
- this.state.items.length - 1 - value,
831
- true,
832
- );
824
+ const id = this.state.items[value]['@id'];
825
+ this.props
826
+ .orderContent(
827
+ getBaseUrl(this.props.pathname),
828
+ id.replace(/^.*\//, ''),
829
+ 'bottom',
830
+ )
831
+ .then(() => {
832
+ this.setState(
833
+ {
834
+ currentPage: 0,
835
+ },
836
+ () => this.fetchContents(),
837
+ );
838
+ });
833
839
  }
834
840
 
835
841
  /**
@@ -1008,6 +1014,7 @@ class Contents extends Component {
1008
1014
  sort_order: this.state.sort_order,
1009
1015
  metadata_fields: '_all',
1010
1016
  b_size: 100000000,
1017
+ show_inactive: true,
1011
1018
  ...(this.state.filter && { SearchableText: `${this.state.filter}*` }),
1012
1019
  });
1013
1020
  } else {
@@ -1019,6 +1026,7 @@ class Contents extends Component {
1019
1026
  ...(this.state.filter && { SearchableText: `${this.state.filter}*` }),
1020
1027
  b_size: this.state.pageSize,
1021
1028
  b_start: this.state.currentPage * this.state.pageSize,
1029
+ show_inactive: true,
1022
1030
  });
1023
1031
  }
1024
1032
  }
@@ -1170,6 +1178,9 @@ class Contents extends Component {
1170
1178
  (this.props.orderRequest?.loading && !this.props.orderRequest?.error) ||
1171
1179
  (this.props.searchRequest?.loading && !this.props.searchRequest?.error);
1172
1180
 
1181
+ const Container =
1182
+ config.getComponent({ name: 'Container' }).component || SemanticContainer;
1183
+
1173
1184
  return this.props.token && this.props.objectActions?.length > 0 ? (
1174
1185
  <>
1175
1186
  {folderContentsAction ? (
@@ -1225,7 +1236,10 @@ class Contents extends Component {
1225
1236
  Show all items
1226
1237
  </Button>
1227
1238
  )}
1228
- {this.state.linkIntegrityBreakages.length > 0 ? (
1239
+ {this.state.linkIntegrityBreakages.reduce(
1240
+ (a, b) => a + b.breaches.length,
1241
+ 0,
1242
+ ) ? (
1229
1243
  <div>
1230
1244
  <h3>
1231
1245
  {this.props.intl.formatMessage(
@@ -1238,9 +1252,8 @@ class Contents extends Component {
1238
1252
  )}
1239
1253
  </p>
1240
1254
  <ul className="content">
1241
- {map(
1242
- this.state.linkIntegrityBreakages,
1243
- (item) => (
1255
+ {map(this.state.linkIntegrityBreakages, (item) =>
1256
+ item.breaches.length ? (
1244
1257
  <li key={item['@id']}>
1245
1258
  <a href={item['@id']}>{item.title}</a>
1246
1259
  <p>
@@ -1258,7 +1271,7 @@ class Contents extends Component {
1258
1271
  ))}
1259
1272
  </ul>
1260
1273
  </li>
1261
- ),
1274
+ ) : null,
1262
1275
  )}
1263
1276
  </ul>
1264
1277
  </div>
@@ -1780,7 +1793,9 @@ class Contents extends Component {
1780
1793
  <Menu.Header
1781
1794
  content={this.props.intl.formatMessage(
1782
1795
  messages.selected,
1783
- { count: this.state.selected.length },
1796
+ {
1797
+ count: this.state.selected.length,
1798
+ },
1784
1799
  )}
1785
1800
  />
1786
1801
  <Input
@@ -169,6 +169,12 @@ export const ContentsItemComponent = ({
169
169
  <FormattedMessage id="Expired" defaultMessage="Expired" />
170
170
  </Button>
171
171
  )}
172
+ {item.EffectiveDate !== 'None' &&
173
+ new Date(item.EffectiveDate).getTime() > new Date().getTime() && (
174
+ <Button className="button-margin effective-future" size="mini">
175
+ <FormattedMessage id="Scheduled" defaultMessage="Scheduled" />
176
+ </Button>
177
+ )}
172
178
  </Link>
173
179
  </Table.Cell>
174
180
  {map(indexes, (index) => (
@@ -25,6 +25,7 @@ import { readAsDataURL } from 'promise-file-reader';
25
25
  import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
26
26
  import { FormattedRelativeDate } from '@plone/volto/components';
27
27
  import { createContent } from '@plone/volto/actions';
28
+ import { validateFileUploadSize } from '@plone/volto/helpers';
28
29
 
29
30
  const Dropzone = loadable(() => import('react-dropzone'));
30
31
 
@@ -121,14 +122,18 @@ class ContentsUploadModal extends Component {
121
122
  * @returns {undefined}
122
123
  */
123
124
  onDrop = async (files) => {
125
+ const validFiles = [];
124
126
  for (let i = 0; i < files.length; i++) {
125
- await readAsDataURL(files[i]).then((data) => {
126
- const fields = data.match(/^data:(.*);(.*),(.*)$/);
127
- files[i].preview = fields[0];
128
- });
127
+ if (validateFileUploadSize(files[i], this.props.intl.formatMessage)) {
128
+ await readAsDataURL(files[i]).then((data) => {
129
+ const fields = data.match(/^data:(.*);(.*),(.*)$/);
130
+ files[i].preview = fields[0];
131
+ });
132
+ validFiles.push(files[i]);
133
+ }
129
134
  }
130
135
  this.setState({
131
- files: concat(this.state.files, files),
136
+ files: concat(this.state.files, validFiles),
132
137
  });
133
138
  };
134
139
 
@@ -43,7 +43,7 @@ const messages = defineMessages({
43
43
  addAddons: {
44
44
  id: 'Add Addons',
45
45
  defaultMessage:
46
- 'To make new add-ons show up here, add them to your buildout configuration, run buildout, and restart the server process. For detailed instructions see',
46
+ 'To make new add-ons show up here, add them to your configuration, build, and restart the server process. For detailed instructions see',
47
47
  },
48
48
  addonsSettings: {
49
49
  id: 'Add-ons Settings',
@@ -380,11 +380,11 @@ class AddonsControlpanel extends Component {
380
380
  </Header>
381
381
  <FormattedMessage
382
382
  id="Add Addons"
383
- defaultMessage="To make new add-ons show up here, add them to your buildout configuration, run buildout, and restart the server process. For detailed instructions see"
383
+ defaultMessage="To make new add-ons show up here, add them to your configuration, build, and restart the server process. For detailed instructions see"
384
384
  />
385
385
  &nbsp;
386
386
  <a
387
- href="http://docs.plone.org/manage/installing/installing_addons.html"
387
+ href="https://6.docs.plone.org/install/"
388
388
  target="_blank"
389
389
  rel="noopener noreferrer"
390
390
  >