@eeacms/volto-tableau 7.0.2 → 7.0.4

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,22 @@ 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.4](https://github.com/eea/volto-tableau/compare/7.0.3...7.0.4) - 5 December 2023
8
+
9
+ #### :hammer_and_wrench: Others
10
+
11
+ - fix tests [Miu Razvan - [`3a880ab`](https://github.com/eea/volto-tableau/commit/3a880aba0ff02bb568a1778e07b48b572472e44a)]
12
+ - fix default height [Miu Razvan - [`0eb7ebb`](https://github.com/eea/volto-tableau/commit/0eb7ebb7c5f702ffb3f0ae679b90f27ad7cbb080)]
13
+ ### [7.0.3](https://github.com/eea/volto-tableau/compare/7.0.2...7.0.3) - 29 November 2023
14
+
15
+ #### :hammer_and_wrench: Others
16
+
17
+ - fix tests [Miu Razvan - [`01eebe9`](https://github.com/eea/volto-tableau/commit/01eebe9580fdf85a8ca64a5a7f3970d93a7dd73f)]
18
+ - update tests [Miu Razvan - [`c0897ea`](https://github.com/eea/volto-tableau/commit/c0897eacff0afe9458faf991276f250bba807269)]
19
+ - fix tests [Miu Razvan - [`096203b`](https://github.com/eea/volto-tableau/commit/096203bb5b70f97e2fed381308afd727767477fb)]
20
+ - update cypress [Miu Razvan - [`d5cb322`](https://github.com/eea/volto-tableau/commit/d5cb3222e0a316d2627cade3d2534942264b24ac)]
21
+ - update [Miu Razvan - [`0df72ba`](https://github.com/eea/volto-tableau/commit/0df72babc50e4d092d3cb2d80e720202dc2e95be)]
22
+ ### [7.0.2](https://github.com/eea/volto-tableau/compare/7.0.1...7.0.2) - 29 November 2023
8
23
 
9
24
  #### :bug: Bug Fixes
10
25
 
@@ -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.4",
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,256 @@
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={
25
+ Object {
26
+ "height": "700px",
27
+ }
28
+ }
29
+ />
30
+ </div>
31
+ </div>
32
+ </div>,
33
+ <div
34
+ id="sidebar"
35
+ >
36
+ <div
37
+ className="ui form"
38
+ >
39
+ <header
40
+ className="header pulled"
41
+ >
42
+ <h2>
43
+ Embed Dashboard (Tableau)
44
+ </h2>
45
+ </header>
46
+ <div
47
+ id="blockform-fieldset-default"
48
+ >
49
+ <div
50
+ className="ui segment form attached"
51
+ >
52
+ <div
53
+ className="mocked-url-widget"
54
+ id="mocked-field-tableau_vis_url"
55
+ >
56
+ Tableau visualization
57
+ -
58
+ No description
59
+ </div>
60
+ <div
61
+ className="mocked-default-widget"
62
+ id="mocked-field-tableau_height"
63
+ >
64
+ <a
65
+ href="https://developer.mozilla.org/en-US/docs/Web/CSS/height"
66
+ rel="noreferrer"
67
+ target="_blank"
68
+ >
69
+ CSS height
70
+ </a>
71
+ -
72
+ Tableau height
73
+ </div>
74
+ </div>
75
+ </div>
76
+ <div
77
+ className="accordion ui fluid styled form"
78
+ >
79
+ <div
80
+ id="blockform-fieldset-toolbar"
81
+ >
82
+ <div
83
+ className="active title"
84
+ onClick={[Function]}
85
+ >
86
+ Toolbar
87
+ <svg
88
+ className="icon"
89
+ dangerouslySetInnerHTML={
90
+ Object {
91
+ "__html": undefined,
92
+ }
93
+ }
94
+ onClick={null}
95
+ style={
96
+ Object {
97
+ "fill": "currentColor",
98
+ "height": "20px",
99
+ "width": "auto",
100
+ }
101
+ }
102
+ viewBox=""
103
+ xmlns=""
104
+ />
105
+ </div>
106
+ <div
107
+ className="content active"
108
+ >
109
+ <div
110
+ aria-hidden={false}
111
+ className="rah-static rah-static--height-auto"
112
+ style={
113
+ Object {
114
+ "height": "auto",
115
+ "overflow": "visible",
116
+ }
117
+ }
118
+ >
119
+ <div
120
+ style={
121
+ Object {
122
+ "WebkitTransition": "opacity 500ms ease 0ms",
123
+ "transition": "opacity 500ms ease 0ms",
124
+ }
125
+ }
126
+ >
127
+ <div
128
+ className="ui segment attached"
129
+ >
130
+ <div
131
+ className="mocked-boolean-widget"
132
+ id="mocked-field-with_notes"
133
+ >
134
+ Show note
135
+ -
136
+ No description
137
+ </div>
138
+ <div
139
+ className="mocked-boolean-widget"
140
+ id="mocked-field-with_sources"
141
+ >
142
+ Show sources
143
+ -
144
+ Will show sources set in this page Data provenance
145
+ </div>
146
+ <div
147
+ className="mocked-boolean-widget"
148
+ id="mocked-field-with_more_info"
149
+ >
150
+ Show more info
151
+ -
152
+ No description
153
+ </div>
154
+ <div
155
+ className="mocked-boolean-widget"
156
+ id="mocked-field-with_download"
157
+ >
158
+ Show download button
159
+ -
160
+ No description
161
+ </div>
162
+ <div
163
+ className="mocked-boolean-widget"
164
+ id="mocked-field-with_share"
165
+ >
166
+ Show share button
167
+ -
168
+ No description
169
+ </div>
170
+ <div
171
+ className="mocked-boolean-widget"
172
+ id="mocked-field-with_enlarge"
173
+ >
174
+ Show enlarge button
175
+ -
176
+ No description
177
+ </div>
178
+ </div>
179
+ </div>
180
+ </div>
181
+ </div>
182
+ </div>
183
+ </div>
184
+ <div
185
+ className="accordion ui fluid styled form"
186
+ >
187
+ <div
188
+ id="blockform-fieldset-privacy"
189
+ >
190
+ <div
191
+ className="title"
192
+ onClick={[Function]}
193
+ >
194
+ Privacy
195
+ <svg
196
+ className="icon"
197
+ dangerouslySetInnerHTML={
198
+ Object {
199
+ "__html": undefined,
200
+ }
201
+ }
202
+ onClick={null}
203
+ style={
204
+ Object {
205
+ "fill": "currentColor",
206
+ "height": "20px",
207
+ "width": "auto",
208
+ }
209
+ }
210
+ viewBox=""
211
+ xmlns=""
212
+ />
213
+ </div>
214
+ <div
215
+ className="content"
216
+ >
217
+ <div
218
+ aria-hidden={true}
219
+ className="rah-static rah-static--height-zero"
220
+ style={
221
+ Object {
222
+ "height": 0,
223
+ "overflow": "hidden",
224
+ }
225
+ }
226
+ >
227
+ <div
228
+ style={
229
+ Object {
230
+ "WebkitTransition": "opacity 500ms ease 0ms",
231
+ "opacity": 0,
232
+ "transition": "opacity 500ms ease 0ms",
233
+ }
234
+ }
235
+ >
236
+ <div
237
+ className="ui segment attached"
238
+ >
239
+ <div
240
+ className="mocked-default-widget"
241
+ id="mocked-field-dataprotection"
242
+ >
243
+ No title
244
+ -
245
+ No description
246
+ </div>
247
+ </div>
248
+ </div>
249
+ </div>
250
+ </div>
251
+ </div>
252
+ </div>
253
+ </div>
254
+ </div>,
255
+ ]
20
256
  `;
@@ -5,16 +5,28 @@ 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",
19
+ className="tableau-wrapper"
20
+ >
21
+ <div
22
+ className="tableau tableau-2.8.0"
23
+ style={
24
+ Object {
25
+ "height": "700px",
26
+ }
15
27
  }
16
- }
17
- />
28
+ />
29
+ </div>
18
30
  </div>
19
31
  </div>
20
32
  `;
@@ -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 || '700px';
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={{ 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
  );
@@ -9,6 +9,17 @@ import Tableau from '@eeacms/volto-tableau/Tableau/Tableau';
9
9
  const VisualizationView = (props) => {
10
10
  const { content = {} } = props;
11
11
  const { tableau_visualization = {} } = content;
12
+ const { staticParameters = [] } = tableau_visualization;
13
+
14
+ const extraOptions = React.useMemo(() => {
15
+ const options = {};
16
+ staticParameters.forEach((parameter) => {
17
+ if (parameter.field && parameter.value) {
18
+ options[parameter.field] = parameter.value;
19
+ }
20
+ });
21
+ return options;
22
+ }, [staticParameters]);
12
23
 
13
24
  return (
14
25
  <Container id="page-document">
@@ -22,10 +33,11 @@ const VisualizationView = (props) => {
22
33
  with_notes: false,
23
34
  with_sources: false,
24
35
  with_more_info: false,
25
- with_share: false,
26
- with_enlarge: false,
36
+ with_share: true,
37
+ with_enlarge: true,
27
38
  with_download: true,
28
39
  }}
40
+ extraOptions={extraOptions}
29
41
  breakpoints={
30
42
  config.blocks.blocksConfig.embed_tableau_visualization.breakpoints
31
43
  }
@@ -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
  );