@eeacms/volto-tableau 8.0.6 → 8.1.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
CHANGED
|
@@ -4,12 +4,47 @@ 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
|
+
### [8.1.0](https://github.com/eea/volto-tableau/compare/8.0.7...8.1.0) - 11 September 2024
|
|
8
|
+
|
|
9
|
+
#### :hammer_and_wrench: Others
|
|
10
|
+
|
|
11
|
+
- Update version [dobri1408 - [`dc7280a`](https://github.com/eea/volto-tableau/commit/dc7280ae0a99dd91af2c589715ee16a789eae9f9)]
|
|
12
|
+
- Make an extra cleaning step for the action [dobri1408 - [`cec9ff9`](https://github.com/eea/volto-tableau/commit/cec9ff98dde77a729c04339bac889463949f3d1c)]
|
|
13
|
+
### [8.0.7](https://github.com/eea/volto-tableau/compare/8.0.6...8.0.7) - 9 September 2024
|
|
14
|
+
|
|
15
|
+
#### :house: Internal changes
|
|
16
|
+
|
|
17
|
+
- style: Automated code fix [eea-jenkins - [`ef00271`](https://github.com/eea/volto-tableau/commit/ef00271928ae63ba0d22485f9343fc304e090b03)]
|
|
18
|
+
|
|
19
|
+
#### :hammer_and_wrench: Others
|
|
20
|
+
|
|
21
|
+
- Update View.test.jsx [dobri1408 - [`984f762`](https://github.com/eea/volto-tableau/commit/984f76249550287ef297526d3962a61fd498a0be)]
|
|
22
|
+
- increase code coverage [dobri1408 - [`4a0b444`](https://github.com/eea/volto-tableau/commit/4a0b4449f244c4deacc4015b0d2373d0baa49e2f)]
|
|
23
|
+
- increase code coverage [dobri1408 - [`0a036f4`](https://github.com/eea/volto-tableau/commit/0a036f4d45401da63e71104cae57f7378a4d3624)]
|
|
24
|
+
- increase code coverage [dobri1408 - [`0438558`](https://github.com/eea/volto-tableau/commit/0438558970650d3a01d74802e622cd9d27ebda81)]
|
|
25
|
+
- double check preview [dobri1408 - [`85e0689`](https://github.com/eea/volto-tableau/commit/85e0689f800064e98937be6f74bfdd9959ccd1da)]
|
|
26
|
+
- double check preview [dobri1408 - [`1671a45`](https://github.com/eea/volto-tableau/commit/1671a45608c765f832b48789721dbe7b06b65ed4)]
|
|
27
|
+
- Update preview_image.js [dobri1408 - [`87925c5`](https://github.com/eea/volto-tableau/commit/87925c5c45d8395c9c5b956ead2a7d988823233a)]
|
|
28
|
+
- double check preview [dobri1408 - [`1579659`](https://github.com/eea/volto-tableau/commit/1579659822d56993dd147a6256013b0e7c12bbb5)]
|
|
29
|
+
- Create preview_image.test.js [dobri1408 - [`c562940`](https://github.com/eea/volto-tableau/commit/c562940a2f0bb7ae34ef98a62d2c95f4fe2506c0)]
|
|
30
|
+
- Update preview_image.js [dobri1408 - [`aa3b15e`](https://github.com/eea/volto-tableau/commit/aa3b15edd95d64c8ca969a8252f7d9371e142a6d)]
|
|
31
|
+
- merge [dobri1408 - [`ba63a8f`](https://github.com/eea/volto-tableau/commit/ba63a8f95349d00e5782ebff31870e96891362ca)]
|
|
32
|
+
- manage redux and action right [dobri1408 - [`85be516`](https://github.com/eea/volto-tableau/commit/85be51613a3789adbebd3a517f6b87f600ed3e92)]
|
|
33
|
+
- Update preview_image.js [dobri1408 - [`bb20a02`](https://github.com/eea/volto-tableau/commit/bb20a0204292ef9f94734b343eea9f2fd3e5a96a)]
|
|
34
|
+
- Update VisualizationWidget.jsx [dobri1408 - [`e5ee11c`](https://github.com/eea/volto-tableau/commit/e5ee11ca4f5ee10a42f28e7087582744628aa144)]
|
|
35
|
+
- Update VisualizationWidget.jsx [dobri1408 - [`f0d3bdf`](https://github.com/eea/volto-tableau/commit/f0d3bdf6edff339a037a64453eea714496c39d92)]
|
|
36
|
+
- fix multiple rerenders [dobri1408 - [`6cc0ef0`](https://github.com/eea/volto-tableau/commit/6cc0ef0b8d1bb7f3a0770666c6e60bb3c28df0d4)]
|
|
37
|
+
- Update VisualizationWidget.jsx [dobri1408 - [`56d94fd`](https://github.com/eea/volto-tableau/commit/56d94fdf9bd26db1512d2ae5ee5f65e743b795b5)]
|
|
38
|
+
- fix eslint [dobri1408 - [`d7d754e`](https://github.com/eea/volto-tableau/commit/d7d754e9d89b60951ac7da27b14db93389832216)]
|
|
39
|
+
- fix eslint [dobri1408 - [`58b50d9`](https://github.com/eea/volto-tableau/commit/58b50d995059eea0cc31a0bb6e8e80b48ace99ea)]
|
|
40
|
+
- middleware to save preview image [dobri1408 - [`4b9d1b3`](https://github.com/eea/volto-tableau/commit/4b9d1b3efc5c1cc04d273ce91ccc0621cb60b324)]
|
|
41
|
+
- Update package.json [dobri1408 - [`12a1c94`](https://github.com/eea/volto-tableau/commit/12a1c9478591ba4729f00a55932858b5ef616ff2)]
|
|
42
|
+
- middleware to save preview image [dobri1408 - [`9fe3dd7`](https://github.com/eea/volto-tableau/commit/9fe3dd795842f40e2f0d91475df04b7b97de922e)]
|
|
7
43
|
### [8.0.6](https://github.com/eea/volto-tableau/compare/8.0.5...8.0.6) - 25 July 2024
|
|
8
44
|
|
|
9
45
|
#### :hammer_and_wrench: Others
|
|
10
46
|
|
|
11
47
|
- Update Jenkinsfile [Alexandru Ghica - [`d5e7d48`](https://github.com/eea/volto-tableau/commit/d5e7d48a52e494ebf139b14ea06d0cac8cce82f3)]
|
|
12
|
-
- more checks [Miu Razvan - [`575a1d5`](https://github.com/eea/volto-tableau/commit/575a1d5db3310f9b2dec343adca7c9b912316414)]
|
|
13
48
|
### [8.0.5](https://github.com/eea/volto-tableau/compare/8.0.4...8.0.5) - 23 July 2024
|
|
14
49
|
|
|
15
50
|
### [8.0.4](https://github.com/eea/volto-tableau/compare/8.0.3...8.0.4) - 22 July 2024
|
package/package.json
CHANGED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import { Provider } from 'react-redux';
|
|
4
|
+
import configureStore from 'redux-mock-store';
|
|
5
|
+
import View from './View';
|
|
6
|
+
import '@testing-library/jest-dom/extend-expect';
|
|
7
|
+
import Tableau from '@eeacms/volto-tableau/Tableau/Tableau';
|
|
8
|
+
|
|
9
|
+
jest.mock('@eeacms/volto-tableau/Tableau/Tableau', () =>
|
|
10
|
+
jest.fn(() => <div>Mocked Tableau</div>),
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
jest.mock('@plone/volto/registry', () => ({
|
|
14
|
+
blocks: {
|
|
15
|
+
blocksConfig: {
|
|
16
|
+
tableau_block: {
|
|
17
|
+
breakpoints: {},
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
const mockStore = configureStore([]);
|
|
24
|
+
|
|
25
|
+
describe('View component', () => {
|
|
26
|
+
let store;
|
|
27
|
+
|
|
28
|
+
beforeEach(() => {
|
|
29
|
+
store = mockStore({
|
|
30
|
+
router: {
|
|
31
|
+
location: {
|
|
32
|
+
search: '?param1=value1',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
discodata_query: {
|
|
36
|
+
search: {},
|
|
37
|
+
},
|
|
38
|
+
screen: {},
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('renders correctly with title and description when loaded', () => {
|
|
43
|
+
const mockProps = {
|
|
44
|
+
block: '1234',
|
|
45
|
+
data: {
|
|
46
|
+
title: 'Test Title',
|
|
47
|
+
description: 'Test Description',
|
|
48
|
+
staticParameters: [],
|
|
49
|
+
urlParameters: [],
|
|
50
|
+
},
|
|
51
|
+
mode: 'view',
|
|
52
|
+
query: {},
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
render(
|
|
56
|
+
<Provider store={store}>
|
|
57
|
+
<View {...mockProps} />
|
|
58
|
+
</Provider>,
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
// Simulăm vizualizarea încărcată
|
|
62
|
+
const tableauBlock = screen.getByText('Mocked Tableau');
|
|
63
|
+
expect(tableauBlock).toBeInTheDocument();
|
|
64
|
+
|
|
65
|
+
// Verificăm titlul și descrierea
|
|
66
|
+
expect(screen.queryByText('Test Title')).not.toBeInTheDocument();
|
|
67
|
+
expect(screen.queryByText('Test Description')).not.toBeInTheDocument();
|
|
68
|
+
|
|
69
|
+
// Aici simulăm setVizState pentru a actualiza starea vizualizării ca fiind "loaded"
|
|
70
|
+
mockProps.setVizState = jest.fn((state) => {
|
|
71
|
+
state.loaded = true;
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Re-render după schimbarea stării
|
|
75
|
+
render(
|
|
76
|
+
<Provider store={store}>
|
|
77
|
+
<View {...mockProps} />
|
|
78
|
+
</Provider>,
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
expect(screen.getByText('Test Title')).toBeInTheDocument();
|
|
82
|
+
expect(screen.getByText('Test Description')).toBeInTheDocument();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('sets extraFilters correctly based on query parameters', () => {
|
|
86
|
+
const mockProps = {
|
|
87
|
+
block: '1234',
|
|
88
|
+
data: {
|
|
89
|
+
staticParameters: [],
|
|
90
|
+
urlParameters: [{ field: 'filter1', urlParam: 'param1' }],
|
|
91
|
+
},
|
|
92
|
+
mode: 'view',
|
|
93
|
+
query: { param1: 'value1' },
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
render(
|
|
97
|
+
<Provider store={store}>
|
|
98
|
+
<View {...mockProps} />
|
|
99
|
+
</Provider>,
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
expect(Tableau).toHaveBeenCalledWith(
|
|
103
|
+
expect.objectContaining({
|
|
104
|
+
extraFilters: { filter1: 'value1' },
|
|
105
|
+
}),
|
|
106
|
+
{},
|
|
107
|
+
);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('renders Tableau with correct props', () => {
|
|
111
|
+
const mockProps = {
|
|
112
|
+
block: '1234',
|
|
113
|
+
data: {
|
|
114
|
+
title: 'Test Title',
|
|
115
|
+
description: 'Test Description',
|
|
116
|
+
staticParameters: [{ field: 'static1', value: 'staticValue' }],
|
|
117
|
+
urlParameters: [],
|
|
118
|
+
},
|
|
119
|
+
mode: 'view',
|
|
120
|
+
query: {},
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
render(
|
|
124
|
+
<Provider store={store}>
|
|
125
|
+
<View {...mockProps} />
|
|
126
|
+
</Provider>,
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
expect(Tableau).toHaveBeenCalledWith(
|
|
130
|
+
expect.objectContaining({
|
|
131
|
+
data: expect.objectContaining({
|
|
132
|
+
title: 'Test Title',
|
|
133
|
+
description: 'Test Description',
|
|
134
|
+
with_sources: true,
|
|
135
|
+
with_download: true,
|
|
136
|
+
with_share: true,
|
|
137
|
+
with_enlarge: true,
|
|
138
|
+
}),
|
|
139
|
+
extraOptions: { static1: 'staticValue' },
|
|
140
|
+
}),
|
|
141
|
+
{},
|
|
142
|
+
);
|
|
143
|
+
});
|
|
144
|
+
});
|
|
@@ -16,9 +16,21 @@ import {
|
|
|
16
16
|
} from '@eeacms/volto-tableau/Tableau/helpers';
|
|
17
17
|
|
|
18
18
|
import '@eeacms/volto-tableau/less/tableau.less';
|
|
19
|
+
import { getBaseUrl } from '@plone/volto/helpers';
|
|
20
|
+
|
|
21
|
+
function blobToBase64(blob) {
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
const reader = new FileReader();
|
|
24
|
+
reader.onloadend = () => {
|
|
25
|
+
resolve(reader.result);
|
|
26
|
+
};
|
|
27
|
+
reader.onerror = reject;
|
|
28
|
+
reader.readAsDataURL(blob);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
19
31
|
|
|
20
32
|
const VisualizationWidget = (props) => {
|
|
21
|
-
const { location, content } = props;
|
|
33
|
+
const { location, content, onChange, id } = props;
|
|
22
34
|
const ogValue = props.value || {};
|
|
23
35
|
const inAddForm = props.location.pathname.split('/').pop() === 'add';
|
|
24
36
|
const viz = React.useRef();
|
|
@@ -120,6 +132,29 @@ const VisualizationWidget = (props) => {
|
|
|
120
132
|
);
|
|
121
133
|
}, [vizState, value]);
|
|
122
134
|
|
|
135
|
+
React.useEffect(() => {
|
|
136
|
+
if (value && value.url && value.preview_url_loaded !== value.url) {
|
|
137
|
+
fetch(
|
|
138
|
+
`${getBaseUrl(
|
|
139
|
+
'',
|
|
140
|
+
)}/cors-proxy/https://screenshot.eea.europa.eu/api/v1/retrieve_image_for_url?url=${encodeURIComponent(
|
|
141
|
+
value.url,
|
|
142
|
+
)}&w=1920&h=1000&waitfor=4000`,
|
|
143
|
+
)
|
|
144
|
+
.then((e) => e.blob())
|
|
145
|
+
.then((myBlob) => {
|
|
146
|
+
blobToBase64(myBlob).then((base64String) => {
|
|
147
|
+
onChange(id, {
|
|
148
|
+
...value,
|
|
149
|
+
preview: base64String,
|
|
150
|
+
preview_url_loaded: value.url,
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
})
|
|
154
|
+
.catch(() => {});
|
|
155
|
+
}
|
|
156
|
+
}, [value, onChange, id]);
|
|
157
|
+
|
|
123
158
|
return (
|
|
124
159
|
<FormFieldWrapper {...props}>
|
|
125
160
|
<Modal id="tableau-editor-modal" open={open}>
|
package/src/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
VisualizationViewWidget,
|
|
6
6
|
CreatableSelectWidget,
|
|
7
7
|
} from './Widgets';
|
|
8
|
+
import { preview_image } from './middlewares/preview_image';
|
|
8
9
|
|
|
9
10
|
const applyConfig = (config) => {
|
|
10
11
|
config.settings.allowed_cors_destinations = [
|
|
@@ -12,7 +13,10 @@ const applyConfig = (config) => {
|
|
|
12
13
|
'public.tableau.com',
|
|
13
14
|
];
|
|
14
15
|
|
|
15
|
-
config.settings.storeExtenders = [
|
|
16
|
+
config.settings.storeExtenders = [
|
|
17
|
+
...(config.settings.storeExtenders || []),
|
|
18
|
+
preview_image,
|
|
19
|
+
];
|
|
16
20
|
|
|
17
21
|
config.views.contentTypesViews.tableau_visualization = VisualizationView;
|
|
18
22
|
config.widgets.id.tableau_visualization = VisualizationWidget;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CREATE_CONTENT,
|
|
3
|
+
UPDATE_CONTENT,
|
|
4
|
+
} from '@plone/volto/constants/ActionTypes';
|
|
5
|
+
|
|
6
|
+
const cleanAction = (action) => {
|
|
7
|
+
if (action?.request?.data?.tableau_visualization) {
|
|
8
|
+
const tableauVisualizationData = {
|
|
9
|
+
...action.request.data.tableau_visualization,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
if (
|
|
13
|
+
tableauVisualizationData.preview &&
|
|
14
|
+
tableauVisualizationData.preview_url_loaded
|
|
15
|
+
)
|
|
16
|
+
delete tableauVisualizationData.preview;
|
|
17
|
+
delete tableauVisualizationData.preview_url_loaded;
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
...action,
|
|
21
|
+
request: {
|
|
22
|
+
...action.request,
|
|
23
|
+
data: {
|
|
24
|
+
...action.request.data,
|
|
25
|
+
|
|
26
|
+
tableau_visualization: tableauVisualizationData,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
} else return action;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const preview_image = (middlewares) => [
|
|
34
|
+
(store) => (next) => (action) => {
|
|
35
|
+
if (![CREATE_CONTENT, UPDATE_CONTENT].includes(action.type)) {
|
|
36
|
+
return next(action);
|
|
37
|
+
}
|
|
38
|
+
const state = store.getState();
|
|
39
|
+
const contentData = state.content.data;
|
|
40
|
+
const lastPreviewImage = Object.keys(action?.request?.data).includes(
|
|
41
|
+
'preview_image',
|
|
42
|
+
)
|
|
43
|
+
? action?.request?.data.preview_image
|
|
44
|
+
: contentData?.preview_image;
|
|
45
|
+
const type = action?.request?.data?.['@type'] || contentData['@type'];
|
|
46
|
+
if (
|
|
47
|
+
!contentData ||
|
|
48
|
+
type !== 'tableau_visualization' ||
|
|
49
|
+
contentData.preview_image_saved ||
|
|
50
|
+
!action?.request?.data?.tableau_visualization?.preview
|
|
51
|
+
) {
|
|
52
|
+
return next(cleanAction(action));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (
|
|
56
|
+
lastPreviewImage &&
|
|
57
|
+
lastPreviewImage !== 'preview_image_generated_tableau_visualization.png'
|
|
58
|
+
) {
|
|
59
|
+
return next(cleanAction(action));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
const previewImage = {
|
|
64
|
+
preview_image: {
|
|
65
|
+
data: action.request.data.tableau_visualization.preview.split(',')[1],
|
|
66
|
+
encoding: 'base64',
|
|
67
|
+
'content-type': 'image/png',
|
|
68
|
+
filename: 'preview_image_generated_tableau_visualization.png',
|
|
69
|
+
},
|
|
70
|
+
preview_image_saved: true,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const tableauVisualizationData = {
|
|
74
|
+
...action.request.data.tableau_visualization,
|
|
75
|
+
};
|
|
76
|
+
delete tableauVisualizationData.preview;
|
|
77
|
+
delete tableauVisualizationData.preview_url_loaded;
|
|
78
|
+
|
|
79
|
+
return next({
|
|
80
|
+
...action,
|
|
81
|
+
request: {
|
|
82
|
+
...action.request,
|
|
83
|
+
data: {
|
|
84
|
+
...action.request.data,
|
|
85
|
+
...previewImage,
|
|
86
|
+
tableau_visualization: tableauVisualizationData,
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
} catch (error) {
|
|
91
|
+
if (action.request.data.tableau_visualization.preview) {
|
|
92
|
+
const tableauVisualizationData = {
|
|
93
|
+
...action.request.data.tableau_visualization,
|
|
94
|
+
};
|
|
95
|
+
delete tableauVisualizationData.preview;
|
|
96
|
+
delete tableauVisualizationData.preview_url_loaded;
|
|
97
|
+
|
|
98
|
+
return next({
|
|
99
|
+
...action,
|
|
100
|
+
request: {
|
|
101
|
+
...action.request,
|
|
102
|
+
data: {
|
|
103
|
+
...action.request.data,
|
|
104
|
+
tableau_visualization: tableauVisualizationData,
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
} else return next(action);
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
...middlewares,
|
|
112
|
+
];
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { preview_image } from './preview_image';
|
|
2
|
+
describe('preview_image middleware', () => {
|
|
3
|
+
let store;
|
|
4
|
+
let next;
|
|
5
|
+
let action;
|
|
6
|
+
let middlewares;
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
store = {
|
|
10
|
+
getState: jest.fn(() => ({
|
|
11
|
+
content: {
|
|
12
|
+
data: {
|
|
13
|
+
'@type': 'tableau_visualization',
|
|
14
|
+
preview_image: 'existing_image.png',
|
|
15
|
+
preview_image_saved: false,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
})),
|
|
19
|
+
};
|
|
20
|
+
next = jest.fn();
|
|
21
|
+
middlewares = [];
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should pass through if action type is not CREATE_CONTENT or UPDATE_CONTENT', () => {
|
|
25
|
+
action = { type: 'UPDATE_CONTENT', request: { data: {} } };
|
|
26
|
+
const middleware = preview_image(middlewares)[0]; // Accesăm prima funcție din array
|
|
27
|
+
middleware(store)(next)(action); // Executăm funcția de middleware
|
|
28
|
+
expect(next).toHaveBeenCalledWith(action); // Verificăm că funcția next a fost apelată cu acțiunea originală
|
|
29
|
+
});
|
|
30
|
+
});
|