@eeacms/volto-tableau 3.0.8 → 4.0.0

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 (44) hide show
  1. package/CHANGELOG.md +14 -7
  2. package/Jenkinsfile +2 -0
  3. package/jest-addon.config.js +2 -2
  4. package/package.json +1 -1
  5. package/src/Blocks/EmbedTableauVisualization/Edit.jsx +31 -0
  6. package/src/Blocks/EmbedTableauVisualization/View.jsx +63 -0
  7. package/src/Blocks/EmbedTableauVisualization/index.js +30 -0
  8. package/src/Blocks/{EmbedEEATableauBlock → EmbedTableauVisualization}/schema.js +29 -13
  9. package/src/{TableauBlock → Blocks/TableauBlock}/Edit.jsx +3 -2
  10. package/src/{TableauBlock → Blocks/TableauBlock}/View.jsx +29 -40
  11. package/src/Blocks/TableauBlock/index.js +30 -0
  12. package/src/{TableauBlock → Blocks/TableauBlock}/schema.js +50 -2
  13. package/src/Blocks/index.js +9 -0
  14. package/src/Tableau/Tableau.jsx +263 -0
  15. package/src/Utils/Download/Download.jsx +72 -0
  16. package/src/Utils/Share/Share.jsx +21 -0
  17. package/src/Utils/Sources/Sources.jsx +66 -0
  18. package/src/Views/VisualizationView.jsx +12 -32
  19. package/src/Widgets/VisualizationWidget.jsx +60 -124
  20. package/src/Widgets/schema.js +62 -131
  21. package/src/helpers.js +15 -34
  22. package/src/hooks.js +18 -0
  23. package/src/icons/download.svg +5 -0
  24. package/src/index.js +4 -66
  25. package/src/less/tableau.less +131 -72
  26. package/src/less/tableau.variables +6 -13
  27. package/src/Blocks/EmbedEEATableauBlock/Edit.jsx +0 -56
  28. package/src/Blocks/EmbedEEATableauBlock/View.jsx +0 -74
  29. package/src/ConnectedTableau/ConnectedTableau.jsx +0 -29
  30. package/src/CustomWidgets/UrlParamsWidget.jsx +0 -29
  31. package/src/DownloadExtras/TableauDownload.jsx +0 -124
  32. package/src/DownloadExtras/TableauFullscreen.jsx +0 -78
  33. package/src/DownloadExtras/TableauShare.jsx +0 -81
  34. package/src/DownloadExtras/style.less +0 -152
  35. package/src/Sources/Sources.jsx +0 -50
  36. package/src/Sources/index.js +0 -3
  37. package/src/Sources/style.css +0 -7
  38. package/src/Tableau/View.jsx +0 -254
  39. package/src/Widgets/style.less +0 -8
  40. package/src/actions.js +0 -9
  41. package/src/constants.js +0 -1
  42. package/src/downloadHelpers/downloadHelpers.js +0 -25
  43. package/src/middleware.js +0 -39
  44. package/src/store.js +0 -72
