@eeacms/volto-tableau 3.0.2 → 3.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,6 +4,18 @@ 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
+ ### [3.0.4](https://github.com/eea/volto-tableau/compare/3.0.3...3.0.4) - 18 January 2023
8
+
9
+ #### :hammer_and_wrench: Others
10
+
11
+ - Fix lint issues [dana-cfc4 - [`9bbf908`](https://github.com/eea/volto-tableau/commit/9bbf908195a9e90c606ebc87042ae3c7a44e7973)]
12
+ - Add available fields, remove default version, manage no version selected [dana-cfc4 - [`66e510e`](https://github.com/eea/volto-tableau/commit/66e510e5f2e47e049e157ab046d0499f14b8f700)]
13
+ ### [3.0.3](https://github.com/eea/volto-tableau/compare/3.0.2...3.0.3) - 17 January 2023
14
+
15
+ #### :hammer_and_wrench: Others
16
+
17
+ - Add volto-embed and volto-block-style addons [dana-cfc4 - [`e557a05`](https://github.com/eea/volto-tableau/commit/e557a0561a46fa7de139d733e72dc17affa8f5e1)]
18
+ - Fix default tableau version, add privacy protection, add style wrapper, add title for tableau edit [dana-cfc4 - [`9859224`](https://github.com/eea/volto-tableau/commit/98592247bd58895bd253411cfce981e639093e85)]
7
19
  ### [3.0.2](https://github.com/eea/volto-tableau/compare/3.0.1...3.0.2) - 13 January 2023
8
20
 
9
21
  #### :hammer_and_wrench: Others
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-tableau",
3
- "version": "3.0.2",
3
+ "version": "3.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",
@@ -17,10 +17,14 @@
17
17
  "url": "git@github.com:eea/volto-tableau.git"
18
18
  },
19
19
  "addons": [
20
- "@eeacms/volto-resize-helper"
20
+ "@eeacms/volto-resize-helper",
21
+ "@eeacms/volto-embed",
22
+ "@eeacms/volto-block-style"
21
23
  ],
22
24
  "dependencies": {
23
- "@eeacms/volto-resize-helper": "^0.2.4"
25
+ "@eeacms/volto-resize-helper": "^0.2.4",
26
+ "@eeacms/volto-embed": "5.0.0",
27
+ "@eeacms/volto-block-style": "4.1.0"
24
28
  },
25
29
  "devDependencies": {
26
30
  "@cypress/code-coverage": "^3.9.5",
@@ -4,11 +4,16 @@ import { SidebarPortal } from '@plone/volto/components';
4
4
  import { getContent } from '@plone/volto/actions';
5
5
  import View from './View';
6
6
  import Schema from './schema';
7
+
8
+ import { BlockStyleWrapperEdit } from '@eeacms/volto-block-style/BlockStyleWrapper';
9
+ import cx from 'classnames';
10
+
7
11
  import { connect } from 'react-redux';
8
12
  import { compose } from 'redux';
9
13
 
10
14
  const Edit = (props) => {
11
- const { data, block, onChangeBlock, id } = props;
15
+ const { block, onChangeBlock, id } = props;
16
+ const data = React.useMemo(() => props.data || {}, [props.data]);
12
17
  const schema = React.useMemo(() => Schema(props), [props]);
13
18
 
14
19
  React.useEffect(() => {
@@ -21,8 +26,21 @@ const Edit = (props) => {
21
26
  }, [block, data, onChangeBlock]);
22
27
 
23
28
  return (
24
- <>
25
- <View data={data} id={id} />
29
+ <BlockStyleWrapperEdit
30
+ {...props}
31
+ role="presentation"
32
+ data={{
33
+ ...(props.data || {}),
34
+ styles: {
35
+ ...(props.data?.styles || {}),
36
+ customClass: cx(
37
+ props.data?.styles?.customClass || '',
38
+ 'custom-embed-class',
39
+ ),
40
+ },
41
+ }}
42
+ >
43
+ <View {...props} data={data} id={id} mode="edit" />
26
44
  <SidebarPortal selected={props.selected}>
27
45
  <BlockDataForm
28
46
  block={block}
@@ -37,7 +55,7 @@ const Edit = (props) => {
37
55
  formData={data}
38
56
  />
39
57
  </SidebarPortal>
40
- </>
58
+ </BlockStyleWrapperEdit>
41
59
  );
42
60
  };
43
61
 
@@ -51,4 +69,4 @@ export default compose(
51
69
  getContent,
52
70
  },
53
71
  ),
54
- )(Edit);
72
+ )(React.memo(Edit));
@@ -1,6 +1,10 @@
1
1
  import React from 'react';
2
2
  import ConnectedTableau from '../../ConnectedTableau/ConnectedTableau';
3
3
  import { Sources } from '../../Sources';
4
+ import { PrivacyProtection } from '@eeacms/volto-embed';
5
+
6
+ import { StyleWrapperView } from '@eeacms/volto-block-style/StyleWrapper';
7
+ import cx from 'classnames';
4
8
 
5
9
  import { getContent } from '@plone/volto/actions';
6
10
 
@@ -8,7 +12,8 @@ import { connect } from 'react-redux';
8
12
  import { compose } from 'redux';
9
13
 
10
14
  const View = (props) => {
11
- const { data, data_provenance, tableau_visualization } = props || {};
15
+ const { data_provenance, tableau_visualization } = props || {};
16
+ const data = React.useMemo(() => props.data || {}, [props.data]);
12
17
  const { vis_url = '' } = data;
13
18
  const show_sources = data?.show_sources ?? false;
14
19
 
@@ -20,25 +25,59 @@ const View = (props) => {
20
25
  }, [vis_url]);
21
26
 
22
27
  return (
23
- <>
24
- {data?.vis_url ? (
25
- <>
26
- <ConnectedTableau {...props.tableau_visualization} id={props.id} />
27
- {show_sources &&
28
- data_provenance &&
29
- data_provenance?.data?.data_provenance &&
30
- tableau_visualization ? (
31
- <Sources sources={data_provenance.data.data_provenance} />
32
- ) : show_sources ? (
33
- <div>Data provenance is not set in the visualization</div>
34
- ) : (
35
- ''
36
- )}
37
- </>
38
- ) : (
39
- <div>Please select a visualization from block editor.</div>
40
- )}
41
- </>
28
+ <StyleWrapperView
29
+ {...props}
30
+ data={data}
31
+ styleData={{
32
+ ...data.styles,
33
+ customClass: cx(data.styles?.customClass || '', 'embed-container'),
34
+ }}
35
+ >
36
+ <PrivacyProtection data={data} {...props}>
37
+ {data?.vis_url ? (
38
+ <>
39
+ {tableau_visualization?.general?.url &&
40
+ tableau_visualization?.general?.version ? (
41
+ <>
42
+ <div className="tableau-block">
43
+ {props.mode === 'edit' ? (
44
+ <div className="tableau-info">
45
+ <h3 className="tableau-version">
46
+ == Tableau {tableau_visualization?.general?.version}{' '}
47
+ loaded ==
48
+ </h3>
49
+ </div>
50
+ ) : (
51
+ ''
52
+ )}
53
+ <ConnectedTableau
54
+ {...props.tableau_visualization}
55
+ id={props.id}
56
+ {...props}
57
+ />
58
+ </div>
59
+ {show_sources &&
60
+ data_provenance &&
61
+ data_provenance?.data?.data_provenance &&
62
+ tableau_visualization ? (
63
+ <Sources sources={data_provenance.data.data_provenance} />
64
+ ) : show_sources ? (
65
+ <div>Data provenance is not set in the visualization</div>
66
+ ) : (
67
+ ''
68
+ )}
69
+ </>
70
+ ) : !tableau_visualization?.general?.url ? (
71
+ <div>Url is not set in the visualization</div>
72
+ ) : (
73
+ <div>Version is not set in the visualization</div>
74
+ )}
75
+ </>
76
+ ) : (
77
+ <div>Please select a visualization from block editor.</div>
78
+ )}
79
+ </PrivacyProtection>
80
+ </StyleWrapperView>
42
81
  );
43
82
  };
44
83
 
@@ -53,4 +92,4 @@ export default compose(
53
92
  getContent,
54
93
  },
55
94
  ),
56
- )(View);
95
+ )(React.memo(View));
@@ -14,6 +14,7 @@ const ConnectedTableau = (props) => {
14
14
  data={{ ...props?.general, ...props?.options, ...props?.extraOptions }}
15
15
  url={props?.general?.url}
16
16
  version={props?.general?.version}
17
+ {...props}
17
18
  />
18
19
  </div>
19
20
  );
@@ -0,0 +1,29 @@
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;
@@ -23,7 +23,7 @@ const Tableau = (props) => {
23
23
  screen = {},
24
24
  setError = () => {},
25
25
  setLoaded = () => {},
26
- version = '2.8.0',
26
+ version = '',
27
27
  } = props;
28
28
  const {
29
29
  autoScale = false,
@@ -212,7 +212,11 @@ const Tableau = (props) => {
212
212
  ''
213
213
  ) : (
214
214
  <div className="tableau-loader">
215
- <span>Loading Tableau v{version}</span>
215
+ <span>
216
+ {mode === 'edit'
217
+ ? 'Loading...'
218
+ : `Loading Tableau v${version}`}
219
+ </span>
216
220
  </div>
217
221
  )}
218
222
  </>
@@ -34,14 +34,15 @@ const View = (props) => {
34
34
  description = null,
35
35
  autoScale = false,
36
36
  } = data;
37
- const version =
38
- props.data.version || config.settings.tableauVersion || '2.8.0';
37
+ const version = props.data.version || config.settings.tableauVersion;
39
38
  const device = getDevice(config, screen.page?.width || Infinity);
40
39
  const breakpointUrl = breakpointUrls.filter(
41
40
  (breakpoint) => breakpoint.device === device,
42
41
  )[0]?.url;
43
42
  const url = breakpointUrl || data.url;
44
43
 
44
+ const displayCondition = url && version;
45
+
45
46
  React.useEffect(() => {
46
47
  setMounted(true);
47
48
  /* eslint-disable-next-line */
@@ -67,33 +68,39 @@ const View = (props) => {
67
68
 
68
69
  return mounted ? (
69
70
  <div className="tableau-block">
70
- {props.mode === 'edit' ? (
71
- <div className="tableau-info">
72
- <h3 className="tableau-version">== Tableau {version} ==</h3>
73
- {!props.data.url ? <p className="tableau-error">URL required</p> : ''}
74
- {error ? <p className="tableau-error">{error}</p> : ''}
75
- </div>
76
- ) : (
77
- ''
78
- )}
71
+ <div className="tableau-info">
72
+ {displayCondition && props.mode === 'edit' ? (
73
+ <h3 className="tableau-version">== Tableau {version} loaded ==</h3>
74
+ ) : null}
75
+ {!url ? <p className="tableau-error">URL required</p> : ''}
76
+ {url && !version ? (
77
+ <p className="tableau-error">Version required</p>
78
+ ) : (
79
+ ''
80
+ )}
81
+ {error ? <p className="tableau-error">{error}</p> : ''}
82
+ </div>
83
+
79
84
  {loaded && title ? <h3 className="tableau-title">{title}</h3> : ''}
80
85
  {loaded && description ? (
81
86
  <p className="tableau-description">{description}</p>
82
87
  ) : (
83
88
  ''
84
89
  )}
85
- <Tableau
86
- {...props}
87
- canUpdateUrl={!breakpointUrl}
88
- extraFilters={extraFilters}
89
- extraOptions={{ device: autoScale ? 'desktop' : device }}
90
- error={error}
91
- loaded={loaded}
92
- setError={setError}
93
- setLoaded={setLoaded}
94
- version={version}
95
- url={url}
96
- />
90
+ {displayCondition ? (
91
+ <Tableau
92
+ {...props}
93
+ canUpdateUrl={!breakpointUrl}
94
+ extraFilters={extraFilters}
95
+ extraOptions={{ device: autoScale ? 'desktop' : device }}
96
+ error={error}
97
+ loaded={loaded}
98
+ setError={setError}
99
+ setLoaded={setLoaded}
100
+ version={version}
101
+ url={url}
102
+ />
103
+ ) : null}
97
104
  </div>
98
105
  ) : (
99
106
  ''
@@ -82,7 +82,7 @@ export default (config) => ({
82
82
  '2.0.3',
83
83
  ].map((version) => [version, `tableau-${version}`]),
84
84
  ],
85
- default: config.settings.tableauVersion || '2.8.0',
85
+ default: config.settings.tableauVersion,
86
86
  },
87
87
  url: {
88
88
  title: 'Url',
@@ -12,6 +12,8 @@ const VisualizationView = (props) => {
12
12
  <div className="tableau-info">
13
13
  {!tableau_visualization_data.general?.url ? (
14
14
  <p className="tableau-error">URL required</p>
15
+ ) : !tableau_visualization_data.general?.version ? (
16
+ <p className="tableau-error">Version required</p>
15
17
  ) : tableauError ? (
16
18
  <p className="tableau-error">{tableauError}</p>
17
19
  ) : (
@@ -23,19 +25,20 @@ const VisualizationView = (props) => {
23
25
  };
24
26
  return (
25
27
  <div>
26
- {!tableau_visualization_data.general?.url || tableauError ? (
28
+ {!tableau_visualization_data?.general?.url ||
29
+ !tableau_visualization_data?.general?.version ||
30
+ tableauError ? (
27
31
  <TableauNotDisplayed />
28
32
  ) : (
29
- ''
33
+ <TableauView
34
+ setTableauError={setTableauError}
35
+ data={{
36
+ ...tableau_visualization_data.general,
37
+ ...tableau_visualization_data.options,
38
+ ...tableau_visualization_data.extraOptions,
39
+ }}
40
+ />
30
41
  )}
31
- <TableauView
32
- setTableauError={setTableauError}
33
- data={{
34
- ...tableau_visualization_data.general,
35
- ...tableau_visualization_data.options,
36
- ...tableau_visualization_data.extraOptions,
37
- }}
38
- />
39
42
  </div>
40
43
  );
41
44
  };
@@ -40,6 +40,8 @@ const VisualizationWidget = (props) => {
40
40
  <div className="tableau-info">
41
41
  {intValue && intValue.general && !intValue.general.url ? (
42
42
  <p className="tableau-error">URL required</p>
43
+ ) : intValue && intValue.general && !intValue.general.version ? (
44
+ <p className="tableau-error">Version required</p>
43
45
  ) : tableauError ? (
44
46
  <p className="tableau-error">{tableauError}</p>
45
47
  ) : (
@@ -53,6 +55,15 @@ const VisualizationWidget = (props) => {
53
55
  let schema = Schema(config);
54
56
 
55
57
  React.useEffect(() => {
58
+ if (!intValue?.general || !intValue?.general?.version) {
59
+ setIntValue({
60
+ ...intValue,
61
+ general: {
62
+ url: intValue?.general?.url,
63
+ version: '',
64
+ },
65
+ });
66
+ }
56
67
  if (!intValue?.options) {
57
68
  setIntValue({
58
69
  ...intValue,
@@ -65,7 +76,7 @@ const VisualizationWidget = (props) => {
65
76
  });
66
77
  }
67
78
  // eslint-disable-next-line react-hooks/exhaustive-deps
68
- }, [intValue]);
79
+ }, []);
69
80
 
70
81
  return (
71
82
  <FormFieldWrapper {...props}>
@@ -107,22 +118,23 @@ const VisualizationWidget = (props) => {
107
118
  />
108
119
  </Grid.Column>
109
120
  <Grid.Column mobile={12} tablet={12} computer={7}>
110
- {(intValue && intValue.general && !intValue.general.url) ||
121
+ {(intValue &&
122
+ intValue.general &&
123
+ (!intValue.general.url || !intValue.general.version)) ||
111
124
  tableauError ? (
112
125
  <TableauNotDisplayed />
113
126
  ) : (
114
- ''
127
+ <div className="tableau-container">
128
+ <TableauView
129
+ setTableauError={setTableauError}
130
+ data={{
131
+ ...intValue?.general,
132
+ ...intValue?.options,
133
+ ...intValue?.extraOptions,
134
+ }}
135
+ />
136
+ </div>
115
137
  )}
116
- <div className="tableau-container">
117
- <TableauView
118
- setTableauError={setTableauError}
119
- data={{
120
- ...intValue?.general,
121
- ...intValue?.options,
122
- ...intValue?.extraOptions,
123
- }}
124
- />
125
- </div>
126
138
  </Grid.Column>
127
139
  </Grid>
128
140
  </Modal.Content>
@@ -140,19 +152,23 @@ const VisualizationWidget = (props) => {
140
152
  </Modal.Actions>
141
153
  </Modal>
142
154
  )}
143
- {(intValue && intValue.general && !intValue.general.url) ||
155
+ {(intValue &&
156
+ intValue.general &&
157
+ (!intValue.general.url || !intValue.general.version)) ||
144
158
  tableauError ? (
145
159
  <TableauNotDisplayed />
146
160
  ) : (
147
- ''
161
+ <TableauView
162
+ setTableauError={setTableauError}
163
+ data={{
164
+ ...value?.general,
165
+ ...value?.options,
166
+ ...value?.extraOptions,
167
+ }}
168
+ />
148
169
  )}
149
-
150
- <TableauView
151
- setTableauError={setTableauError}
152
- data={{ ...value?.general, ...value?.options, ...value?.extraOptions }}
153
- />
154
170
  </FormFieldWrapper>
155
171
  );
156
172
  };
157
173
 
158
- export default VisualizationWidget;
174
+ export default React.memo(VisualizationWidget);
@@ -27,7 +27,7 @@ const generalSchema = (config) => {
27
27
  '2.0.3',
28
28
  ].map((version) => [version, `tableau-${version}`]),
29
29
  ],
30
- default: config.settings.tableauVersion || '2.8.0',
30
+ default: config.settings.tableauVersion,
31
31
  },
32
32
  url: {
33
33
  title: 'Url',
@@ -92,7 +92,11 @@ const optionsSchema = {
92
92
  const urlParametersSchema = {
93
93
  title: 'Parameter',
94
94
  fieldsets: [
95
- { id: 'default', title: 'Default', fields: ['field', 'urlParam'] },
95
+ {
96
+ id: 'default',
97
+ title: 'Default',
98
+ fields: ['field', 'urlParam'],
99
+ },
96
100
  ],
97
101
  properties: {
98
102
  field: {
@@ -139,7 +143,7 @@ const extraOptionsSchema = (config) => {
139
143
  {
140
144
  id: 'default',
141
145
  title: 'Extra Options Data',
142
- fields: ['urlParameters', 'breakpointUrls'],
146
+ fields: ['urlParameters', 'availableFields', 'breakpointUrls'],
143
147
  },
144
148
  ],
145
149
 
@@ -150,6 +154,10 @@ const extraOptionsSchema = (config) => {
150
154
  schema: urlParametersSchema,
151
155
  description: 'Set a list of url parameters to filter the tableau',
152
156
  },
157
+ availableFields: {
158
+ title: 'Available Fields:',
159
+ widget: 'url_params_widget',
160
+ },
153
161
  breakpointUrls: {
154
162
  title: 'Breakpoint urls',
155
163
  widget: 'object_list',
package/src/index.js CHANGED
@@ -5,6 +5,7 @@ import EmbedTableauView from './Blocks/EmbedEEATableauBlock/View';
5
5
  import EmbedTableauEdit from './Blocks/EmbedEEATableauBlock/Edit';
6
6
  import { VisualizationView } from './Views';
7
7
  import { VisualizationWidget } from './Widgets';
8
+ import UrlParamsWidget from './CustomWidgets/UrlParamsWidget';
8
9
 
9
10
  import tableauStore from './store';
10
11
 
@@ -72,6 +73,7 @@ const applyConfig = (config) => {
72
73
 
73
74
  config.views.contentTypesViews.tableau_visualization = VisualizationView;
74
75
  config.widgets.id.tableau_visualization_data = VisualizationWidget;
76
+ config.widgets.widget.url_params_widget = UrlParamsWidget;
75
77
 
76
78
  return config;
77
79
  };
@@ -9,7 +9,11 @@
9
9
  .tableau-block {
10
10
  .tableau-info {
11
11
  h3.tableau-version {
12
- margin-right: 0.5rem;
12
+ display: flex;
13
+ height: 75px;
14
+ align-items: center;
15
+ justify-content: center;
16
+ background-color: #f4f4f1;
13
17
  color: @tableauTitleColor;
14
18
  }
15
19
 
@@ -104,4 +108,20 @@
104
108
  }
105
109
  }
106
110
 
107
- .loadAddonOverrides();
111
+ .availableFieldsContainer {
112
+ padding: 0 5px 5px 0;
113
+ border-bottom: 1px solid #d9d9d9;
114
+ }
115
+
116
+ .availableFieldsTitle {
117
+ color: darkgray;
118
+ font-size: 13px;
119
+ font-weight: bold;
120
+ }
121
+
122
+ .availableFields {
123
+ padding: 0 5px;
124
+ font-size: 12px;
125
+ }
126
+
127
+ .loadAddonVariables();