@eeacms/volto-tableau 1.2.5 → 2.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/.coverage.babel.config.js +1 -1
- package/.i18n.babel.config.js +1 -0
- package/CHANGELOG.md +20 -1
- package/Jenkinsfile +10 -10
- package/babel.config.js +17 -0
- package/cypress/{integration/block-basics.js → e2e/block-basics.cy.js} +8 -11
- package/cypress/support/commands.js +230 -9
- package/cypress/support/e2e.js +125 -0
- package/cypress.config.js +26 -0
- package/jest-addon.config.js +3 -4
- package/package.json +5 -4
- package/src/Tableau/View.jsx +8 -19
- package/src/TableauBlock/Edit.jsx +0 -1
- package/src/TableauBlock/View.jsx +1 -4
- package/src/TableauBlock/schema.js +12 -4
- package/src/helpers.js +33 -0
- package/src/index.js +5 -0
- package/src/middleware.js +23 -25
- package/src/store.js +0 -1
- package/cypress/plugins/index.js +0 -26
- package/cypress/support/index.js +0 -53
- package/cypress.json +0 -17
|
@@ -2,7 +2,7 @@ const defaultBabel = require('@plone/volto/babel');
|
|
|
2
2
|
|
|
3
3
|
function applyDefault(api) {
|
|
4
4
|
const voltoBabel = defaultBabel(api);
|
|
5
|
-
voltoBabel.plugins.push('
|
|
5
|
+
voltoBabel.plugins.push('istanbul');
|
|
6
6
|
return voltoBabel;
|
|
7
7
|
}
|
|
8
8
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('@plone/volto/babel');
|
package/CHANGELOG.md
CHANGED
|
@@ -4,12 +4,31 @@ 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
|
+
### [2.0.0](https://github.com/eea/volto-tableau/compare/1.3.0...2.0.0) - 31 October 2022
|
|
8
|
+
|
|
9
|
+
#### :bug: Bug Fixes
|
|
10
|
+
|
|
11
|
+
- fix(cypress): fix silly test [Nilesh - [`d53131a`](https://github.com/eea/volto-tableau/commit/d53131adc4a38252727a6202860e258fbc4d899c)]
|
|
12
|
+
|
|
13
|
+
#### :hammer_and_wrench: Others
|
|
14
|
+
|
|
15
|
+
- Update block-basics.cy.js [Nilesh - [`e4f7ca4`](https://github.com/eea/volto-tableau/commit/e4f7ca45969d379fa373bb4b88a1680945b5ca7e)]
|
|
16
|
+
- prepare 2.0 [Nilesh - [`e60db00`](https://github.com/eea/volto-tableau/commit/e60db002471ca193a446edbbfc3d015ad88bbc8c)]
|
|
17
|
+
- Update block-basics.cy.js [Nilesh - [`65b6419`](https://github.com/eea/volto-tableau/commit/65b64190af746d24e87276d397db2ad6473e9883)]
|
|
18
|
+
- Update commands.js [Nilesh - [`7c48437`](https://github.com/eea/volto-tableau/commit/7c4843780efb9b85a4728de73c00d831c1d8fdcf)]
|
|
19
|
+
- Update e2e.js [Nilesh - [`f67b45c`](https://github.com/eea/volto-tableau/commit/f67b45c170f58f8d0301192994226f173e4cb00a)]
|
|
20
|
+
- latest volto compatibility refs #154757 [nileshgulia1 - [`881ba48`](https://github.com/eea/volto-tableau/commit/881ba482dc9b82e7fdac16549d41e80a6d26b3de)]
|
|
21
|
+
### [1.3.0](https://github.com/eea/volto-tableau/compare/1.2.5...1.3.0) - 28 September 2022
|
|
22
|
+
|
|
23
|
+
#### :hammer_and_wrench: Others
|
|
24
|
+
|
|
25
|
+
- Bump version [Miu Razvan - [`837f8a7`](https://github.com/eea/volto-tableau/commit/837f8a70257660253b70b818977693101d6576e9)]
|
|
26
|
+
- clear lint [andreiggr - [`69d83b8`](https://github.com/eea/volto-tableau/commit/69d83b806aa48a6a696e01b6e026de07e6a34dfe)]
|
|
7
27
|
### [1.2.5](https://github.com/eea/volto-tableau/compare/1.2.4...1.2.5) - 2 September 2022
|
|
8
28
|
|
|
9
29
|
#### :hammer_and_wrench: Others
|
|
10
30
|
|
|
11
31
|
- Use volto 16 alpha 14 [Miu Razvan - [`93641be`](https://github.com/eea/volto-tableau/commit/93641be4c2393f49008aff789400cf7c947949fd)]
|
|
12
|
-
- Fix filter update [Miu Razvan - [`d613762`](https://github.com/eea/volto-tableau/commit/d613762734bbba2460ad8e8860d95197fc86786b)]
|
|
13
32
|
- Revert volto-tableau group to common [Andrei Grigore - [`9d24c6d`](https://github.com/eea/volto-tableau/commit/9d24c6d2767fed6a840cddaee55dbd5cecb544b5)]
|
|
14
33
|
- Tableaugroup typo fix [Andrei Grigore - [`b0b5378`](https://github.com/eea/volto-tableau/commit/b0b5378a437043120a96c9e5e8802584145daa22)]
|
|
15
34
|
- Refs #142010 - Optimize Volto-addons gitflow pipelines [valentinab25 - [`d237e1c`](https://github.com/eea/volto-tableau/commit/d237e1c72817d7e68a3eb698563674d1514db24f)]
|
package/Jenkinsfile
CHANGED
|
@@ -4,9 +4,9 @@ pipeline {
|
|
|
4
4
|
environment {
|
|
5
5
|
GIT_NAME = "volto-tableau"
|
|
6
6
|
NAMESPACE = "@eeacms"
|
|
7
|
-
SONARQUBE_TAGS = "volto.eea.europa.eu,climate-energy.eea.europa.eu,forest.eea.europa.eu,biodiversity.europa.eu,water.europa.eu-freshwater"
|
|
7
|
+
SONARQUBE_TAGS = "volto.eea.europa.eu,climate-energy.eea.europa.eu,forest.eea.europa.eu,biodiversity.europa.eu,water.europa.eu-freshwater,water.europa.eu-marine"
|
|
8
8
|
DEPENDENCIES = ""
|
|
9
|
-
VOLTO = "
|
|
9
|
+
VOLTO = "alpha"
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
stages {
|
|
@@ -41,19 +41,19 @@ pipeline {
|
|
|
41
41
|
|
|
42
42
|
"ES lint": {
|
|
43
43
|
node(label: 'docker') {
|
|
44
|
-
sh '''docker run -i --rm --name="$BUILD_TAG-eslint" -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" plone/volto-addon-ci eslint'''
|
|
44
|
+
sh '''docker run -i --rm --name="$BUILD_TAG-eslint" -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e VOLTO=$VOLTO plone/volto-addon-ci:alpha eslint'''
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
47
|
|
|
48
48
|
"Style lint": {
|
|
49
49
|
node(label: 'docker') {
|
|
50
|
-
sh '''docker run -i --rm --name="$BUILD_TAG-stylelint" -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" plone/volto-addon-ci stylelint'''
|
|
50
|
+
sh '''docker run -i --rm --name="$BUILD_TAG-stylelint" -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e VOLTO=$VOLTO plone/volto-addon-ci:alpha stylelint'''
|
|
51
51
|
}
|
|
52
52
|
},
|
|
53
53
|
|
|
54
54
|
"Prettier": {
|
|
55
55
|
node(label: 'docker') {
|
|
56
|
-
sh '''docker run -i --rm --name="$BUILD_TAG-prettier" -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" plone/volto-addon-ci prettier'''
|
|
56
|
+
sh '''docker run -i --rm --name="$BUILD_TAG-prettier" -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e VOLTO=$VOLTO plone/volto-addon-ci:alpha prettier'''
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
)
|
|
@@ -77,8 +77,8 @@ pipeline {
|
|
|
77
77
|
node(label: 'docker') {
|
|
78
78
|
script {
|
|
79
79
|
try {
|
|
80
|
-
sh '''docker pull plone/volto-addon-ci'''
|
|
81
|
-
sh '''docker run -i --name="$BUILD_TAG-volto" -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" plone/volto-addon-ci'''
|
|
80
|
+
sh '''docker pull plone/volto-addon-ci:alpha'''
|
|
81
|
+
sh '''docker run -i --name="$BUILD_TAG-volto" -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e VOLTO=$VOLTO plone/volto-addon-ci:alpha'''
|
|
82
82
|
sh '''rm -rf xunit-reports'''
|
|
83
83
|
sh '''mkdir -p xunit-reports'''
|
|
84
84
|
sh '''docker cp $BUILD_TAG-volto:/opt/frontend/my-volto-project/coverage xunit-reports/'''
|
|
@@ -125,8 +125,8 @@ pipeline {
|
|
|
125
125
|
node(label: 'docker') {
|
|
126
126
|
script {
|
|
127
127
|
try {
|
|
128
|
-
sh '''docker pull eeacms/plone-backend; docker run -d --
|
|
129
|
-
sh '''docker pull plone/volto-addon-ci; docker run -i --name="$BUILD_TAG-cypress" --link $BUILD_TAG-plone:plone -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e DEPENDENCIES="$DEPENDENCIES" -e NODE_ENV=development -e VOLTO
|
|
128
|
+
sh '''docker pull eeacms/plone-backend; docker run --rm -d --name="$BUILD_TAG-plone" -e SITE="Plone" -e PROFILES="eea.kitkat:testing" eeacms/plone-backend'''
|
|
129
|
+
sh '''docker pull plone/volto-addon-ci:alpha; docker run -i --name="$BUILD_TAG-cypress" --link $BUILD_TAG-plone:plone -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e DEPENDENCIES="$DEPENDENCIES" -e NODE_ENV=development -e VOLTO=$VOLTO plone/volto-addon-ci:alpha cypress'''
|
|
130
130
|
} finally {
|
|
131
131
|
try {
|
|
132
132
|
sh '''rm -rf cypress-reports cypress-results cypress-coverage'''
|
|
@@ -239,4 +239,4 @@ pipeline {
|
|
|
239
239
|
}
|
|
240
240
|
}
|
|
241
241
|
}
|
|
242
|
-
}
|
|
242
|
+
}
|
package/babel.config.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module.exports = function (api) {
|
|
2
|
+
api.cache(true);
|
|
3
|
+
const presets = ['razzle'];
|
|
4
|
+
const plugins = [
|
|
5
|
+
[
|
|
6
|
+
'react-intl', // React Intl extractor, required for the whole i18n infrastructure to work
|
|
7
|
+
{
|
|
8
|
+
messagesDir: './build/messages/',
|
|
9
|
+
},
|
|
10
|
+
],
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
plugins,
|
|
15
|
+
presets,
|
|
16
|
+
};
|
|
17
|
+
};
|
|
@@ -1,20 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { slateBeforeEach, slateAfterEach } from '../support/e2e';
|
|
2
2
|
|
|
3
3
|
describe('Blocks Tests', () => {
|
|
4
|
-
beforeEach(
|
|
5
|
-
afterEach(
|
|
4
|
+
beforeEach(slateBeforeEach);
|
|
5
|
+
afterEach(slateAfterEach);
|
|
6
6
|
|
|
7
7
|
it('Add Block: Empty', () => {
|
|
8
8
|
// Change page title
|
|
9
|
-
cy.
|
|
10
|
-
|
|
11
|
-
.type('My Add-on Page')
|
|
12
|
-
.get('.documentFirstHeading span[data-text]')
|
|
13
|
-
.contains('My Add-on Page');
|
|
9
|
+
cy.clearSlateTitle();
|
|
10
|
+
cy.getSlateTitle().type('My Add-on Page');
|
|
14
11
|
|
|
15
|
-
cy.get('.documentFirstHeading
|
|
16
|
-
|
|
17
|
-
);
|
|
12
|
+
cy.get('.documentFirstHeading').contains('My Add-on Page');
|
|
13
|
+
|
|
14
|
+
cy.getSlate().click();
|
|
18
15
|
|
|
19
16
|
// Add block
|
|
20
17
|
cy.get('.ui.basic.icon.button.block-add-button').first().click();
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
/* eslint no-console: ["error", { allow: ["log"] }] */
|
|
2
2
|
|
|
3
|
+
const SLATE_SELECTOR = '.content-area .slate-editor [contenteditable=true]';
|
|
4
|
+
const SLATE_TITLE_SELECTOR = '.block.inner.title [contenteditable="true"]';
|
|
5
|
+
|
|
3
6
|
// --- AUTOLOGIN -------------------------------------------------------------
|
|
4
7
|
Cypress.Commands.add('autologin', () => {
|
|
5
8
|
let api_url, user, password;
|
|
@@ -68,8 +71,7 @@ Cypress.Commands.add(
|
|
|
68
71
|
id: contentId,
|
|
69
72
|
title: contentTitle,
|
|
70
73
|
image: {
|
|
71
|
-
data:
|
|
72
|
-
'iVBORw0KGgoAAAANSUhEUgAAANcAAAA4CAMAAABZsZ3QAAAAM1BMVEX29fK42OU+oMvn7u9drtIPisHI4OhstdWZyt4fkcXX5+sAg74umMhNp86p0eJ7vNiKw9v/UV4wAAAAAXRSTlMAQObYZgAABBxJREFUeF7tmuty4yAMhZG4X2zn/Z92J5tsBJwWXG/i3XR6frW2Y/SBLIRAfaQUDNt8E5tLUt9BycfcKfq3R6Mlfyimtx4rzp+K3dtibXkor99zsEqLYZltblTecciogoh+TXfY1Ve4dn07rCDGG9dHSEEOg/GmXl0U1XDxTKxNK5De7BxsyyBr6gGm2/vPxKJ8F6f7BXKfRMp1xIWK9A+5ks25alSb353dWnDJN1k35EL5f8dVGifTf/4tjUuuFq7u4srmXC60yAmldLXIWbg65RKU87lcGxJCFqUPv0IacW0PmSivOZFLE908inPToMmii/roG+MRV/O8FU88i8tFsxV3a06MFUw0Qu7RmAtdV5/HVVaOVMTWNOWSwMljLhzhcB6XIS7OK5V6AvRDNN7t5VJWQs1J40UmalbK56usBG/CuCHSYuc+rkUGeMCViNRARPrzW52N3oQLe6WifNliSuuGaH3czbVNudI9s7ZLUCLHVwWlyES522o1t14uvmbblmVTKqFjaZYJFSTPP4dLL1kU1z7p0lzdbRulmEWLxoQX+z9ce7A8GqEEucllLxePuZwdJl1Lezu0hoswvTPt61DrFcRuujV/2cmlxaGBC7Aw6cpovGANwRiSdOAWJ5AGy4gLL64dl0QhUEAuEUNws+XxV+OKGPdw/hESGYF9XEGaFC7sNLMSXWJjHsnanYi87VK428N2uxpOjOFANcagLM5l+7mSycM8KknZpKLcGi6jmzWGr/vLurZ/0g4u9AZuAoeb5r1ceQhyiTPY1E4wUR6u/F3H2ojSpXMMriBPT9cezTto8Cx+MsglHL4fv1Rxrb1LVw9yvyQpJ3AhFnLZfuRLH2QsOG3FGGD20X/th/u5bFAt16Bt308KjF+MNOXgl/SquIEySX3GhaZvc67KZbDxcCDORz2N8yCWPaY5lyQZO7lQ29fnZbt3Xu6qoge4+DjXl/MocySPOp9rlvdyznahRyHEYd77v3LhugOXDv4J65QXfl803BDAdaWBEDhfVx7nKofjoVCgxnUAqw/UAUDPn788BDvQuG4TDtdtUPvzjSlXAB8DvaDOhhrmhwbywylXAm8CvaouikJTL93gs3y7Yy4VYbIxOHrcMizPqWOjqO9l3Uz52kibQy4xxOgqhJvD+w5rvokOcAlGvNCfeqCv1ste1stzLm0f71Iq3ZfTrPfuE5nhPtF+LvQE2lffQC7pYtQy3tdzdrKvd5TLVVzDetScS3nEKmmwDyt1Cev1kX3YfbvzNK4fzrlw+cB6vm+uiUgf2zdXI62241LawCb7Pi5FXFPF8KpzDoF/Sw2lg+GrHNbno1mhPu+VCF/vfMnw06PnUl6j48dVHD3jHNHPua+fc3o/5yp/zsGi0vYtzi3Pz5mHd4T6BWMIlewacd63AAAAAElFTkSuQmCC',
|
|
74
|
+
data: 'iVBORw0KGgoAAAANSUhEUgAAANcAAAA4CAMAAABZsZ3QAAAAM1BMVEX29fK42OU+oMvn7u9drtIPisHI4OhstdWZyt4fkcXX5+sAg74umMhNp86p0eJ7vNiKw9v/UV4wAAAAAXRSTlMAQObYZgAABBxJREFUeF7tmuty4yAMhZG4X2zn/Z92J5tsBJwWXG/i3XR6frW2Y/SBLIRAfaQUDNt8E5tLUt9BycfcKfq3R6Mlfyimtx4rzp+K3dtibXkor99zsEqLYZltblTecciogoh+TXfY1Ve4dn07rCDGG9dHSEEOg/GmXl0U1XDxTKxNK5De7BxsyyBr6gGm2/vPxKJ8F6f7BXKfRMp1xIWK9A+5ks25alSb353dWnDJN1k35EL5f8dVGifTf/4tjUuuFq7u4srmXC60yAmldLXIWbg65RKU87lcGxJCFqUPv0IacW0PmSivOZFLE908inPToMmii/roG+MRV/O8FU88i8tFsxV3a06MFUw0Qu7RmAtdV5/HVVaOVMTWNOWSwMljLhzhcB6XIS7OK5V6AvRDNN7t5VJWQs1J40UmalbK56usBG/CuCHSYuc+rkUGeMCViNRARPrzW52N3oQLe6WifNliSuuGaH3czbVNudI9s7ZLUCLHVwWlyES522o1t14uvmbblmVTKqFjaZYJFSTPP4dLL1kU1z7p0lzdbRulmEWLxoQX+z9ce7A8GqEEucllLxePuZwdJl1Lezu0hoswvTPt61DrFcRuujV/2cmlxaGBC7Aw6cpovGANwRiSdOAWJ5AGy4gLL64dl0QhUEAuEUNws+XxV+OKGPdw/hESGYF9XEGaFC7sNLMSXWJjHsnanYi87VK428N2uxpOjOFANcagLM5l+7mSycM8KknZpKLcGi6jmzWGr/vLurZ/0g4u9AZuAoeb5r1ceQhyiTPY1E4wUR6u/F3H2ojSpXMMriBPT9cezTto8Cx+MsglHL4fv1Rxrb1LVw9yvyQpJ3AhFnLZfuRLH2QsOG3FGGD20X/th/u5bFAt16Bt308KjF+MNOXgl/SquIEySX3GhaZvc67KZbDxcCDORz2N8yCWPaY5lyQZO7lQ29fnZbt3Xu6qoge4+DjXl/MocySPOp9rlvdyznahRyHEYd77v3LhugOXDv4J65QXfl803BDAdaWBEDhfVx7nKofjoVCgxnUAqw/UAUDPn788BDvQuG4TDtdtUPvzjSlXAB8DvaDOhhrmhwbywylXAm8CvaouikJTL93gs3y7Yy4VYbIxOHrcMizPqWOjqO9l3Uz52kibQy4xxOgqhJvD+w5rvokOcAlGvNCfeqCv1ste1stzLm0f71Iq3ZfTrPfuE5nhPtF+LvQE2lffQC7pYtQy3tdzdrKvd5TLVVzDetScS3nEKmmwDyt1Cev1kX3YfbvzNK4fzrlw+cB6vm+uiUgf2zdXI62241LawCb7Pi5FXFPF8KpzDoF/Sw2lg+GrHNbno1mhPu+VCF/vfMnw06PnUl6j48dVHD3jHNHPua+fc3o/5yp/zsGi0vYtzi3Pz5mHd4T6BWMIlewacd63AAAAAElFTkSuQmCC',
|
|
73
75
|
encoding: 'base64',
|
|
74
76
|
filename: 'image.png',
|
|
75
77
|
'content-type': 'image/png',
|
|
@@ -92,7 +94,7 @@ Cypress.Commands.add(
|
|
|
92
94
|
title: contentTitle,
|
|
93
95
|
blocks: {
|
|
94
96
|
'd3f1c443-583f-4e8e-a682-3bf25752a300': { '@type': 'title' },
|
|
95
|
-
'7624cf59-05d0-4055-8f55-5fd6597d84b0': { '@type': '
|
|
97
|
+
'7624cf59-05d0-4055-8f55-5fd6597d84b0': { '@type': 'slate' },
|
|
96
98
|
},
|
|
97
99
|
blocks_layout: {
|
|
98
100
|
items: [
|
|
@@ -122,9 +124,103 @@ Cypress.Commands.add(
|
|
|
122
124
|
})
|
|
123
125
|
.then(() => console.log(`${contentType} created`));
|
|
124
126
|
}
|
|
125
|
-
}
|
|
127
|
+
}
|
|
126
128
|
);
|
|
127
129
|
|
|
130
|
+
// --- Add DX Content-Type ----------------------------------------------------------
|
|
131
|
+
Cypress.Commands.add('addContentType', (name) => {
|
|
132
|
+
let api_url, auth;
|
|
133
|
+
api_url = Cypress.env('API_PATH') || 'http://localhost:8080/Plone';
|
|
134
|
+
auth = {
|
|
135
|
+
user: 'admin',
|
|
136
|
+
pass: 'admin',
|
|
137
|
+
};
|
|
138
|
+
return cy
|
|
139
|
+
.request({
|
|
140
|
+
method: 'POST',
|
|
141
|
+
url: `${api_url}/@controlpanels/dexterity-types/${name}`,
|
|
142
|
+
headers: {
|
|
143
|
+
Accept: 'application/json',
|
|
144
|
+
},
|
|
145
|
+
auth: auth,
|
|
146
|
+
body: {
|
|
147
|
+
title: name,
|
|
148
|
+
},
|
|
149
|
+
})
|
|
150
|
+
.then(() => console.log(`${name} content-type added.`));
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// --- Remove DX behavior ----------------------------------------------------------
|
|
154
|
+
Cypress.Commands.add('removeContentType', (name) => {
|
|
155
|
+
let api_url, auth;
|
|
156
|
+
api_url = Cypress.env('API_PATH') || 'http://localhost:8080/Plone';
|
|
157
|
+
auth = {
|
|
158
|
+
user: 'admin',
|
|
159
|
+
pass: 'admin',
|
|
160
|
+
};
|
|
161
|
+
return cy
|
|
162
|
+
.request({
|
|
163
|
+
method: 'DELETE',
|
|
164
|
+
url: `${api_url}/@controlpanels/dexterity-types/${name}`,
|
|
165
|
+
headers: {
|
|
166
|
+
Accept: 'application/json',
|
|
167
|
+
},
|
|
168
|
+
auth: auth,
|
|
169
|
+
body: {},
|
|
170
|
+
})
|
|
171
|
+
.then(() => console.log(`${name} content-type removed.`));
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
// --- Add DX field ----------------------------------------------------------
|
|
175
|
+
Cypress.Commands.add('addSlateJSONField', (type, name) => {
|
|
176
|
+
let api_url, auth;
|
|
177
|
+
api_url = Cypress.env('API_PATH') || 'http://localhost:8080/Plone';
|
|
178
|
+
auth = {
|
|
179
|
+
user: 'admin',
|
|
180
|
+
pass: 'admin',
|
|
181
|
+
};
|
|
182
|
+
return cy
|
|
183
|
+
.request({
|
|
184
|
+
method: 'POST',
|
|
185
|
+
url: `${api_url}/@types/${type}`,
|
|
186
|
+
headers: {
|
|
187
|
+
Accept: 'application/json',
|
|
188
|
+
},
|
|
189
|
+
auth: auth,
|
|
190
|
+
body: {
|
|
191
|
+
id: name,
|
|
192
|
+
title: name,
|
|
193
|
+
description: 'Slate JSON Field',
|
|
194
|
+
factory: 'SlateJSONField',
|
|
195
|
+
required: false,
|
|
196
|
+
},
|
|
197
|
+
})
|
|
198
|
+
.then(() => console.log(`${name} SlateJSONField field added to ${type}`));
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
// --- Remove DX field ----------------------------------------------------------
|
|
202
|
+
Cypress.Commands.add('removeSlateJSONField', (type, name) => {
|
|
203
|
+
let api_url, auth;
|
|
204
|
+
api_url = Cypress.env('API_PATH') || 'http://localhost:8080/Plone';
|
|
205
|
+
auth = {
|
|
206
|
+
user: 'admin',
|
|
207
|
+
pass: 'admin',
|
|
208
|
+
};
|
|
209
|
+
return cy
|
|
210
|
+
.request({
|
|
211
|
+
method: 'DELETE',
|
|
212
|
+
url: `${api_url}/@types/${type}/${name}`,
|
|
213
|
+
headers: {
|
|
214
|
+
Accept: 'application/json',
|
|
215
|
+
},
|
|
216
|
+
auth: auth,
|
|
217
|
+
body: {},
|
|
218
|
+
})
|
|
219
|
+
.then(() =>
|
|
220
|
+
console.log(`${name} SlateJSONField field removed from ${type}`)
|
|
221
|
+
);
|
|
222
|
+
});
|
|
223
|
+
|
|
128
224
|
// --- REMOVE CONTENT --------------------------------------------------------
|
|
129
225
|
Cypress.Commands.add('removeContent', (path) => {
|
|
130
226
|
let api_url, auth;
|
|
@@ -146,6 +242,41 @@ Cypress.Commands.add('removeContent', (path) => {
|
|
|
146
242
|
.then(() => console.log(`${path} removed`));
|
|
147
243
|
});
|
|
148
244
|
|
|
245
|
+
Cypress.Commands.add('typeInSlate', { prevSubject: true }, (subject, text) => {
|
|
246
|
+
return (
|
|
247
|
+
cy
|
|
248
|
+
.wrap(subject)
|
|
249
|
+
.then((subject) => {
|
|
250
|
+
subject[0].dispatchEvent(
|
|
251
|
+
new InputEvent('beforeinput', {
|
|
252
|
+
inputType: 'insertText',
|
|
253
|
+
data: text,
|
|
254
|
+
})
|
|
255
|
+
);
|
|
256
|
+
return subject;
|
|
257
|
+
})
|
|
258
|
+
// TODO: do this only for Electron-based browser which does not understand instantaneously
|
|
259
|
+
// that the user inserted some text in the block
|
|
260
|
+
.wait(1000)
|
|
261
|
+
);
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
Cypress.Commands.add('lineBreakInSlate', { prevSubject: true }, (subject) => {
|
|
265
|
+
return (
|
|
266
|
+
cy
|
|
267
|
+
.wrap(subject)
|
|
268
|
+
.then((subject) => {
|
|
269
|
+
subject[0].dispatchEvent(
|
|
270
|
+
new InputEvent('beforeinput', { inputType: 'insertLineBreak' })
|
|
271
|
+
);
|
|
272
|
+
return subject;
|
|
273
|
+
})
|
|
274
|
+
// TODO: do this only for Electron-based browser which does not understand instantaneously
|
|
275
|
+
// that the block was split
|
|
276
|
+
.wait(1000)
|
|
277
|
+
);
|
|
278
|
+
});
|
|
279
|
+
|
|
149
280
|
// --- SET WORKFLOW ----------------------------------------------------------
|
|
150
281
|
Cypress.Commands.add(
|
|
151
282
|
'setWorkflow',
|
|
@@ -184,7 +315,7 @@ Cypress.Commands.add(
|
|
|
184
315
|
include_children: include_children,
|
|
185
316
|
},
|
|
186
317
|
});
|
|
187
|
-
}
|
|
318
|
+
}
|
|
188
319
|
);
|
|
189
320
|
|
|
190
321
|
// --- waitForResourceToLoad ----------------------------------------------------------
|
|
@@ -244,9 +375,86 @@ Cypress.Commands.add(
|
|
|
244
375
|
setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset);
|
|
245
376
|
}
|
|
246
377
|
});
|
|
247
|
-
}
|
|
378
|
+
}
|
|
248
379
|
);
|
|
249
380
|
|
|
381
|
+
Cypress.Commands.add('getSlate', ({ createNewSlate = true } = {}) => {
|
|
382
|
+
let slate;
|
|
383
|
+
cy.getIfExists(
|
|
384
|
+
SLATE_SELECTOR,
|
|
385
|
+
() => {
|
|
386
|
+
slate = cy.get(SLATE_SELECTOR).last();
|
|
387
|
+
},
|
|
388
|
+
() => {
|
|
389
|
+
if (createNewSlate) {
|
|
390
|
+
cy.get('.block.inner').last().type('{moveToEnd}{enter}');
|
|
391
|
+
}
|
|
392
|
+
slate = cy.get(SLATE_SELECTOR, { timeout: 10000 }).last();
|
|
393
|
+
}
|
|
394
|
+
);
|
|
395
|
+
return slate;
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
Cypress.Commands.add('clearSlate', (selector) => {
|
|
399
|
+
return cy
|
|
400
|
+
.get(selector)
|
|
401
|
+
.focus()
|
|
402
|
+
.click()
|
|
403
|
+
.wait(1000)
|
|
404
|
+
.type('{selectAll}')
|
|
405
|
+
.wait(1000)
|
|
406
|
+
.type('{backspace}');
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
Cypress.Commands.add('getSlateTitle', () => {
|
|
410
|
+
return cy.get(SLATE_TITLE_SELECTOR, {
|
|
411
|
+
timeout: 10000,
|
|
412
|
+
});
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
Cypress.Commands.add('clearSlateTitle', () => {
|
|
416
|
+
return cy.clearSlate(SLATE_TITLE_SELECTOR);
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
Cypress.Commands.add('setSlateSelection', (subject, query, endQuery) => {
|
|
420
|
+
cy.get('.slate-editor.selected [contenteditable=true]')
|
|
421
|
+
.focus()
|
|
422
|
+
.click()
|
|
423
|
+
.setSelection(subject, query, endQuery)
|
|
424
|
+
.wait(1000); // this wait is needed for the selection change to be detected after
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
Cypress.Commands.add('getSlateEditorAndType', (type) => {
|
|
428
|
+
cy.getSlate().focus().click().type(type);
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
Cypress.Commands.add('setSlateCursor', (subject, query, endQuery) => {
|
|
432
|
+
cy.get('.slate-editor.selected [contenteditable=true]')
|
|
433
|
+
.focus()
|
|
434
|
+
.click()
|
|
435
|
+
.setCursor(subject, query, endQuery)
|
|
436
|
+
.wait(1000);
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
Cypress.Commands.add('clickSlateButton', (button) => {
|
|
440
|
+
cy.get(`.slate-inline-toolbar .button-wrapper a[title="${button}"]`, {
|
|
441
|
+
timeout: 10000,
|
|
442
|
+
}).click({ force: true }); //force click is needed to ensure the button in visible in view.
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
Cypress.Commands.add('toolbarSave', () => {
|
|
446
|
+
cy.wait(1000);
|
|
447
|
+
|
|
448
|
+
// Save
|
|
449
|
+
cy.get('#toolbar-save').click();
|
|
450
|
+
cy.waitForResourceToLoad('@navigation');
|
|
451
|
+
cy.waitForResourceToLoad('@breadcrumbs');
|
|
452
|
+
cy.waitForResourceToLoad('@actions');
|
|
453
|
+
cy.waitForResourceToLoad('@types');
|
|
454
|
+
cy.waitForResourceToLoad('my-page');
|
|
455
|
+
cy.url().should('eq', Cypress.config().baseUrl + '/cypress/my-page');
|
|
456
|
+
});
|
|
457
|
+
|
|
250
458
|
// Low level command reused by `setCursorBefore` and `setCursorAfter`, equal to `setCursorAfter`
|
|
251
459
|
Cypress.Commands.add(
|
|
252
460
|
'setCursor',
|
|
@@ -262,7 +470,7 @@ Cypress.Commands.add(
|
|
|
262
470
|
});
|
|
263
471
|
// Depending on what you're testing, you may need to chain a `.click()` here to ensure
|
|
264
472
|
// further commands are picked up by whatever you're testing (this was required for Slate, for example).
|
|
265
|
-
}
|
|
473
|
+
}
|
|
266
474
|
);
|
|
267
475
|
|
|
268
476
|
Cypress.Commands.add(
|
|
@@ -270,7 +478,7 @@ Cypress.Commands.add(
|
|
|
270
478
|
{ prevSubject: true },
|
|
271
479
|
(subject, query) => {
|
|
272
480
|
cy.wrap(subject).setCursor(query, true);
|
|
273
|
-
}
|
|
481
|
+
}
|
|
274
482
|
);
|
|
275
483
|
|
|
276
484
|
Cypress.Commands.add(
|
|
@@ -278,7 +486,7 @@ Cypress.Commands.add(
|
|
|
278
486
|
{ prevSubject: true },
|
|
279
487
|
(subject, query) => {
|
|
280
488
|
cy.wrap(subject).setCursor(query);
|
|
281
|
-
}
|
|
489
|
+
}
|
|
282
490
|
);
|
|
283
491
|
|
|
284
492
|
// Helper functions
|
|
@@ -313,3 +521,16 @@ Cypress.Commands.add('store', () => {
|
|
|
313
521
|
Cypress.Commands.add('settings', (key, value) => {
|
|
314
522
|
return cy.window().its('settings');
|
|
315
523
|
});
|
|
524
|
+
|
|
525
|
+
Cypress.Commands.add(
|
|
526
|
+
'getIfExists',
|
|
527
|
+
(selector, successAction = () => {}, failAction = () => {}) => {
|
|
528
|
+
cy.get('body').then((body) => {
|
|
529
|
+
if (body.find(selector).length > 0 && successAction) {
|
|
530
|
+
successAction();
|
|
531
|
+
} else if (failAction) {
|
|
532
|
+
failAction();
|
|
533
|
+
}
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
);
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// ***********************************************************
|
|
2
|
+
// This example support/index.js is processed and
|
|
3
|
+
// loaded automatically before your test files.
|
|
4
|
+
//
|
|
5
|
+
// This is a great place to put global configuration and
|
|
6
|
+
// behavior that modifies Cypress.
|
|
7
|
+
//
|
|
8
|
+
// You can change the location of this file or turn off
|
|
9
|
+
// automatically serving support files with the
|
|
10
|
+
// 'supportFile' configuration option.
|
|
11
|
+
//
|
|
12
|
+
// You can read more here:
|
|
13
|
+
// https://on.cypress.io/configuration
|
|
14
|
+
// ***********************************************************
|
|
15
|
+
|
|
16
|
+
// Import commands.js using ES2015 syntax:
|
|
17
|
+
import './commands';
|
|
18
|
+
// Alternatively you can use CommonJS syntax:
|
|
19
|
+
// require('./commands')
|
|
20
|
+
|
|
21
|
+
//Generate code-coverage
|
|
22
|
+
import '@cypress/code-coverage/support';
|
|
23
|
+
|
|
24
|
+
export const slateBeforeEach = (contentType = 'Document') => {
|
|
25
|
+
cy.autologin();
|
|
26
|
+
cy.createContent({
|
|
27
|
+
contentType: 'Document',
|
|
28
|
+
contentId: 'cypress',
|
|
29
|
+
contentTitle: 'Cypress',
|
|
30
|
+
});
|
|
31
|
+
cy.createContent({
|
|
32
|
+
contentType: contentType,
|
|
33
|
+
contentId: 'my-page',
|
|
34
|
+
contentTitle: 'My Page',
|
|
35
|
+
path: 'cypress',
|
|
36
|
+
});
|
|
37
|
+
cy.visit('/cypress/my-page');
|
|
38
|
+
cy.waitForResourceToLoad('@navigation');
|
|
39
|
+
cy.waitForResourceToLoad('@breadcrumbs');
|
|
40
|
+
cy.waitForResourceToLoad('@actions');
|
|
41
|
+
cy.waitForResourceToLoad('@types');
|
|
42
|
+
cy.waitForResourceToLoad('my-page');
|
|
43
|
+
cy.navigate('/cypress/my-page/edit');
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const slateAfterEach = () => {
|
|
47
|
+
cy.autologin();
|
|
48
|
+
cy.removeContent('cypress');
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const slateJsonBeforeEach = (contentType = 'slate') => {
|
|
52
|
+
cy.autologin();
|
|
53
|
+
cy.addContentType(contentType);
|
|
54
|
+
cy.addSlateJSONField(contentType, 'slate');
|
|
55
|
+
slateBeforeEach(contentType);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const slateJsonAfterEach = (contentType = 'slate') => {
|
|
59
|
+
cy.autologin();
|
|
60
|
+
cy.removeContentType(contentType);
|
|
61
|
+
slateAfterEach();
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export const getSelectedSlateEditor = () => {
|
|
65
|
+
return cy.get('.slate-editor.selected [contenteditable=true]').click();
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const createSlateBlock = () => {
|
|
69
|
+
cy.get('.ui.basic.icon.button.block-add-button').first().click();
|
|
70
|
+
cy.get('.blocks-chooser .title').contains('Text').click();
|
|
71
|
+
cy.get('.ui.basic.icon.button.slate').contains('Text').click();
|
|
72
|
+
return getSelectedSlateEditor();
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export const getSlateBlockValue = (sb) => {
|
|
76
|
+
return sb.invoke('attr', 'data-slate-value').then((str) => {
|
|
77
|
+
return typeof str === 'undefined' ? [] : JSON.parse(str);
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export const createSlateBlockWithList = ({
|
|
82
|
+
numbered,
|
|
83
|
+
firstItemText,
|
|
84
|
+
secondItemText,
|
|
85
|
+
}) => {
|
|
86
|
+
let s1 = createSlateBlock();
|
|
87
|
+
|
|
88
|
+
s1.typeInSlate(firstItemText + secondItemText);
|
|
89
|
+
|
|
90
|
+
// select all contents of slate block
|
|
91
|
+
// - this opens hovering toolbar
|
|
92
|
+
cy.contains(firstItemText + secondItemText).then((el) => {
|
|
93
|
+
selectSlateNodeOfWord(el);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// TODO: do not hardcode these selectors:
|
|
97
|
+
if (numbered) {
|
|
98
|
+
// this is the numbered list option in the hovering toolbar
|
|
99
|
+
cy.get('.slate-inline-toolbar > :nth-child(9)').click();
|
|
100
|
+
} else {
|
|
101
|
+
// this is the bulleted list option in the hovering toolbar
|
|
102
|
+
cy.get('.slate-inline-toolbar > :nth-child(10)').click();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// move the text cursor
|
|
106
|
+
const sse = getSelectedSlateEditor();
|
|
107
|
+
sse.type('{leftarrow}');
|
|
108
|
+
for (let i = 0; i < firstItemText.length; ++i) {
|
|
109
|
+
sse.type('{rightarrow}');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// simulate pressing Enter
|
|
113
|
+
getSelectedSlateEditor().lineBreakInSlate();
|
|
114
|
+
|
|
115
|
+
return s1;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export const selectSlateNodeOfWord = (el) => {
|
|
119
|
+
return cy.window().then((win) => {
|
|
120
|
+
var event = new CustomEvent('Test_SelectWord', {
|
|
121
|
+
detail: el[0],
|
|
122
|
+
});
|
|
123
|
+
win.document.dispatchEvent(event);
|
|
124
|
+
});
|
|
125
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const { defineConfig } = require('cypress');
|
|
2
|
+
|
|
3
|
+
module.exports = defineConfig({
|
|
4
|
+
viewportWidth: 1280,
|
|
5
|
+
defaultCommandTimeout: 8888,
|
|
6
|
+
chromeWebSecurity: false,
|
|
7
|
+
reporter: 'junit',
|
|
8
|
+
video: true,
|
|
9
|
+
retries: {
|
|
10
|
+
runMode: 8,
|
|
11
|
+
openMode: 0,
|
|
12
|
+
},
|
|
13
|
+
reporterOptions: {
|
|
14
|
+
mochaFile: 'cypress/reports/cypress-[hash].xml',
|
|
15
|
+
jenkinsMode: true,
|
|
16
|
+
toConsole: true,
|
|
17
|
+
},
|
|
18
|
+
e2e: {
|
|
19
|
+
setupNodeEvents(on, config) {
|
|
20
|
+
// e2e testing node events setup code
|
|
21
|
+
require('@cypress/code-coverage/task')(on, config);
|
|
22
|
+
return config;
|
|
23
|
+
},
|
|
24
|
+
baseUrl: 'http://localhost:3000',
|
|
25
|
+
},
|
|
26
|
+
});
|
package/jest-addon.config.js
CHANGED
|
@@ -11,16 +11,15 @@ module.exports = {
|
|
|
11
11
|
'@package/(.*)$': '<rootDir>/src/$1',
|
|
12
12
|
'@plone/volto-quanta/(.*)$': '<rootDir>/src/addons/volto-quanta/src/$1',
|
|
13
13
|
'@eeacms/(.*?)/(.*)$': '<rootDir>/src/addons/$1/src/$2',
|
|
14
|
-
'volto-slate
|
|
14
|
+
'@plone/volto-slate':
|
|
15
|
+
'<rootDir>/node_modules/@plone/volto/packages/volto-slate/src',
|
|
15
16
|
'~/(.*)$': '<rootDir>/src/$1',
|
|
16
17
|
'load-volto-addons':
|
|
17
18
|
'<rootDir>/node_modules/@plone/volto/jest-addons-loader.js',
|
|
19
|
+
'\\.(css|less|scss|sass)$': 'identity-obj-proxy',
|
|
18
20
|
},
|
|
19
21
|
transform: {
|
|
20
22
|
'^.+\\.js(x)?$': 'babel-jest',
|
|
21
|
-
'^.+\\.css$': 'jest-css-modules',
|
|
22
|
-
'^.+\\.less$': 'jest-css-modules',
|
|
23
|
-
'^.+\\.scss$': 'jest-css-modules',
|
|
24
23
|
'^.+\\.(png)$': 'jest-file',
|
|
25
24
|
'^.+\\.(jpg)$': 'jest-file',
|
|
26
25
|
'^.+\\.(svg)$': './node_modules/@plone/volto/jest-svgsystem-transform.js',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eeacms/volto-tableau",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "@eeacms/volto-tableau: Volto add-on",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"author": "European Environment Agency: IDM2 A-Team",
|
|
@@ -20,12 +20,13 @@
|
|
|
20
20
|
"@eeacms/volto-resize-helper"
|
|
21
21
|
],
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@eeacms/volto-resize-helper": "^0.2.4"
|
|
24
|
-
"tableau-api-js": "github:eea/tableau-api-js#1.1.1"
|
|
23
|
+
"@eeacms/volto-resize-helper": "^0.2.4"
|
|
25
24
|
},
|
|
26
25
|
"devDependencies": {
|
|
27
26
|
"@cypress/code-coverage": "^3.9.5",
|
|
28
|
-
"
|
|
27
|
+
"@plone/scripts": "*",
|
|
28
|
+
"babel-plugin-transform-class-properties": "^6.24.1",
|
|
29
|
+
"md5": "^2.3.0"
|
|
29
30
|
},
|
|
30
31
|
"scripts": {
|
|
31
32
|
"release": "release-it",
|
package/src/Tableau/View.jsx
CHANGED
|
@@ -3,9 +3,9 @@ import { connect } from 'react-redux';
|
|
|
3
3
|
import { compose } from 'redux';
|
|
4
4
|
import { toast } from 'react-toastify';
|
|
5
5
|
import { Toast } from '@plone/volto/components';
|
|
6
|
-
import { getLatestTableauVersion } from 'tableau-api-js';
|
|
7
6
|
import { setTableauApi } from '@eeacms/volto-tableau/actions';
|
|
8
7
|
import cx from 'classnames';
|
|
8
|
+
import { isMyScriptLoaded, loadTableauScript } from '../helpers';
|
|
9
9
|
|
|
10
10
|
const Tableau = (props) => {
|
|
11
11
|
const ref = React.useRef(null);
|
|
@@ -23,7 +23,7 @@ const Tableau = (props) => {
|
|
|
23
23
|
screen = {},
|
|
24
24
|
setError = () => {},
|
|
25
25
|
setLoaded = () => {},
|
|
26
|
-
version =
|
|
26
|
+
version = '2.8.0',
|
|
27
27
|
} = props;
|
|
28
28
|
const {
|
|
29
29
|
autoScale = false,
|
|
@@ -34,7 +34,9 @@ const Tableau = (props) => {
|
|
|
34
34
|
} = data;
|
|
35
35
|
const defaultUrl = data.url;
|
|
36
36
|
const url = props.url || defaultUrl;
|
|
37
|
-
|
|
37
|
+
|
|
38
|
+
//load tableau from script tag
|
|
39
|
+
const tableau = isMyScriptLoaded(version) && __CLIENT__ ? window.tableau : '';
|
|
38
40
|
|
|
39
41
|
const onFilterChange = (filter) => {
|
|
40
42
|
const newFilters = { ...filters.current };
|
|
@@ -159,6 +161,9 @@ const Tableau = (props) => {
|
|
|
159
161
|
if (__CLIENT__ && !props.tableau[version]) {
|
|
160
162
|
props.setTableauApi(version, props.mode);
|
|
161
163
|
}
|
|
164
|
+
if (__CLIENT__) {
|
|
165
|
+
loadTableauScript(() => {}, version);
|
|
166
|
+
}
|
|
162
167
|
/* eslint-disable-next-line */
|
|
163
168
|
}, [version]);
|
|
164
169
|
|
|
@@ -197,22 +202,6 @@ const Tableau = (props) => {
|
|
|
197
202
|
/* eslint-disable-next-line */
|
|
198
203
|
}, [loaded, screen?.page?.width]);
|
|
199
204
|
|
|
200
|
-
// React.useEffect(() => {
|
|
201
|
-
// if (mounted.current && loaded && viz) {
|
|
202
|
-
// const workbook = viz.getWorkbook();
|
|
203
|
-
// if (extraOptions.device === 'desktop') {
|
|
204
|
-
// workbook.activateSheetAsync(0);
|
|
205
|
-
// } else if (extraOptions.device === 'tablet') {
|
|
206
|
-
// workbook.activateSheetAsync(1);
|
|
207
|
-
// } else {
|
|
208
|
-
// workbook.activateSheetAsync(2);
|
|
209
|
-
// }
|
|
210
|
-
// console.log('HERE', workbook.getPublishedSheetsInfo());
|
|
211
|
-
// addExtraFilters(extraOptions);
|
|
212
|
-
// }
|
|
213
|
-
// /* eslint-disable-next-line */
|
|
214
|
-
// }, [JSON.stringify(extraOptions)]);
|
|
215
|
-
|
|
216
205
|
return (
|
|
217
206
|
<div id="tableau-wrap">
|
|
218
207
|
<div id="tableau-outer">
|
|
@@ -4,7 +4,6 @@ import { compose } from 'redux';
|
|
|
4
4
|
import { withRouter } from 'react-router';
|
|
5
5
|
import Tableau from '@eeacms/volto-tableau/Tableau/View';
|
|
6
6
|
import config from '@plone/volto/registry';
|
|
7
|
-
import { getLatestTableauVersion } from 'tableau-api-js';
|
|
8
7
|
import qs from 'querystring';
|
|
9
8
|
import '@eeacms/volto-tableau/less/tableau.less';
|
|
10
9
|
|
|
@@ -36,9 +35,7 @@ const View = (props) => {
|
|
|
36
35
|
autoScale = false,
|
|
37
36
|
} = data;
|
|
38
37
|
const version =
|
|
39
|
-
props.data.version ||
|
|
40
|
-
config.settings.tableauVersion ||
|
|
41
|
-
getLatestTableauVersion();
|
|
38
|
+
props.data.version || config.settings.tableauVersion || '2.8.0';
|
|
42
39
|
const device = getDevice(config, screen.page?.width || Infinity);
|
|
43
40
|
const breakpointUrl = breakpointUrls.filter(
|
|
44
41
|
(breakpoint) => breakpoint.device === device,
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { tableauVersions, getLatestTableauVersion } from 'tableau-api-js';
|
|
2
|
-
|
|
3
1
|
const urlParametersSchema = {
|
|
4
2
|
title: 'Parameter',
|
|
5
3
|
fieldsets: [
|
|
@@ -72,9 +70,19 @@ export default (config) => ({
|
|
|
72
70
|
title: 'Version',
|
|
73
71
|
type: 'array',
|
|
74
72
|
choices: [
|
|
75
|
-
...
|
|
73
|
+
...[
|
|
74
|
+
'2.8.0',
|
|
75
|
+
'2.7.0',
|
|
76
|
+
'2.6.0',
|
|
77
|
+
'2.5.0',
|
|
78
|
+
'2.4.0',
|
|
79
|
+
'2.3.0',
|
|
80
|
+
'2.2.2',
|
|
81
|
+
'2.1.2',
|
|
82
|
+
'2.0.3',
|
|
83
|
+
].map((version) => [version, `tableau-${version}`]),
|
|
76
84
|
],
|
|
77
|
-
default: config.settings.tableauVersion ||
|
|
85
|
+
default: config.settings.tableauVersion || '2.8.0',
|
|
78
86
|
},
|
|
79
87
|
url: {
|
|
80
88
|
title: 'Url',
|
package/src/helpers.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const loadTableauScript = (callback, version) => {
|
|
2
|
+
const existingScript = document.getElementById(`tableauJS`);
|
|
3
|
+
//replace script loaded on each version change
|
|
4
|
+
if (existingScript) {
|
|
5
|
+
existingScript.setAttribute(
|
|
6
|
+
'src',
|
|
7
|
+
`https://public.tableau.com/javascripts/api/tableau-${version}.min.js`,
|
|
8
|
+
);
|
|
9
|
+
}
|
|
10
|
+
if (!existingScript) {
|
|
11
|
+
const script = document.createElement('script');
|
|
12
|
+
script.src = `https://public.tableau.com/javascripts/api/tableau-${version}.min.js`;
|
|
13
|
+
script.id = `tableauJS`;
|
|
14
|
+
document.body.appendChild(script);
|
|
15
|
+
script.onload = () => {
|
|
16
|
+
if (callback) callback();
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
//callback, if needed
|
|
20
|
+
if (existingScript && callback) callback();
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const isMyScriptLoaded = (id) => {
|
|
24
|
+
//check for loaded Tableau script in dom scripts
|
|
25
|
+
var scripts = document.getElementsByTagName('script');
|
|
26
|
+
for (var i = scripts.length; i--; ) {
|
|
27
|
+
// eslint-disable-next-line eqeqeq
|
|
28
|
+
if (scripts[i].id == `tableauJS`) return true;
|
|
29
|
+
}
|
|
30
|
+
return false;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export { loadTableauScript, isMyScriptLoaded };
|
package/src/index.js
CHANGED
|
@@ -12,6 +12,11 @@ const applyConfig = (config) => {
|
|
|
12
12
|
tableau: tableauStore,
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
+
config.settings.allowed_cors_destinations = [
|
|
16
|
+
...(config.settings.allowed_cors_destinations || []),
|
|
17
|
+
'public.tableau.com',
|
|
18
|
+
];
|
|
19
|
+
|
|
15
20
|
config.settings.storeExtenders = [
|
|
16
21
|
...(config.settings.storeExtenders || []),
|
|
17
22
|
tableauMiddleware,
|
package/src/middleware.js
CHANGED
|
@@ -1,38 +1,36 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { toast } from 'react-toastify';
|
|
3
|
-
import { Toast } from '@plone/volto/components';
|
|
4
1
|
import { SET_TABLEAU_API } from '@eeacms/volto-tableau/constants';
|
|
5
|
-
import loadTableauApi from 'tableau-api-js';
|
|
6
2
|
|
|
3
|
+
//need to see if we need redux anymore for this
|
|
7
4
|
export default (middlewares) => [
|
|
8
5
|
(store) => (next) => (action) => {
|
|
9
6
|
const state = store.getState();
|
|
10
|
-
const { version = ''
|
|
7
|
+
const { version = '' } = action || {};
|
|
11
8
|
|
|
12
9
|
if (
|
|
13
10
|
action.type === `${SET_TABLEAU_API}_PENDING` &&
|
|
14
11
|
!state.tableau.loading[version]
|
|
15
12
|
) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
13
|
+
// loadTableauScript(() => {}, version);
|
|
14
|
+
// fetchTableau(version)
|
|
15
|
+
// .then((response) => {
|
|
16
|
+
// if (mode === 'edit') {
|
|
17
|
+
// toast.success(<Toast success title={response.message} />);
|
|
18
|
+
// }
|
|
19
|
+
// store.dispatch({
|
|
20
|
+
// type: `${SET_TABLEAU_API}_SUCCESS`,
|
|
21
|
+
// version,
|
|
22
|
+
// api: response,
|
|
23
|
+
// });
|
|
24
|
+
// })
|
|
25
|
+
// .catch((error) => {
|
|
26
|
+
// if (mode === 'edit') {
|
|
27
|
+
// toast.error(<Toast error title={error.message} />);
|
|
28
|
+
// }
|
|
29
|
+
// store.dispatch({
|
|
30
|
+
// type: `${SET_TABLEAU_API}_FAILED`,
|
|
31
|
+
// version,
|
|
32
|
+
// });
|
|
33
|
+
// });
|
|
36
34
|
}
|
|
37
35
|
|
|
38
36
|
return next(action);
|
package/src/store.js
CHANGED
package/cypress/plugins/index.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/// <reference types="cypress" />
|
|
2
|
-
// ***********************************************************
|
|
3
|
-
// This example plugins/index.js can be used to load plugins
|
|
4
|
-
//
|
|
5
|
-
// You can change the location of this file or turn off loading
|
|
6
|
-
// the plugins file with the 'pluginsFile' configuration option.
|
|
7
|
-
//
|
|
8
|
-
// You can read more here:
|
|
9
|
-
// https://on.cypress.io/plugins-guide
|
|
10
|
-
// ***********************************************************
|
|
11
|
-
|
|
12
|
-
// This function is called when a project is opened or re-opened (e.g. due to
|
|
13
|
-
// the project's config changing)
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* @type {Cypress.PluginConfig}
|
|
17
|
-
*/
|
|
18
|
-
module.exports = (on, config) => {
|
|
19
|
-
// `on` is used to hook into various events Cypress emits
|
|
20
|
-
// `config` is the resolved Cypress config
|
|
21
|
-
/* coverage-start
|
|
22
|
-
require('@cypress/code-coverage/task')(on, config)
|
|
23
|
-
on('file:preprocessor', require('@cypress/code-coverage/use-babelrc'))
|
|
24
|
-
return config
|
|
25
|
-
coverage-end */
|
|
26
|
-
};
|
package/cypress/support/index.js
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
// ***********************************************************
|
|
2
|
-
// This example support/index.js is processed and
|
|
3
|
-
// loaded automatically before your test files.
|
|
4
|
-
//
|
|
5
|
-
// This is a great place to put global configuration and
|
|
6
|
-
// behavior that modifies Cypress.
|
|
7
|
-
//
|
|
8
|
-
// You can change the location of this file or turn off
|
|
9
|
-
// automatically serving support files with the
|
|
10
|
-
// 'supportFile' configuration option.
|
|
11
|
-
//
|
|
12
|
-
// You can read more here:
|
|
13
|
-
// https://on.cypress.io/configuration
|
|
14
|
-
// ***********************************************************
|
|
15
|
-
|
|
16
|
-
// Import commands.js using ES2015 syntax:
|
|
17
|
-
import './commands';
|
|
18
|
-
|
|
19
|
-
// Alternatively you can use CommonJS syntax:
|
|
20
|
-
// require('./commands')
|
|
21
|
-
|
|
22
|
-
/* coverage-start
|
|
23
|
-
//Generate code-coverage
|
|
24
|
-
import '@cypress/code-coverage/support';
|
|
25
|
-
coverage-end */
|
|
26
|
-
|
|
27
|
-
export const setupBeforeEach = () => {
|
|
28
|
-
cy.autologin();
|
|
29
|
-
cy.createContent({
|
|
30
|
-
contentType: 'Document',
|
|
31
|
-
contentId: 'cypress',
|
|
32
|
-
contentTitle: 'Cypress',
|
|
33
|
-
});
|
|
34
|
-
cy.createContent({
|
|
35
|
-
contentType: 'Document',
|
|
36
|
-
contentId: 'my-page',
|
|
37
|
-
contentTitle: 'My Page',
|
|
38
|
-
path: 'cypress',
|
|
39
|
-
});
|
|
40
|
-
cy.visit('/cypress/my-page');
|
|
41
|
-
cy.waitForResourceToLoad('@navigation');
|
|
42
|
-
cy.waitForResourceToLoad('@breadcrumbs');
|
|
43
|
-
cy.waitForResourceToLoad('@actions');
|
|
44
|
-
cy.waitForResourceToLoad('@types');
|
|
45
|
-
cy.waitForResourceToLoad('my-page');
|
|
46
|
-
cy.navigate('/cypress/my-page/edit');
|
|
47
|
-
cy.get(`.block.title [data-contents]`);
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
export const tearDownAfterEach = () => {
|
|
51
|
-
cy.autologin();
|
|
52
|
-
cy.removeContent('cypress');
|
|
53
|
-
};
|
package/cypress.json
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"baseUrl": "http://localhost:3000",
|
|
3
|
-
"viewportWidth": 1280,
|
|
4
|
-
"defaultCommandTimeout": 8888,
|
|
5
|
-
"reporter": "junit",
|
|
6
|
-
"video": true,
|
|
7
|
-
"reporterOptions": {
|
|
8
|
-
"mochaFile": "cypress/reports/cypress-[hash].xml",
|
|
9
|
-
"jenkinsMode": true,
|
|
10
|
-
"toConsole": true
|
|
11
|
-
},
|
|
12
|
-
"chromeWebSecurity": false,
|
|
13
|
-
"retries": {
|
|
14
|
-
"runMode": 8,
|
|
15
|
-
"openMode": 0
|
|
16
|
-
}
|
|
17
|
-
}
|