@plone/volto 18.0.0-alpha.4 → 18.0.0-alpha.6

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 (47) hide show
  1. package/.eslintignore +1 -0
  2. package/.release-it.json +1 -0
  3. package/CHANGELOG.md +55 -0
  4. package/package.json +8 -5
  5. package/src/components/manage/Add/Add.jsx +6 -0
  6. package/src/components/manage/BlockChooser/BlockChooser.jsx +3 -1
  7. package/src/components/manage/BlockChooser/BlockChooserButton.jsx +5 -0
  8. package/src/components/manage/Blocks/Block/BlocksForm.jsx +4 -0
  9. package/src/components/manage/Blocks/Block/DefaultEdit.jsx +3 -1
  10. package/src/components/manage/Blocks/Block/EditBlockWrapper.jsx +10 -2
  11. package/src/components/manage/Blocks/Block/Settings.jsx +10 -1
  12. package/src/components/manage/Blocks/Block/StyleWrapper.jsx +7 -1
  13. package/src/components/manage/Blocks/Container/Data.jsx +4 -1
  14. package/src/components/manage/Blocks/Grid/View.jsx +2 -1
  15. package/src/components/manage/Blocks/HeroImageLeft/Data.jsx +3 -1
  16. package/src/components/manage/Blocks/Image/ImageSidebar.jsx +4 -1
  17. package/src/components/manage/Blocks/Image/View.jsx +2 -1
  18. package/src/components/manage/Blocks/Listing/ListingData.jsx +4 -1
  19. package/src/components/manage/Blocks/Listing/View.jsx +2 -1
  20. package/src/components/manage/Blocks/Maps/MapsSidebar.jsx +3 -1
  21. package/src/components/manage/Blocks/Search/SearchBlockEdit.jsx +4 -0
  22. package/src/components/manage/Blocks/Search/hocs/withSearch.jsx +46 -4
  23. package/src/components/manage/Blocks/Teaser/Data.jsx +4 -1
  24. package/src/components/manage/Blocks/Teaser/DefaultBody.jsx +2 -2
  25. package/src/components/manage/Blocks/ToC/Edit.jsx +2 -0
  26. package/src/components/manage/Blocks/Video/VideoSidebar.jsx +3 -1
  27. package/src/components/manage/Edit/Edit.jsx +1 -0
  28. package/src/components/manage/Form/Form.jsx +9 -1
  29. package/src/components/manage/Sidebar/SidebarPopup.jsx +1 -1
  30. package/src/components/theme/Comments/CommentEditModal.jsx +1 -0
  31. package/src/components/theme/Image/Image.jsx +4 -2
  32. package/src/components/theme/Image/Image.test.jsx +32 -0
  33. package/src/components/theme/Login/Login.jsx +12 -2
  34. package/src/components/theme/Navigation/Navigation.jsx +34 -32
  35. package/src/components/theme/PreviewImage/PreviewImage.jsx +7 -2
  36. package/src/components/theme/Sitemap/Sitemap.jsx +4 -4
  37. package/src/components/theme/Sitemap/Sitemap.test.jsx +52 -0
  38. package/src/components/theme/Unauthorized/Unauthorized.jsx +12 -11
  39. package/src/helpers/Blocks/Blocks.js +67 -3
  40. package/src/helpers/Blocks/Blocks.test.js +57 -0
  41. package/src/helpers/Extensions/withBlockSchemaEnhancer.js +20 -9
  42. package/src/helpers/Url/Url.js +5 -4
  43. package/src/helpers/Url/Url.test.js +52 -0
  44. package/src/helpers/index.js +1 -0
  45. package/theme/themes/pastanaga/extras/blocks.less +2 -0
  46. package/theme/themes/pastanaga/extras/sidebar.less +2 -1
  47. package/types/helpers/Extensions/withBlockSchemaEnhancer.d.ts +3 -1
package/.eslintignore CHANGED
@@ -0,0 +1 @@
1
+ types/
package/.release-it.json CHANGED
@@ -15,6 +15,7 @@
15
15
  "publish": false
16
16
  },
