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

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 (297) hide show
  1. package/.yarn/install-state.gz +0 -0
  2. package/CHANGELOG.md +530 -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 +56 -4
  8. package/cypress/support/volto-slate.js +4 -5
  9. package/docker-compose.yml +1 -1
  10. package/locales/ca/LC_MESSAGES/volto.po +272 -6
  11. package/locales/ca.json +1 -1
  12. package/locales/de/LC_MESSAGES/volto.po +291 -25
  13. package/locales/de.json +1 -1
  14. package/locales/en/LC_MESSAGES/volto.po +271 -5
  15. package/locales/en.json +1 -1
  16. package/locales/es/LC_MESSAGES/volto.po +281 -15
  17. package/locales/es.json +1 -1
  18. package/locales/eu/LC_MESSAGES/volto.po +272 -6
  19. package/locales/eu.json +1 -1
  20. package/locales/fi/LC_MESSAGES/volto.po +4882 -0
  21. package/locales/fi.json +1 -1
  22. package/locales/fr/LC_MESSAGES/volto.po +272 -6
  23. package/locales/fr.json +1 -1
  24. package/locales/it/LC_MESSAGES/volto.po +273 -7
  25. package/locales/it.json +1 -1
  26. package/locales/ja/LC_MESSAGES/volto.po +272 -6
  27. package/locales/ja.json +1 -1
  28. package/locales/nl/LC_MESSAGES/volto.po +927 -649
  29. package/locales/nl.json +1 -1
  30. package/locales/pt/LC_MESSAGES/volto.po +272 -6
  31. package/locales/pt.json +1 -1
  32. package/locales/pt_BR/LC_MESSAGES/volto.po +281 -15
  33. package/locales/pt_BR.json +1 -1
  34. package/locales/ro/LC_MESSAGES/volto.po +272 -6
  35. package/locales/ro.json +1 -1
  36. package/locales/volto.pot +272 -6
  37. package/locales/zh_CN/LC_MESSAGES/volto.po +272 -6
  38. package/locales/zh_CN.json +1 -1
  39. package/package.json +5 -3
  40. package/packages/volto-slate/build/messages/src/blocks/Table/TableBlockEdit.json +1 -1
  41. package/packages/volto-slate/build/messages/src/blocks/Text/DefaultTextBlockEditor.json +1 -1
  42. package/packages/volto-slate/build/messages/src/blocks/Text/DetachedTextBlockEditor.json +1 -1
  43. package/packages/volto-slate/build/messages/src/blocks/Text/SlashMenu.json +1 -1
  44. package/packages/volto-slate/build/messages/src/editor/plugins/AdvancedLink/index.json +1 -1
  45. package/packages/volto-slate/build/messages/src/editor/plugins/Link/index.json +1 -1
  46. package/packages/volto-slate/build/messages/src/editor/plugins/Table/index.json +1 -1
  47. package/packages/volto-slate/build/messages/src/elementEditor/messages.json +1 -1
  48. package/packages/volto-slate/build/messages/src/widgets/HtmlSlateWidget.json +1 -1
  49. package/packages/volto-slate/build/messages/src/widgets/RichTextWidgetView.json +1 -1
  50. package/packages/volto-slate/package.json +1 -1
  51. package/packages/volto-slate/src/actions/index.js +1 -1
  52. package/packages/volto-slate/src/blocks/Table/TableBlockEdit.jsx +21 -212
  53. package/packages/volto-slate/src/blocks/Table/schema.js +122 -0
  54. package/packages/volto-slate/src/blocks/Text/DefaultTextBlockEditor.jsx +8 -3
  55. package/packages/volto-slate/src/blocks/Text/SlashMenu.jsx +4 -3
  56. package/packages/volto-slate/src/blocks/Text/TextBlockView.jsx +20 -16
  57. package/packages/volto-slate/src/blocks/Text/extensions/withDeserializers.js +3 -1
  58. package/packages/volto-slate/src/blocks/Text/index.js +10 -2
  59. package/packages/volto-slate/src/editor/config.jsx +5 -4
  60. package/packages/volto-slate/src/editor/deserialize.js +0 -1
  61. package/packages/volto-slate/src/editor/index.js +4 -4
  62. package/packages/volto-slate/src/editor/less/slate.less +28 -0
  63. package/packages/volto-slate/src/editor/plugins/StyleMenu/StyleMenu.jsx +14 -4
  64. package/packages/volto-slate/src/editor/plugins/StyleMenu/utils.js +14 -5
  65. package/packages/volto-slate/src/editor/render.jsx +68 -8
  66. package/packages/volto-slate/src/editor/ui/SlateContextToolbar.jsx +2 -2
  67. package/packages/volto-slate/src/editor/ui/index.js +15 -15
  68. package/packages/volto-slate/src/index.js +2 -2
  69. package/packages/volto-slate/src/utils/blocks.js +7 -0
  70. package/packages/volto-slate/src/widgets/RichTextWidget.jsx +15 -8
  71. package/razzle.config.js +28 -0
  72. package/src/actions/index.js +6 -0
  73. package/src/actions/language/language.js +9 -8
  74. package/src/actions/querystringsearch/querystringsearch.js +20 -14
  75. package/src/actions/relations/rebuild.js +25 -0
  76. package/src/actions/relations/relations.js +86 -0
  77. package/src/actions/relations/relations.test.js +15 -0
  78. package/src/components/index.js +2 -0
  79. package/src/components/manage/Add/Add.jsx +2 -2
  80. package/src/components/manage/AnchorPlugin/index.jsx +2 -2
  81. package/src/components/manage/AnchorPlugin/utils/EditorUtils.js +3 -1
  82. package/src/components/manage/BlockChooser/BlockChooser.jsx +14 -5
  83. package/src/components/manage/BlockChooser/BlockChooser.test.jsx +5 -0
  84. package/src/components/manage/Blocks/Block/BlocksForm.jsx +19 -2
  85. package/src/components/manage/Blocks/Block/Edit.jsx +1 -1
  86. package/src/components/manage/Blocks/Block/Style.jsx +2 -2
  87. package/src/components/manage/Blocks/Container/Data.jsx +32 -0
  88. package/src/components/manage/Blocks/Container/Edit.jsx +174 -0
  89. package/src/components/manage/Blocks/Container/EditBlockWrapper.jsx +120 -0
  90. package/src/components/manage/Blocks/Container/NewBlockAddButton.jsx +84 -0
  91. package/src/components/manage/Blocks/Container/SimpleContainerToolbar.jsx +54 -0
  92. package/src/components/manage/Blocks/Grid/Edit.jsx +33 -0
  93. package/src/components/manage/Blocks/Grid/View.jsx +43 -0
  94. package/src/components/manage/Blocks/Grid/adapter.js +14 -0
  95. package/src/components/manage/Blocks/Grid/grid-1.svg +6 -0
  96. package/src/components/manage/Blocks/Grid/grid-2.svg +9 -0
  97. package/src/components/manage/Blocks/Grid/grid-3.svg +10 -0
  98. package/src/components/manage/Blocks/Grid/grid-4.svg +11 -0
  99. package/src/components/manage/Blocks/Grid/schema.js +35 -0
  100. package/src/components/manage/Blocks/Grid/templates.js +47 -0
  101. package/src/components/manage/Blocks/HeroImageLeft/Edit.jsx +6 -1
  102. package/src/components/manage/Blocks/Image/Edit.jsx +11 -7
  103. package/src/components/manage/Blocks/Image/ImageSidebar.jsx +2 -1
  104. package/src/components/manage/Blocks/Image/schema.js +11 -0
  105. package/src/components/manage/Blocks/Listing/DefaultTemplate.jsx +18 -3
  106. package/src/components/manage/Blocks/Listing/Edit.jsx +0 -14
  107. package/src/components/manage/Blocks/Listing/ListingBody.jsx +30 -8
  108. package/src/components/manage/Blocks/Listing/ListingBody.test.jsx +20 -0
  109. package/src/components/manage/Blocks/Listing/getAsyncData.js +9 -3
  110. package/src/components/manage/Blocks/Listing/withQuerystringResults.jsx +26 -18
  111. package/src/components/manage/Blocks/Search/SearchBlockEdit.jsx +5 -4
  112. package/src/components/manage/Blocks/Search/SearchBlockView.jsx +2 -1
  113. package/src/components/manage/Blocks/Search/components/DateRangeFacet.jsx +4 -1
  114. package/src/components/manage/Blocks/Search/components/Facets.jsx +64 -4
  115. package/src/components/manage/Blocks/Search/components/SearchInput.jsx +9 -2
  116. package/src/components/manage/Blocks/Search/components/index.js +13 -13
  117. package/src/components/manage/Blocks/Search/hocs/index.js +2 -2
  118. package/src/components/manage/Blocks/Search/hocs/withQueryString.jsx +2 -2
  119. package/src/components/manage/Blocks/Search/hocs/withSearch.jsx +43 -15
  120. package/src/components/manage/Blocks/Search/layout/LeftColumnFacets.jsx +17 -5
  121. package/src/components/manage/Blocks/Search/layout/RightColumnFacets.jsx +17 -5
  122. package/src/components/manage/Blocks/Search/layout/TopSideFacets.jsx +21 -5
  123. package/src/components/manage/Blocks/Search/schema.js +16 -1
  124. package/src/components/manage/Blocks/Teaser/Body.jsx +0 -1
  125. package/src/components/manage/Blocks/Teaser/DefaultBody.jsx +20 -15
  126. package/src/components/manage/Blocks/Teaser/schema.js +5 -0
  127. package/src/components/manage/Blocks/Title/View.jsx +15 -5
  128. package/src/components/manage/Blocks/Title/View.test.jsx +16 -1
  129. package/src/components/manage/Blocks/ToC/Schema.jsx +5 -1
  130. package/src/components/manage/Blocks/ToC/View.jsx +8 -1
  131. package/src/components/manage/Blocks/ToC/variations/DefaultTocRenderer.jsx +17 -4
  132. package/src/components/manage/Blocks/ToC/variations/HorizontalMenu.jsx +148 -10
  133. package/src/components/manage/Blocks/ToC/variations/index.js +3 -1
  134. package/src/components/manage/Contents/Contents.jsx +39 -26
  135. package/src/components/manage/Contents/ContentsItem.jsx +6 -0
  136. package/src/components/manage/Contents/ContentsUploadModal.jsx +10 -5
  137. package/src/components/manage/Controlpanels/AddonsControlpanel.jsx +3 -3
  138. package/src/components/manage/Controlpanels/Controlpanels.jsx +199 -224
  139. package/src/components/manage/Controlpanels/Controlpanels.test.jsx +46 -7
  140. package/src/components/manage/Controlpanels/Relations/BrokenRelations.jsx +66 -0
  141. package/src/components/manage/Controlpanels/Relations/Relations.jsx +114 -0
  142. package/src/components/manage/Controlpanels/Relations/RelationsListing.jsx +479 -0
  143. package/src/components/manage/Controlpanels/Relations/RelationsMatrix.jsx +531 -0
  144. package/src/components/manage/Controlpanels/Users/UserGroupMembershipControlPanel.jsx +3 -3
  145. package/src/components/manage/Controlpanels/Users/UserGroupMembershipListing.jsx +51 -82
  146. package/src/components/manage/Controlpanels/Users/UserGroupMembershipMatrix.jsx +79 -75
  147. package/src/components/manage/DragDropList/DragDropList.jsx +18 -13
  148. package/src/components/manage/Form/Form.jsx +5 -3
  149. package/src/components/manage/Form/InlineForm.jsx +39 -9
  150. package/src/components/manage/Form/InlineFormState.js +8 -0
  151. package/src/components/manage/History/History.jsx +11 -1
  152. package/src/components/manage/LinksToItem/LinksToItem.jsx +209 -0
  153. package/src/components/manage/LinksToItem/LinksToItem.test.jsx +97 -0
  154. package/src/components/manage/Multilingual/CreateTranslation.jsx +2 -2
  155. package/src/components/manage/Multilingual/TranslationObject.jsx +4 -3
  156. package/src/components/manage/Preferences/ChangePassword.jsx +2 -2
  157. package/src/components/manage/Preferences/PersonalPreferences.jsx +2 -2
  158. package/src/components/manage/Sharing/Sharing.jsx +5 -1
  159. package/src/components/manage/TemplateChooser/TemplateChooser.jsx +38 -0
  160. package/src/components/manage/TemplateChooser/TemplateChooser.test.jsx +34 -0
  161. package/src/components/manage/TemplateChooser/template.svg +10 -0
  162. package/src/components/manage/Toast/Toast.jsx +2 -2
  163. package/src/components/manage/Toolbar/More.jsx +15 -0
  164. package/src/components/manage/Toolbar/Types.jsx +2 -2
  165. package/src/components/manage/UniversalLink/UniversalLink.jsx +2 -6
  166. package/src/components/manage/UniversalLink/UniversalLink.test.jsx +36 -0
  167. package/src/components/manage/Widgets/ColorPickerWidget.jsx +6 -1
  168. package/src/components/manage/Widgets/DatetimeWidget.jsx +9 -5
  169. package/src/components/manage/Widgets/FileWidget.jsx +2 -1
  170. package/src/components/manage/Widgets/ObjectListWidget.jsx +3 -8
  171. package/src/components/manage/Widgets/RecurrenceWidget/ByDayField.jsx +2 -1
  172. package/src/components/manage/Widgets/RecurrenceWidget/MonthOfTheYearField.jsx +2 -1
  173. package/src/components/manage/Widgets/RecurrenceWidget/Occurences.jsx +2 -1
  174. package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.jsx +8 -3
  175. package/src/components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthField.jsx +2 -1
  176. package/src/components/manage/Widgets/SelectUtils.js +1 -1
  177. package/src/components/manage/Widgets/SelectWidget.jsx +1 -1
  178. package/src/components/theme/Anontools/Anontools.jsx +44 -72
  179. package/src/components/theme/Anontools/Anontools.stories.jsx +16 -6
  180. package/src/components/theme/Anontools/Anontools.test.jsx +16 -2
  181. package/src/components/theme/Breadcrumbs/Breadcrumbs.jsx +52 -99
  182. package/src/components/theme/Breadcrumbs/Breadcrumbs.stories.jsx +14 -13
  183. package/src/components/theme/Comments/CommentEditModal.jsx +63 -115
  184. package/src/components/theme/Component/Component.jsx +1 -1
  185. package/src/components/theme/ContactForm/ContactForm.jsx +108 -192
  186. package/src/components/theme/ContactForm/ContactForm.stories.jsx +1 -1
  187. package/src/components/theme/ContactForm/ContactForm.test.jsx +2 -3
  188. package/src/components/theme/Footer/Footer.jsx +2 -13
  189. package/src/components/theme/Header/Header.jsx +37 -63
  190. package/src/components/theme/Header/Header.test.jsx +18 -0
  191. package/src/components/theme/Icon/Icon.jsx +2 -2
  192. package/src/components/theme/LanguageSelector/LanguageSelector.js +8 -3
  193. package/src/components/theme/Login/Login.jsx +1 -0
  194. package/src/components/theme/Logo/Logo.jsx +2 -1
  195. package/src/components/theme/MultilingualRedirector/MultilingualRedirector.jsx +2 -2
  196. package/src/components/theme/Navigation/NavItem.jsx +4 -2
  197. package/src/components/theme/NotFound/NotFound.jsx +55 -41
  198. package/src/components/theme/PasswordReset/PasswordReset.jsx +7 -4
  199. package/src/components/theme/PasswordReset/RequestPasswordReset.jsx +1 -1
  200. package/src/components/theme/SearchWidget/SearchWidget.jsx +38 -98
  201. package/src/components/theme/Sitemap/Sitemap.jsx +5 -3
  202. package/src/components/theme/View/AlbumView.jsx +9 -1
  203. package/src/components/theme/View/DefaultView.jsx +1 -1
  204. package/src/components/theme/View/EventDatesInfo.jsx +2 -1
  205. package/src/components/theme/View/EventView.jsx +6 -2
  206. package/src/components/theme/View/FileView.jsx +23 -18
  207. package/src/components/theme/View/ImageView.jsx +37 -32
  208. package/src/components/theme/View/LinkView.jsx +53 -78
  209. package/src/components/theme/View/ListingView.jsx +33 -27
  210. package/src/components/theme/View/NewsItemView.jsx +10 -5
  211. package/src/components/theme/View/RenderBlocks.jsx +56 -21
  212. package/src/components/theme/View/RenderEmptyBlock.jsx +5 -0
  213. package/src/components/theme/View/SummaryView.jsx +47 -38
  214. package/src/components/theme/View/TabularView.jsx +59 -53
  215. package/src/components/theme/Widgets/DateWidget.jsx +2 -1
  216. package/src/components/theme/Widgets/DatetimeWidget.jsx +2 -1
  217. package/src/components/theme/Widgets/RelationsWidget.jsx +13 -11
  218. package/src/config/Blocks.jsx +44 -0
  219. package/src/config/ControlPanels.js +2 -0
  220. package/src/config/NonContentRoutes.jsx +1 -0
  221. package/src/config/RichTextEditor/Blocks.jsx +2 -2
  222. package/src/config/RichTextEditor/FromHTML.jsx +2 -2
  223. package/src/config/RichTextEditor/Styles.jsx +1 -1
  224. package/src/config/Widgets.jsx +2 -0
  225. package/src/config/index.js +24 -0
  226. package/src/config/server.js +2 -0
  227. package/src/constants/ActionTypes.js +4 -0
  228. package/src/constants/Indexes.js +3 -1
  229. package/src/constants/Languages.js +8 -4
  230. package/src/express-middleware/devproxy.js +1 -1
  231. package/src/express-middleware/files.js +3 -3
  232. package/src/express-middleware/images.js +4 -4
  233. package/src/express-middleware/ok.js +16 -0
  234. package/src/express-middleware/robotstxt.js +1 -1
  235. package/src/express-middleware/sitemap.js +37 -5
  236. package/src/express-middleware/static.js +3 -3
  237. package/src/helpers/Api/Api.js +1 -1
  238. package/src/helpers/Blocks/Blocks.js +48 -0
  239. package/src/helpers/Blocks/Blocks.test.js +79 -0
  240. package/src/helpers/Extensions/index.js +2 -1
  241. package/src/helpers/Extensions/withBlockSchemaEnhancer.js +15 -11
  242. package/src/helpers/Extensions/withBlockSchemaEnhancer.test.js +145 -0
  243. package/src/helpers/FormValidation/FormValidation.js +40 -2
  244. package/src/helpers/FormValidation/FormValidation.test.js +73 -0
  245. package/src/helpers/Html/Html.jsx +3 -1
  246. package/src/helpers/Html/Html.test.jsx +5 -0
  247. package/src/helpers/MessageLabels/MessageLabels.js +80 -0
  248. package/src/helpers/Robots/Robots.js +24 -6
  249. package/src/helpers/ScrollToTop/ScrollToTop.jsx +5 -3
  250. package/src/helpers/Sitemap/Sitemap.js +44 -2
  251. package/src/helpers/Url/Url.js +27 -6
  252. package/src/helpers/Url/Url.test.js +26 -0
  253. package/src/helpers/Utils/UseDetectClickOutside.stories.jsx +191 -0
  254. package/src/helpers/Utils/Utils.js +63 -13
  255. package/src/helpers/Utils/Utils.test.js +4 -4
  256. package/src/helpers/Utils/usePagination.js +67 -14
  257. package/src/helpers/Utils/usePagination.test.js +115 -0
  258. package/src/helpers/index.js +20 -10
  259. package/src/hooks/client/useClient.js +11 -0
  260. package/src/hooks/clipboard/useClipboard.js +26 -0
  261. package/src/hooks/index.js +2 -0
  262. package/src/icons/grid-block.svg +11 -0
  263. package/src/middleware/Api.test.js +54 -0
  264. package/src/middleware/api.js +24 -6
  265. package/src/middleware/index.js +2 -2
  266. package/src/reducers/actions/actions.js +8 -6
  267. package/src/reducers/actions/actions.test.js +70 -0
  268. package/src/reducers/breadcrumbs/breadcrumbs.js +1 -1
  269. package/src/reducers/index.js +2 -0
  270. package/src/reducers/navigation/navigation.js +1 -1
  271. package/src/reducers/relations/relations.js +173 -0
  272. package/src/reducers/types/types.js +1 -1
  273. package/src/routes.js +14 -0
  274. package/src/server.jsx +28 -23
  275. package/src/start-server.js +2 -2
  276. package/test-setup-config.js +2 -0
  277. package/theme/themes/pastanaga/extras/blocks.less +3 -1
  278. package/theme/themes/pastanaga/extras/contents.less +1 -0
  279. package/theme/themes/pastanaga/extras/grid.less +426 -0
  280. package/theme/themes/pastanaga/extras/main.less +3 -1
  281. package/theme/themes/pastanaga/extras/search.less +6 -0
  282. package/theme/themes/pastanaga/extras/sidebar.less +4 -0
  283. package/theme/themes/pastanaga/extras/toc.less +29 -0
  284. package/theme/themes/pastanaga/extras/userscontrolpanel.less +99 -76
  285. package/.changelog.draft +0 -31
  286. package/.editorconfig +0 -36
  287. package/.storybook/main.js +0 -127
  288. package/.storybook/manager.js +0 -15
  289. package/.storybook/preview.js +0 -21
  290. package/.storybook/static/previewImage.svg +0 -48
  291. package/.yarnrc.yml +0 -5
  292. package/jsdoc.json +0 -16
  293. package/netlify.toml +0 -5
  294. package/pyvenv.cfg +0 -3
  295. package/share/man/man1/ttx.1 +0 -225
  296. package/src/components/theme/Header/Header.md +0 -27
  297. package/towncrier.toml +0 -33