@@ -0,0 +1,263 @@
1
+ import React, { useState, useRef } from 'react';
2
+ import { connect } from 'react-redux';
3
+ import { toast } from 'react-toastify';
4
+ import isEqual from 'lodash/isEqual';
5
+ import { Toast } from '@plone/volto/components';
6
+ import cx from 'classnames';
7
+ import { useTableau } from '@eeacms/volto-tableau/hooks';
8
+ import Sources from '@eeacms/volto-tableau/Utils/Sources/Sources';
9
+ import Download from '@eeacms/volto-tableau/Utils/Download/Download';
10
+ import Share from '@eeacms/volto-tableau/Utils/Share/Share';
11
+
12
+ const TableauDebug = ({ mode, vizState, url, version, sheetSize }) => {
13
+ const { loaded, error } = vizState;
14
+
15
+ const showTableauInfo = mode === 'edit' && (!url || (loaded && url) || error);
16
+
17
+ return showTableauInfo ? (
18
+ <div
19
+ className="tableau-debug"
20
+ style={{ ...(sheetSize.width ? { width: sheetSize.width } : {}) }}
21
+ >
22
+ {!url ? <p className="tableau-error">URL required</p> : ''}
23
+ {vizState.loaded && url ? (
24
+ <h3 className="tableau-version">
25
+ Tableau <span className="version">{version}</span>
26
+ </h3>
27
+ ) : null}
28
+ {vizState.error ? <p className="tableau-error">{vizState.error}</p> : ''}
29
+ </div>
30
+ ) : null;
31
+ };
32
+
33
+ const Tableau = (props) => {
34
+ const filters = useRef(props.data.filters || {});
35
+ const vizEl = useRef(null);
36
+ const viz = useRef();
37
+ const vizState = useRef({});
38
+ const [loaded, setLoaded] = useState(false);
39
+ const [loading, setLoading] = useState(false);
40
+ const [error, setError] = useState(null);
41
+ const [sheetSize, setSheetSize] = useState({});
42
+ const {
43
+ canUpdateUrl = true,
44
+ data = {},
45
+ extraFilters = {},
46
+ extraOptions = {},
47
+ mode = 'view',
48
+ screen = {},
49
+ version = '2.9.1',
50
+ with_sources,
51
+ with_download,
52
+ with_share,
53
+ sources,
54
+ // noSizeUpdate = false,
55
+ } = props;
56
+ const {
57
+ autoScale = false,
58
+ hideTabs = false,
59
+ hideToolbar = false,
60
+ sheetname = '',
61
+ toolbarPosition = 'Top',
62
+ } = data;
63
+ const defaultUrl = data.url;
64
+ const url = props.url || defaultUrl;
65
+
66
+ // Load tableau from script tag
67
+ const tableau = useTableau(version);
68
+
69
+ const onFilterChange = (filter) => {
70
+ const newFilters = { ...filters.current };
71
+ const fieldName = filter.getFieldName();
72
+ const values = filter
73
+ .getAppliedValues()
74
+ .map((appliedValue) => appliedValue.value);
75
+ newFilters[fieldName] = values;
76
+ if (!isEqual(newFilters, filters)) {
77
+ props.onChangeBlock(props.block, {
78
+ ...data,
79
+ filters: {
80
+ ...newFilters,
81
+ },
82
+ });
83
+ filters.current = { ...newFilters };
84
+ }
85
+ };
86
+
87
+ const onVizStateUpdate = (loaded, loading, error) => {
88
+ vizState.current = { ...vizState.current, loaded, loading, error };
89
+ setLoaded(loaded);
90
+ setLoading(loading);
91
+ setError(error);
92
+ if (props.setVizState) {
93
+ props.setVizState({ loaded, loading, error });
94
+ }
95
+ };
96
+
97
+ const disposeViz = () => {
98
+ if (viz.current) {
99
+ viz.current.dispose();
100
+ viz.current = null;
101
+ }
102
+ onVizStateUpdate(false, false, null);
103
+ };
104
+
105
+ const initViz = () => {
106
+ disposeViz();
107
+ try {
108
+ onVizStateUpdate(false, true, vizState.current.error);
109
+ setSheetSize({});
110
+ viz.current = new tableau.Viz(vizEl.current, url || defaultUrl, {
111
+ hideTabs,
112
+ hideToolbar,
113
+ sheetname,
114
+ toolbarPosition,
115
+ ...data.filters,
116
+ ...extraFilters,
117
+ ...extraOptions,
118
+ onFirstInteractive: () => {
119
+ onVizStateUpdate(true, false, null);
120
+ if (viz.current && mode === 'edit') {
121
+ const workbook = viz.current.getWorkbook();
122
+ const newData = {
123
+ url: canUpdateUrl ? viz.current.getUrl() : defaultUrl,
124
+ sheetname: workbook.getActiveSheet().getName(),
125
+ };
126
+ if (newData.url !== url || newData.sheetname !== sheetname) {
127
+ props.onChangeBlock(props.block, {
128
+ ...data,
129
+ ...newData,
130
+ });
131
+ toast.success(
132
+ <Toast success title={'Tableau data updated'} content={null} />,
133
+ );
134
+ }
135
+ // Filter change event
136
+ viz.current.addEventListener(
137
+ tableau.TableauEventName.FILTER_CHANGE,
138
+ (event) => {
139
+ event.getFilterAsync().then((filter) => {
140
+ onFilterChange(filter);
141
+ });
142
+ },
143
+ );
144
+ }
145
+ },
146
+ // onFirstVizSizeKnown: (e) => {
147
+ // if (!noSizeUpdate) {
148
+ // setSheetSize(e.$2.sheetSize.maxSize);
149
+ // }
150
+ // },
151
+ });
152
+ } catch (e) {
153
+ onVizStateUpdate(false, false, e._message);
154
+ setSheetSize({});
155
+ }
156
+ };
157
+
158
+ const addExtraFilters = (extraFilters) => {
159
+ const worksheets =
160
+ viz.current.getWorkbook().getActiveSheet().getWorksheets() || [];
161
+
162
+ worksheets.forEach((worksheet) => {
163
+ if (worksheet.getSheetType() === tableau.DashboardObjectType.WORKSHEET) {
164
+ Object.keys(extraFilters).forEach((filter) => {
165
+ if (!extraFilters[filter]) {
166
+ worksheet.clearFilterAsync(filter);
167
+ } else {
168
+ worksheet.applyFilterAsync(
169
+ filter,
170
+ extraFilters[filter],
171
+ tableau.FilterUpdateType.REPLACE,
172
+ );
173
+ }
174
+ });
175
+ }
176
+ });
177
+ };
178
+
179
+ const updateScale = () => {
180
+ const tableauEl = vizEl.current;
181
+ const tableau = tableauEl.querySelector('iframe');
182
+ const { sheetSize = {} } = viz.current.getVizSize() || {};
183
+ const vizWidth = sheetSize?.minSize?.width || 1;
184
+ const vizHeight = sheetSize?.minSize?.height || 0;
185
+ const scale = Math.min(tableauEl.clientWidth / vizWidth, 1);
186
+ tableau.style.transform = `scale(${scale})`;
187
+ tableau.style.width = `${100 / scale}%`;
188
+ tableauEl.style.height = `${scale * vizHeight}px`;
189
+ };
190
+
191
+ React.useEffect(() => {
192
+ if (tableau && url) {
193
+ initViz();
194
+ } else {
195
+ disposeViz();
196
+ }
197
+
198
+ return () => {
199
+ disposeViz();
200
+ };
201
+ /* eslint-disable-next-line */
202
+ }, [
203
+ hideTabs,
204
+ hideToolbar,
205
+ autoScale,
206
+ sheetname,
207
+ tableau,
208
+ toolbarPosition,
209
+ url,
210
+ ]);
211
+
212
+ React.useEffect(() => {
213
+ if (vizState.current.loaded && viz.current) {
214
+ addExtraFilters(extraFilters);
215
+ }
216
+ /* eslint-disable-next-line */
217
+ }, [JSON.stringify(extraFilters)]);
218
+
219
+ React.useEffect(() => {
220
+ if (vizState.current.loaded && viz.current && autoScale) {
221
+ updateScale();
222
+ }
223
+ /* eslint-disable-next-line */
224
+ }, [loaded, screen?.page?.width]);
225
+
226
+ return (
227
+ <div className="tableau-wrapper">
228
+ {loading && (
229
+ <div
230
+ className="tableau-loader"
231
+ style={{ ...(sheetSize.width ? { width: sheetSize.width } : {}) }}
232
+ >
233
+ <span>Loading...</span>
234
+ </div>
235
+ )}
236
+ <TableauDebug
237
+ mode={props.mode}
238
+ vizState={{ loaded, loading, error }}
239
+ url={url}
240
+ version={version}
241
+ sheetSize={sheetSize}
242
+ />
243
+ <div
244
+ className={cx('tableau', `tableau-${version}`, {
245
+ 'tableau-scale': autoScale,
246
+ })}
247
+ ref={vizEl}
248
+ />
249
+ <div
250
+ className="tableau-info"
251
+ style={{ ...(sheetSize.width ? { width: sheetSize.width } : {}) }}
252
+ >
253
+ {with_sources && loaded && <Sources sources={sources} />}
254
+ {with_download && loaded && <Download viz={viz.current} />}
255
+ {with_share && loaded && <Share viz={viz.current} />}
256
+ </div>
257
+ </div>
258
+ );
259
+ };
260
+
261
+ export default connect((state) => ({
262
+ screen: state.screen,
263
+ }))(Tableau);
@@ -0,0 +1,72 @@
1
+ import React from 'react';
2
+ import { Button, Popup } from 'semantic-ui-react';
3
+ import cx from 'classnames';
4
+ import { Icon } from '@plone/volto/components';
5
+ import downloadSVG from '@eeacms/volto-tableau/icons/download.svg';
6
+
7
+ const Download = ({ viz }) => {
8
+ const [expanded, setExpanded] = React.useState(false);
9
+ const popupRef = React.useRef();
10
+
11
+ return (
12
+ <Popup
13
+ popper={{ id: 'tableau-download-popup' }}
14
+ trigger={
15
+ <div className="tableau-download-container">
16
+ <button className={cx('tableau-download-button', { expanded })}>
17
+ <span>Download data</span>
18
+ <Icon name={downloadSVG} size="24px" />
19
+ </button>
20
+ </div>
21
+ }
22
+ position="bottom left"
23
+ on="click"
24
+ onClose={() => {
25
+ setExpanded(false);
26
+ }}
27
+ onOpen={() => {
28
+ setExpanded(true);
29
+ }}
30
+ ref={popupRef}
31
+ >
32
+ <Button
33
+ color="primary"
34
+ onClick={() => {
35
+ viz.showExportImageDialog();
36
+ popupRef.current.triggerRef.current.click();
37
+ }}
38
+ >
39
+ Image
40
+ </Button>
41
+ <Button
42
+ color="primary"
43
+ onClick={() => {
44
+ viz.showExportPDFDialog();
45
+ popupRef.current.triggerRef.current.click();
46
+ }}
47
+ >
48
+ PDF
49
+ </Button>
50
+ <Button
51
+ color="primary"
52
+ onClick={() => {
53
+ viz.showExportCrossTabDialog();
54
+ popupRef.current.triggerRef.current.click();
55
+ }}
56
+ >
57
+ CSV
58
+ </Button>
59
+ <Button
60
+ color="primary"
61
+ onClick={() => {
62
+ viz.exportCrossTabToExcel();
63
+ popupRef.current.triggerRef.current.click();
64
+ }}
65
+ >
66
+ Excel
67
+ </Button>
68
+ </Popup>
69
+ );
70
+ };
71
+
72
+ export default Download;
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import { Icon } from '@plone/volto/components';
3
+ import shareSVG from '@plone/volto/icons/share.svg';
4
+
5
+ const Share = ({ viz }) => {
6
+ return (
7
+ <div className="tableau-share-container">
8
+ <button
9
+ className="tableau-share-button"
10
+ onClick={() => {
11
+ viz.showShareDialog();
12
+ }}
13
+ >
14
+ <span>Share</span>
15
+ <Icon name={shareSVG} size="24px" />
16
+ </button>
17
+ </div>
18
+ );
19
+ };
20
+
21
+ export default Share;
@@ -0,0 +1,66 @@
1
+ import React from 'react';
2
+ import cx from 'classnames';
3
+ import { Popup } from 'semantic-ui-react';
4
+ import { UniversalLink } from '@plone/volto/components';
5
+
6
+ const Link = ({ children, ...props }) => {
7
+ if (props.href) {
8
+ return <UniversalLink {...props}>{children}</UniversalLink>;
9
+ }
10
+ return <span {...props}>{children}</span>;
11
+ };
12
+
13
+ const Source = ({ source }) => {
14
+ return (
15
+ <>
16
+ <Link className="embed-sources-param-title" href={source.link}>
17
+ {source.title},{' '}
18
+ <span className="embed-sources-param-description">
19
+ {source.organisation}
20
+ </span>
21
+ </Link>
22
+ </>
23
+ );
24
+ };
25
+
26
+ const SourcesWidget = ({ sources }) => {
27
+ const [expanded, setExpanded] = React.useState(false);
28
+
29
+ return (
30
+ <div className="tableau-sources-container">
31
+ <Popup
32
+ content={
33
+ sources?.length ? (
34
+ <ol className="sources-list">
35
+ {sources?.map((source, index) => {
36
+ return (
37
+ <li key={index}>
38
+ <Source source={source} />
39
+ </li>
40
+ );
41
+ })}
42
+ </ol>
43
+ ) : (
44
+ <p>Data provenance is not set for this visualization.</p>
45
+ )
46
+ }
47
+ position="bottom left"
48
+ popper={{ id: 'tableau-sources-popup' }}
49
+ trigger={
50
+ <button className={cx('tableau-sources-button', { expanded })}>
51
+ Sources
52
+ </button>
53
+ }
54
+ on="click"
55
+ onClose={() => {
56
+ setExpanded(false);
57
+ }}
58
+ onOpen={() => {
59
+ setExpanded(true);
60
+ }}
61
+ />
62
+ </div>
63
+ );
64
+ };
65
+
66
+ export default SourcesWidget;
@@ -1,41 +1,21 @@
1
1
  import React from 'react';
