@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.
- package/CHANGELOG.md +14 -7
- package/Jenkinsfile +2 -0
- package/jest-addon.config.js +2 -2
- package/package.json +1 -1
- package/src/Blocks/EmbedTableauVisualization/Edit.jsx +31 -0
- package/src/Blocks/EmbedTableauVisualization/View.jsx +63 -0
- package/src/Blocks/EmbedTableauVisualization/index.js +30 -0
- package/src/Blocks/{EmbedEEATableauBlock → EmbedTableauVisualization}/schema.js +29 -13
- package/src/{TableauBlock → Blocks/TableauBlock}/Edit.jsx +3 -2
- package/src/{TableauBlock → Blocks/TableauBlock}/View.jsx +29 -40
- package/src/Blocks/TableauBlock/index.js +30 -0
- package/src/{TableauBlock → Blocks/TableauBlock}/schema.js +50 -2
- package/src/Blocks/index.js +9 -0
- package/src/Tableau/Tableau.jsx +263 -0
- package/src/Utils/Download/Download.jsx +72 -0
- package/src/Utils/Share/Share.jsx +21 -0
- package/src/Utils/Sources/Sources.jsx +66 -0
- package/src/Views/VisualizationView.jsx +12 -32
- package/src/Widgets/VisualizationWidget.jsx +60 -124
- package/src/Widgets/schema.js +62 -131
- package/src/helpers.js +15 -34
- package/src/hooks.js +18 -0
- package/src/icons/download.svg +5 -0
- package/src/index.js +4 -66
- package/src/less/tableau.less +131 -72
- package/src/less/tableau.variables +6 -13
- package/src/Blocks/EmbedEEATableauBlock/Edit.jsx +0 -56
- package/src/Blocks/EmbedEEATableauBlock/View.jsx +0 -74
- package/src/ConnectedTableau/ConnectedTableau.jsx +0 -29
- package/src/CustomWidgets/UrlParamsWidget.jsx +0 -29
- package/src/DownloadExtras/TableauDownload.jsx +0 -124
- package/src/DownloadExtras/TableauFullscreen.jsx +0 -78
- package/src/DownloadExtras/TableauShare.jsx +0 -81
- package/src/DownloadExtras/style.less +0 -152
- package/src/Sources/Sources.jsx +0 -50
- package/src/Sources/index.js +0 -3
- package/src/Sources/style.css +0 -7
- package/src/Tableau/View.jsx +0 -254
- package/src/Widgets/style.less +0 -8
- package/src/actions.js +0 -9
- package/src/constants.js +0 -1
- package/src/downloadHelpers/downloadHelpers.js +0 -25
- package/src/middleware.js +0 -39
- package/src/store.js +0 -72
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import BlockDataForm from '@plone/volto/components/manage/Form/BlockDataForm';
|
|
3
|
-
import { SidebarPortal } from '@plone/volto/components';
|
|
4
|
-
import { getContent } from '@plone/volto/actions';
|
|
5
|
-
import View from './View';
|
|
6
|
-
import Schema from './schema';
|
|
7
|
-
|
|
8
|
-
import { connect } from 'react-redux';
|
|
9
|
-
import { compose } from 'redux';
|
|
10
|
-
|
|
11
|
-
const Edit = (props) => {
|
|
12
|
-
const { block, onChangeBlock, id } = props;
|
|
13
|
-
const data = React.useMemo(() => props.data || {}, [props.data]);
|
|
14
|
-
const schema = React.useMemo(() => Schema(props), [props]);
|
|
15
|
-
|
|
16
|
-
React.useEffect(() => {
|
|
17
|
-
if (!Object.hasOwn(data, 'show_sources')) {
|
|
18
|
-
onChangeBlock(block, {
|
|
19
|
-
...data,
|
|
20
|
-
show_sources: true,
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
}, [block, data, onChangeBlock]);
|
|
24
|
-
|
|
25
|
-
return (
|
|
26
|
-
<React.Fragment>
|
|
27
|
-
<View {...props} data={data} id={id} mode="edit" />
|
|
28
|
-
<SidebarPortal selected={props.selected}>
|
|
29
|
-
<BlockDataForm
|
|
30
|
-
block={block}
|
|
31
|
-
title={schema.title}
|
|
32
|
-
schema={schema}
|
|
33
|
-
onChangeField={(id, value) => {
|
|
34
|
-
props.onChangeBlock(block, {
|
|
35
|
-
...data,
|
|
36
|
-
[id]: value,
|
|
37
|
-
});
|
|
38
|
-
}}
|
|
39
|
-
formData={data}
|
|
40
|
-
/>
|
|
41
|
-
</SidebarPortal>
|
|
42
|
-
</React.Fragment>
|
|
43
|
-
);
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
export default compose(
|
|
47
|
-
connect(
|
|
48
|
-
(state, props) => ({
|
|
49
|
-
block_data: state.content.data,
|
|
50
|
-
data_provenance: state.content.subrequests?.[props.id]?.data_provenance,
|
|
51
|
-
}),
|
|
52
|
-
{
|
|
53
|
-
getContent,
|
|
54
|
-
},
|
|
55
|
-
),
|
|
56
|
-
)(React.memo(Edit));
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import ConnectedTableau from '../../ConnectedTableau/ConnectedTableau';
|
|
3
|
-
import { Sources } from '../../Sources';
|
|
4
|
-
import { PrivacyProtection } from '@eeacms/volto-embed';
|
|
5
|
-
|
|
6
|
-
import { getContent } from '@plone/volto/actions';
|
|
7
|
-
|
|
8
|
-
import { connect } from 'react-redux';
|
|
9
|
-
import { compose } from 'redux';
|
|
10
|
-
|
|
11
|
-
const View = (props) => {
|
|
12
|
-
const { data_provenance, tableau_visualization } = props || {};
|
|
13
|
-
const data = React.useMemo(() => props.data || {}, [props.data]);
|
|
14
|
-
const { vis_url = '' } = data;
|
|
15
|
-
const show_sources = data?.show_sources ?? false;
|
|
16
|
-
|
|
17
|
-
React.useEffect(() => {
|
|
18
|
-
if (vis_url) {
|
|
19
|
-
props.getContent(vis_url, null, props.id);
|
|
20
|
-
}
|
|
21
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
22
|
-
}, [vis_url]);
|
|
23
|
-
|
|
24
|
-
return (
|
|
25
|
-
<div className="embed-container">
|
|
26
|
-
<PrivacyProtection
|
|
27
|
-
{...props}
|
|
28
|
-
data={{ ...data, url: tableau_visualization?.general?.url }}
|
|
29
|
-
>
|
|
30
|
-
{data?.vis_url ? (
|
|
31
|
-
<>
|
|
32
|
-
{tableau_visualization?.general?.url ? (
|
|
33
|
-
<>
|
|
34
|
-
<ConnectedTableau
|
|
35
|
-
{...props.tableau_visualization}
|
|
36
|
-
id={props.id}
|
|
37
|
-
{...props}
|
|
38
|
-
/>
|
|
39
|
-
|
|
40
|
-
{show_sources &&
|
|
41
|
-
data_provenance &&
|
|
42
|
-
data_provenance?.data?.data_provenance &&
|
|
43
|
-
tableau_visualization ? (
|
|
44
|
-
<Sources sources={data_provenance.data.data_provenance} />
|
|
45
|
-
) : show_sources ? (
|
|
46
|
-
<div>Data provenance is not set in the visualization</div>
|
|
47
|
-
) : (
|
|
48
|
-
''
|
|
49
|
-
)}
|
|
50
|
-
</>
|
|
51
|
-
) : !tableau_visualization?.general?.url ? (
|
|
52
|
-
<div>Url is not set in the visualization</div>
|
|
53
|
-
) : null}
|
|
54
|
-
</>
|
|
55
|
-
) : (
|
|
56
|
-
<div>Please select a visualization from block editor.</div>
|
|
57
|
-
)}
|
|
58
|
-
</PrivacyProtection>
|
|
59
|
-
</div>
|
|
60
|
-
);
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
export default compose(
|
|
64
|
-
connect(
|
|
65
|
-
(state, props) => ({
|
|
66
|
-
data_provenance: state.content.subrequests?.[props.id],
|
|
67
|
-
tableau_visualization:
|
|
68
|
-
state.content.subrequests?.[props.id]?.data?.tableau_visualization_data,
|
|
69
|
-
}),
|
|
70
|
-
{
|
|
71
|
-
getContent,
|
|
72
|
-
},
|
|
73
|
-
),
|
|
74
|
-
)(React.memo(View));
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import Tableau from '@eeacms/volto-tableau/Tableau/View';
|
|
3
|
-
|
|
4
|
-
const ConnectedTableau = (props) => {
|
|
5
|
-
const [error, setError] = React.useState(null);
|
|
6
|
-
const [loaded, setLoaded] = React.useState(null);
|
|
7
|
-
return (
|
|
8
|
-
<div className="tableau-block">
|
|
9
|
-
{loaded && props.mode === 'edit' ? (
|
|
10
|
-
<div className="tableau-info">
|
|
11
|
-
<h3 className="tableau-version">== Tableau ==</h3>
|
|
12
|
-
</div>
|
|
13
|
-
) : (
|
|
14
|
-
''
|
|
15
|
-
)}
|
|
16
|
-
<Tableau
|
|
17
|
-
error={error}
|
|
18
|
-
loaded={loaded}
|
|
19
|
-
setError={setError}
|
|
20
|
-
setLoaded={setLoaded}
|
|
21
|
-
data={{ ...props?.general, ...props?.options, ...props?.extraOptions }}
|
|
22
|
-
url={props?.general?.url}
|
|
23
|
-
{...props}
|
|
24
|
-
/>
|
|
25
|
-
</div>
|
|
26
|
-
);
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export default ConnectedTableau;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import '@eeacms/volto-tableau/less/tableau.less';
|
|
3
|
-
|
|
4
|
-
const UrlParamsWidget = () => {
|
|
5
|
-
const fields = [
|
|
6
|
-
'embed',
|
|
7
|
-
'isGuestRedirectFromVizportal',
|
|
8
|
-
'showShareOptions',
|
|
9
|
-
'jsdebug',
|
|
10
|
-
'sheetname',
|
|
11
|
-
'display_count',
|
|
12
|
-
'showVizHome',
|
|
13
|
-
'origin',
|
|
14
|
-
'device',
|
|
15
|
-
];
|
|
16
|
-
|
|
17
|
-
return (
|
|
18
|
-
<div className="availableFieldsContainer">
|
|
19
|
-
<p className="availableFieldsTitle">Available Fields:</p>
|
|
20
|
-
{fields.map((field) => (
|
|
21
|
-
<p className="availableFields">
|
|
22
|
-
<strong>{field}</strong>
|
|
23
|
-
</p>
|
|
24
|
-
))}
|
|
25
|
-
</div>
|
|
26
|
-
);
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export default UrlParamsWidget;
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Popup, Button, Modal, Dropdown } from 'semantic-ui-react';
|
|
3
|
-
import { Icon } from '@plone/volto/components';
|
|
4
|
-
import downloadSVG from '@plone/volto/icons/download.svg';
|
|
5
|
-
|
|
6
|
-
const TableauDownload = (props) => {
|
|
7
|
-
const viz = props.viz || {};
|
|
8
|
-
|
|
9
|
-
const [open, setOpen] = React.useState(false);
|
|
10
|
-
const [
|
|
11
|
-
isSheetSelectorCsvVisible,
|
|
12
|
-
setIsSheetSelectorCsvVisible,
|
|
13
|
-
] = React.useState(false);
|
|
14
|
-
const [
|
|
15
|
-
isSheetSelectorExcelVisible,
|
|
16
|
-
setIsSheetSelectorExcelVisible,
|
|
17
|
-
] = React.useState(false);
|
|
18
|
-
const [availableSheets, setAvailableSheets] = React.useState([]);
|
|
19
|
-
|
|
20
|
-
const initializeDropdown = () => {
|
|
21
|
-
const sheets = viz
|
|
22
|
-
?.getWorkbook()
|
|
23
|
-
?.getActiveSheet()
|
|
24
|
-
?.getWorksheets()
|
|
25
|
-
.map((sheet, index) => ({
|
|
26
|
-
key: index,
|
|
27
|
-
text: sheet.getName(),
|
|
28
|
-
value: sheet.getName(),
|
|
29
|
-
}));
|
|
30
|
-
setAvailableSheets(sheets);
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const exportImage = () => {
|
|
34
|
-
setIsSheetSelectorCsvVisible(false);
|
|
35
|
-
setIsSheetSelectorExcelVisible(false);
|
|
36
|
-
viz.showExportImageDialog();
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const exportToCSV = () => {
|
|
40
|
-
setIsSheetSelectorExcelVisible(false);
|
|
41
|
-
initializeDropdown();
|
|
42
|
-
setIsSheetSelectorCsvVisible(true);
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const exportToExcel = () => {
|
|
46
|
-
setIsSheetSelectorCsvVisible(false);
|
|
47
|
-
initializeDropdown();
|
|
48
|
-
setIsSheetSelectorExcelVisible(true);
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
const handleSheetSelectionCsvChange = (e, data) => {
|
|
52
|
-
viz.showExportCrossTabDialog(data.value);
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const handleSheetSelectionExcelChange = (e, data) => {
|
|
56
|
-
viz.exportCrossTabToExcel(data.value);
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const hideDropdowns = () => {
|
|
60
|
-
setIsSheetSelectorCsvVisible(false);
|
|
61
|
-
setIsSheetSelectorExcelVisible(false);
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
return (
|
|
65
|
-
<>
|
|
66
|
-
<Popup
|
|
67
|
-
basic
|
|
68
|
-
className="tableau-download-dialog"
|
|
69
|
-
position="top center"
|
|
70
|
-
on="click"
|
|
71
|
-
trigger={
|
|
72
|
-
<div className="toolbar-button-wrapper">
|
|
73
|
-
<Button
|
|
74
|
-
className="toolbar-button"
|
|
75
|
-
title="Download"
|
|
76
|
-
onClick={hideDropdowns}
|
|
77
|
-
>
|
|
78
|
-
<Icon name={downloadSVG} size="26px" />
|
|
79
|
-
</Button>
|
|
80
|
-
<span className="btn-text">Save</span>
|
|
81
|
-
</div>
|
|
82
|
-
}
|
|
83
|
-
>
|
|
84
|
-
<Popup.Header>Download</Popup.Header>
|
|
85
|
-
<Popup.Content>
|
|
86
|
-
<p>Select your file format.</p>
|
|
87
|
-
<Button onClick={exportImage}>Image</Button>
|
|
88
|
-
<Button onClick={exportToCSV}>CSV</Button>
|
|
89
|
-
{isSheetSelectorCsvVisible ? (
|
|
90
|
-
<Dropdown
|
|
91
|
-
placeholder="Sheet"
|
|
92
|
-
selection
|
|
93
|
-
options={availableSheets}
|
|
94
|
-
onChange={handleSheetSelectionCsvChange}
|
|
95
|
-
/>
|
|
96
|
-
) : null}
|
|
97
|
-
<Button onClick={exportToExcel}>Excel</Button>
|
|
98
|
-
{isSheetSelectorExcelVisible ? (
|
|
99
|
-
<Dropdown
|
|
100
|
-
placeholder="Sheet"
|
|
101
|
-
selection
|
|
102
|
-
options={availableSheets}
|
|
103
|
-
onChange={handleSheetSelectionExcelChange}
|
|
104
|
-
/>
|
|
105
|
-
) : null}
|
|
106
|
-
</Popup.Content>
|
|
107
|
-
</Popup>
|
|
108
|
-
|
|
109
|
-
<Modal onClose={() => setOpen(false)} open={open}>
|
|
110
|
-
<Modal.Content>
|
|
111
|
-
Permissions are required to download the workbook.
|
|
112
|
-
</Modal.Content>
|
|
113
|
-
|
|
114
|
-
<Modal.Actions>
|
|
115
|
-
<Button primary onClick={() => setOpen(false)}>
|
|
116
|
-
OK
|
|
117
|
-
</Button>
|
|
118
|
-
</Modal.Actions>
|
|
119
|
-
</Modal>
|
|
120
|
-
</>
|
|
121
|
-
);
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
export default TableauDownload;
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Modal, Button } from 'semantic-ui-react';
|
|
3
|
-
import { Icon } from '@plone/volto/components';
|
|
4
|
-
import { useHistory, useLocation } from 'react-router-dom';
|
|
5
|
-
import fullscreenSVG from '@plone/volto/icons/fullscreen.svg';
|
|
6
|
-
|
|
7
|
-
import config from '@plone/volto/registry';
|
|
8
|
-
|
|
9
|
-
const TableauFullscreen = (props) => {
|
|
10
|
-
const tableau_url = props.data.url;
|
|
11
|
-
const modalHash = props?.item.getId + '_preview';
|
|
12
|
-
const [open, setOpen] = React.useState(false);
|
|
13
|
-
const history = useHistory();
|
|
14
|
-
const location = useLocation();
|
|
15
|
-
const {
|
|
16
|
-
blocks: { blocksConfig },
|
|
17
|
-
} = config;
|
|
18
|
-
const TableauBlockView = blocksConfig.tableau_block.view;
|
|
19
|
-
|
|
20
|
-
React.useEffect(() => {
|
|
21
|
-
if (location.hash.includes(modalHash)) {
|
|
22
|
-
setOpen(true);
|
|
23
|
-
} else {
|
|
24
|
-
setOpen(false);
|
|
25
|
-
}
|
|
26
|
-
}, [location, modalHash]);
|
|
27
|
-
|
|
28
|
-
const closeModal = () => {
|
|
29
|
-
history.push({
|
|
30
|
-
hash: '',
|
|
31
|
-
});
|
|
32
|
-
setOpen(false);
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
return (
|
|
36
|
-
<>
|
|
37
|
-
<div className="toolbar-button-wrapper">
|
|
38
|
-
<Button
|
|
39
|
-
className="toolbar-button"
|
|
40
|
-
title="Full Screen"
|
|
41
|
-
onClick={() => {
|
|
42
|
-
setOpen(true);
|
|
43
|
-
if (props.item) {
|
|
44
|
-
history.push({
|
|
45
|
-
hash: props.item.getId + '_preview',
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
}}
|
|
49
|
-
>
|
|
50
|
-
<Icon name={fullscreenSVG} size="23px" />
|
|
51
|
-
</Button>
|
|
52
|
-
<span className="btn-text">Enlarge</span>
|
|
53
|
-
</div>
|
|
54
|
-
|
|
55
|
-
<Modal
|
|
56
|
-
className="tableau-fullscreen"
|
|
57
|
-
onClose={closeModal}
|
|
58
|
-
onOpen={() => setOpen(true)}
|
|
59
|
-
open={open}
|
|
60
|
-
>
|
|
61
|
-
<Modal.Content>
|
|
62
|
-
<TableauBlockView
|
|
63
|
-
{...props}
|
|
64
|
-
data={{ url: tableau_url, hideToolbar: true }}
|
|
65
|
-
></TableauBlockView>
|
|
66
|
-
</Modal.Content>
|
|
67
|
-
|
|
68
|
-
<Modal.Actions>
|
|
69
|
-
<Button primary onClick={closeModal}>
|
|
70
|
-
Close
|
|
71
|
-
</Button>
|
|
72
|
-
</Modal.Actions>
|
|
73
|
-
</Modal>
|
|
74
|
-
</>
|
|
75
|
-
);
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
export default TableauFullscreen;
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Popup, Tab, Button, Menu, Input } from 'semantic-ui-react';
|
|
3
|
-
import { Icon } from '@plone/volto/components';
|
|
4
|
-
import useCopyToClipboard from '../downloadHelpers/downloadHelpers';
|
|
5
|
-
|
|
6
|
-
import shareSVG from '@plone/volto/icons/share.svg';
|
|
7
|
-
import linkSVG from '@plone/volto/icons/link.svg';
|
|
8
|
-
|
|
9
|
-
import cx from 'classnames';
|
|
10
|
-
|
|
11
|
-
const TableauShare = (props) => {
|
|
12
|
-
const tableau_url = props.data.url;
|
|
13
|
-
|
|
14
|
-
const CopyUrlButton = ({ url, buttonText }) => {
|
|
15
|
-
const [copyUrlStatus, copyUrl] = useCopyToClipboard(url);
|
|
16
|
-
|
|
17
|
-
if (copyUrlStatus === 'copied') {
|
|
18
|
-
buttonText = 'Copied!';
|
|
19
|
-
} else if (copyUrlStatus === 'failed') {
|
|
20
|
-
buttonText = 'Copy failed. Please try again.';
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return (
|
|
24
|
-
<Button
|
|
25
|
-
primary
|
|
26
|
-
onClick={copyUrl}
|
|
27
|
-
className={cx('copy-button', {
|
|
28
|
-
'green-button': copyUrlStatus === 'copied',
|
|
29
|
-
})}
|
|
30
|
-
>
|
|
31
|
-
{buttonText}
|
|
32
|
-
</Button>
|
|
33
|
-
);
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const panes = [
|
|
37
|
-
{
|
|
38
|
-
menuItem: (
|
|
39
|
-
<Menu.Item key="location">
|
|
40
|
-
<span className="nav-dot">
|
|
41
|
-
<Icon name={linkSVG} size="24px" />
|
|
42
|
-
</span>
|
|
43
|
-
<span className="nav-dot-title">URL</span>
|
|
44
|
-
</Menu.Item>
|
|
45
|
-
),
|
|
46
|
-
render: () => (
|
|
47
|
-
<Tab.Pane>
|
|
48
|
-
<Input defaultValue={tableau_url} />
|
|
49
|
-
<CopyUrlButton url={tableau_url} buttonText="Copy sharing URL" />
|
|
50
|
-
</Tab.Pane>
|
|
51
|
-
),
|
|
52
|
-
},
|
|
53
|
-
];
|
|
54
|
-
|
|
55
|
-
return (
|
|
56
|
-
<Popup
|
|
57
|
-
basic
|
|
58
|
-
className="tableau-share-dialog"
|
|
59
|
-
position="top center"
|
|
60
|
-
on="click"
|
|
61
|
-
trigger={
|
|
62
|
-
<div className="toolbar-button-wrapper">
|
|
63
|
-
<Button className="toolbar-button" title="Share">
|
|
64
|
-
<Icon name={shareSVG} size="26px" />
|
|
65
|
-
</Button>
|
|
66
|
-
<span className="btn-text">Share</span>
|
|
67
|
-
</div>
|
|
68
|
-
}
|
|
69
|
-
>
|
|
70
|
-
<Popup.Header>Share Visualization</Popup.Header>
|
|
71
|
-
<Popup.Content>
|
|
72
|
-
<Tab
|
|
73
|
-
menu={{ secondary: true, pointing: true, fluid: true }}
|
|
74
|
-
panes={panes}
|
|
75
|
-
/>
|
|
76
|
-
</Popup.Content>
|
|
77
|
-
</Popup>
|
|
78
|
-
);
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
export default TableauShare;
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
.dashboard-wrapper {
|
|
2
|
-
display: flex;
|
|
3
|
-
flex-direction: row;
|
|
4
|
-
flex-wrap: wrap;
|
|
5
|
-
background-color: #f5f5f5;
|
|
6
|
-
|
|
7
|
-
.tableau-block {
|
|
8
|
-
position: relative;
|
|
9
|
-
display: flex;
|
|
10
|
-
flex: 1 1;
|
|
11
|
-
flex-direction: column;
|
|
12
|
-
padding: 1em 0.5em;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
.toolbar-button {
|
|
16
|
-
position: relative;
|
|
17
|
-
width: 32px;
|
|
18
|
-
height: 32px;
|
|
19
|
-
padding: 2px !important;
|
|
20
|
-
background-color: #ff421b !important;
|
|
21
|
-
border-radius: 3px !important;
|
|
22
|
-
color: white !important;
|
|
23
|
-
|
|
24
|
-
&:hover {
|
|
25
|
-
opacity: 0.6;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
svg {
|
|
29
|
-
position: absolute;
|
|
30
|
-
top: 50%;
|
|
31
|
-
left: 50%;
|
|
32
|
-
margin: 0 !important;
|
|
33
|
-
fill: #fff !important;
|
|
34
|
-
-webkit-transform: translate(-50%, -50%);
|
|
35
|
-
transform: translate(-50%, -50%);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
.tableau-download-dialog {
|
|
41
|
-
max-width: 282px !important;
|
|
42
|
-
|
|
43
|
-
.header {
|
|
44
|
-
padding: 0.5em 0 !important;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
button {
|
|
48
|
-
display: block;
|
|
49
|
-
width: 100%;
|
|
50
|
-
margin: 5px 0 !important;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
.tableau-share-dialog {
|
|
55
|
-
min-width: 400px !important;
|
|
56
|
-
|
|
57
|
-
.ui.secondary.pointing.menu .item {
|
|
58
|
-
display: flex;
|
|
59
|
-
flex-direction: column;
|
|
60
|
-
padding: 10px 25px;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
.nav-dot-title {
|
|
64
|
-
margin-top: 5px;
|
|
65
|
-
font-size: 14px;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
.ui.secondary.pointing.menu .active.item {
|
|
69
|
-
border-color: #09b;
|
|
70
|
-
|
|
71
|
-
.nav-dot-title {
|
|
72
|
-
font-weight: 500;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
.nav-dot {
|
|
76
|
-
opacity: 1;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
.nav-dot {
|
|
81
|
-
display: flex;
|
|
82
|
-
width: 37px;
|
|
83
|
-
height: 37px;
|
|
84
|
-
align-items: center;
|
|
85
|
-
justify-content: center;
|
|
86
|
-
margin: 8px auto;
|
|
87
|
-
background-color: #09b;
|
|
88
|
-
border-radius: 50%;
|
|
89
|
-
opacity: 0.6;
|
|
90
|
-
|
|
91
|
-
svg {
|
|
92
|
-
fill: #fff !important;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
.ui.secondary.pointing.menu .active.item:hover {
|
|
97
|
-
border-color: #09b;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
.ui.tab {
|
|
101
|
-
.ui.input {
|
|
102
|
-
display: block;
|
|
103
|
-
margin-bottom: 1em;
|
|
104
|
-
|
|
105
|
-
input {
|
|
106
|
-
width: 100%;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
textarea {
|
|
111
|
-
display: block;
|
|
112
|
-
width: 100%;
|
|
113
|
-
height: 100px;
|
|
114
|
-
padding: 6px 12px;
|
|
115
|
-
border: 1px solid grey;
|
|
116
|
-
margin-bottom: 1.5em;
|
|
117
|
-
color: #696969;
|
|
118
|
-
font-family: 'Lucida Console', Monaco, monospace;
|
|
119
|
-
font-size: 13px;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
.copy-button {
|
|
125
|
-
margin-top: 1rem !important;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
.copy-button.green-button {
|
|
129
|
-
background-color: #269b65 !important;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
.toolbar-button-wrapper {
|
|
133
|
-
display: flex;
|
|
134
|
-
flex-direction: column;
|
|
135
|
-
text-align: center;
|
|
136
|
-
|
|
137
|
-
.btn-text {
|
|
138
|
-
font-family: Roboto, Helvetica Neue, Arial, Helvetica, sans-serif;
|
|
139
|
-
font-size: 12px;
|
|
140
|
-
font-weight: 400;
|
|
141
|
-
line-height: 20px;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
.ui.button.toolbar-button {
|
|
145
|
-
margin: 0 7px !important;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
.tableau-icons {
|
|
150
|
-
display: flex;
|
|
151
|
-
flex-direction: row;
|
|
152
|
-
}
|
package/src/Sources/Sources.jsx
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
|
2
|
-
/* eslint-disable jsx-a11y/click-events-have-key-events */
|
|
3
|
-
/* eslint-disable jsx-a11y/anchor-is-valid */
|
|
4
|
-
|
|
5
|
-
import React from 'react';
|
|
6
|
-
import { UniversalLink, Icon } from '@plone/volto/components';
|
|
7
|
-
|
|
8
|
-
import rightKeySVG from '@plone/volto/icons/right-key.svg';
|
|
9
|
-
import downKeySVG from '@plone/volto/icons/down-key.svg';
|
|
10
|
-
|
|
11
|
-
import './style.css';
|
|
12
|
-
|
|
13
|
-
const SourcesWidget = ({ sources }) => {
|
|
14
|
-
const [expand, setExpand] = React.useState(true);
|
|
15
|
-
return (
|
|
16
|
-
<div>
|
|
17
|
-
<a className="embed-sources-header" onClick={() => setExpand(!expand)}>
|
|
18
|
-
<h3>
|
|
19
|
-
<Icon
|
|
20
|
-
name={expand ? downKeySVG : rightKeySVG}
|
|
21
|
-
title={expand ? 'Collapse' : 'Expand'}
|
|
22
|
-
size="17px"
|
|
23
|
-
/>
|
|
24
|
-
Sources:
|
|
25
|
-
</h3>
|
|
26
|
-
</a>
|
|
27
|
-
{expand && (
|
|
28
|
-
<ul>
|
|
29
|
-
{sources &&
|
|
30
|
-
sources.data &&
|
|
31
|
-
sources.data.map((param, i) =>
|
|
32
|
-
param.link ? (
|
|
33
|
-
<li key={i} className="embed-source-param">
|
|
34
|
-
<UniversalLink
|
|
35
|
-
className="embed-sources-param-title"
|
|
36
|
-
href={param.link}
|
|
37
|
-
>
|
|
38
|
-
{param.title}
|
|
39
|
-
</UniversalLink>
|
|
40
|
-
, {param.organisation}
|
|
41
|
-
</li>
|
|
42
|
-
) : null,
|
|
43
|
-
)}
|
|
44
|
-
</ul>
|
|
45
|
-
)}
|
|
46
|
-
</div>
|
|
47
|
-
);
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
export default SourcesWidget;
|
package/src/Sources/index.js
DELETED