17
17
  "git": {
18
+ "commitArgs": ["--no-verify"],
18
19
  "changelog": "pipx run towncrier build --draft --yes --version 0.0.0",
19
20
  "requireUpstream": false,
20
21
  "requireCleanWorkingDir": false
package/CHANGELOG.md CHANGED
@@ -17,6 +17,61 @@ myst:
17
17
 
18
18
  <!-- towncrier release notes start -->
19
19
 
20
+ ## 18.0.0-alpha.6 (2024-01-02)
21
+
22
+ ### Feature
23
+
24
+ - Added support for custom CSS properties in the `StyleWrapper`. @sneridagh [#5581](https://github.com/plone/volto/issues/5581)
25
+
26
+ ### Bugfix
27
+
28
+ - Use a textarea in the form for editing an existing comment. @Ravi-kumar9347 [#5265](https://github.com/plone/volto/issues/5265)
29
+ - The hamburger icon to open the mobile/tablet navigation is now hidden if there are no navigation items. @Aarav238 [#5353](https://github.com/plone/volto/issues/5353)
30
+ - Fix preview image component @steffenri [#5379](https://github.com/plone/volto/issues/5379)
31
+ - Fix autopopulated value of facet when settings the value for another one. @iFlameing [#5432](https://github.com/plone/volto/issues/5432)
32
+ - Fix sitemap for multilingual sites
33
+ [erral] [#5501](https://github.com/plone/volto/issues/5501)
34
+ - Replace createRef with useRef in SidebarPopup
35
+ [razvanMiu] [#5519](https://github.com/plone/volto/issues/5519)
36
+ - Fixed the project generator's ESLint configuration, added code quality checks to the CI to ensure a generated project can run these checks, and added documentation for how to reconfigure ESLint in projects. @sneridagh [#5530](https://github.com/plone/volto/issues/5530)
37
+ - Fixed edge case error in Unauthorised page and Login route behavior @sneridagh [#5536](https://github.com/plone/volto/issues/5536)
38
+ - changed typo of pnp to pnpm. @ujjwaleee26 [#5537](https://github.com/plone/volto/issues/5537)
39
+
40
+ ### Internal
41
+
42
+ - Added Cypress tests to verify that the modal dialog for deleting linked items pops up correctly. @Molochem [#5529](https://github.com/plone/volto/issues/5529)
43
+ - Fix stylelint violations @sneridagh [#5544](https://github.com/plone/volto/issues/5544)
44
+ - Update Plone to 6.0.9 @sneridagh [#5562](https://github.com/plone/volto/issues/5562)
45
+
46
+ ### Documentation
47
+
48
+ - Removed outdated acceptance tests docs @sneridagh [#5533](https://github.com/plone/volto/issues/5533)
49
+ - Add `how-to-restrict-blocks` to `recipes/index.md`, avoiding Sphinx warning. @stevepiercy [#5546](https://github.com/plone/volto/issues/5546)
50
+ - Point developers to correct installation documentation, replaced yarn commands with pnpm, and correct some misspellings. We also now use includes to keep instructions consistent within Volto and in the main Plone 6 documentation. Finally the `NVM_VERSION` substitution now works. @ujjwaleee26 @stevepiercy [#5556](https://github.com/plone/volto/issues/5556)
51
+ - Fix redirects. @stevepiercy [#5563](https://github.com/plone/volto/issues/5563)
52
+ - Fix redirect for `nvm.fish`. @stevepiercy [#5569](https://github.com/plone/volto/issues/5569)
53
+
54
+ ## 18.0.0-alpha.5 (2023-12-13)
55
+
56
+ ### Feature
57
+
58
+ - Added conditional variations support. @sneridagh @robgietema [#5424](https://github.com/plone/volto/issues/5424)
59
+ - Added `navRoot` and `contentType` to `restricted` key in blocks configuration. @sneridagh [#5517](https://github.com/plone/volto/issues/5517)
60
+ - Add support for `preview_image_link` behavior in Volto Image component @sneridagh [#5523](https://github.com/plone/volto/issues/5523)
61
+
62
+ ### Internal
63
+
64
+ - Add missing dependency on jsdom @sneridagh [#5490](https://github.com/plone/volto/issues/5490)
65
+ - Fix cypress artifacts path in acceptance tests. @davisagli [#5498](https://github.com/plone/volto/issues/5498)
66
+ - Make sure that the dependencies are built and available on all processes @sneridagh [#5514](https://github.com/plone/volto/issues/5514)
67
+
68
+ ### Documentation
69
+
70
+ - Less comment blocks must have `*` as the first character on the second and subsequent lines, else the Pygments lexer fails. @stevepiercy [#5500](https://github.com/plone/volto/issues/5500)
71
+ - Revert #5500. See #5499 for actual cause of Pygments failure. @stevepiercy [#5504](https://github.com/plone/volto/issues/5504)
72
+ - Clarified where to run Make commands for building documentation. @stevepiercy [#5505](https://github.com/plone/volto/issues/5505)
73
+ - Changed installation of Vale from manual to automatic via `make docs-vale`. @stevepiercy [#5508](https://github.com/plone/volto/issues/5508)
74
+
20
75
  ## 18.0.0-alpha.4 (2023-12-02)
21
76
 
22
77
  ### Feature
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  }
10
10
  ],
11
11
  "license": "MIT",
12
- "version": "18.0.0-alpha.4",
12
+ "version": "18.0.0-alpha.6",
13
13
  "repository": {
14
14
  "type": "git",
15
15
  "url": "git@github.com:plone/volto.git"
@@ -189,7 +189,7 @@
189
189
  "eslint-import-resolver-alias": "1.1.2",
190
190
  "eslint-import-resolver-babel-plugin-root-import": "1.1.1",
191
191
  "eslint-plugin-import": "2.28.1",
192
- "eslint-plugin-jsx-a11y": "6.7.1",
192
+ "eslint-plugin-jsx-a11y": "^6.7.1",
193
193
  "eslint-plugin-prettier": "5.0.0",
194
194
  "eslint-plugin-react": "7.33.2",
195
195
  "eslint-plugin-react-hooks": "4.6.0",
@@ -312,9 +312,9 @@
312
312
  "webpack-node-externals": "3.0.0",
313
313
  "xmlrpc": "1.3.2",
314
314
  "yarnhook": "0.5.1",
315
- "@plone/registry": "1.0.1",
316
- "@plone/scripts": "3.1.0",
317
- "@plone/volto-slate": "18.0.0-alpha.4"
315
+ "@plone/registry": "1.2.0",
316
+ "@plone/volto-slate": "18.0.0-alpha.5",
317
+ "@plone/scripts": "3.1.0"
318
318
  },
319
319
  "devDependencies": {
320
320
  "@jest/globals": "^29.7.0",
@@ -344,6 +344,7 @@
344
344
  "identity-obj-proxy": "3.0.0",
345
345
  "jest": "26.6.3",
346
346
  "jest-environment-jsdom": "^26",
347
+ "jsdom": "^16.7.0",
347
348
  "jsonwebtoken": "9.0.0",
348
349
  "react-error-overlay": "6.0.9",
349
350
  "react-is": "^16.13.1",
@@ -374,11 +375,13 @@
374
375
  "start:prod": "NODE_ENV=production node build/server.js",
375
376
  "prettier": "./node_modules/.bin/prettier --single-quote --check '{src,cypress}/**/*.{js,jsx,ts,tsx}' --check '*.js'",
376
377
  "prettier:fix": "./node_modules/.bin/prettier --single-quote --write '{src,cypress}/**/*.{js,jsx,ts,tsx}' --write '*.js'",
378
+ "prettier:husky": "prettier --single-quote --write",
377
379
  "stylelint": "./node_modules/.bin/stylelint 'theme/**/*.{css,less}' 'src/**/*.{css,less}'",
378
380
  "stylelint:overrides": "./node_modules/.bin/stylelint 'theme/**/*.overrides' 'src/**/*.overrides'",
379
381
  "stylelint:fix": "yarn stylelint --fix && yarn stylelint:overrides --fix",
380
382
  "lint": "./node_modules/eslint/bin/eslint.js --max-warnings=0 'src/**/*.{js,jsx,ts,tsx,json}'",
381
383
  "lint:fix": "./node_modules/eslint/bin/eslint.js --fix 'src/**/*.{js,jsx,ts,tsx,json}'",
384
+ "lint:husky": "eslint --max-warnings=0 --fix",
382
385
  "i18n": "rm -rf build/messages && NODE_ENV=production i18n",
383
386
  "i18n:ci": "pnpm i18n && git diff -G'^[^\"POT]' --exit-code",
384
387
  "typecheck": "tsc --project tsconfig.json --noEmit",
@@ -315,6 +315,9 @@ class Add extends Component {
315
315
  <Form
316
316
  ref={this.form}
317
317
  key="translated-or-new-content-form"
318
+ navRoot={
319
+ this.props.content?.['@components']?.navroot?.navroot || {}
320
+ }
318
321
  schema={this.props.schema}
319
322
  type={this.props.type}
320
323
  formData={{
@@ -334,6 +337,9 @@ class Add extends Component {
334
337
  // Copy the Language Independent Fields values from the to-be translated content
335
338
  // into the default values of the translated content Add form.
336
339
  ...lifData(),
340
+ parent: {
341
+ '@id': this.props.content?.['@id'] || '',
342
+ },
337
343
  }}
338
344
  requestError={this.state.error}
339
345
  onSubmit={this.onSubmit}
@@ -31,6 +31,8 @@ const BlockChooser = ({
31
31
  blocksConfig = config.blocks.blocksConfig,
32
32
  blockChooserRef,
33
33
  properties = {},
34
+ navRoot,
35
+ contentType,
34
36
  }) => {
35
37
  const intl = useIntl();
36
38
  const hasAllowedBlocks = !isEmpty(allowedBlocks);
@@ -55,7 +57,7 @@ const BlockChooser = ({
55
57
  // depending on this function, given properties (current present blocks) and the
56
58
  // block being evaluated
57
59
  return typeof item.restricted === 'function'
58
- ? !item.restricted({ properties, block: item })
60
+ ? !item.restricted({ properties, block: item, navRoot, contentType })
59
61
  : !item.restricted;
60
62
  }
61
63
  }
@@ -54,7 +54,10 @@ const BlockChooserButton = (props) => {
54
54
  blocksConfig,
55
55
  buttonComponent,
56
56
  properties,
57
+ navRoot,
58
+ contentType,
57
59
  } = props;
60
+
58
61
  const { disableNewBlocks } = data;
59
62
  const [addNewBlockOpened, setAddNewBlockOpened] = React.useState(false);
60
63
 
@@ -142,6 +145,8 @@ const BlockChooserButton = (props) => {
142
145
  properties={properties}
143
146
  showRestricted={showRestricted}
144
147
  ref={blockChooserRef}
148
+ navRoot={navRoot}
149
+ contentType={contentType}
145
150
  />
146
151
  </div>
147
152
  </Portal>
@@ -28,6 +28,8 @@ const BlocksForm = (props) => {
28
28
  pathname,
29
29
  onChangeField,
30
30
  properties,
31
+ type,
32
+ navRoot,
31
33
  onChangeFormData,
32
34
  selectedBlock,
33
35
  multiSelected,
@@ -260,6 +262,8 @@ const BlocksForm = (props) => {
260
262
  pathname,
261
263
  metadata,
262
264
  properties,
265
+ contentType: type,
266
+ navRoot,
263
267
  blocksConfig,
264
268
  selected: selectedBlock === childId,
265
269
  multiSelected: multiSelected?.includes(childId),
@@ -7,7 +7,7 @@ import DefaultBlockView from './DefaultView';
7
7
 
8
8
  const DefaultBlockEdit = (props) => {
9
9
  const { blocksConfig = config.blocks.blocksConfig } = props;
10
- const { data, onChangeBlock, block, selected } = props;
10
+ const { data, onChangeBlock, block, selected, navRoot, contentType } = props;
11
11
  const intl = useIntl();
12
12
  const blockSchema = blocksConfig?.[data['@type']]?.blockSchema;
13
13
  const schema =
@@ -32,6 +32,8 @@ const DefaultBlockEdit = (props) => {
32
32
  });
33
33
  }}
34
34
  formData={data}
35
+ navRoot={navRoot}
36
+ contentType={contentType}
35
37
  />
36
38
  </SidebarPortal>
37
39
  ) : (
@@ -3,6 +3,7 @@ import { Icon } from '@plone/volto/components';
3
3
  import {
4
4
  blockHasValue,
5
5
  buildStyleClassNamesFromData,
6
+ buildStyleObjectFromData,
6
7
  } from '@plone/volto/helpers';
7
8
  import dragSVG from '@plone/volto/icons/drag.svg';
8
9
  import { Button } from 'semantic-ui-react';
@@ -47,14 +48,18 @@ const EditBlockWrapper = (props) => {
47
48
  editable,
48
49
  properties,
49
50
  showBlockChooser,
51
+ navRoot,
52
+ contentType,
50
53
  } = blockProps;
54
+
51
55
  const visible = selected && !hideHandler(data);
52
56
 
53
57
  const required = isBoolean(data.required)
54
58
  ? data.required
55
59
  : includes(config.blocks.requiredBlocks, type);
56
60
 
57
- const styles = buildStyleClassNamesFromData(data.styles);
61
+ const classNames = buildStyleClassNamesFromData(data.styles);
62
+ const style = buildStyleObjectFromData(data.styles);
58
63
 
59
64
  return (
60
65
  <div
@@ -63,9 +68,10 @@ const EditBlockWrapper = (props) => {
63
68
  // Right now, we can have the alignment information in the styles property or in the
64
69
  // block data root, we inject the classname here for having control over the whole
65
70
  // Block Edit wrapper
66
- className={cx(`block-editor-${data['@type']}`, styles, {
71
+ className={cx(`block-editor-${data['@type']}`, classNames, {
67
72
  [data.align]: data.align,
68
73
  })}
74
+ style={style}
69
75
  >
70
76
  <div style={{ position: 'relative' }}>
71
77
  <div
@@ -107,6 +113,8 @@ const EditBlockWrapper = (props) => {
107
113
  blocksConfig={blocksConfig}
108
114
  size="24px"
109
115
  properties={properties}
116
+ navRoot={navRoot}
117
+ contentType={contentType}
110
118
  />
111
119
  )}
112
120
  </div>
@@ -3,7 +3,14 @@ import PropTypes from 'prop-types';
3
3
  import { injectIntl } from 'react-intl';
4
4
  import BlockDataForm from '@plone/volto/components/manage/Form/BlockDataForm';
5
5
 
6
- const Settings = ({ data, block, onChangeBlock, schema }) => {
6
+ const Settings = ({
7
+ data,
8
+ block,
9
+ onChangeBlock,
10
+ schema,
11
+ navRoot,
12
+ contentType,
13
+ }) => {
7
14
  return (
8
15
  <BlockDataForm
9
16
  schema={schema}
@@ -17,6 +24,8 @@ const Settings = ({ data, block, onChangeBlock, schema }) => {
17
24
  onChangeBlock={onChangeBlock}
18
25
  formData={data}
19
26
  applySchemaEnhancers={false}
27
+ navRoot={navRoot}
28
+ contentType={contentType}
20
29
  />
21
30
  );
22
31
  };
@@ -3,10 +3,12 @@ import cx from 'classnames';
3
3
  import {
4
4
  buildStyleClassNamesFromData,
5
5
  buildStyleClassNamesExtenders,
6
+ buildStyleObjectFromData,
6
7
  } from '@plone/volto/helpers';
7
8
 
8
9
  const StyleWrapper = (props) => {
9
- let classNames = [];
10
+ let classNames,
11
+ style = [];
10
12
  const { children, content, data = {}, block } = props;
11
13
  classNames = buildStyleClassNamesFromData(data.styles);
12
14
 
@@ -16,11 +18,15 @@ const StyleWrapper = (props) => {
16
18
  data,
17
19
  classNames,
18
20
  });
21
+
22
+ style = buildStyleObjectFromData(data.styles);
23
+
19
24
  const rewrittenChildren = React.Children.map(children, (child) => {
20
25
  if (React.isValidElement(child)) {
21
26
  const childProps = {
22
27
  ...props,
23
28
  className: cx([child.props.className, ...classNames]),
29
+ style: { ...child.props.style, ...style },
24
30
  };
25
31
  return React.cloneElement(child, childProps);
26
32
  }
@@ -2,7 +2,8 @@ import { useIntl } from 'react-intl';
2
2
  import { BlockDataForm } from '@plone/volto/components';
3
3
 
4
4
  const ContainerData = (props) => {
5
- const { block, blocksConfig, data, onChangeBlock } = props;
5
+ const { block, blocksConfig, data, onChangeBlock, navRoot, contentType } =
6
+ props;
6
7
  const intl = useIntl();
7
8
 
8
9
  const schema = blocksConfig[data['@type']].blockSchema({ intl });
@@ -25,6 +26,8 @@ const ContainerData = (props) => {
25
26
  block={block}
26
27
  onChangeBlock={onChangeBlock}
27
28
  blocksConfig={blocksConfig}
29
+ navRoot={navRoot}
30
+ contentType={contentType}
28
31
  />
29
32
  );
30
33
  };
@@ -5,7 +5,7 @@ import { withBlockExtensions } from '@plone/volto/helpers';
5
5
  import config from '@plone/volto/registry';
6
6
 
7
7
  const GridBlockView = (props) => {
8
- const { data, path, className } = props;
8
+ const { data, path, className, style } = props;
9
9
  const metadata = props.metadata || props.properties;
10
10
  const columns = data.blocks_layout.items;
11
11
  const blocksConfig =
@@ -22,6 +22,7 @@ const GridBlockView = (props) => {
22
22
  three: columns?.length === 3,
23
23
  four: columns?.length === 4,
24
24
  })}
25
+ style={style}
25
26
  >
26
27
  {data.headline && <h2 className="headline">{data.headline}</h2>}
27
28
 
@@ -4,7 +4,7 @@ import schemaHero from './schema.js';
4
4
  import { BlockDataForm } from '@plone/volto/components';
5
5
 
6
6
  const HeroImageLeftBlockData = (props) => {
7
- const { block, data, onChangeBlock } = props;
7
+ const { block, data, onChangeBlock, navRoot, contentType } = props;
8
8
  const intl = useIntl();
9
9
  const schema = schemaHero({ ...props, intl });
10
10
  return (
@@ -20,6 +20,8 @@ const HeroImageLeftBlockData = (props) => {
20
20
  onChangeBlock={onChangeBlock}
21
21
  formData={data}
22
22
  block={block}
23
+ navRoot={navRoot}
24
+ contentType={contentType}
23
25
  />
24
26
  );
25
27
  };
@@ -9,7 +9,8 @@ import imageSVG from '@plone/volto/icons/image.svg';
9
9
  import trashSVG from '@plone/volto/icons/delete.svg';
10
10
 
11
11
  const ImageSidebar = (props) => {
12
- const { blocksConfig, data, block, onChangeBlock } = props;
12
+ const { blocksConfig, data, block, onChangeBlock, navRoot, contentType } =
13
+ props;
13
14
  const intl = useIntl();
14
15
  const schema = ImageSchema({ formData: data, intl });
15
16
  return (
@@ -94,6 +95,8 @@ const ImageSidebar = (props) => {
94
95
  formData={data}
95
96
  block={block}
96
97
  blocksConfig={blocksConfig}
98
+ navRoot={navRoot}
99
+ contentType={contentType}
97
100
  />
98
101
  </>
99
102
  );
@@ -9,7 +9,7 @@ import {
9
9
  } from '@plone/volto/helpers';
10
10
  import config from '@plone/volto/registry';
11
11
 
12
- export const View = ({ className, data, detached, properties }) => {
12
+ export const View = ({ className, data, detached, properties, style }) => {
13
13
  const href = data?.href?.[0]?.['@id'] || '';
14
14
 
15
15
  const Image = config.getComponent({ name: 'Image' }).component;
@@ -25,6 +25,7 @@ export const View = ({ className, data, detached, properties }) => {
25
25
  data.align,
26
26
  className,
27
27
  )}
28
+ style={style}
28
29
  >
29
30
  {data.url && (
30
31
  <>
@@ -4,7 +4,8 @@ import { useIntl } from 'react-intl';
4
4
  import { BlockDataForm } from '@plone/volto/components';
5
5
 
6
6
  const ListingData = (props) => {
7
- const { data, block, blocksConfig, onChangeBlock } = props;
7
+ const { data, block, blocksConfig, onChangeBlock, navRoot, contentType } =
8
+ props;
8
9
  const intl = useIntl();
9
10
  const schema = blocksConfig.listing.blockSchema({
10
11
  ...props,
@@ -25,6 +26,8 @@ const ListingData = (props) => {
25
26
  formData={data}
26
27
  blocksConfig={blocksConfig}
27
28
  block={block}
29
+ navRoot={navRoot}
30
+ contentType={contentType}
28
31
  />
29
32
  );
30
33
  };
@@ -6,11 +6,12 @@ import { withBlockExtensions } from '@plone/volto/helpers';
6
6
  import { ListingBlockBody as ListingBody } from '@plone/volto/components';
7
7
 
8
8
  const View = (props) => {
9
- const { data, path, pathname, className } = props;
9
+ const { data, path, pathname, className, style } = props;
10
10
 
11
11
  return (
12
12
  <div
13
13
  className={cx('block listing', data.variation || 'default', className)}
14
+ style={style}
14
15
  >
15
16
  <ListingBody {...props} path={path ?? pathname} />
16
17
  </div>
@@ -18,7 +18,7 @@ const messages = defineMessages({
18
18
  });
19
19
 
20
20
  const MapsSidebar = (props) => {
21
- const { data, block, onChangeBlock } = props;
21
+ const { data, block, onChangeBlock, navRoot, contentType } = props;
22
22
  const intl = useIntl();
23
23
  const schema = MapsSchema({ ...props, intl });
24
24
 
@@ -42,6 +42,8 @@ const MapsSidebar = (props) => {
42
42
  onChangeBlock={onChangeBlock}
43
43
  formData={data}
44
44
  block={block}
45
+ navRoot={navRoot}
46
+ contentType={contentType}
45
47
  />
46
48
  )}
47
49
  </>
@@ -26,6 +26,8 @@ const SearchBlockEdit = (props) => {
26
26
  data,
27
27
  selected,
28
28
  intl,
29
+ navRoot,
30
+ contentType,
29
31
  onTriggerSearch,
30
32
  querystring = {},
31
33
  } = props;
@@ -83,6 +85,8 @@ const SearchBlockEdit = (props) => {
83
85
  }}
84
86
  onChangeBlock={onChangeBlock}
85
87
  formData={data}
88
+ navRoot={navRoot}
89
+ contentType={contentType}
86
90
  />
87
91
  </SidebarPortal>
88
92
  </>
@@ -96,9 +96,21 @@ function normalizeState({
96
96
  const { types: facetWidgetTypes } =
97
97
  config.blocks.blocksConfig.search.extensions.facetWidgets;
98
98
 
99
+ // Here, we are removing the QueryString of the Listing ones, which is present in the Facet
100
+ // because we already initialize the facet with those values.
101
+ const configuredFacets = facetSettings
102
+ ? facetSettings.map((facet) => facet?.field?.value)
103
+ : [];
104
+
105
+ let copyOfQuery = query.query ? [...query.query] : [];
106
+
107
+ const queryWithoutFacet = copyOfQuery.filter((query) => {
108
+ return !configuredFacets.includes(query.i);
109
+ });
110
+
99
111
  const params = {
100
112
  query: [
101
- ...(query.query || []),
113
+ ...(queryWithoutFacet || []),
102
114
  ...(facetSettings || []).map((facet) => {
103
115
  if (!facet?.field) return null;
104
116
 
@@ -261,14 +273,34 @@ const withSearch = (options) => (WrappedComponent) => {
261
273
  // eslint-disable-next-line react-hooks/exhaustive-deps
262
274
  const configuredFacets =
263
275
  data.facets?.map((facet) => facet?.field?.value) || [];
276
+
277
+ // Here we are getting the initial value of the facet if Listing Query contains the same criteria as
278
+ // facet.
279
+ const queryData = data?.query?.query
280
+ ? deserializeQuery(JSON.stringify(data?.query?.query))
281
+ : [];
282
+
283
+ let intializeFacetWithQueryValue = [];
284
+
285
+ for (let value of configuredFacets) {
286
+ const queryString = queryData.find((item) => item.i === value);
287
+ if (queryString) {
288
+ intializeFacetWithQueryValue = [
289
+ ...intializeFacetWithQueryValue,
290
+ { [queryString.i]: queryString.v },
291
+ ];
292
+ }
293
+ }
294
+
264
295
  const multiFacets = data.facets
265
296
  ?.filter((facet) => facet?.multiple)
266
297
  .map((facet) => facet?.field?.value);
267
298
  const [facets, setFacets] = React.useState(
268
299
  Object.assign(
269
300
  {},
270
- ...urlQuery.map(({ i, v }) => ({ [i]: v })), // TODO: the 'o' should be kept. This would be a major refactoring of the facets
271
-
301
+ ...urlQuery.map(({ i, v }) => ({ [i]: v })),
302
+ // TODO: the 'o' should be kept. This would be a major refactoring of the facets
303
+ ...intializeFacetWithQueryValue,
272
304
  // support for simple filters like ?Subject=something
273
305
  // TODO: since the move to hash params this is no longer working.
274
306
  // We'd have to treat the location.search and manage it just like the
@@ -288,8 +320,17 @@ const withSearch = (options) => (WrappedComponent) => {
288
320
  );
289
321
  const previousUrlQuery = usePrevious(urlQuery);
290
322
 
323
+ // During first render the previousUrlQuery is undefined and urlQuery
324
+ // is empty so it ressetting the facet when you are navigating but during reload we have urlQuery and we need
325
+ // to set the facet at first render.
326
+ const preventOverrideOfFacetState =
327
+ previousUrlQuery === undefined && urlQuery.length === 0;
328
+
291
329
  React.useEffect(() => {
292
- if (!isEqual(urlQuery, previousUrlQuery)) {
330
+ if (
331
+ !isEqual(urlQuery, previousUrlQuery) &&
332
+ !preventOverrideOfFacetState
333
+ ) {
293
334
  setFacets(
294
335
  Object.assign(
295
336
  {},
@@ -319,6 +360,7 @@ const withSearch = (options) => (WrappedComponent) => {
319
360
  locationSearchData,
320
361
  multiFacets,
321
362
  previousUrlQuery,
363
+ preventOverrideOfFacetState,
322
364
  ]);
323
365
 
324
366
  const [sortOn, setSortOn] = React.useState(data?.query?.sort_on);
@@ -14,7 +14,8 @@ const messages = defineMessages({
14
14
  });
15
15
 
16
16
  const TeaserData = (props) => {
17
- const { block, blocksConfig, data, onChangeBlock } = props;
17
+ const { block, blocksConfig, data, onChangeBlock, navRoot, contentType } =
18
+ props;
18
19
  const intl = useIntl();
19
20
 
20
21
  const reset = () => {
@@ -64,6 +65,8 @@ const TeaserData = (props) => {
64
65
  block={block}
65
66
  blocksConfig={blocksConfig}
66
67
  headerActions={HeaderActions}
68
+ navRoot={navRoot}
69
+ contentType={contentType}
67
70
  />
68
71
  );
69
72
  };
@@ -18,7 +18,7 @@ const messages = defineMessages({
18
18
  });
19
19
 
20
20
  const TeaserDefaultTemplate = (props) => {
21
- const { className, data, isEditMode } = props;
21
+ const { className, data, isEditMode, style } = props;
22
22
  const intl = useIntl();
23
23
  const href = data.href?.[0];
24
24
  const image = data.preview_image?.[0];
@@ -27,7 +27,7 @@ const TeaserDefaultTemplate = (props) => {
27
27
  const { openExternalLinkInNewTab } = config.settings;
28
28
 
29
29
  return (
30
- <div className={cx('block teaser', className)}>
30
+ <div className={cx('block teaser', className)} style={style}>
31
31
  <>
32
32
  {!href && isEditMode && (
33
33
  <Message>
@@ -27,6 +27,8 @@ class Edit extends Component {
27
27
  onChangeBlock={this.props.onChangeBlock}
28
28
  formData={this.props.data}
29
29
  block={this.props.block}
30
+ navRoot={this.props.navRoot}
31
+ contentType={this.props.contentType}
30
32
  />
31
33
  </SidebarPortal>
32
34
  </>
@@ -18,7 +18,7 @@ const messages = defineMessages({
18
18
  });
19
19
 
20
20
  const VideoSidebar = (props) => {
21
- const { data, block, onChangeBlock } = props;
21
+ const { data, block, onChangeBlock, navRoot, contentType } = props;
22
22
  const intl = useIntl();
23
23
  const schema = VideoBlockSchema({ ...props, intl });
24
24
 
@@ -42,6 +42,8 @@ const VideoSidebar = (props) => {
42
42
  onChangeBlock={onChangeBlock}
43
43
  formData={data}
44
44
  block={block}
45
+ navRoot={navRoot}
46
+ contentType={contentType}
45
47
  />
46
48
  )}
47
49
  </>
@@ -286,6 +286,7 @@ class Edit extends Component {
286
286
  <Form
287
287
  isEditForm
288
288
  ref={this.form}
289
+ navRoot={this.props.content?.['@components']?.navroot?.navroot || {}}
289
290
  schema={this.props.schema}
290
291
  type={this.props.content?.['@type']}
291
292
  formData={this.props.content}