2
- import TableauView from '../TableauBlock/View';
2
+ import { Container } from 'semantic-ui-react';
3
+ import Tableau from '@eeacms/volto-tableau/Tableau/Tableau';
3
4
 
4
5
  const VisualizationView = (props) => {
5
- const [tableauError, setTableauError] = React.useState('');
6
6
  const { content = {} } = props;
7
- const { tableau_visualization_data = {} } = content;
7
+ const { tableau_visualization = {}, data_provenance = {} } = content;
8
8
 
9
- const TableauNotDisplayed = () => {
10
- return (
11
- <div className="tableau-block not_displayed_tableau">
12
- <div className="tableau-info">
13
- {!tableau_visualization_data.general?.url ? (
14
- <p className="tableau-error">URL required</p>
15
- ) : tableauError ? (
16
- <p className="tableau-error">{tableauError}</p>
17
- ) : (
18
- ''
19
- )}
20
- </div>
21
- </div>
22
- );
23
- };
24
9
  return (
25
- <div>
26
- {!tableau_visualization_data?.general?.url || tableauError ? (
27
- <TableauNotDisplayed />
28
- ) : (
29
- <TableauView
30
- setTableauError={setTableauError}
31
- data={{
32
- ...tableau_visualization_data.general,
33
- ...tableau_visualization_data.options,
34
- ...tableau_visualization_data.extraOptions,
35
- }}
36
- />
37
- )}
38
- </div>
10
+ <Container id="page-document">
11
+ <Tableau
12
+ data={tableau_visualization}
13
+ with_sources={true}
14
+ with_download={true}
15
+ with_share={true}
16
+ sources={data_provenance.data || []}
17
+ />
18
+ </Container>
39
19
  );
40
20
  };