@@ -28,13 +28,13 @@ const StyleMenuButton = ({ icon, active, ...props }) => (
28
28
  <ToolbarButton {...props} icon={icon} active={active} />
29
29
  );
30
30
 
31
- const MenuOpts = ({ editor, toSelect, option, ...rest }) => {
31
+ const MenuOpts = ({ editor, toSelect, option, type }) => {
32
32
  const isActive = toSelect.includes(option);
33
33
  return (
34
34
  <Dropdown.Item
35
35
  as="span"
36
36
  active={isActive}
37
- className={cx({ active: isActive })}
37
+ className={cx(`${type}-${option.value}`, { active: isActive })}
38
38
  {...omit(option, ['isBlock'])}
39
39
  data-isblock={option.isBlock}
40
40
  onClick={(event, selItem) => {
@@ -118,7 +118,12 @@ const StylingsButton = (props) => {
118
118
  content={intl.formatMessage(messages.inlineStyle)}
119
119
  />
120
120
  {inlineOpts.map((option, index) => (
121
- <MenuOpts {...menuItemProps} option={option} key={index} />
121
+ <MenuOpts
122
+ {...menuItemProps}
123
+ type="inline-style"
124
+ option={option}
125
+ key={index}
126
+ />
122
127
  ))}
123
128
  </>
124
129
  )}
@@ -129,7 +134,12 @@ const StylingsButton = (props) => {
129
134
  content={intl.formatMessage(messages.paragraphStyle)}
130
135
  />
131
136
  {blockOpts.map((option, index) => (
132
- <MenuOpts {...menuItemProps} option={option} key={index} />
137
+ <MenuOpts
138
+ {...menuItemProps}
139
+ type="block-style"
140
+ option={option}
141
+ key={index}
142
+ />
133
143
  ))}
134
144
  </>
135
145
  )}
@@ -72,19 +72,28 @@ export const toggleInlineStyle = (editor, style) => {
72
72
  };
73
73
 
74
74
  export const isBlockStyleActive = (editor, style) => {
75
+ const keyName = `style-${style}`;
75
76
  const sn = Array.from(
76
77
  Editor.nodes(editor, {
77
- match: (n) => !Editor.isEditor(n) && typeof n.styleName === 'string',
78
- mode: 'highest',
78
+ match: (n) => {
79
+ const isStyle = typeof n.styleName === 'string' || n[keyName];
80
+ return !Editor.isEditor(n) && isStyle;
81
+ },
82
+ mode: 'all',
79
83
  }),
80
84
  );
81
85
 
82
86
  for (const [n] of sn) {
83
- if (n.styleName.split(' ').filter((x) => x === style).length > 0) {
87
+ if (typeof n.styleName === 'string') {
88
+ if (n.styleName.split(' ').filter((x) => x === style).length > 0) {
89
+ return true;
90
+ }
91
+ } else if (
92
+ n[keyName] &&
93
+ keyName.split('-').filter((x) => x === style).length > 0
94
+ )
84
95
  return true;
85
- }
86
96
  }
87
-
88
97
  return false;
89
98
  };
90
99
 
@@ -1,9 +1,18 @@
1
1
  import React from 'react';
2
2
  import { renderToStaticMarkup } from 'react-dom/server';
3
+ import { useLocation } from 'react-router-dom';
4
+ import { toast } from 'react-toastify';
5
+ import { useIntl } from 'react-intl';
3
6
  import { Node, Text } from 'slate';
4
7
  import cx from 'classnames';
5
- import { isEmpty, isEqual, omit } from 'lodash';
8
+ import { isEmpty, omit } from 'lodash';
9
+ import { UniversalLink, Toast } from '@plone/volto/components';
10
+ import { messages, addAppURL } from '@plone/volto/helpers';
11
+ import useClipboard from '@plone/volto/hooks/clipboard/useClipboard';
6
12
  import config from '@plone/volto/registry';
13
+ import linkSVG from '@plone/volto/icons/link.svg';
14
+
15
+ import './less/slate.less';
7
16
 
8
17
  const OMITTED = ['editor', 'path'];
9
18
 
@@ -106,13 +115,7 @@ export const serializeNodes = (nodes, getAttributes, extras = {}) => {
106
115
  mode="view"
107
116
  key={path}
108
117
  data-slate-data={node.data ? serializeData(node) : null}
109
- attributes={
110
- isEqual(path, [0])
111
- ? getAttributes
112
- ? getAttributes(node, path)
113
- : null
114
- : null
115
- }
118
+ attributes={getAttributes ? getAttributes(node, path) : null}
116
119
  extras={extras}
117
120
  >
118
121
  {_serializeNodes(Array.from(Node.children(editor, path)))}
@@ -153,3 +156,60 @@ export const serializeNodesToText = (nodes) => {
153
156
 
154
157
  export const serializeNodesToHtml = (nodes) =>
155
158
  renderToStaticMarkup(serializeNodes(nodes));
159
+
160
+ export const renderLinkElement = (tagName) => {
161
+ function LinkElement({
162
+ attributes,
163
+ children,
164
+ mode = 'edit',
165
+ className = null,
166
+ }) {
167
+ const { slate = {} } = config.settings;
168
+ const Tag = tagName;
169
+ const slug = attributes.id || '';
170
+ const location = useLocation();
171
+ const appPathname = addAppURL(location.pathname);
172
+ // eslint-disable-next-line no-unused-vars
173
+ const [copied, copy, setCopied] = useClipboard(
174
+ appPathname.concat(`#${slug}`),
175
+ );
176
+ const intl = useIntl();
177
+
178
+ return slate.useLinkedHeadings === false ? (
179
+ <Tag {...attributes} className={className}>
180
+ {children}
181
+ </Tag>
182
+ ) : (
183
+ <Tag {...attributes} className={className}>
184
+ {children}
185
+ {mode === 'view' && slug && (
186
+ <UniversalLink
187
+ className="anchor"
188
+ aria-hidden="true"
189
+ tabIndex={-1}
190
+ href={`#${slug}`}
191
+ >
192
+ <svg
193
+ {...linkSVG.attributes}
194
+ dangerouslySetInnerHTML={{ __html: linkSVG.content }}
195
+ height={null}
196
+ onClick={() => {
197
+ copy();
198
+
199
+ toast.info(
200
+ <Toast
201
+ info
202
+ title={intl.formatMessage(messages.success)}
203
+ content={intl.formatMessage(messages.urlClipboardCopy)}
204
+ />,
205
+ );
206
+ }}
207
+ ></svg>
208
+ </UniversalLink>
209
+ )}
210
+ </Tag>
211
+ );
212
+ }
213
+ LinkElement.displayName = `${tagName}LinkElement`;
214
+ return LinkElement;
215
+ };
@@ -3,11 +3,11 @@ import Toolbar from './Toolbar';
3
3
 
4
4
  // A toolbar that conditionally renders itself based on the presense of
5
5
  // children
6
- export default ({ editor, plugins, show }) => {
6
+ export default function SlateContextToolbar({ editor, plugins, show }) {
7
7
  if (!show) {
8
8
  return null;
9
9
  }
10
10
 
11
11
  const components = plugins.map((plug) => plug(editor)).filter((c) => !!c);
12
12
  return components.length ? <Toolbar>{components}</Toolbar> : '';
13
- };
13
+ }
@@ -1,15 +1,15 @@
1
- export BasicToolbar from './BasicToolbar';
2
- export BlockButton from './BlockButton';
3
- export ClearFormattingButton from './ClearFormattingButton';
4
- export ExpandedToolbar from './ExpandedToolbar';
5
- export Expando from './Expando';
6
- export MarkButton from './MarkButton';
7
- export Menu from './Menu';
8
- export Separator from './Separator';
9
- export SlateContextToolbar from './SlateContextToolbar';
10
- export SlateToolbar from './SlateToolbar';
11
- export Toolbar from './Toolbar';
12
- export ToolbarButton from './ToolbarButton';
13
- export MarkElementButton from './MarkElementButton';
14
- export PositionedToolbar from './PositionedToolbar';
15
- export InlineToolbar from './InlineToolbar';
1
+ export { default as BasicToolbar } from './BasicToolbar';
2
+ export { default as BlockButton } from './BlockButton';
3
+ export { default as ClearFormattingButton } from './ClearFormattingButton';
4
+ export { default as ExpandedToolbar } from './ExpandedToolbar';
5
+ export { default as Expando } from './Expando';
6
+ export { default as MarkButton } from './MarkButton';
7
+ export { default as Menu } from './Menu';
8
+ export { default as Separator } from './Separator';
9
+ export { default as SlateContextToolbar } from './SlateContextToolbar';
10
+ export { default as SlateToolbar } from './SlateToolbar';
11
+ export { default as Toolbar } from './Toolbar';
12
+ export { default as ToolbarButton } from './ToolbarButton';
13
+ export { default as MarkElementButton } from './MarkElementButton';
14
+ export { default as PositionedToolbar } from './PositionedToolbar';
15
+ export { default as InlineToolbar } from './InlineToolbar';
@@ -8,7 +8,7 @@ import RichTextWidgetView from './widgets/RichTextWidgetView';
8
8
  import HtmlSlateWidget from './widgets/HtmlSlateWidget';
9
9
  import ObjectByTypeWidget from './widgets/ObjectByTypeWidget';
10
10
 
11
- export default (config) => {
11
+ export default function applyConfig(config) {
12
12
  config = [installSlate, installTextBlock, installTableBlock].reduce(
13
13
  (acc, apply) => apply(acc),
14
14
  config,
@@ -58,4 +58,4 @@ export default (config) => {
58
58
  }
59
59
 
60
60
  return config;
61
- };
61
+ }
@@ -125,6 +125,13 @@ export function createEmptyParagraph() {
125
125
  };
126
126
  }
127
127
 
128
+ export function createParagraph(text) {
129
+ return {
130
+ type: config.settings.slate.defaultBlockType,
131
+ children: [{ text }],
132
+ };
133
+ }
134
+
128
135
  export const isSingleBlockTypeActive = (editor, format) => {
129
136
  const [match] = Editor.nodes(editor, {
130
137
  match: (n) => n.type === format,
@@ -4,13 +4,26 @@
4
4
  */
5
5
 
6
6
  import React from 'react';
7
+ import isUndefined from 'lodash/isUndefined';
8
+ import isString from 'lodash/isString';
7
9
  import { FormFieldWrapper } from '@plone/volto/components';
8
10
  import SlateEditor from '@plone/volto-slate/editor/SlateEditor';
9
11
 
10
- import { createEmptyParagraph } from '../utils/blocks';
12
+ import { createEmptyParagraph, createParagraph } from '../utils/blocks';
11
13
 
12
14
  import './style.css';
13
15
 
16
+ const getValue = (value) => {
17
+ if (isUndefined(value) || !isUndefined(value?.data)) {
18
+ return [createEmptyParagraph()];
19
+ }
20
+ // Previously this was a text field
21
+ if (isString(value)) {
22
+ return [createParagraph(value)];
23
+ }
24
+ return value;
25
+ };
26
+
14
27
  const SlateRichTextWidget = (props) => {
15
28
  const {
16
29
  id,
@@ -42,13 +55,7 @@ const SlateRichTextWidget = (props) => {
42
55
  readOnly={readOnly}
43
56
  id={id}
44
57
  name={id}
45
- value={
46
- typeof value === 'undefined' ||
47
- typeof value?.data !==
48
- 'undefined' /* previously this was a Draft block */
49
- ? [createEmptyParagraph()]
50
- : value
51
- }
58
+ value={getValue(value)}
52
59
  onChange={(newValue) => {
53
60
  onChange(id, newValue);
54
61
  }}
package/razzle.config.js CHANGED
@@ -8,6 +8,7 @@ const fs = require('fs');
8
8
  const RootResolverPlugin = require('./webpack-plugins/webpack-root-resolver');
9
9
  const RelativeResolverPlugin = require('./webpack-plugins/webpack-relative-resolver');
10
10
  const createAddonsLoader = require('./create-addons-loader');
11
+ const createThemeAddonsLoader = require('./create-theme-addons-loader');
11
12
  const AddonConfigurationRegistry = require('./addon-registry');
12
13
  const CircularDependencyPlugin = require('circular-dependency-plugin');
13
14
  const TerserPlugin = require('terser-webpack-plugin');
@@ -245,6 +246,28 @@ const defaultModify = ({
245
246
  'lodash-es': path.dirname(require.resolve('lodash')),
246
247
  };
247
248
 
249
+ const [
250
+ addonsThemeLoaderVariablesPath,
251
+ addonsThemeLoaderMainPath,
252
+ ] = createThemeAddonsLoader(registry.getCustomThemeAddons());
253
+
254
+ // Automatic Theme Loading
255
+ if (registry.theme) {
256
+ // The themes should be located in `src/theme`
257
+ const themePath = registry.packages[registry.theme].modulePath;
258
+ const themeConfigPath = `${themePath}/theme/theme.config`;
259
+ config.resolve.alias['../../theme.config$'] = themeConfigPath;
260
+ config.resolve.alias['../../theme.config'] = themeConfigPath;
261
+
262
+ // We create an alias for each custom theme insertion point (variables, main)
263
+ config.resolve.alias[
264
+ 'addonsThemeCustomizationsVariables'
265
+ ] = addonsThemeLoaderVariablesPath;
266
+ config.resolve.alias[
267
+ 'addonsThemeCustomizationsMain'
268
+ ] = addonsThemeLoaderMainPath;
269
+ }
270
+
248
271
  config.performance = {
249
272
  maxAssetSize: 10000000,
250
273
  maxEntrypointSize: 10000000,
@@ -318,6 +341,11 @@ const defaultModify = ({
318
341
 
319
342
  if (config.devServer) {
320
343
  config.devServer.static.watch.ignored = /node_modules\/(?!@plone\/volto)/;
344
+ config.snapshot = {
345
+ managedPaths: [
346
+ /^(.+?[\\/]node_modules[\\/](?!(@plone[\\/]volto))(@.+?[\\/])?.+?)[\\/]/,
347
+ ],
348
+ };
321
349
  }
322
350
 
323
351
  return config;
@@ -71,6 +71,12 @@ export {
71
71
  purgeMessages,
72
72
  } from '@plone/volto/actions/messages/messages';
73
73
  export { getNavigation } from '@plone/volto/actions/navigation/navigation';
74
+ export {
75
+ createRelations,
76
+ deleteRelations,
77
+ queryRelations,
78
+ } from '@plone/volto/actions/relations/relations';
79
+ export { rebuildRelations } from '@plone/volto/actions/relations/rebuild';
74
80
  export { listRoles } from '@plone/volto/actions/roles/roles';
75
81
  export {
76
82
  getSchema,
@@ -1,5 +1,9 @@
1
1
  import { updateIntl } from 'react-intl-redux';
2
- import { normalizeLanguageName, getCookieOptions } from '@plone/volto/helpers';
2
+ import {
3
+ toGettextLang,
4
+ toReactIntlLang,
5
+ getCookieOptions,
6
+ } from '@plone/volto/helpers';
3
7
  import Cookies from 'universal-cookie';
4
8
 
5
9
  export function changeLanguageCookies(language, req) {
@@ -7,18 +11,15 @@ export function changeLanguageCookies(language, req) {
7
11
 
8
12
  const cookieOptions = getCookieOptions({
9
13
  secure: req?.protocol?.startsWith('https') ? true : false,
14
+ sameSite: 'strict',
10
15
  });
11
16
 
12
17
  if (!req) {
13
- cookies.set(
14
- 'I18N_LANGUAGE',
15
- normalizeLanguageName(language) || '',
16
- cookieOptions,
17
- );
18
+ cookies.set('I18N_LANGUAGE', toGettextLang(language) || '', cookieOptions);
18
19
  } else {
19
20
  req.universalCookies.set(
20
21
  'I18N_LANGUAGE',
21
- normalizeLanguageName(language) || '',
22
+ toGettextLang(language) || '',
22
23
  cookieOptions,
23
24
  );
24
25
  }
@@ -35,7 +36,7 @@ export function changeLanguage(language, locale, req) {
35
36
  changeLanguageCookies(language, req);
36
37
 
37
38
  return updateIntl({
38
- locale: language,
39
+ locale: toReactIntlLang(language),
39
40
  messages: locale,
40
41
  });
41
42
  }
@@ -31,24 +31,30 @@ export function getQueryStringResults(path, data, subrequest, page) {
31
31
  }
32
32
  }
33
33
 
34
+ const query = {
35
+ ...requestData,
36
+ ...(!requestData.b_size && {
37
+ b_size: settings.defaultPageSize,
38
+ }),
39
+ ...(page && {
40
+ b_start: requestData.b_size
41
+ ? data.b_size * (page - 1)
42
+ : settings.defaultPageSize * (page - 1),
43
+ }),
44
+ query: requestData?.query,
45
+ };
46
+
34
47
  return {
35
48
  type: GET_QUERYSTRING_RESULTS,
36
49
  subrequest,
37
50
  request: {
38
- op: 'post',
39
- path: `${path}/@querystring-search`,
40
- data: {
41
- ...requestData,
42
- ...(!requestData.b_size && {
43
- b_size: settings.defaultPageSize,
44
- }),
45
- ...(page && {
46
- b_start: requestData.b_size
47
- ? data.b_size * (page - 1)
48
- : settings.defaultPageSize * (page - 1),
49
- }),
50
- query: requestData?.query,
51
- },
51
+ op: settings.querystringSearchGet ? 'get' : 'post',
52
+ path: `${path}/@querystring-search${
53
+ settings.querystringSearchGet
54
+ ? `?query=${encodeURIComponent(JSON.stringify(query))}`
55
+ : ''
56
+ }`,
57
+ data: settings.querystringSearchGet ? null : query,
52
58
  },
53
59
  };
54
60
  }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Rebuild relations action.
3
+ * @module actions/relations/rebuild
4
+ */
5
+
6
+ import { REBUILD_RELATIONS } from '@plone/volto/constants/ActionTypes';
7
+
8
+ /**
9
+ * Rebuild relation function.
10
+ * @function rebuildRelations
11
+ * @param {Boolean} flush Flush intids
12
+ * @returns {Object} Rebuild relation action.
13
+ */
14
+ export function rebuildRelations(flush = false) {
15
+ let path = '/@relations';
16
+ var searchParams = new URLSearchParams();
17
+ searchParams.append('rebuild', '1');
18
+ flush && searchParams.append('flush', '1');
19
+ const searchParamsToString = searchParams.toString();
20
+ path += `?${searchParamsToString}`;
21
+ return {
22
+ type: REBUILD_RELATIONS,
23
+ request: { op: 'get', path: path },
24
+ };
25
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Relations actions.
3
+ * @module actions/relations/relations
4
+ */
5
+
6
+ import {
7
+ CREATE_RELATIONS,
8
+ DELETE_RELATIONS,
9
+ LIST_RELATIONS,
10
+ } from '@plone/volto/constants/ActionTypes';
11
+
12
+ /**
13
+ * Create relation function.
14
+ * @function createRelations
15
+ * @param {Object|Array} content Relation data.
16
+ * @returns {Object} Create relation action.
17
+ */
18
+ export function createRelations(content) {
19
+ return {
20
+ type: CREATE_RELATIONS,
21
+ request: {
22
+ op: 'post',
23
+ path: '/@relations',
24
+ data: {
25
+ items: content,
26
+ },
27
+ },
28
+ };
29
+ }
30
+
31
+ /**
32
+ * Delete relation function.
33
+ * @function deleteRelations
34
+ * @param {string} id Relation id
35
+ * @returns {Object} Delete relation action.
36
+ */
37
+ export function deleteRelations(content) {
38
+ return {
39
+ type: DELETE_RELATIONS,
40
+ request: {
41
+ op: 'del',
42
+ path: `/@relations`,
43
+ data: {
44
+ items: content,
45
+ },
46
+ },
47
+ };
48
+ }
49
+
50
+ /**
51
+ * Query relations
52
+ * @function queryRelations
53
+ * @param {string} relation Name of relation
54
+ * @param {boolean} onlyBroken
55
+ * @returns {Object} List relations action
56
+ */
57
+ export function queryRelations(
58
+ relation = null,
59
+ onlyBroken = false,
60
+ subrequest = null,
61
+ source = null,
62
+ target = null,
63
+ query_source = null,
64
+ query_target = null,
65
+ ) {
66
+ let path = '/@relations';
67
+ var searchParams = new URLSearchParams();
68
+ relation && searchParams.append('relation', relation);
69
+ onlyBroken && searchParams.append('onlyBroken', onlyBroken);
70
+ source && searchParams.append('source', source);
71
+ target && searchParams.append('target', target);
72
+ query_source && searchParams.append('query_source', query_source);
73
+ query_target && searchParams.append('query_target', query_target);
74
+ const searchParamsToString = searchParams.toString();
75
+ if (searchParamsToString) {
76
+ path += `?${searchParamsToString}`;
77
+ }
78
+ return {
79
+ type: LIST_RELATIONS,
80
+ subrequest,
81
+ request: {
82
+ op: 'get',
83
+ path: path,
84
+ },
85
+ };
86
+ }
@@ -0,0 +1,15 @@
1
+ import { queryRelations } from './relations';
2
+ import { LIST_RELATIONS } from '@plone/volto/constants/ActionTypes';
3
+
4
+ describe('Relations action', () => {
5
+ describe('queryRelations', () => {
6
+ it('should create an action to get relations of type "relatedItems"', () => {
7
+ const relation = 'relatedItems';
8
+ const action = queryRelations(relation);
9
+
10
+ expect(action.type).toEqual(LIST_RELATIONS);
11
+ expect(action.request.op).toEqual('get');
12
+ expect(action.request.path).toEqual(`/@relations?relation=${relation}`);
13
+ });
14
+ });
15
+ });
@@ -89,6 +89,7 @@ export ContentTypeSchema from '@plone/volto/components/manage/Controlpanels/Cont
89
89
  export ContentTypesActions from '@plone/volto/components/manage/Controlpanels/ContentTypesActions';
90
90
  export UsersControlpanel from '@plone/volto/components/manage/Controlpanels/Users/UsersControlpanel';
91
91
  export UserGroupMembershipControlPanel from '@plone/volto/components/manage/Controlpanels/Users/UserGroupMembershipControlPanel';
92
+ export Relations from '@plone/volto/components/manage/Controlpanels/Relations/Relations';
92
93
  export GroupsControlpanel from '@plone/volto/components/manage/Controlpanels/Groups/GroupsControlpanel';
93
94
  export RulesControlpanel from '@plone/volto/components/manage/Controlpanels/Rules/Rules';
94
95
  export AddRuleControlpanel from '@plone/volto/components/manage/Controlpanels/Rules/AddRule';
@@ -107,6 +108,7 @@ export History from '@plone/volto/components/manage/History/History';
107
108
  export Sharing from '@plone/volto/components/manage/Sharing/Sharing';
108
109
  export Rules from '@plone/volto/components/manage/Rules/Rules';
109
110
  export Aliases from '@plone/volto/components/manage/Aliases/Aliases';
111
+ export LinksToItem from '@plone/volto/components/manage/LinksToItem/LinksToItem';
110
112
  export Workflow from '@plone/volto/components/manage/Workflow/Workflow';
111
113
  export Messages from '@plone/volto/components/manage/Messages/Messages';
112
114
  export BlockChooser from '@plone/volto/components/manage/BlockChooser/BlockChooser';
@@ -33,7 +33,7 @@ import {
33
33
  getBlocksLayoutFieldname,
34
34
  getLanguageIndependentFields,
35
35
  langmap,
36
- normalizeLanguageName,
36
+ toGettextLang,
37
37
  } from '@plone/volto/helpers';
38
38
 
39
39
  import { preloadLazyLibs } from '@plone/volto/helpers/Loadable';
@@ -219,7 +219,7 @@ class Add extends Component {
219
219
  onCancel() {
220
220
  if (this.props.location?.state?.translationOf) {
221
221
  const language = this.props.location.state.languageFrom;
222
- const langFileName = normalizeLanguageName(language);
222
+ const langFileName = toGettextLang(language);
223
223
  import('@root/../locales/' + langFileName + '.json').then((locale) => {
224
224
  this.props.changeLanguage(language, locale.default);
225
225
  });
@@ -44,7 +44,7 @@ function unboundRemoveEntity(editorState) {
44
44
  return newEditorState;
45
45
  }
46
46
 
47
- export default (config = {}) => {
47
+ export default function AnchorPlugin(config = {}) {
48
48
  // ToDo: Get rif of the remainings of having the original CSS modules
49
49
  const defaultTheme = {};
50
50
 
@@ -79,4 +79,4 @@ export default (config = {}) => {
79
79
  setEditorState(removeEntity(getEditorState())),
80
80
  }),
81
81
  };
82
- };
82
+ }
@@ -1,4 +1,4 @@
1
- export default ({ draftJs }) => ({
1
+ const EditorUtils = ({ draftJs }) => ({
2
2
  createLinkAtSelection(editorState, url) {
3
3
  const contentState = editorState
4
4
  .getCurrentContent()
@@ -43,3 +43,5 @@ export default ({ draftJs }) => ({
43
43
  return entity && entity.getType() === entityType;
44
44
  },
45
45
  });
46
+
47
+ export default EditorUtils;