@eeacms/volto-eea-website-policy 1.6.3 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,31 @@ All notable changes to this project will be documented in this file. Dates are d
4
4
 
5
5
  Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
6
 
7
+ ### [1.7.1](https://github.com/eea/volto-eea-website-policy/compare/1.7.0...1.7.1) - 24 July 2023
8
+
9
+ #### :rocket: New Features
10
+
11
+ - feat: Add IMSv4 custom widgets - refs #145772 [Alin Voinea - [`367f0b6`](https://github.com/eea/volto-eea-website-policy/commit/367f0b611d6f69f217b1b0aaa25783968b8911ba)]
12
+
13
+ #### :house: Internal changes
14
+
15
+ - chore: Disable InstitutionalMandate DataProvenance widgets for now as there are issues - refs #160747 [Alin Voinea - [`bbdc3fb`](https://github.com/eea/volto-eea-website-policy/commit/bbdc3fb85a6ebd04205d763a75a1288f00efa634)]
16
+
17
+ #### :hammer_and_wrench: Others
18
+
19
+ - test: add unit tests - refs #254313 [ana-oprea - [`b51c1a9`](https://github.com/eea/volto-eea-website-policy/commit/b51c1a95f6a0624e75d168627d80009762ac4803)]
20
+ ### [1.7.0](https://github.com/eea/volto-eea-website-policy/compare/1.6.3...1.7.0) - 16 June 2023
21
+
22
+ #### :house: Internal changes
23
+
24
+ - chore: Move IMS dataFigure to data_visualizations group - refs #253827 [Alin Voinea - [`0d782f9`](https://github.com/eea/volto-eea-website-policy/commit/0d782f90c72080f48f14f5f28a6ef63fba12cc7c)]
25
+
26
+ #### :hammer_and_wrench: Others
27
+
28
+ - Release 1.7.0 [Alin Voinea - [`93c05fa`](https://github.com/eea/volto-eea-website-policy/commit/93c05fae93b075223ef3f232963b7b4c9c682f42)]
29
+ - fix overrideBlocks [Miu Razvan - [`6e1a27e`](https://github.com/eea/volto-eea-website-policy/commit/6e1a27e15d1576643be6b88d2b8e888a538fc6e5)]
30
+ - call appendGroup with all parameters [Miu Razvan - [`09a914e`](https://github.com/eea/volto-eea-website-policy/commit/09a914e695c0f05a3076c2e7ae5c708dac2a7787)]
31
+ - changed gropup of plotly to data_visualizations [Miu Razvan - [`6974dc4`](https://github.com/eea/volto-eea-website-policy/commit/6974dc4126d876510bb8ec63732bf350cf79d1ab)]
7
32
  ### [1.6.3](https://github.com/eea/volto-eea-website-policy/compare/1.6.2...1.6.3) - 13 June 2023
8
33
 
9
34
  #### :bug: Bug Fixes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-eea-website-policy",
3
- "version": "1.6.3",
3
+ "version": "1.7.1",
4
4
  "description": "@eeacms/volto-eea-website-policy: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: IDM2 A-Team",
@@ -0,0 +1,64 @@
1
+ import React from 'react';
2
+ import { render, fireEvent } from '@testing-library/react';
3
+ import ContextNavigationEdit from './ContextNavigationEdit';
4
+ import { Router } from 'react-router-dom';
5
+ import { createMemoryHistory } from 'history';
6
+ import '@testing-library/jest-dom/extend-expect';
7
+
8
+ jest.mock('@plone/volto/components', () => ({
9
+ InlineForm: ({ onChangeField }) => (
10
+ <div>
11
+ <p>InlineForm</p>
12
+ <input id="test" onChange={onChangeField} />
13
+ </div>
14
+ ),
15
+ SidebarPortal: ({ children }) => (
16
+ <div>
17
+ <div>SidebarPortal</div>
18
+ {children}
19
+ </div>
20
+ ),
21
+ }));
22
+
23
+ jest.mock('@plone/volto/components/theme/Navigation/ContextNavigation', () => {
24
+ return {
25
+ __esModule: true,
26
+ default: ({ params }) => {
27
+ return <div>ConnectedContextNavigation {params.root_path}</div>;
28
+ },
29
+ };
30
+ });
31
+
32
+ describe('ContextNavigationEdit', () => {
33
+ it('renders corectly', () => {
34
+ const history = createMemoryHistory();
35
+ const { getByText, queryByText } = render(
36
+ <Router history={history}>
37
+ <ContextNavigationEdit />
38
+ </Router>,
39
+ );
40
+
41
+ expect(getByText('Context navigation')).toBeInTheDocument();
42
+ expect(getByText('ConnectedContextNavigation')).toBeInTheDocument();
43
+ expect(queryByText('InlineForm')).toBeNull();
44
+ expect(getByText('SidebarPortal')).toBeInTheDocument();
45
+ });
46
+
47
+ it('renders corectly', () => {
48
+ const history = createMemoryHistory();
49
+ const { container, getByText } = render(
50
+ <Router history={history}>
51
+ <ContextNavigationEdit selected={true} onChangeBlock={() => {}} />
52
+ </Router>,
53
+ );
54
+
55
+ expect(getByText('Context navigation')).toBeInTheDocument();
56
+ expect(getByText('ConnectedContextNavigation')).toBeInTheDocument();
57
+ expect(getByText('InlineForm')).toBeInTheDocument();
58
+ expect(getByText('SidebarPortal')).toBeInTheDocument();
59
+
60
+ fireEvent.change(container.querySelector('#test'), {
61
+ target: { value: 'test' },
62
+ });
63
+ });
64
+ });
@@ -0,0 +1,50 @@
1
+ import React from 'react';
2
+ import { render } from '@testing-library/react';
3
+ import ContextNavigationView from './ContextNavigationView';
4
+ import { Router } from 'react-router-dom';
5
+ import { createMemoryHistory } from 'history';
6
+ import '@testing-library/jest-dom/extend-expect';
7
+
8
+ jest.mock('@plone/volto/components/theme/Navigation/ContextNavigation', () => {
9
+ return {
10
+ __esModule: true,
11
+ default: ({ params }) => {
12
+ return <div>ConnectedContextNavigation {params.root_path}</div>;
13
+ },
14
+ };
15
+ });
16
+
17
+ describe('ContextNavigationView', () => {
18
+ let history;
19
+ beforeEach(() => {
20
+ history = createMemoryHistory();
21
+ });
22
+
23
+ it('renders corectly', () => {
24
+ const { container } = render(
25
+ <Router history={history}>
26
+ <ContextNavigationView />
27
+ </Router>,
28
+ );
29
+
30
+ expect(container.firstChild).toHaveTextContent(
31
+ 'ConnectedContextNavigation',
32
+ );
33
+ });
34
+
35
+ it('renders corectly', () => {
36
+ const { container } = render(
37
+ <Router history={history}>
38
+ <ContextNavigationView
39
+ data={{
40
+ navProps: { root_path: 'https://localhost:3000/test' },
41
+ root_node: [{ '@id': 'root_node' }],
42
+ }}
43
+ />
44
+ </Router>,
45
+ );
46
+ expect(container.firstChild).toHaveTextContent(
47
+ 'ConnectedContextNavigation root_node',
48
+ );
49
+ });
50
+ });
@@ -0,0 +1,6 @@
1
+ // import React from 'react';
2
+ // import RichTextWidget from '@plone/volto-slate/widgets/RichTextWidget';
3
+
4
+ export const DataProvenance = () =>
5
+ // <RichTextWidget {...props} readOnly={true} />
6
+ ' Data Provenance ';
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import cx from 'classnames';
3
+
4
+ export const FrequencyOfDissemination = ({ value, children, className }) => {
5
+ if (!value) {
6
+ return '';
7
+ }
8
+
9
+ const text = value > 1 ? `Every ${value} years` : 'Once a year';
10
+ return (
11
+ <span className={cx(className, 'text', 'widget')}>
12
+ {children ? children(text) : text}
13
+ </span>
14
+ );
15
+ };
@@ -0,0 +1,6 @@
1
+ // import React from 'react';
2
+ // import RichTextWidget from '@plone/volto-slate/widgets/RichTextWidget';
3
+
4
+ export const InstitutionalMandate = () =>
5
+ // <RichTextWidget {...props} readOnly={true} />
6
+ ' Institutional Mandate ';
package/src/helpers.js CHANGED
@@ -9,3 +9,21 @@ export const createSlateParagraph = (text) => {
9
9
  export const serializeText = (text) => {
10
10
  return isArray(text) ? serializeNodes(text) : text;
11
11
  };
12
+
13
+ export const appendGroup = (config, id, title) => {
14
+ const groupExists =
15
+ config.blocks.groupBlocksOrder.filter((group) => group.id === id).length >
16
+ 0;
17
+
18
+ if (!groupExists) {
19
+ config.blocks.groupBlocksOrder = [
20
+ ...config.blocks.groupBlocksOrder,
21
+ {
22
+ id,
23
+ title,
24
+ },
25
+ ];
26
+ }
27
+
28
+ return config.blocks.groupBlocksOrder;
29
+ };
@@ -0,0 +1,86 @@
1
+ import * as helpers from './helpers';
2
+ import config from '@plone/volto/registry';
3
+ import { serializeNodes } from '@plone/volto-slate/editor/render';
4
+ import { isArray } from 'lodash';
5
+ import '@testing-library/jest-dom/extend-expect';
6
+
7
+ jest.mock('@plone/volto/registry', () => ({
8
+ settings: {
9
+ slate: {
10
+ defaultValue: jest.fn(),
11
+ },
12
+ },
13
+ blocks: {
14
+ groupBlocksOrder: [
15
+ { id: 'group1', title: 'Group1' },
16
+ { id: 'group2', title: 'Group2' },
17
+ ],
18
+ },
19
+ }));
20
+
21
+ jest.mock('@plone/volto-slate/editor/render', () => ({
22
+ serializeNodes: jest.fn(),
23
+ }));
24
+
25
+ describe('createSlateParagraph', () => {
26
+ it('should return default value when input is not an array', () => {
27
+ const input = 'test';
28
+ helpers.createSlateParagraph(input);
29
+ expect(config.settings.slate.defaultValue).toHaveBeenCalledTimes(1);
30
+ });
31
+
32
+ it('should return input when input is an array', () => {
33
+ const input = ['test'];
34
+ const result = helpers.createSlateParagraph(input);
35
+ expect(result).toBe(input);
36
+ });
37
+ });
38
+
39
+ describe('serializeText', () => {
40
+ beforeEach(() => {
41
+ jest.resetAllMocks();
42
+ });
43
+
44
+ it('should return the text when it is not an array', () => {
45
+ const text = 'Hello, World!';
46
+
47
+ expect(helpers.serializeText(text)).toEqual(text);
48
+ expect(isArray(text)).toBe(false);
49
+ expect(serializeNodes).not.toHaveBeenCalled();
50
+ });
51
+
52
+ it('should call serializeNodes when text is an array', () => {
53
+ const text = ['Hello', 'World!'];
54
+
55
+ helpers.serializeText(text);
56
+ expect(isArray(text)).toBe(true);
57
+ expect(serializeNodes).toHaveBeenCalledWith(text);
58
+ });
59
+ });
60
+
61
+ describe('appendGroup', () => {
62
+ beforeEach(() => {
63
+ jest.resetAllMocks();
64
+ });
65
+
66
+ it('should return the text when it is not an array', () => {
67
+ const id = 'group2';
68
+ const title = 'Group2';
69
+ const result = helpers.appendGroup(config, id, title);
70
+ expect(result).toEqual([
71
+ { id: 'group1', title: 'Group1' },
72
+ { id: 'group2', title: 'Group2' },
73
+ ]);
74
+ });
75
+
76
+ it('should return the text when it is not an array', () => {
77
+ const id = 'group3';
78
+ const title = 'Group3';
79
+ const result = helpers.appendGroup(config, id, title);
80
+ expect(result).toEqual([
81
+ { id: 'group1', title: 'Group1' },
82
+ { id: 'group2', title: 'Group2' },
83
+ { id, title },
84
+ ]);
85
+ });
86
+ });
package/src/index.js CHANGED
@@ -1,10 +1,12 @@
1
1
  import { runtimeConfig } from '@plone/volto/runtime_config';
2
2
  import installContextNavigationBlock from '@eeacms/volto-eea-website-policy/components/Blocks/ContextNavigation';
3
+ import { appendGroup } from './helpers';
4
+ import { FrequencyOfDissemination } from '@eeacms/volto-eea-website-policy/components/Widgets/FrequencyOfDissemination';
5
+ import { DataProvenance } from '@eeacms/volto-eea-website-policy/components/Widgets/DataProvenance';
6
+ import { InstitutionalMandate } from '@eeacms/volto-eea-website-policy/components/Widgets/InstitutionalMandate';
3
7
 
4
8
  const restrictedBlocks = [
5
9
  'imagecards',
6
- 'embed_eea_tableau_block',
7
- 'embed_eea_map_block',
8
10
  // TODO: use what is needed from volto-datablocks after clean-up
9
11
  'conditionalDataBlock',
10
12
  'countryFlag',
@@ -15,6 +17,21 @@ const restrictedBlocks = [
15
17
  'simpleDataConnectedTable',
16
18
  ];
17
19
 
20
+ const overrideBlocks = {
21
+ embed_tableau_visualization: {
22
+ group: 'data_visualizations',
23
+ },
24
+ tableau_block: {
25
+ group: 'data_visualizations',
26
+ },
27
+ embed_eea_map_block: {
28
+ group: 'data_visualizations',
29
+ },
30
+ dataFigure: {
31
+ group: 'data_visualizations',
32
+ },
33
+ };
34
+
18
35
  const applyConfig = (config) => {
19
36
  // #158717#note-25 any path that isn't static, en or controlpanel is treated as external
20
37
  const notInEN = /^(?!(#|\/en|\/static|\/controlpanel|\/cypress|\/login|\/logout|\/contact-form)).*$/;
@@ -78,6 +95,13 @@ const applyConfig = (config) => {
78
95
  config,
79
96
  );
80
97
 
98
+ // Add groups
99
+ config.blocks.groupBlocksOrder = appendGroup(
100
+ config,
101
+ 'data_visualizations',
102
+ 'Data Visualizations (Beta)',
103
+ );
104
+
81
105
  // Disable some blocks
82
106
  restrictedBlocks.forEach((block) => {
83
107
  if (config.blocks.blocksConfig[block]) {
@@ -85,6 +109,22 @@ const applyConfig = (config) => {
85
109
  }
86
110
  });
87
111
 
112
+ // Override blocks config
113
+ Object.keys(overrideBlocks).forEach((block) => {
114
+ if (config.blocks.blocksConfig[block]) {
115
+ config.blocks.blocksConfig[block] = {
116
+ ...config.blocks.blocksConfig[block],
117
+ ...overrideBlocks[block],
118
+ };
119
+ }
120
+ });
121
+
122
+ // Custom widgets
123
+ config.widgets.id.data_provenance = DataProvenance;
124
+ config.widgets.id.institutional_mandate = InstitutionalMandate;
125
+ config.widgets.views.id.frequency_of_dissemination = FrequencyOfDissemination;
126
+
127
+ // Subsite
88
128
  config.settings.apiExpanders = [
89
129
  ...config.settings.apiExpanders,
90
130
  {