41
21
 
@@ -1,77 +1,82 @@
1
1
  import React from 'react';
2
2
  import { Modal, Button, Grid } from 'semantic-ui-react';
3
- import '@eeacms/volto-tableau/less/tableau.less';
4
3
  import config from '@plone/volto/registry';
5
-
6
4
  import { FormFieldWrapper, InlineForm } from '@plone/volto/components';
5
+ import Tableau from '@eeacms/volto-tableau/Tableau/Tableau';
6
+ import getSchema from './schema';
7
7
 
8
- import TableauView from '../TableauBlock/View';
9
- import Schema from './schema';
8
+ import '@eeacms/volto-tableau/less/tableau.less';
10
9
 
11
10
  const VisualizationWidget = (props) => {
12
11
  const [open, setOpen] = React.useState(false);
13
- const { onChange = {}, id } = props;
14
-
15
- const block = React.useMemo(() => props.block, [props.block]);
16
- const value = React.useMemo(() => props.value, [props.value]);
17
-
18
- const [intValue, setIntValue] = React.useState(value);
19
- const [tableauError, setTableauError] = React.useState('');
20
-
21
- const dataForm = { tableau_data: intValue };
12
+ const [schema] = React.useState(getSchema(config));
13
+ const [value, setValue] = React.useState(props.value);
22
14
 
23
15
  const handleApplyChanges = () => {
24
- onChange(id, intValue);
16
+ props.onChange(props.id, value);
25
17
  setOpen(false);
26
18
  };
27
19
 
28
20
  const handleClose = () => {
29
- setIntValue(value);
21
+ setValue(props.value);
30
22
  setOpen(false);
31
23
  };
32
24
 
33
- const handleChangeField = (val) => {
34
- setIntValue(val);
35
- };
36
-
37
- const TableauNotDisplayed = () => {
38
- return (
39
- <div className="tableau-block not_displayed_tableau">
40
- <div className="tableau-info">
41
- {intValue && intValue.general && !intValue.general.url ? (
42
- <p className="tableau-error">URL required</p>
43
- ) : tableauError ? (
44
- <p className="tableau-error">{tableauError}</p>
45
- ) : (
46
- ''
47
- )}
48
- </div>
49
- </div>
50
- );
51
- };
52
-
53
- let schema = Schema(config);
54
-
55
- React.useEffect(() => {
56
- if (!intValue?.options) {
57
- setIntValue({
58
- ...intValue,
59
- options: {
60
- autoScale: false,
61
- hideTabs: false,
62
- hideToolbar: false,
63
- toolbarPosition: 'Top',
64
- },
65
- });
66
- }
67
- // eslint-disable-next-line react-hooks/exhaustive-deps
68
- }, []);
69
-
70
25
  return (
71
26
  <FormFieldWrapper {...props}>
72
- <div className="wrapper">
27
+ <Modal id="tableau-editor-modal" open={open}>
28
+ <Modal.Content scrolling>
29
+ <Grid>
30
+ <Grid.Column
31
+ mobile={4}
32
+ tablet={4}
33
+ computer={4}
34
+ className="tableau-editor-column"
35
+ >
36
+ <InlineForm
37
+ block={props.block}
38
+ schema={schema}
39
+ onChangeField={(id, fieldValue) => {
40
+ setValue((value) => ({
41
+ ...value,
42
+ [id]: fieldValue,
43
+ }));
44
+ }}
45
+ formData={value}
46
+ />
47
+ </Grid.Column>
48
+ <Grid.Column
49
+ mobile={8}
50
+ tablet={8}
51
+ computer={8}
52
+ className="tableau-visualization-column"
53
+ >
54
+ <Tableau
55
+ data={value}
56
+ onChangeBlock={(_, newValue) => {
57
+ setValue(newValue);
58
+ }}
59
+ mode="edit"
60
+ noSizeUpdate
61
+ />
62
+ </Grid.Column>
63
+ </Grid>
64
+ </Modal.Content>
65
+ <Modal.Actions>
66
+ <Grid>
67
+ <Grid.Row>
68
+ <div className="map-edit-actions-container">
69
+ <Button onClick={handleClose}>Close</Button>
70
+ <Button color="green" onClick={handleApplyChanges}>
71
+ Apply changes
72
+ </Button>
73
+ </div>
74
+ </Grid.Row>
75
+ </Grid>
76
+ </Modal.Actions>
77
+ </Modal>
78
+ <div>
73
79
  <Button
74
- floated="right"
75
80
  size="tiny"
76
81
  onClick={(e) => {
77
82
  e.preventDefault();
@@ -82,76 +87,7 @@ const VisualizationWidget = (props) => {
82
87
  Open Tableau Editor
83
88
  </Button>
84
89
  </div>
85
-
86
- {open && (
87
- <Modal
88
- id="tableau-editor-modal"
89
- style={{ width: '95% !important' }}
90
- open={true}
91
- >
92
- <Modal.Content scrolling>
93
- <Grid stackable reversed="mobile vertically tablet vertically">
94
- <Grid.Column
95
- mobile={12}
96
- tablet={12}
97
- computer={5}
98
- className="tableau-editor-column"
99
- >
100
- <InlineForm
101
- block={block}
102
- schema={schema}
103
- onChangeField={(id, value) => {
104
- handleChangeField(value);
105
- }}
106
- formData={dataForm}
107
- />
108
- </Grid.Column>
109
- <Grid.Column mobile={12} tablet={12} computer={7}>
110
- {(intValue && intValue.general && !intValue.general.url) ||
111
- tableauError ? (
112
- <TableauNotDisplayed />
113
- ) : (
114
- <div className="tableau-container">
115
- <TableauView
116
- setTableauError={setTableauError}
117
- data={{
118
- ...intValue?.general,
119
- ...intValue?.options,
120
- ...intValue?.extraOptions,
121
- }}
122
- />
123
- </div>
124
- )}
125
- </Grid.Column>
126
- </Grid>
127
- </Modal.Content>
128
- <Modal.Actions>
129
- <Grid>
130
- <Grid.Row>
131
- <div className="map-edit-actions-container">
132
- <Button onClick={handleClose}>Close</Button>
133
- <Button color="green" onClick={handleApplyChanges}>
134
- Apply changes
135
- </Button>
136
- </div>
137
- </Grid.Row>
138
- </Grid>
139
- </Modal.Actions>
140
- </Modal>
141
- )}
142
- {(intValue && intValue.general && !intValue.general.url) ||
143
- tableauError ? (
144
- <TableauNotDisplayed />
145
- ) : (
146
- <TableauView
147
- setTableauError={setTableauError}
148
- data={{
149
- ...value?.general,
150
- ...value?.options,
151
- ...value?.extraOptions,
152
- }}
153
- />
154
- )}
90
+ <Tableau data={props.value} noSizeUpdate />
155
91
  </FormFieldWrapper>
156
92
  );
157
93
  };