@eeacms/volto-tableau 7.0.2 → 7.0.3

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,7 +4,16 @@ 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
- ### [7.0.2](https://github.com/eea/volto-tableau/compare/7.0.1...7.0.2) - 28 November 2023
7
+ ### [7.0.3](https://github.com/eea/volto-tableau/compare/7.0.2...7.0.3) - 29 November 2023
8
+
9
+ #### :hammer_and_wrench: Others
10
+
11
+ - fix tests [Miu Razvan - [`01eebe9`](https://github.com/eea/volto-tableau/commit/01eebe9580fdf85a8ca64a5a7f3970d93a7dd73f)]
12
+ - update tests [Miu Razvan - [`c0897ea`](https://github.com/eea/volto-tableau/commit/c0897eacff0afe9458faf991276f250bba807269)]
13
+ - fix tests [Miu Razvan - [`096203b`](https://github.com/eea/volto-tableau/commit/096203bb5b70f97e2fed381308afd727767477fb)]
14
+ - update cypress [Miu Razvan - [`d5cb322`](https://github.com/eea/volto-tableau/commit/d5cb3222e0a316d2627cade3d2534942264b24ac)]
15
+ - update [Miu Razvan - [`0df72ba`](https://github.com/eea/volto-tableau/commit/0df72babc50e4d092d3cb2d80e720202dc2e95be)]
16
+ ### [7.0.2](https://github.com/eea/volto-tableau/compare/7.0.1...7.0.2) - 29 November 2023
8
17
 
9
18
  #### :bug: Bug Fixes
10
19
 
@@ -30,16 +30,11 @@ describe('Blocks Tests', () => {
30
30
  // when I add a maps block
31
31
  cy.addNewBlock('tableau');
32
32
 
33
- cy.get(`.sidebar-container .field-wrapper-url #field-url`).type(
34
- 'https://tableau-public.discomap.eea.europa.eu/views/GHGProjections/Dashboard1&:jsdebug=n',
35
- );
33
+ cy.get(
34
+ `.sidebar-container .field-wrapper-tableau_vis_url #field-tableau_vis_url`,
35
+ ).type('/path/to/dashboard');
36
36
  cy.get('#toolbar-save').click();
37
37
  cy.wait('@content');
38
38
  cy.url().should('eq', Cypress.config().baseUrl + '/cypress/my-page');
39
-
40
- // then the page view should contain the maps block
41
- cy.get('#page-document iframe')
42
- .should('have.attr', 'src')
43
- .and('match', /\/\/tableau-public.discomap.eea.europa.eu\//);
44
39
  });
45
40
  });
@@ -9,15 +9,19 @@ module.exports = {
9
9
  '@plone/volto/cypress': '<rootDir>/node_modules/@plone/volto/cypress',
10
10
  '@plone/volto/babel': '<rootDir>/node_modules/@plone/volto/babel',
11
11
  '@plone/volto/(.*)$': '<rootDir>/node_modules/@plone/volto/src/$1',
12
- '@package/(.*)$': '<rootDir>/src/$1',
12
+ '@package/(.*)$': '<rootDir>/node_modules/@plone/volto/src/$1',
13
+ '@root/(.*)$': '<rootDir>/node_modules/@plone/volto/src/$1',
13
14
  '@plone/volto-quanta/(.*)$': '<rootDir>/src/addons/volto-quanta/src/$1',
14
15
  '@eeacms/(.*?)/(.*)$': '<rootDir>/node_modules/@eeacms/$1/src/$2',
15
- '@plone/volto-slate':
16
- '<rootDir>/node_modules/@plone/volto/packages/volto-slate/src',
16
+ '@plone/volto-slate/(.*)$':
17
+ '<rootDir>/node_modules/@plone/volto/packages/volto-slate/src/$1',
17
18
  '~/(.*)$': '<rootDir>/src/$1',
18
19
  'load-volto-addons':
19
20
  '<rootDir>/node_modules/@plone/volto/jest-addons-loader.js',
20
21
  },
22
+ transformIgnorePatterns: [
23
+ '/node_modules/(?!(@plone|@root|@package|@eeacms)/).*/',
24
+ ],
21
25
  transform: {
22
26
  '^.+\\.js(x)?$': 'babel-jest',
23
27
  '^.+\\.(png)$': 'jest-file',
@@ -32,4 +36,7 @@ module.exports = {
32
36
  statements: 5,
33
37
  },
34
38
  },
39
+ setupFilesAfterEnv: [
40
+ '<rootDir>/node_modules/@eeacms/volto-tableau/jest.setup.js',
41
+ ],
35
42
  };
package/jest.setup.js ADDED
@@ -0,0 +1,49 @@
1
+ import { jest } from '@jest/globals';
2
+ import configureStore from 'redux-mock-store';
3
+
4
+ const mockStore = configureStore();
5
+
6
+ global.store = mockStore({
7
+ intl: {
8
+ locale: 'en',
9
+ messages: {},
10
+ },
11
+ content: {
12
+ create: {},
13
+ subrequests: [],
14
+ },
15
+ connected_data_parameters: {},
16
+ });
17
+
18
+ const mockSemanticComponents = jest.requireActual('semantic-ui-react');
19
+ const mockComponents = jest.requireActual('@plone/volto/components');
20
+
21
+ jest.mock('semantic-ui-react', () => ({
22
+ ...mockSemanticComponents,
23
+ Popup: ({ content, trigger }) => {
24
+ return (
25
+ <div className="popup">
26
+ <div className="trigger">{trigger}</div>
27
+ <div className="content">{content}</div>
28
+ </div>
29
+ );
30
+ },
31
+ }));
32
+
33
+ jest.doMock('@plone/volto/components', () => {
34
+ return {
35
+ __esModule: true,
36
+ ...mockComponents,
37
+ Toast: ({ children }) => <div className="toast">{children}</div>,
38
+ SidebarPortal: ({ children }) => <div id="sidebar">{children}</div>,
39
+ UniversalLink: ({ children, href }) => {
40
+ return <a href={href}>{children}</a>;
41
+ },
42
+ };
43
+ });
44
+
45
+ global.fetch = jest.fn(() =>
46
+ Promise.resolve({
47
+ json: () => Promise.resolve({}),
48
+ }),
49
+ );
@@ -11,4 +11,12 @@ msgstr ""
11
11
  "Content-Transfer-Encoding: \n"
12
12
  "Plural-Forms: \n"
13
13
 
14
+ #: Blocks/EmbedTableauVisualization/schema
15
+ # defaultMessage: CSS height
16
+ msgid "CSS height"
17
+ msgstr ""
14
18
 
19
+ #: Blocks/EmbedTableauVisualization/schema
20
+ # defaultMessage: Tableau height
21
+ msgid "Tableau height"
22
+ msgstr ""
@@ -11,4 +11,12 @@ msgstr ""
11
11
  "Content-Transfer-Encoding: \n"
12
12
  "Plural-Forms: \n"
13
13
 
14
+ #: Blocks/EmbedTableauVisualization/schema
15
+ # defaultMessage: CSS height
16
+ msgid "CSS height"
17
+ msgstr ""
14
18
 
19
+ #: Blocks/EmbedTableauVisualization/schema
20
+ # defaultMessage: Tableau height
21
+ msgid "Tableau height"
22
+ msgstr ""
@@ -11,4 +11,12 @@ msgstr ""
11
11
  "Content-Transfer-Encoding: \n"
12
12
  "Plural-Forms: \n"
13
13
 
14
+ #: Blocks/EmbedTableauVisualization/schema
15
+ # defaultMessage: CSS height
16
+ msgid "CSS height"
17
+ msgstr ""
14
18
 
19
+ #: Blocks/EmbedTableauVisualization/schema
20
+ # defaultMessage: Tableau height
21
+ msgid "Tableau height"
22
+ msgstr ""
@@ -11,4 +11,12 @@ msgstr ""
11
11
  "Content-Transfer-Encoding: \n"
12
12
  "Plural-Forms: \n"
13
13
 
14
+ #: Blocks/EmbedTableauVisualization/schema
15
+ # defaultMessage: CSS height
16
+ msgid "CSS height"
17
+ msgstr ""
14
18
 
19
+ #: Blocks/EmbedTableauVisualization/schema
20
+ # defaultMessage: Tableau height
21
+ msgid "Tableau height"
22
+ msgstr ""
package/locales/volto.pot CHANGED
@@ -1,7 +1,7 @@
1
1
  msgid ""
2
2
  msgstr ""
3
3
  "Project-Id-Version: Plone\n"
4
- "POT-Creation-Date: 2023-06-28T10:48:22.678Z\n"
4
+ "POT-Creation-Date: 2023-11-29T13:30:10.494Z\n"
5
5
  "Last-Translator: Plone i18n <plone-i18n@lists.sourceforge.net>\n"
6
6
  "Language-Team: Plone i18n <plone-i18n@lists.sourceforge.net>\n"
7
7
  "MIME-Version: 1.0\n"
@@ -13,4 +13,12 @@ msgstr ""
13
13
  "Preferred-Encodings: utf-8\n"
14
14
  "Domain: volto\n"
15
15
 
16
+ #: Blocks/EmbedTableauVisualization/schema
17
+ # defaultMessage: CSS height
18
+ msgid "CSS height"
19
+ msgstr ""
16
20
 
21
+ #: Blocks/EmbedTableauVisualization/schema
22
+ # defaultMessage: Tableau height
23
+ msgid "Tableau height"
24
+ msgstr ""
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-tableau",
3
- "version": "7.0.2",
3
+ "version": "7.0.3",
4
4
  "description": "@eeacms/volto-tableau: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: IDM2 A-Team",
@@ -1,4 +1,6 @@
1
1
  import React from 'react';
2
+ import { compose } from 'redux';
3
+ import { injectIntl } from 'react-intl';
2
4
  import BlockDataForm from '@plone/volto/components/manage/Form/BlockDataForm';
3
5
  import { SidebarPortal } from '@plone/volto/components';
4
6
  import getSchema from './schema';
@@ -6,27 +8,28 @@ import getSchema from './schema';
6
8
  import View from './View';
7
9
 
8
10
  const Edit = (props) => {
11
+ const { block, data, selected, onChangeBlock } = props;
9
12
  const schema = React.useMemo(() => getSchema(props), [props]);
10
13
 
11
14
  return (
12
15
  <React.Fragment>
13
16
  <View mode="edit" {...props} />
14
- <SidebarPortal selected={props.selected}>
17
+ <SidebarPortal selected={selected}>
15
18
  <BlockDataForm
16
- block={props.block}
19
+ block={block}
17
20
  schema={schema}
18
21
  title={schema.title}
19
22
  onChangeField={(id, value) => {
20
- props.onChangeBlock(props.block, {
21
- ...props.data,
23
+ onChangeBlock(block, {
24
+ ...data,
22
25
  [id]: value,
23
26
  });
24
27
  }}
25
- formData={props.data}
28
+ formData={data}
26
29
  />
27
30
  </SidebarPortal>
28
31
  </React.Fragment>
29
32
  );
30
33
  };
31
34
 
32
- export default Edit;
35
+ export default compose(injectIntl)(Edit);
@@ -1,6 +1,5 @@
1
1
  import React from 'react';
2
2
  import renderer from 'react-test-renderer';
3
- import configureStore from 'redux-mock-store';
4
3
  import { Provider } from 'react-intl-redux';
5
4
  import config from '@plone/volto/registry';
6
5
 
@@ -9,45 +8,6 @@ import installEmbedTableau from '.';
9
8
 
10
9
  installEmbedTableau(config);
11
10
 
12
- const mockStore = configureStore([]);
13
-
14
- window.URL.createObjectURL = jest.fn(() => 'test');
15
-
16
- jest.mock('@plone/volto/components', () => ({
17
- Icon: ({ children }) => <img alt="incon">{children}</img>,
18
- Toast: ({ children }) => <p>{children}</p>,
19
- SidebarPortal: jest.requireActual(
20
- '@plone/volto/components/manage/Sidebar/SidebarPortal',
21
- ).default,
22
- }));
23
-
24
- jest.mock('@eeacms/volto-matomo/utils', () => ({
25
- trackLink: jest.fn(),
26
- }));
27
-
28
- jest.mock(
29
- '@eeacms/volto-embed/PrivacyProtection/PrivacyProtection',
30
- () => ({ children }) => {
31
- return children;
32
- },
33
- );
34
-
35
- jest.mock('@eeacms/volto-embed/helpers', () => ({
36
- pickMetadata: (data) => data,
37
- }));
38
-
39
- const store = mockStore({
40
- intl: {
41
- locale: 'en',
42
- messages: {},
43
- },
44
- content: {
45
- create: {},
46
- subrequests: [],
47
- },
48
- connected_data_parameters: {},
49
- });
50
-
51
11
  describe('Edit', () => {
52
12
  const data = {
53
13
  '@type': 'embed_tableau_visualization',
@@ -63,7 +23,7 @@ describe('Edit', () => {
63
23
 
64
24
  it('should render the component', () => {
65
25
  const component = renderer.create(
66
- <Provider store={store}>
26
+ <Provider store={global.store}>
67
27
  <Edit
68
28
  id="my-tableau"
69
29
  data={data}
@@ -78,6 +38,7 @@ describe('Edit', () => {
78
38
  onFocusNextBlock={() => {}}
79
39
  handleKeyDown={() => {}}
80
40
  content={{}}
41
+ useVisibilitySensor={false}
81
42
  />
82
43
  </Provider>,
83
44
  );
@@ -24,7 +24,7 @@ function getTableauVisualization(props) {
24
24
  }
25
25
 
26
26
  const View = (props) => {
27
- const { isBlock, id, mode, data, getContent } = props;
27
+ const { isBlock, id, mode, data, getContent, useVisibilitySensor } = props;
28
28
  const {
29
29
  with_notes = true,
30
30
  with_sources = true,
@@ -32,7 +32,7 @@ const View = (props) => {
32
32
  with_download = true,
33
33
  with_share = true,
34
34
  with_enlarge = true,
35
- tableau_height = 700,
35
+ tableau_height,
36
36
  } = data;
37
37
 
38
38
  const tableau_vis_url = flattenToAppURL(data.tableau_vis_url || '');
@@ -60,17 +60,19 @@ const View = (props) => {
60
60
  <PrivacyProtection
61
61
  {...props}
62
62
  data={{ ...data, url: tableau_visualization?.url }}
63
+ useVisibilitySensor={useVisibilitySensor}
63
64
  >
64
65
  <Tableau
65
66
  data={{
66
67
  ...tableau_visualization,
68
+ tableau_height:
69
+ tableau_height || tableau_visualization.tableau_height,
67
70
  with_notes,
68
71
  with_sources,
69
72
  with_more_info,
70
73
  with_download,
71
74
  with_share,
72
75
  with_enlarge,
73
- tableau_height,
74
76
  tableau_vis_url,
75
77
  }}
76
78
  />
@@ -1,45 +1,8 @@
1
1
  import React from 'react';
2
2
  import renderer from 'react-test-renderer';
3
- import configureStore from 'redux-mock-store';
4
3
  import { Provider } from 'react-intl-redux';
5
4
  import View from './View';
6
5
 
7
- const mockStore = configureStore([]);
8
-
9
- window.URL.createObjectURL = jest.fn(() => 'test');
10
-
11
- jest.mock('@plone/volto/components', () => ({
12
- Icon: ({ children }) => <img alt="incon">{children}</img>,
13
- Toast: ({ children }) => <p>{children}</p>,
14
- }));
15
-
16
- jest.mock('@eeacms/volto-matomo/utils', () => ({
17
- trackLink: jest.fn(),
18
- }));
19
-
20
- jest.mock(
21
- '@eeacms/volto-embed/PrivacyProtection/PrivacyProtection',
22
- () => ({ children }) => {
23
- return children;
24
- },
25
- );
26
-
27
- jest.mock('@eeacms/volto-embed/helpers', () => ({
28
- pickMetadata: (data) => data,
29
- }));
30
-
31
- const store = mockStore({
32
- intl: {
33
- locale: 'en',
34
- messages: {},
35
- },
36
- content: {
37
- create: {},
38
- subrequests: [],
39
- },
40
- connected_data_parameters: {},
41
- });
42
-
43
6
  describe('View', () => {
44
7
  const data = {
45
8
  '@type': 'embed_tableau_visualization',
@@ -55,8 +18,8 @@ describe('View', () => {
55
18
 
56
19
  it('should render the component', () => {
57
20
  const component = renderer.create(
58
- <Provider store={store}>
59
- <View data={data} />
21
+ <Provider store={global.store}>
22
+ <View data={data} useVisibilitySensor={false} />
60
23
  </Provider>,
61
24
  );
62
25
  const json = component.toJSON();
@@ -1,20 +1,252 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`Edit should render the component 1`] = `
4
- <div
5
- className="embed-tableau"
6
- >
4
+ Array [
7
5
  <div
8
- className="tableau-wrapper"
6
+ className="embed-tableau"
9
7
  >
10
8
  <div
11
- className="tableau tableau-2.8.0"
9
+ className="privacy-protection-wrapper"
12
10
  style={
13
11
  Object {
14
- "height": "700px",
12
+ "height": "auto",
13
+ "minHeight": "200px",
14
+ "overflow": "hidden",
15
+ "position": "relative",
15
16
  }
16
17
  }
17
- />
18
- </div>
19
- </div>
18
+ >
19
+ <div
20
+ className="tableau-wrapper"
21
+ >
22
+ <div
23
+ className="tableau tableau-2.8.0"
24
+ style={Object {}}
25
+ />
26
+ </div>
27
+ </div>
28
+ </div>,
29
+ <div
30
+ id="sidebar"
31
+ >
32
+ <div
33
+ className="ui form"
34
+ >
35
+ <header
36
+ className="header pulled"
37
+ >
38
+ <h2>
39
+ Embed Dashboard (Tableau)
40
+ </h2>
41
+ </header>
42
+ <div
43
+ id="blockform-fieldset-default"
44
+ >
45
+ <div
46
+ className="ui segment form attached"
47
+ >
48
+ <div
49
+ className="mocked-url-widget"
50
+ id="mocked-field-tableau_vis_url"
51
+ >
52
+ Tableau visualization
53
+ -
54
+ No description
55
+ </div>
56
+ <div
57
+ className="mocked-default-widget"
58
+ id="mocked-field-tableau_height"
59
+ >
60
+ <a
61
+ href="https://developer.mozilla.org/en-US/docs/Web/CSS/height"
62
+ rel="noreferrer"
63
+ target="_blank"
64
+ >
65
+ CSS height
66
+ </a>
67
+ -
68
+ Tableau height
69
+ </div>
70
+ </div>
71
+ </div>
72
+ <div
73
+ className="accordion ui fluid styled form"
74
+ >
75
+ <div
76
+ id="blockform-fieldset-toolbar"
77
+ >
78
+ <div
79
+ className="active title"
80
+ onClick={[Function]}
81
+ >
82
+ Toolbar
83
+ <svg
84
+ className="icon"
85
+ dangerouslySetInnerHTML={
86
+ Object {
87
+ "__html": undefined,
88
+ }
89
+ }
90
+ onClick={null}
91
+ style={
92
+ Object {
93
+ "fill": "currentColor",
94
+ "height": "20px",
95
+ "width": "auto",
96
+ }
97
+ }
98
+ viewBox=""
99
+ xmlns=""
100
+ />
101
+ </div>
102
+ <div
103
+ className="content active"
104
+ >
105
+ <div
106
+ aria-hidden={false}
107
+ className="rah-static rah-static--height-auto"
108
+ style={
109
+ Object {
110
+ "height": "auto",
111
+ "overflow": "visible",
112
+ }
113
+ }
114
+ >
115
+ <div
116
+ style={
117
+ Object {
118
+ "WebkitTransition": "opacity 500ms ease 0ms",
119
+ "transition": "opacity 500ms ease 0ms",
120
+ }
121
+ }
122
+ >
123
+ <div
124
+ className="ui segment attached"
125
+ >
126
+ <div
127
+ className="mocked-boolean-widget"
128
+ id="mocked-field-with_notes"
129
+ >
130
+ Show note
131
+ -
132
+ No description
133
+ </div>
134
+ <div
135
+ className="mocked-boolean-widget"
136
+ id="mocked-field-with_sources"
137
+ >
138
+ Show sources
139
+ -
140
+ Will show sources set in this page Data provenance
141
+ </div>
142
+ <div
143
+ className="mocked-boolean-widget"
144
+ id="mocked-field-with_more_info"
145
+ >
146
+ Show more info
147
+ -
148
+ No description
149
+ </div>
150
+ <div
151
+ className="mocked-boolean-widget"
152
+ id="mocked-field-with_download"
153
+ >
154
+ Show download button
155
+ -
156
+ No description
157
+ </div>
158
+ <div
159
+ className="mocked-boolean-widget"
160
+ id="mocked-field-with_share"
161
+ >
162
+ Show share button
163
+ -
164
+ No description
165
+ </div>
166
+ <div
167
+ className="mocked-boolean-widget"
168
+ id="mocked-field-with_enlarge"
169
+ >
170
+ Show enlarge button
171
+ -
172
+ No description
173
+ </div>
174
+ </div>
175
+ </div>
176
+ </div>
177
+ </div>
178
+ </div>
179
+ </div>
180
+ <div
181
+ className="accordion ui fluid styled form"
182
+ >
183
+ <div
184
+ id="blockform-fieldset-privacy"
185
+ >
186
+ <div
187
+ className="title"
188
+ onClick={[Function]}
189
+ >
190
+ Privacy
191
+ <svg
192
+ className="icon"
193
+ dangerouslySetInnerHTML={
194
+ Object {
195
+ "__html": undefined,
196
+ }
197
+ }
198
+ onClick={null}
199
+ style={
200
+ Object {
201
+ "fill": "currentColor",
202
+ "height": "20px",
203
+ "width": "auto",
204
+ }
205
+ }
206
+ viewBox=""
207
+ xmlns=""
208
+ />
209
+ </div>
210
+ <div
211
+ className="content"
212
+ >
213
+ <div
214
+ aria-hidden={true}
215
+ className="rah-static rah-static--height-zero"
216
+ style={
217
+ Object {
218
+ "height": 0,
219
+ "overflow": "hidden",
220
+ }
221
+ }
222
+ >
223
+ <div
224
+ style={
225
+ Object {
226
+ "WebkitTransition": "opacity 500ms ease 0ms",
227
+ "opacity": 0,
228
+ "transition": "opacity 500ms ease 0ms",
229
+ }
230
+ }
231
+ >
232
+ <div
233
+ className="ui segment attached"
234
+ >
235
+ <div
236
+ className="mocked-default-widget"
237
+ id="mocked-field-dataprotection"
238
+ >
239
+ No title
240
+ -
241
+ No description
242
+ </div>
243
+ </div>
244
+ </div>
245
+ </div>
246
+ </div>
247
+ </div>
248
+ </div>
249
+ </div>
250
+ </div>,
251
+ ]
20
252
  `;
@@ -5,16 +5,24 @@ exports[`View should render the component 1`] = `
5
5
  className="embed-tableau"
6
6
  >
7
7
  <div
8
- className="tableau-wrapper"
8
+ className="privacy-protection-wrapper"
9
+ style={
10
+ Object {
11
+ "height": "auto",
12
+ "minHeight": "200px",
13
+ "overflow": "hidden",
14
+ "position": "relative",
15
+ }
16
+ }
9
17
  >
10
18
  <div
11
- className="tableau tableau-2.8.0"
12
- style={
13
- Object {
14
- "height": "700px",
15
- }
16
- }
17
- />
19
+ className="tableau-wrapper"
20
+ >
21
+ <div
22
+ className="tableau tableau-2.8.0"
23
+ style={Object {}}
24
+ />
25
+ </div>
18
26
  </div>
19
27
  </div>
20
28
  `;
@@ -8,7 +8,7 @@ export default (config) => {
8
8
  id: 'embed_tableau_visualization',
9
9
  title: 'Embed Dashboard (Tableau)',
10
10
  icon: sliderSVG,
11
- group: 'common',
11
+ group: 'data_visualizations',
12
12
  edit: EmbedTableauVisualizatonEdit,
13
13
  view: EmbedTableauVisualizatonView,
14
14
  restricted: false,
@@ -1,3 +1,16 @@
1
+ import { defineMessages } from 'react-intl';
2
+
3
+ const messages = defineMessages({
4
+ CSSHeight: {
5
+ id: 'CSS height',
6
+ defaultMessage: 'CSS height',
7
+ },
8
+ CSSTableauHeightDescription: {
9
+ id: 'Tableau height',
10
+ defaultMessage: 'Tableau height',
11
+ },
12
+ });
13
+
1
14
  const getProtectionSchema = () => ({
2
15
  title: 'Data Protection',
3
16
 
@@ -40,9 +53,9 @@ const getProtectionSchema = () => ({
40
53
  required: [],
41
54
  });
42
55
 
43
- export default () => {
56
+ export default (props) => {
44
57
  return {
45
- title: 'Embed EEA Tableau visualization',
58
+ title: 'Embed Dashboard (Tableau)',
46
59
  fieldsets: [
47
60
  {
48
61
  id: 'default',
@@ -104,9 +117,18 @@ export default () => {
104
117
  defaultValue: true,
105
118
  },
106
119
  tableau_height: {
107
- title: 'Height',
108
- type: 'text',
109
- defaultValue: '700',
120
+ title: (
121
+ <a
122
+ rel="noreferrer"
123
+ target="_blank"
124
+ href="https://developer.mozilla.org/en-US/docs/Web/CSS/height"
125
+ >
126
+ {props.intl.formatMessage(messages.CSSHeight)}
127
+ </a>
128
+ ),
129
+ description: props.intl.formatMessage(
130
+ messages.CSSTableauHeightDescription,
131
+ ),
110
132
  },
111
133
  dataprotection: {
112
134
  widget: 'object',
@@ -8,10 +8,10 @@ export default (config) => {
8
8
  id: 'tableau_block',
9
9
  title: 'Tableau',
10
10
  icon: sliderSVG,
11
- group: 'common',
11
+ group: 'data_visualizations',
12
12
  edit: TableauEdit,
13
13
  view: TableauView,
14
- restricted: false,
14
+ restricted: true,
15
15
  mostUsed: false,
16
16
  sidebarTab: 1,
17
17
  blocks: {},
@@ -1,7 +1,16 @@
1
+ import { uniqBy } from 'lodash';
1
2
  import installEmbedTableauVisualization from './EmbedTableauVisualization';
2
3
  import installTableauBlock from './TableauBlock';
3
4
 
4
5
  export default (config) => {
6
+ config.blocks.groupBlocksOrder = uniqBy(
7
+ [
8
+ ...config.blocks.groupBlocksOrder,
9
+ { id: 'data_visualizations', title: 'Data Visualizations' },
10
+ ],
11
+ 'id',
12
+ );
13
+
5
14
  return [installEmbedTableauVisualization, installTableauBlock].reduce(
6
15
  (acc, apply) => apply(acc),
7
16
  config,
@@ -9,8 +9,7 @@ import React, {
9
9
  } from 'react';
10
10
  import { connect } from 'react-redux';
11
11
  import { toast } from 'react-toastify';
12
- import isEqual from 'lodash/isEqual';
13
- import isUndefined from 'lodash/isUndefined';
12
+ import { isEqual, isUndefined, isNaN, isNumber } from 'lodash';
14
13
  import cx from 'classnames';
15
14
  import { Button } from 'semantic-ui-react';
16
15
  import { Toast, Icon } from '@plone/volto/components';
@@ -30,6 +29,14 @@ import resetSVG from '@plone/volto/icons/reset.svg';
30
29
 
31
30
  import '@eeacms/volto-embed/Toolbar/styles.less';
32
31
 
32
+ function getHeight(height) {
33
+ const asNumber = isNumber(Number(height)) && !isNaN(Number(height));
34
+ if (asNumber) {
35
+ return `${height}px`;
36
+ }
37
+ return height;
38
+ }
39
+
33
40
  const TableauDebug = ({ mode, data, vizState, url, version, clearData }) => {
34
41
  const { loaded, error } = vizState;
35
42
  const { filters = {}, parameters = {} } = data;
@@ -108,7 +115,7 @@ const Tableau = forwardRef((props, ref) => {
108
115
  with_download = true,
109
116
  with_share = true,
110
117
  with_enlarge = true,
111
- tableau_height = 700,
118
+ tableau_height,
112
119
  } = data;
113
120
  const device = useMemo(
114
121
  () => getDevice(breakpoints, screen.page?.width || Infinity),
@@ -431,7 +438,7 @@ const Tableau = forwardRef((props, ref) => {
431
438
  clearData={clearData}
432
439
  />
433
440
  <div
434
- style={{ height: tableau_height + 'px' }}
441
+ style={tableau_height ? { height: getHeight(tableau_height) } : {}}
435
442
  className={cx('tableau', `tableau-${version}`, {
436
443
  'tableau-autoscale': autoScale,
437
444
  })}
@@ -445,6 +452,8 @@ const Tableau = forwardRef((props, ref) => {
445
452
  {with_more_info && <MoreInfo href={data['@id']} />}
446
453
  </div>
447
454
  <div className="right-col">
455
+ {with_download && loaded && <Download viz={viz.current} />}
456
+ {with_share && loaded && <Share href={data['@id']} />}
448
457
  {with_enlarge && loaded && (
449
458
  <Enlarge>
450
459
  <Tableau
@@ -461,8 +470,6 @@ const Tableau = forwardRef((props, ref) => {
461
470
  />
462
471
  </Enlarge>
463
472
  )}
464
- {with_download && loaded && <Download viz={viz.current} />}
465
- {with_share && loaded && <Share href={data['@id']} />}
466
473
  </div>
467
474
  </div>
468
475
  )}
@@ -2,26 +2,12 @@ import React from 'react';
2
2
  import { render } from '@testing-library/react';
3
3
  import '@testing-library/jest-dom/extend-expect';
4
4
  import { Provider } from 'react-redux';
5
- import configureStore from 'redux-mock-store';
6
5
  import Tableau from './Tableau';
7
6
 
8
- const mockStore = configureStore([]);
9
- const store = mockStore({});
10
-
11
- window.URL.createObjectURL = jest.fn(() => 'test');
12
-
13
- jest.mock('@plone/volto/components', () => ({
14
- Icon: ({ children }) => <img alt="incon">{children}</img>,
15
- }));
16
-
17
- jest.mock('@plone/volto/components', () => ({
18
- Toast: ({ children }) => <p>{children}</p>,
19
- }));
20
-
21
7
  describe('Tableau', () => {
22
8
  it('should render the component', () => {
23
9
  const { container } = render(
24
- <Provider store={store}>
10
+ <Provider store={global.store}>
25
11
  <Tableau />
26
12
  </Provider>,
27
13
  );
@@ -1,40 +1,13 @@
1
1
  import React from 'react';
2
2
  import renderer from 'react-test-renderer';
3
- import configureStore from 'redux-mock-store';
4
3
  import { Provider } from 'react-intl-redux';
5
4
 
6
5
  import Download from './Download';
7
6
 
8
- const mockStore = configureStore([]);
9
-
10
- window.URL.createObjectURL = jest.fn(() => 'test');
11
-
12
- jest.mock('semantic-ui-react', () => ({
13
- Popup: ({ content, trigger }) => {
14
- return (
15
- <div className="popup">
16
- <div className="trigger">{trigger}</div>
17
- <div className="content">{content}</div>
18
- </div>
19
- );
20
- },
21
- }));
22
-
23
- const store = mockStore({
24
- intl: {
25
- locale: 'en',
26
- messages: {},
27
- },
28
- content: {
29
- create: {},
30
- subrequests: [],
31
- },
32
- });
33
-
34
7
  describe('Edit', () => {
35
8
  it('should render the component', () => {
36
9
  const component = renderer.create(
37
- <Provider store={store}>
10
+ <Provider store={global.store}>
38
11
  <Download />
39
12
  </Provider>,
40
13
  );
@@ -2,23 +2,8 @@ import React from 'react';
2
2
  import { render } from '@testing-library/react';
3
3
  import '@testing-library/jest-dom/extend-expect';
4
4
  import { Provider } from 'react-redux';
5
- import configureStore from 'redux-mock-store';
6
5
  import VisualizationViewWidget from './VisualizationViewWidget';
7
6
 
8
- const mockStore = configureStore([]);
9
- const store = mockStore({
10
- content: { data: {} },
11
- });
12
-
13
- jest.mock('@plone/volto/components', () => ({
14
- Icon: ({ children }) => <img alt="incon">{children}</img>,
15
- Toast: ({ children }) => <p>{children}</p>,
16
- }));
17
-
18
- jest.mock('@eeacms/volto-embed/helpers', () => ({
19
- pickMetadata: (data) => data,
20
- }));
21
-
22
7
  describe('VisualizationViewWidget', () => {
23
8
  it('should render the component', () => {
24
9
  const data = {
@@ -34,7 +19,7 @@ describe('VisualizationViewWidget', () => {
34
19
  };
35
20
 
36
21
  const { container } = render(
37
- <Provider store={store}>
22
+ <Provider store={global.store}>
38
23
  <VisualizationViewWidget data={data} value={value} />
39
24
  </Provider>,
40
25
  );
@@ -1,20 +1,9 @@
1
1
  import React from 'react';
2
2
  import { render } from '@testing-library/react';
3
3
  import '@testing-library/jest-dom/extend-expect';
4
- import { Provider } from 'react-redux';
5
- import configureStore from 'redux-mock-store';
4
+ import { Provider } from 'react-intl-redux';
6
5
  import VisualizationWidget from './VisualizationWidget';
7
6
 
8
- const mockStore = configureStore([]);
9
- const store = mockStore({});
10
-
11
- jest.mock('@plone/volto/components', () => ({
12
- FormFieldWrapper: jest.fn(({ children }) => <>{children}</>),
13
- InlineForm: jest.fn(() => <div>Mocked InlineForm</div>),
14
- Icon: ({ children }) => <img alt="incon">{children}</img>,
15
- Toast: ({ children }) => <p>{children}</p>,
16
- }));
17
-
18
7
  describe('VisualizationWidget', () => {
19
8
  it('should render the component', () => {
20
9
  const data = {
@@ -36,7 +25,7 @@ describe('VisualizationWidget', () => {
36
25
  };
37
26
 
38
27
  const { container } = render(
39
- <Provider store={store}>
28
+ <Provider store={global.store}>
40
29
  <VisualizationWidget {...data} />
41
30
  </Provider>,
42
31
  );