@eeacms/volto-tableau 6.0.1 → 6.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,6 +4,17 @@ 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
+ ### [6.0.3](https://github.com/eea/volto-tableau/compare/6.0.2...6.0.3) - 10 November 2023
8
+
9
+ #### :hammer_and_wrench: Others
10
+
11
+ - fix tableau for real this time [Miu Razvan - [`a304c2c`](https://github.com/eea/volto-tableau/commit/a304c2cce2a68cfa6b1123a853cfda0b57501ab3)]
12
+ ### [6.0.2](https://github.com/eea/volto-tableau/compare/6.0.1...6.0.2) - 10 November 2023
13
+
14
+ #### :rocket: New Features
15
+
16
+ - feat: fix tableau not loading on hard reload [Miu Razvan - [`f37867f`](https://github.com/eea/volto-tableau/commit/f37867f3d07c5dd05b91ea0b758eced631afd458)]
17
+
7
18
  ### [6.0.1](https://github.com/eea/volto-tableau/compare/6.0.0...6.0.1) - 10 November 2023
8
19
 
9
20
  #### :house: Internal changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-tableau",
3
- "version": "6.0.1",
3
+ "version": "6.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",
@@ -9,7 +9,7 @@ import Tableau from '@eeacms/volto-tableau/Tableau/Tableau';
9
9
  const View = (props) => {
10
10
  const data = props.data;
11
11
  const {
12
- with_note = true,
12
+ with_notes = true,
13
13
  with_sources = true,
14
14
  with_more_info = true,
15
15
  with_download = true,
@@ -46,7 +46,7 @@ const View = (props) => {
46
46
  <Tableau
47
47
  data={{
48
48
  ...tableau_visualization,
49
- with_note,
49
+ with_notes,
50
50
  with_sources,
51
51
  with_more_info,
52
52
  with_download,
@@ -29,7 +29,7 @@ describe('View', () => {
29
29
  tableau_vis_url: 'http://localhost:3000/tableau-ct',
30
30
  with_download: true,
31
31
  with_more_info: true,
32
- with_note: true,
32
+ with_notes: true,
33
33
  with_share: true,
34
34
  };
35
35
 
@@ -47,14 +47,17 @@ export default () => {
47
47
  {
48
48
  id: 'default',
49
49
  title: 'Default',
50
+ fields: ['tableau_vis_url', 'tableau_height'],
51
+ },
52
+ {
53
+ id: 'toolbar',
54
+ title: 'Toolbar',
50
55
  fields: [
51
- 'tableau_vis_url',
52
- 'with_note',
56
+ 'with_notes',
53
57
  'with_sources',
54
58
  'with_more_info',
55
59
  'with_download',
56
60
  'with_share',
57
- 'tableau_height',
58
61
  ],
59
62
  },
60
63
  {
@@ -68,13 +71,14 @@ export default () => {
68
71
  title: 'Tableau visualization',
69
72
  widget: 'url',
70
73
  },
71
- with_note: {
74
+ with_notes: {
72
75
  title: 'Show note',
73
76
  type: 'boolean',
74
77
  defaultValue: true,
75
78
  },
76
79
  with_sources: {
77
80
  title: 'Show sources',
81
+ description: 'Will show sources set in this page Data provenance',
78
82
  type: 'boolean',
79
83
  defaultValue: true,
80
84
  },
@@ -70,6 +70,7 @@ const TableauDebug = ({ mode, data, vizState, url, version, clearData }) => {
70
70
  };
71
71
 
72
72
  const Tableau = forwardRef((props, ref) => {
73
+ const tableauEl = useRef(null);
73
74
  const vizEl = useRef(null);
74
75
  const viz = useRef();
75
76
  const vizState = useRef({});
@@ -78,6 +79,7 @@ const Tableau = forwardRef((props, ref) => {
78
79
  const [loaded, setLoaded] = useState(false);
79
80
  const [loading, setLoading] = useState(false);
80
81
  const [error, setError] = useState(null);
82
+ const [mobile, setMobile] = useState(false);
81
83
  const {
82
84
  block,
83
85
  data = {},
@@ -100,7 +102,7 @@ const Tableau = forwardRef((props, ref) => {
100
102
  toolbarPosition = 'Top',
101
103
  breakpointUrls = [],
102
104
  tableau_vis_url,
103
- with_note = true,
105
+ with_notes = true,
104
106
  with_sources = true,
105
107
  with_more_info = true,
106
108
  with_download = true,
@@ -370,6 +372,18 @@ const Tableau = forwardRef((props, ref) => {
370
372
  /* eslint-disable-next-line */
371
373
  }, [sheetname]);
372
374
 
375
+ useEffect(() => {
376
+ if (!loading && tableauEl.current) {
377
+ const visWidth = tableauEl.current.offsetWidth;
378
+
379
+ if (visWidth < 600 && !mobile) {
380
+ setMobile(true);
381
+ } else if (visWidth >= 600 && mobile) {
382
+ setMobile(false);
383
+ }
384
+ }
385
+ }, [screen, mobile, loading]);
386
+
373
387
  useImperativeHandle(
374
388
  ref,
375
389
  () => {
@@ -385,7 +399,7 @@ const Tableau = forwardRef((props, ref) => {
385
399
  );
386
400
 
387
401
  return (
388
- <div className="tableau-wrapper">
402
+ <div className="tableau-wrapper" ref={tableauEl}>
389
403
  {loading && (
390
404
  <div className="tableau-loader">
391
405
  <span>Loading...</span>
@@ -423,9 +437,9 @@ const Tableau = forwardRef((props, ref) => {
423
437
  ref={vizEl}
424
438
  />
425
439
  {loaded && (
426
- <div className="visualization-toolbar">
440
+ <div className={cx('visualization-toolbar', { mobile })}>
427
441
  <div className="left-col">
428
- {with_note && <FigureNote note={figure_note || []} />}
442
+ {with_notes && <FigureNote note={figure_note || []} />}
429
443
  {with_sources && <Sources sources={sources} />}
430
444
  {with_more_info && <MoreInfo href={tableau_vis_url || data.url} />}
431
445
  </div>
@@ -17,7 +17,7 @@ const VisualizationView = (props) => {
17
17
  <Tableau
18
18
  data={{
19
19
  ...tableau_visualization,
20
- with_note: false,
20
+ with_notes: false,
21
21
  with_sources: false,
22
22
  with_more_info: false,
23
23
  with_share: false,
@@ -8,7 +8,7 @@ export default function VisualizationViewWidget(props) {
8
8
  <Tableau
9
9
  data={{
10
10
  ...value,
11
- with_note: false,
11
+ with_notes: false,
12
12
  with_sources: false,
13
13
  with_more_info: true,
14
14
  with_share: true,
@@ -74,7 +74,7 @@ const VisualizationWidget = (props) => {
74
74
  ref={viz}
75
75
  data={{
76
76
  ...(value || {}),
77
- with_note: false,
77
+ with_notes: false,
78
78
  with_sources: false,
79
79
  with_more_info: false,
80
80
  with_share: false,
@@ -123,7 +123,7 @@ const VisualizationWidget = (props) => {
123
123
  data={{
124
124
  ...props.value,
125
125
  autoScale: true,
126
- with_note: false,
126
+ with_notes: false,
127
127
  with_sources: false,
128
128
  with_more_info: false,
129
129
  with_share: false,
package/src/helpers.js CHANGED
@@ -1,26 +1,31 @@
1
- export const loadTableauScript = (callback, version) => {
2
- if (!__CLIENT__) return;
3
- const source = `https://public.tableau.com/javascripts/api/tableau-${version}.min.js`;
4
- const existingScript = document.getElementById(`tableauJS-${version}`);
5
- const existingScriptSource =
6
- existingScript && existingScript.getAttribute('src');
7
- // Replace script loaded on each version change
8
- if (existingScript && existingScriptSource !== source) {
9
- existingScript.setAttribute('src', source);
10
- }
11
- if (!existingScript) {
12
- const script = document.createElement('script');
13
- script.src = source;
14
- script.id = `tableauJS-${version}`;
15
- document.body.appendChild(script);
16
- script.onload = () => {
17
- window[`tableau_${version}`] = window.tableau;
18
- if (callback) callback();
19
- };
20
- }
21
- // Trigger callback
22
- if (existingScript && callback) callback();
23
- };
1
+ export async function loadTableauScript(version) {
2
+ return new Promise((resolve) => {
3
+ if (!__CLIENT__) {
4
+ resolve();
5
+ return;
6
+ }
7
+ const source = `https://public.tableau.com/javascripts/api/tableau-${version}.min.js`;
8
+ const existingScript = document.getElementById(`tableauJS-${version}`);
9
+ const existingScriptSource =
10
+ existingScript && existingScript.getAttribute('src');
11
+ // Replace script loaded on each version change
12
+ if (existingScript && existingScriptSource !== source) {
13
+ existingScript.setAttribute('src', source);
14
+ }
15
+ if (!existingScript) {
16
+ const script = document.createElement('script');
17
+ script.src = source;
18
+ script.id = `tableauJS-${version}`;
19
+ document.body.appendChild(script);
20
+ script.addEventListener('load', () => {
21
+ window[`tableau_${version}`] = window.tableau;
22
+ resolve(window[`tableau_${version}`]);
23
+ });
24
+ } else {
25
+ resolve(window[`tableau_${version}`]);
26
+ }
27
+ });
28
+ }
24
29
 
25
30
  // Script url for each version. In case you might need to add them in the load balancer
26
31
  // https://public.tableau.com/javascripts/api/tableau-2.8.0.min.js
package/src/hooks.js CHANGED
@@ -1,17 +1,32 @@
1
- import { useEffect, useState } from 'react';
1
+ import { useEffect, useState, useRef } from 'react';
2
2
  import { loadTableauScript } from './helpers';
3
3
 
4
+ const TIMEOUT = 10000;
5
+
4
6
  export const useTableau = (version) => {
7
+ const clock = useRef();
5
8
  const [tableau, setTableau] = useState();
6
9
 
7
10
  useEffect(() => {
8
- loadTableauScript(() => {
9
- if (window[`tableau_${version}`]) {
10
- setTableau(window[`tableau_${version}`]);
11
- } else {
12
- setTableau(undefined);
11
+ loadTableauScript(version);
12
+
13
+ const startTime = new Date().getTime();
14
+
15
+ clock.current = setInterval(() => {
16
+ const tableauApi = window[`tableau_${version}`];
17
+ if (tableauApi) {
18
+ setTableau(tableauApi);
19
+ clearInterval(clock.current);
20
+ return;
13
21
  }
14
- }, version);
22
+ if (new Date().getTime() - startTime > TIMEOUT) {
23
+ clearInterval(clock.current);
24
+ }
25
+ }, 100);
26
+
27
+ return () => {
28
+ clearInterval(clock.current);
29
+ };
15
30
  }, [version]);
16
31
 
17
32
  return tableau;
@@ -1,4 +1,5 @@
1
1
  @import './globals.less';
2
+ @import './tableau.variables';
2
3
 
3
4
  @addon: 'volto-tableau';
4
5
  @addontype: 'tableauBlock';
@@ -59,19 +60,19 @@
59
60
  animation: spin 1s linear infinite;
60
61
  background-image: linear-gradient(
61
62
  -45deg,
62
- @primaryColor 25%,
63
- @secondaryColor 25%,
64
- @secondaryColor 50%,
65
- @primaryColor 50%,
66
- @primaryColor 75%,
67
- @secondaryColor 75%
63
+ @grey-1 25%,
64
+ @grey-2 25%,
65
+ @grey-2 50%,
66
+ @grey-1 50%,
67
+ @grey-1 75%,
68
+ @grey-2 75%
68
69
  );
69
70
  background-size: 100px 100px;
70
71
  border-radius: 5px;
71
72
 
72
73
  span {
73
74
  margin: 6px auto;
74
- color: white;
75
+ color: @textColor;
75
76
  font-weight: bold;
76
77
  text-align: center;
77
78
  }
@@ -111,227 +112,7 @@
111
112
  }
112
113
  }
113
114
 
114
- // ========= Sources ==========
115
-
116
- .tableau-wrapper .visualization-info-container {
117
- display: flex;
118
- flex-wrap: wrap;
119
- align-items: center;
120
- justify-content: space-between;
121
- gap: 1.2rem;
122
-
123
- > *:first-child {
124
- margin-left: auto;
125
-
126
- > *:not(:last-child) {
127
- border-right: 1px solid @textColor;
128
- }
129
- }
130
-
131
- > *:last-child {
132
- justify-content: flex-end;
133
- }
134
-
135
- .visualization-info {
136
- display: flex;
137
- flex-grow: 0.5;
138
- align-items: center;
139
-
140
- > * {
141
- padding: 0 0.5rem;
142
- border-collapse: collapse;
143
- }
144
-
145
- > *:first-child {
146
- padding-left: 0;
147
- }
148
-
149
- > *:last-child {
150
- padding-right: 0;
151
- margin-right: 0;
152
-
153
- &.tableau-download-container {
154
- margin-left: auto;
155
- }
156
- }
157
- }
158
- }
159
-
160
- .embed-sources-header {
161
- cursor: pointer;
162
- }
163
-
164
- #tableau-share-popup {
165
- .ui.popup {
166
- padding-right: 15px;
167
- padding-left: 0;
168
- }
169
-
170
- .tableau-share-popup-text {
171
- margin-left: 7px;
172
- }
173
- }
174
-
175
- .tableau-share-popup-container {
176
- display: flex;
177
- justify-content: space-between;
178
- gap: 1rem;
179
-
180
- .tableau-share-link {
181
- input {
182
- padding-left: 7px !important;
183
- border-left: 0 !important;
184
-
185
- &:focus {
186
- outline: 1px solid var(--focus-visible, #0083e0);
187
- }
188
- }
189
- }
190
-
191
- .tableau-copy-button {
192
- max-width: 80px;
193
- padding: 10px 17px !important;
194
- border: 1px solid black !important;
195
- margin: 0 !important;
196
- background-color: #4472c4 !important;
197
- border-radius: 7px !important;
198
- }
199
-
200
- @media screen and (max-width: @largestMobileScreen) {
201
- flex-direction: column;
202
- }
203
- }
204
-
205
- .tableau-note-button,
206
- .tableau-more-info-button,
207
- .tableau-download-button,
208
- .tableau-sources-button,
209
- .tableau-share-button {
210
- display: inline-flex;
211
- align-items: center;
212
- padding-bottom: 3px;
213
- border: none;
214
- background-color: transparent;
215
- color: @textColor;
216
- cursor: pointer;
217
-
218
- .icon {
219
- margin-left: 0.5rem;
220
- }
221
-
222
- &:hover {
223
- color: @secondaryColor;
224
- }
225
-
226
- &.expanded {
227
- padding-bottom: 0;
228
- border-bottom: 3px solid @secondaryColor;
229
- color: @secondaryColor;
230
- }
231
- }
232
-
233
- .tableau-more-info-button,
234
- .tableau-download-button,
235
- .tableau-share-button {
236
- gap: 0.25rem;
237
-
238
- i {
239
- margin-bottom: 1px;
240
- }
241
- }
242
-
243
- #tableau-note-popup,
244
- #tableau-sources-popup,
245
- #tableau-download-popup {
246
- .ui.popup {
247
- background-color: @grey-1;
248
- box-shadow: rgba(0, 0, 0, 0.15) 1.95px 1.95px 2.6px;
249
-
250
- &::before {
251
- background-color: @grey-1;
252
- }
253
- }
254
-
255
- .sources-list {
256
- margin: 0;
257
- list-style: decimal inside;
258
- padding-inline-start: 0;
259
- }
260
-
261
- .embed-sources-param-description {
262
- margin-left: 5px;
263
- }
264
-
265
- @media screen and (min-width: @largestMobileScreen) {
266
- .ui.popup {
267
- max-width: 600px;
268
- }
269
- }
270
- }
271
-
272
- #tableau-download-popup {
273
- ul.no-bullets {
274
- padding: 0;
275
- margin: 0;
276
- list-style-type: none;
277
- }
278
-
279
- .visualization-wrapper {
280
- position: relative;
281
-
282
- .visualization-info {
283
- display: flex;
284
- align-items: center;
285
-
286
- > * {
287
- padding: 0 0.5rem;
288
- border-collapse: collapse;
289
- }
290
-
291
- > *:first-child {
292
- padding-left: 0;
293
- }
294
-
295
- > *:last-child {
296
- padding-right: 0;
297
- margin-right: 0;
298
-
299
- &.tableau-download-container {
300
- margin-left: auto;
301
- }
302
- }
303
-
304
- > *:not(:last-child) {
305
- border-right: 2px solid @textColor;
306
- }
307
- }
308
- }
309
-
310
- .tableau-download-button.tableau-format-download {
311
- padding: 0;
312
- color: #679ad6;
313
- font-weight: normal;
314
-
315
- &:hover {
316
- color: #164b7f;
317
- }
318
- }
319
- }
320
-
321
- @media print {
322
- .tableau-download-container,
323
- .tableau-note-container,
324
- .tableau-sources-container,
325
- .tableau-share-container,
326
- #tableau-note-popup,
327
- #tableau-sources-popup {
328
- display: none;
329
- }
330
- }
331
-
332
115
  #tableau-editor-modal {
333
116
  width: 90vw !important;
334
117
  height: calc(80vh - 10em) !important;
335
118
  }
336
-
337
- .loadAddonVariables();
@@ -1,4 +1,7 @@
1
- @tableauWrapperBackground : #f5f5f5;
1
+ @grey-1: #f9f9f9;
2
+ @grey-2: #E6E7E8;
3
+
4
+ @tableauWrapperBackground : @grey-1;
2
5
  @tableauWrapperPadding : 1rem;
3
6
  @tableauWrapperMargin : 0 0 1rem 0;
4
7
 
@@ -6,5 +9,3 @@
6
9
  @tableauIframeMargin : 0 auto 1rem auto;
7
10
  @tableauIframeBorder : none;
8
11
  @tableauIframeBorderRadius : 0;
9
-
10
- @grey-1 : #f9f9f9;