diff --git a/jsconfig.json b/jsconfig.json
index 4e98cf1e..5cb40552 100644
--- a/jsconfig.json
+++ b/jsconfig.json
@@ -19,6 +19,9 @@
"@eeacms/volto-grid-block": [
"addons/volto-grid-block/src"
],
+ "@eeacms/volto-tableau": [
+ "addons/volto-tableau/src"
+ ],
"@eeacms/volto-tabs-block": [
"addons/volto-tabs-block/src"
]
diff --git a/mrs.developer.json b/mrs.developer.json
index fd2e4e93..cb41e9a2 100644
--- a/mrs.developer.json
+++ b/mrs.developer.json
@@ -38,6 +38,13 @@
"package": "@eeacms/volto-grid-block",
"develop": true
},
+ "volto-tableau": {
+ "url": "https://github.com/eea/volto-tableau.git",
+ "path": "src",
+ "package": "@eeacms/volto-tableau",
+ "branch": "master",
+ "develop": true
+ },
"volto-tabs-block": {
"url": "https://github.com/eea/volto-tabs-block.git",
"path": "src",
diff --git a/package.json b/package.json
index cfc45c78..617d6809 100644
--- a/package.json
+++ b/package.json
@@ -45,6 +45,7 @@
"volto-datablocks",
"volto-embed",
"volto-addons",
+ "@eeacms/volto-tableau",
"@eeacms/volto-block-style",
"@eeacms/volto-tabs-block"
],
@@ -66,6 +67,7 @@
"react-iframe": "^1.8.0",
"react-tooltip": "^4.2.9",
"react-visibility-sensor": "^5.1.1",
+ "tableau-api-js": "github:eea/tableau-api-js#1.1.0",
"volto-slate": "github:eea/volto-slate#2.4.0"
},
"devDependencies": {
diff --git a/src/components/manage/Blocks/DiscodataComponents/Custom/View.jsx b/src/components/manage/Blocks/DiscodataComponents/Custom/View.jsx
index da360faa..8b709494 100644
--- a/src/components/manage/Blocks/DiscodataComponents/Custom/View.jsx
+++ b/src/components/manage/Blocks/DiscodataComponents/Custom/View.jsx
@@ -154,7 +154,7 @@ const ReportingYears = (props) => {
>
-
+
Last report was submitted on:
{getDate(packages[0])}
diff --git a/src/components/manage/Blocks/DiscodataComponents/Text/View.jsx b/src/components/manage/Blocks/DiscodataComponents/Text/View.jsx
index 91477e6b..796951bb 100644
--- a/src/components/manage/Blocks/DiscodataComponents/Text/View.jsx
+++ b/src/components/manage/Blocks/DiscodataComponents/Text/View.jsx
@@ -22,7 +22,7 @@ const components = {
{components.bold(bold, text)}
{tooltip && tooltipText ? (
-
+
) : (
''
diff --git a/src/components/manage/Blocks/DiscodataOpenlayersMapBlock/PrivacyProtection.jsx b/src/components/manage/Blocks/DiscodataOpenlayersMapBlock/PrivacyProtection.jsx
index 7a2cb7e3..ef329110 100644
--- a/src/components/manage/Blocks/DiscodataOpenlayersMapBlock/PrivacyProtection.jsx
+++ b/src/components/manage/Blocks/DiscodataOpenlayersMapBlock/PrivacyProtection.jsx
@@ -72,7 +72,7 @@ export default ({ children, data = {}, block, onShow, ...rest }) => {
className="floating-icon mr-1"
data-tip={dataprotection.privacy_statement}
>
-
+
) : (
''
diff --git a/src/components/manage/Blocks/DiscodataOpenlayersMapBlock/View.jsx b/src/components/manage/Blocks/DiscodataOpenlayersMapBlock/View.jsx
index 839ab97a..24a6e7d1 100644
--- a/src/components/manage/Blocks/DiscodataOpenlayersMapBlock/View.jsx
+++ b/src/components/manage/Blocks/DiscodataOpenlayersMapBlock/View.jsx
@@ -144,7 +144,7 @@ const OpenlayersMapView = (props) => {
const siteTerm =
filterSource !== 'query_params'
? props.discodata_query.search.siteTerm || null
- : props.discodata_query.search[queryParams?.siteName?.param] || null;
+ : props.query.siteName || null;
useEffect(() => {
if (__CLIENT__ && document) {
@@ -363,7 +363,8 @@ const OpenlayersMapView = (props) => {
},
// Reporting year
reportingYear: {
- sql: `(Site_reporting_year IN (:options))`,
+ sql: `(Site_reporting_year = :options)`,
+ type: 'multiple',
},
// Plant type
plantTypes: {
@@ -416,13 +417,7 @@ const OpenlayersMapView = (props) => {
where.sql = null;
}
} else {
- if (id === 'reportingYear' && options) {
- where.sql = options
- ? where.sql.replace(/:options/g, options).replace(/'/g, '')
- : null;
- } else {
- where.sql = options ? where.sql.replace(/:options/g, options) : null;
- }
+ where.sql = options ? where.sql.replace(/:options/g, options) : null;
}
if (!where.sql) delete sitesSourceQuery.whereStatements[id];
});
@@ -1441,7 +1436,7 @@ const OpenlayersMapView = (props) => {
export default compose(
connect(
(state, props) => ({
- query: state.router.location.search,
+ query: qs.parse(state.router.location.search.replace('?', '')),
content:
state.prefetch?.[state.router.location.pathname] || state.content.data,
discodata_query: state.discodata_query,
diff --git a/src/components/manage/Blocks/Iframe/Edit.jsx b/src/components/manage/Blocks/Iframe/Edit.jsx
index 6125d077..75cbbc2a 100644
--- a/src/components/manage/Blocks/Iframe/Edit.jsx
+++ b/src/components/manage/Blocks/Iframe/Edit.jsx
@@ -1,4 +1,4 @@
-import React, { useState, useEffect } from 'react';
+import React, { useState } from 'react';
import { connect } from 'react-redux';
import { compose } from 'redux';
import _uniqueId from 'lodash/uniqueId';
@@ -151,18 +151,17 @@ const Edit = (props) => {
schema: getSchema({ ...props, providerUrl: config.settings.providerUrl }),
id: _uniqueId('block_'),
});
- // useEffect(() => {
- // }, [discodata_query, flags]);
return (
+
+
-
);
};
diff --git a/src/components/manage/Blocks/Iframe/View.jsx b/src/components/manage/Blocks/Iframe/View.jsx
index 140da087..d15c100f 100644
--- a/src/components/manage/Blocks/Iframe/View.jsx
+++ b/src/components/manage/Blocks/Iframe/View.jsx
@@ -204,7 +204,7 @@ const View = ({ content, ...props }) => {
{title}
-
+
) : title ? (
diff --git a/src/components/manage/Blocks/SiteBlocks/BatConclusions.jsx b/src/components/manage/Blocks/SiteBlocks/BatConclusions.jsx
index e8452f1f..3c1be9b1 100644
--- a/src/components/manage/Blocks/SiteBlocks/BatConclusions.jsx
+++ b/src/components/manage/Blocks/SiteBlocks/BatConclusions.jsx
@@ -27,7 +27,7 @@ const View = (props) => {
content="Number of individual conclusions that indicate which techniques or combinations of techniques are BAT for achieving a specific environmental objective"
trigger={
-
+
}
/>
@@ -86,7 +86,7 @@ const View = (props) => {
? downSVG
: rightSVG
}
- size={20}
+ size="20px"
color="#D63D27"
onClick={() => {
if (
diff --git a/src/components/manage/Blocks/SiteBlocks/CompetentAuthority.jsx b/src/components/manage/Blocks/SiteBlocks/CompetentAuthority.jsx
index 0d6b8b4c..b3a474d1 100644
--- a/src/components/manage/Blocks/SiteBlocks/CompetentAuthority.jsx
+++ b/src/components/manage/Blocks/SiteBlocks/CompetentAuthority.jsx
@@ -16,7 +16,7 @@ const CompetentAuthority = (props) => {
content="Authority, body or bodies responsible for regulating the facility and reporting the associated E-PRTR data, as designated by the reporting country"
trigger={
-
+
}
/>
diff --git a/src/components/manage/Blocks/SiteBlocks/EnvironmentalFacilityDetails/View.jsx b/src/components/manage/Blocks/SiteBlocks/EnvironmentalFacilityDetails/View.jsx
index 99ccbf54..911a8291 100644
--- a/src/components/manage/Blocks/SiteBlocks/EnvironmentalFacilityDetails/View.jsx
+++ b/src/components/manage/Blocks/SiteBlocks/EnvironmentalFacilityDetails/View.jsx
@@ -1,7 +1,6 @@
import React from 'react';
import { compose } from 'redux';
import { connect } from 'react-redux';
-import { setQueryParam, deleteQueryParam } from 'volto-datablocks/actions';
import CompetentAuthority from '../CompetentAuthority';
import { getDate } from '../helpers';
import qs from 'querystring';
@@ -19,7 +18,7 @@ const getAllIndexes = (arr, val) => {
const View = (props) => {
const [facilities, setFacilities] = React.useState([]);
const { provider_data = {} } = props;
- const query = { ...props.query, ...props.discodata_query.search };
+ const query = { ...props.query };
const siteReportingYear = parseInt(query.siteReportingYear || '');
const competentAuthority = facilities
@@ -74,14 +73,7 @@ const View = (props) => {
};
export default compose(
- connect(
- (state, props) => ({
- query: qs.parse(state.router.location.search.replace('?', '')),
- discodata_query: state.discodata_query,
- }),
- {
- setQueryParam,
- deleteQueryParam,
- },
- ),
+ connect((state, props) => ({
+ query: qs.parse(state.router.location.search.replace('?', '')),
+ })),
)(View);
diff --git a/src/components/manage/Blocks/SiteBlocks/EnvironmentalLcpDetails/View.jsx b/src/components/manage/Blocks/SiteBlocks/EnvironmentalLcpDetails/View.jsx
index 1866b9e4..033851f0 100644
--- a/src/components/manage/Blocks/SiteBlocks/EnvironmentalLcpDetails/View.jsx
+++ b/src/components/manage/Blocks/SiteBlocks/EnvironmentalLcpDetails/View.jsx
@@ -8,7 +8,7 @@ import '../style.css';
const View = (props) => {
const [lcp, setLcp] = React.useState({});
const { provider_data = {} } = props;
- const query = { ...props.query, ...props.discodata_query.search };
+ const query = { ...props.query };
const { lcpInspireId = null } = query;
const siteReportingYear = parseInt(query.siteReportingYear || '');
const index = provider_data?.euregReportingYear?.indexOf(siteReportingYear);
@@ -72,6 +72,5 @@ const View = (props) => {
export default compose(
connect((state, props) => ({
query: qs.parse(state.router.location.search.replace('?', '')),
- discodata_query: state.discodata_query,
})),
)(View);
diff --git a/src/components/manage/Blocks/SiteBlocks/EnvironmentalSiteDetails/View.jsx b/src/components/manage/Blocks/SiteBlocks/EnvironmentalSiteDetails/View.jsx
index 91c8bb93..b493c6ff 100644
--- a/src/components/manage/Blocks/SiteBlocks/EnvironmentalSiteDetails/View.jsx
+++ b/src/components/manage/Blocks/SiteBlocks/EnvironmentalSiteDetails/View.jsx
@@ -1,7 +1,6 @@
import React from 'react';
import { compose } from 'redux';
import { connect } from 'react-redux';
-import { setQueryParam, deleteQueryParam } from 'volto-datablocks/actions';
import CompetentAuthority from '../CompetentAuthority';
import { getDate, getLonLat } from '../helpers';
import { Grid } from 'semantic-ui-react';
@@ -21,7 +20,7 @@ const View = (props) => {
const [siteDetails, setSiteDetails] = React.useState({});
const [facilities, setFacilities] = React.useState([]);
const { provider_data = {} } = props;
- const query = { ...props.query, ...props.discodata_query.search };
+ const query = { ...props.query };
const siteReportingYear = parseInt(query.siteReportingYear || '');
const facilityList = [
@@ -135,14 +134,7 @@ const View = (props) => {
};
export default compose(
- connect(
- (state, props) => ({
- query: qs.parse(state.router.location.search.replace('?', '')),
- discodata_query: state.discodata_query,
- }),
- {
- setQueryParam,
- deleteQueryParam,
- },
- ),
+ connect((state, props) => ({
+ query: qs.parse(state.router.location.search.replace('?', '')),
+ })),
)(View);
diff --git a/src/components/manage/Blocks/SiteBlocks/Header/View.jsx b/src/components/manage/Blocks/SiteBlocks/Header/View.jsx
index 1f1f63ca..56e67e88 100644
--- a/src/components/manage/Blocks/SiteBlocks/Header/View.jsx
+++ b/src/components/manage/Blocks/SiteBlocks/Header/View.jsx
@@ -2,7 +2,6 @@ import React from 'react';
import { compose } from 'redux';
import { connect } from 'react-redux';
import { Grid, Dropdown } from 'semantic-ui-react';
-import { setQueryParam, deleteQueryParam } from 'volto-datablocks/actions';
import qs from 'querystring';
import './style.css';
@@ -14,13 +13,14 @@ const getQueryString = (query) => {
const View = (props) => {
const [siteHeader, setSiteHeader] = React.useState({});
const { provider_data = {} } = props;
- const query = { ...props.query, ...props.discodata_query.search };
+ const query = { ...props.query };
const siteReportingYear = parseInt(query.siteReportingYear || '');
const index = provider_data?.euregReportingYear?.indexOf(siteReportingYear);
- const reportingYears = provider_data.euregReportingYear?.length
+ const reportingYears = provider_data?.euregReportingYear?.length
? provider_data.euregReportingYear
.filter((year) => year)
+ .sort()
.map((year) => ({
key: year,
value: year,
@@ -131,11 +131,6 @@ const View = (props) => {
ignoreScrollBehavior: true,
},
});
- props.setQueryParam({
- queryParam: {
- siteReportingYear: data.value,
- },
- });
}}
placeholder={'Select'}
options={reportingYears}
@@ -153,14 +148,7 @@ const View = (props) => {
};
export default compose(
- connect(
- (state, props) => ({
- query: qs.parse(state.router.location.search.replace('?', '')),
- discodata_query: state.discodata_query,
- }),
- {
- setQueryParam,
- deleteQueryParam,
- },
- ),
+ connect((state, props) => ({
+ query: qs.parse(state.router.location.search.replace('?', '')),
+ })),
)(View);
diff --git a/src/components/manage/Blocks/SiteBlocks/PermitingAuthority.jsx b/src/components/manage/Blocks/SiteBlocks/PermitingAuthority.jsx
index a31cb509..2234c169 100644
--- a/src/components/manage/Blocks/SiteBlocks/PermitingAuthority.jsx
+++ b/src/components/manage/Blocks/SiteBlocks/PermitingAuthority.jsx
@@ -24,7 +24,7 @@ const PermitingAuthority = (props) => {
content="Authority, body or bodies responsible for issuing a permit to a given facility"
trigger={
-
+
}
/>
diff --git a/src/components/manage/Blocks/SiteBlocks/RegulatoryBATConclusions/View.jsx b/src/components/manage/Blocks/SiteBlocks/RegulatoryBATConclusions/View.jsx
index 119430b4..9e5e4be8 100644
--- a/src/components/manage/Blocks/SiteBlocks/RegulatoryBATConclusions/View.jsx
+++ b/src/components/manage/Blocks/SiteBlocks/RegulatoryBATConclusions/View.jsx
@@ -18,7 +18,7 @@ const View = (props) => {
const [batConclusions, setBatConclusions] = React.useState({});
const [installationsNth, setInstallationsNth] = React.useState({});
const { provider_data = {} } = props;
- const query = { ...props.query, ...props.discodata_query.search };
+ const query = { ...props.query };
const siteReportingYear = parseInt(query.siteReportingYear || '');
React.useEffect(() => {
@@ -87,6 +87,5 @@ const View = (props) => {
export default compose(
connect((state, props) => ({
query: qs.parse(state.router.location.search.replace('?', '')),
- discodata_query: state.discodata_query,
})),
)(View);
diff --git a/src/components/manage/Blocks/SiteBlocks/RegulatoryInstallationDetails/Edit.jsx b/src/components/manage/Blocks/SiteBlocks/RegulatoryInstallationDetails/Edit.jsx
deleted file mode 100644
index 8ac90ffb..00000000
--- a/src/components/manage/Blocks/SiteBlocks/RegulatoryInstallationDetails/Edit.jsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import React, { useState, useEffect } from 'react';
-import { connect } from 'react-redux';
-import { compose } from 'redux';
-import _uniqueId from 'lodash/uniqueId';
-import View from './View';
-import config from '@plone/volto/registry';
-import './style.css';
-
-const getSchema = (props) => {
- return {};
-};
-
-const Edit = (props) => {
- const [state, setState] = useState({
- schema: getSchema({ ...props, providerUrl: config.settings.providerUrl }),
- id: _uniqueId('block_'),
- });
- return (
-
-
-
- );
-};
-
-export default compose(
- connect((state, props) => ({
- pathname: state.router.location.pathname,
- })),
-)(Edit);
diff --git a/src/components/manage/Blocks/SiteBlocks/RegulatoryInstallationDetails/View.jsx b/src/components/manage/Blocks/SiteBlocks/RegulatoryInstallationDetails/View.jsx
deleted file mode 100644
index 2dd6bc44..00000000
--- a/src/components/manage/Blocks/SiteBlocks/RegulatoryInstallationDetails/View.jsx
+++ /dev/null
@@ -1,198 +0,0 @@
-import React, { useState } from 'react';
-import { compose } from 'redux';
-import { connect } from 'react-redux';
-import ReactTooltip from 'react-tooltip';
-import { setQueryParam, deleteQueryParam } from 'volto-datablocks/actions';
-import Icon from '@plone/volto/components/theme/Icon/Icon';
-import PermitingAuthority from '../PermitingAuthority';
-import cx from 'classnames';
-import { getDate } from '../helpers';
-import infoSVG from '@plone/volto/icons/info.svg';
-import './style.css';
-
-const View = (props) => {
- const [aels, setAels] = useState(false);
- const {
- siteInspireId = null,
- installationInspireId = null,
- siteReportingYear = null,
- } = props.discodata_query.search;
- const {
- permits = {},
- bat_derogations = {},
- bat_conclusions = {},
- } = props.discodata_resources.data;
-
- const data_permits = permits[siteInspireId] || null;
- const data_bat_derogations = bat_derogations[siteInspireId] || null;
- const data_bat_conclusions = bat_conclusions[siteInspireId] || null;
-
- const permitingAuthority =
- siteReportingYear && data_permits?.euregReportingYears?.[siteReportingYear]
- ? data_permits.euregReportingYears[siteReportingYear]
- .filter(
- (report) =>
- report.EUregReportingYear === siteReportingYear &&
- report.installationInspireId === installationInspireId,
- )
- .map((report) => ({
- permitUpdated: getDate(report.permitUpdated),
- permitingAuthority: report.permitingAuthority,
- permitAvailable: report.permitAvailable,
- seveso: report.seveso,
- entityStatus: report.entityStatus,
- }))
- : [];
- const batDerogations =
- siteReportingYear &&
- data_bat_derogations?.euregReportingYears?.[siteReportingYear]
- ? data_bat_derogations.euregReportingYears[siteReportingYear].filter(
- (report) =>
- report.EUregReportingYear === siteReportingYear &&
- report.installationInspireId === installationInspireId,
- )
- : [];
- const batConclusions =
- siteReportingYear &&
- data_bat_conclusions?.euregReportingYears?.[siteReportingYear]
- ? data_bat_conclusions.euregReportingYears[siteReportingYear].filter(
- (report) =>
- report.EUregReportingYear === siteReportingYear &&
- report.installationInspireId === installationInspireId &&
- report.BATConclusionName,
- )
- : [];
-
- return props.mode === 'edit' ? (
-
Installation details
- ) : (
-
- {true ? (
-
- {/* OPERATING PERMIT */}
-
- {/* BAT CONCLUSION */}
-
-
BAT conclusions
-
-
-
-
- {batConclusions.length || batDerogations.length ? (
-
- {batConclusions.length
- ? batConclusions.map((conclusion, index) => (
-
-
-
{conclusion.BATConclusionName}
-
-
-
-
Status
-
{conclusion.Status || '-'}
-
-
-
Status modified
-
- {conclusion.StatusModifiedYear || '-'}
-
-
-
-
- ))
- : ''}
- {((aels && batDerogations.length) || !batConclusions.length) && (
-
-
-
- BAT AELs
-
-
- {batDerogations.map((ael, index) => (
-
-
-
-
-
Start date
-
- {getDate(ael.StartDate) || '-'}
-
-
-
-
End date
-
{getDate(ael.EndDate)}
-
-
-
-
-
Status
-
{ael.Status || '-'}
-
-
-
- ))}
-
- )}
- {batDerogations.length && batConclusions.length ? (
- <>
-
-
- {
- setAels(!aels);
- }}
- >
- {aels ? 'Hide BAT AELs' : 'View BAT AELs'}
-
-
- >
- ) : (
- ''
- )}
-
- ) : (
-
No data
- )}
-
-
-
- ) : (
- ''
- )}
-
- );
-};
-
-export default compose(
- connect(
- (state, props) => ({
- query: state.router.location.search,
- discodata_query: state.discodata_query,
- discodata_resources: state.discodata_resources,
- }),
- {
- setQueryParam,
- deleteQueryParam,
- },
- ),
-)(View);
diff --git a/src/components/manage/Blocks/SiteBlocks/RegulatoryInstallationDetails/style.css b/src/components/manage/Blocks/SiteBlocks/RegulatoryInstallationDetails/style.css
deleted file mode 100644
index f0af14ac..00000000
--- a/src/components/manage/Blocks/SiteBlocks/RegulatoryInstallationDetails/style.css
+++ /dev/null
@@ -1,38 +0,0 @@
-.facility-details h3.blue {
- color: #4296b2;
-}
-
-.facility-details .header-tooltip {
- display: flex;
- align-items: center;
-}
-
-.facility-details .floating-icon {
- display: flex;
-}
-
-.facility-details .header-tooltip h3 {
- margin-right: 0.3rem;
- margin-bottom: 0;
-}
-
-.facility-details .list {
- display: flex;
- flex-flow: row;
- flex-wrap: wrap;
- padding: 0;
- color: #ec776a;
- grid-gap: 20px;
- list-style: none;
-}
-
-.facility-details .list li button {
- padding: 0;
- border: none;
- background: transparent;
- color: #ec776a;
-}
-
-.facility-details .list li button:focus {
- outline: none;
-}
diff --git a/src/components/manage/Blocks/SiteBlocks/RegulatoryPermits/View.jsx b/src/components/manage/Blocks/SiteBlocks/RegulatoryPermits/View.jsx
index 3a6fdcf1..a2183f5e 100644
--- a/src/components/manage/Blocks/SiteBlocks/RegulatoryPermits/View.jsx
+++ b/src/components/manage/Blocks/SiteBlocks/RegulatoryPermits/View.jsx
@@ -18,7 +18,7 @@ const getAllIndexes = (arr, val) => {
const View = (props) => {
const [permits, setPermits] = React.useState([]);
const { provider_data = {} } = props;
- const query = { ...props.query, ...props.discodata_query.search };
+ const query = { ...props.query };
const siteReportingYear = parseInt(query.siteReportingYear || '');
React.useEffect(() => {
@@ -94,6 +94,5 @@ const View = (props) => {
export default compose(
connect((state, props) => ({
query: qs.parse(state.router.location.search.replace('?', '')),
- discodata_query: state.discodata_query,
})),
)(View);
diff --git a/src/components/manage/Blocks/SiteBlocks/RegulatorySiteDetails/View.jsx b/src/components/manage/Blocks/SiteBlocks/RegulatorySiteDetails/View.jsx
index b7d645d2..856d669a 100644
--- a/src/components/manage/Blocks/SiteBlocks/RegulatorySiteDetails/View.jsx
+++ b/src/components/manage/Blocks/SiteBlocks/RegulatorySiteDetails/View.jsx
@@ -3,7 +3,6 @@ import { compose } from 'redux';
import { connect } from 'react-redux';
import { Grid, Popup } from 'semantic-ui-react';
import Icon from '@plone/volto/components/theme/Icon/Icon';
-import { setQueryParam, deleteQueryParam } from 'volto-datablocks/actions';
import infoSVG from '@plone/volto/icons/info.svg';
import qs from 'querystring';
import '../style.css';
@@ -11,7 +10,7 @@ import '../style.css';
const View = (props) => {
const [siteDetails, setSiteDetails] = React.useState({});
const { provider_data = {} } = props;
- const query = { ...props.query, ...props.discodata_query.search };
+ const query = { ...props.query };
const siteReportingYear = parseInt(query.siteReportingYear || '');
const index = provider_data?.euregReportingYear?.indexOf(siteReportingYear);
@@ -37,7 +36,7 @@ const View = (props) => {
content="Information regarding the facilities included in the industrial site"
trigger={
-
+
}
/>
@@ -63,14 +62,7 @@ const View = (props) => {
};
export default compose(
- connect(
- (state, props) => ({
- query: qs.parse(state.router.location.search.replace('?', '')),
- discodata_query: state.discodata_query,
- }),
- {
- setQueryParam,
- deleteQueryParam,
- },
- ),
+ connect((state, props) => ({
+ query: qs.parse(state.router.location.search.replace('?', '')),
+ })),
)(View);
diff --git a/src/components/manage/Blocks/SiteBlocks/RegulatorySitePermits/View.jsx b/src/components/manage/Blocks/SiteBlocks/RegulatorySitePermits/View.jsx
index 55269675..cea3e047 100644
--- a/src/components/manage/Blocks/SiteBlocks/RegulatorySitePermits/View.jsx
+++ b/src/components/manage/Blocks/SiteBlocks/RegulatorySitePermits/View.jsx
@@ -18,7 +18,7 @@ const getAllIndexes = (arr, val) => {
const View = (props) => {
const [permits, setPermits] = React.useState([]);
const { provider_data = {} } = props;
- const query = { ...props.query, ...props.discodata_query.search };
+ const query = { ...props.query };
const siteReportingYear = parseInt(query.siteReportingYear || '');
React.useEffect(() => {
@@ -91,6 +91,5 @@ const View = (props) => {
export default compose(
connect((state, props) => ({
query: qs.parse(state.router.location.search.replace('?', '')),
- discodata_query: state.discodata_query,
})),
)(View);
diff --git a/src/components/manage/Blocks/SiteBlocks/style.css b/src/components/manage/Blocks/SiteBlocks/style.css
index 8f86843f..d4ac9bc8 100644
--- a/src/components/manage/Blocks/SiteBlocks/style.css
+++ b/src/components/manage/Blocks/SiteBlocks/style.css
@@ -52,15 +52,18 @@ h3.orange {
padding: 0;
}
+/* ?? */
.site-block .ui.grid .row .column {
- padding: 0 1rem 1rem 1rem;
+ padding: 0 1rem;
+ margin-bottom: 1rem;
}
.site-block div.eprtrBanner {
color: #fff;
border-radius: 10px;
margin-bottom: 1rem;
- padding: 1rem 1rem;
+ padding: 1rem;
+ padding-bottom: 0;
}
.site-block div.eprtrBanner.blue {
@@ -135,6 +138,11 @@ h3.orange {
background-color: #b4b4b4;
}
+.ui.grid .row .column .label,
+.ui.grid .row .column .info {
+ word-break: break-all;
+}
+
.ui.grid .row .column .label {
font-weight: bold;
margin-bottom: 0;
@@ -182,6 +190,7 @@ h3.orange {
position: relative;
width: 100%;
border: 1px solid #000;
+ margin-bottom: 1rem;
padding: 0 1rem;
border-radius: 10px;
}
@@ -258,3 +267,120 @@ h3.orange {
text-decoration: underline;
padding: 0;
}
+
+.custom-selector h1.ui.header {
+ margin-bottom: 0;
+}
+
+.custom-selector .ui.selection.dropdown {
+ width: fit-content;
+ min-width: unset;
+ min-height: unset;
+ padding: 0;
+ border-bottom: none;
+ line-height: 1em;
+}
+
+.custom-selector .ui.selection.dropdown > .default.text,
+.custom-selector .ui.selection.dropdown > .text,
+.custom-selector .ui.selection.visible.dropdown > .text:not(.default) {
+ padding-left: 0;
+}
+
+.custom-selector .ui.selection.dropdown > .dropdown.icon {
+ position: relative;
+ top: unset;
+ right: unset;
+ bottom: unset;
+ left: unset;
+ margin: 0;
+ margin-left: 0 !important;
+ font-size: 1.7em !important;
+ line-height: 1em;
+}
+
+.custom-selector .ui.active.selection.dropdown {
+ border-bottom: 0;
+}
+
+.custom-selector.big h1.ui.header {
+ font-size: 36px;
+ font-weight: bold;
+ line-height: 45px;
+}
+
+.custom-selector.big .ui.selection.dropdown > .dropdown.icon {
+ margin-right: 1em;
+ font-size: 30px !important;
+ line-height: 39px;
+}
+
+.custom-selector.big .ui.selection.dropdown > .default.text,
+.custom-selector.big .ui.selection.dropdown > .text,
+.custom-selector.big .ui.selection.visible.dropdown > .text:not(.default) {
+ font-size: 30px;
+ font-weight: bold;
+ line-height: 39px;
+}
+
+.custom-selector.red h1.ui.header,
+.custom-selector.red .ui.selection.dropdown,
+.custom-selector.red .ui.selection.dropdown > .default.text,
+.custom-selector.red .ui.selection.dropdown > .text,
+.custom-selector.red .ui.selection.visible.dropdown > .text:not(.default) {
+ background-color: transparent;
+ color: #ec776a;
+}
+
+.custom-selector.grey h1.ui.header,
+.custom-selector.grey .ui.selection.dropdown,
+.custom-selector.grey .ui.selection.dropdown > .default.text,
+.custom-selector.grey .ui.selection.dropdown > .text,
+.custom-selector.grey .ui.selection.visible.dropdown > .text:not(.default) {
+ border-bottom: none;
+ background-color: transparent;
+ color: #989898;
+}
+
+.custom-selector.grey .ui.selection.dropdown .menu {
+ width: 100% !important;
+ min-width: 100% !important;
+}
+
+.custom-selector.grey .ui.selection.dropdown {
+ padding: 0 1rem;
+ margin-left: -1rem;
+}
+
+.custom-selector.grey .ui.selection.dropdown .menu > .item {
+ padding-right: 1rem !important;
+ padding-left: 1rem !important;
+}
+
+.custom-selector.grey .ui.selection.dropdown > .dropdown.icon {
+ font-size: 1.3em !important;
+}
+
+.custom-selector.blue h1.ui.header,
+.custom-selector.blue .ui.selection.dropdown,
+.custom-selector.blue .ui.selection.dropdown > .default.text,
+.custom-selector.blue .ui.selection.dropdown > .text,
+.custom-selector.blue .ui.selection.visible.dropdown > .text:not(.default) {
+ background-color: transparent;
+ color: #4296b3;
+}
+
+.custom-selector.white h1.ui.header,
+.custom-selector.white .ui.selection.dropdown,
+.custom-selector.white .ui.selection.dropdown > .default.text,
+.custom-selector.white .ui.selection.dropdown > .text,
+.custom-selector.white .ui.selection.visible.dropdown > .text:not(.default) {
+ background-color: transparent;
+ color: #fff;
+}
+
+@media (max-width: 500px) {
+ .custom-selector .selector-container {
+ flex-flow: column;
+ }
+}
diff --git a/src/components/manage/Blocks/SiteStructureSidebar/style.css b/src/components/manage/Blocks/SiteStructureSidebar/style.css
index 35c069f6..a809b5ab 100644
--- a/src/components/manage/Blocks/SiteStructureSidebar/style.css
+++ b/src/components/manage/Blocks/SiteStructureSidebar/style.css
@@ -2,7 +2,6 @@
flex-flow: column;
border-bottom: none;
background: transparent;
- min-height: 800px;
}
.sidebar-block .ui.menu .ui.menu {
@@ -119,7 +118,3 @@
color: #333333;
/* font-weight: bold;; */
}
-
-.permiting-authority .info {
- margin-bottom: 1rem;
-}
\ No newline at end of file
diff --git a/src/components/manage/Blocks/SiteTableau/Edit.jsx b/src/components/manage/Blocks/SiteTableau/Edit.jsx
new file mode 100644
index 00000000..344ff62b
--- /dev/null
+++ b/src/components/manage/Blocks/SiteTableau/Edit.jsx
@@ -0,0 +1,40 @@
+import React from 'react';
+import { SidebarPortal } from '@plone/volto/components';
+import InlineForm from '@plone/volto/components/manage/Form/InlineForm';
+import config from '@plone/volto/registry';
+import { connectBlockToProviderData } from 'volto-datablocks/hocs';
+import getSchema from './schema';
+import View from './View';
+
+const Edit = (props) => {
+ const { provider_data = null } = props;
+ const provider_keys = Object.keys(provider_data || {});
+ const [schema, setSchema] = React.useState(getSchema(config, provider_keys));
+
+ React.useEffect(() => {
+ setSchema(getSchema(config, provider_keys));
+ /* eslint-disable-next-line */
+ }, [JSON.stringify(provider_keys)]);
+
+ return (
+ <>
+
+
+
+ {
+ props.onChangeBlock(props.block, {
+ ...props.data,
+ [id]: value,
+ });
+ }}
+ formData={props.data}
+ />
+
+ >
+ );
+};
+
+export default connectBlockToProviderData(Edit);
diff --git a/src/components/manage/Blocks/SiteTableau/View.jsx b/src/components/manage/Blocks/SiteTableau/View.jsx
new file mode 100644
index 00000000..eb4ad979
--- /dev/null
+++ b/src/components/manage/Blocks/SiteTableau/View.jsx
@@ -0,0 +1,113 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import { compose } from 'redux';
+import Tableau from '@eeacms/volto-tableau/Tableau/View';
+import config from '@plone/volto/registry';
+import { getLatestTableauVersion } from 'tableau-api-js';
+import { connectBlockToProviderData } from 'volto-datablocks/hocs';
+import qs from 'querystring';
+import '@eeacms/volto-tableau/less/tableau.less';
+
+const getDevice = (config, width) => {
+ const breakpoints = config.blocks.blocksConfig.tableau_block.breakpoints;
+ let device = 'default';
+ Object.keys(breakpoints).forEach((breakpoint) => {
+ if (
+ width <= breakpoints[breakpoint][0] &&
+ width >= breakpoints[breakpoint][1]
+ ) {
+ device = breakpoint;
+ }
+ });
+ return device;
+};
+
+const View = (props) => {
+ const [error, setError] = React.useState(null);
+ const [mounted, setMounted] = React.useState(false);
+ const [extraFilters, setExtraFilters] = React.useState({});
+ const { data = {}, query = {}, screen = {}, provider_data = null } = props;
+ const {
+ disabledKey = null,
+ breakpointUrls = [],
+ urlParameters = [],
+ title = null,
+ description = null,
+ } = data;
+ const version =
+ props.data.version ||
+ config.settings.tableauVersion ||
+ getLatestTableauVersion();
+ const device = getDevice(config, screen.screenWidth || Infinity);
+ const breakpointUrl = breakpointUrls.filter(
+ (breakpoint) => breakpoint.device === device,
+ )[0]?.url;
+ const url = breakpointUrl || data.url;
+ const disabled = disabledKey ? !provider_data?.[disabledKey]?.[0] : false;
+
+ React.useEffect(() => {
+ setMounted(true);
+ /* eslint-disable-next-line */
+ }, []);
+
+ React.useEffect(() => {
+ const newExtraFilters = { ...extraFilters };
+ urlParameters.forEach((element) => {
+ if (element.field && typeof query[element.urlParam] !== 'undefined') {
+ newExtraFilters[element.field] = query[element.urlParam];
+ } else if (newExtraFilters[element.field]) {
+ delete newExtraFilters[element.field];
+ }
+ });
+ setExtraFilters(newExtraFilters);
+ /* eslint-disable-next-line */
+ }, [JSON.stringify(query), JSON.stringify(urlParameters)]);
+
+ return mounted ? (
+
+ {props.mode === 'edit' ? (
+
+
== Tableau {version} ==
+ {!props.data.url ?
URL required
: ''}
+ {error ?
{error}
: ''}
+
+ ) : (
+ ''
+ )}
+ {!disabled ? (
+ <>
+ {title ?
{title} : ''}
+ {description ? (
+
{description}
+ ) : (
+ ''
+ )}
+
+ >
+ ) : (
+ ''
+ )}
+
+ ) : (
+ ''
+ );
+};
+
+export default compose(
+ connect((state, props) => ({
+ query: {
+ ...(qs.parse(state.router.location?.search?.replace('?', '')) || {}),
+ ...(state.discodata_query?.search || {}),
+ },
+ screen: state.screen,
+ })),
+)(connectBlockToProviderData(View));
diff --git a/src/components/manage/Blocks/SiteTableau/index.js b/src/components/manage/Blocks/SiteTableau/index.js
new file mode 100644
index 00000000..4de7f815
--- /dev/null
+++ b/src/components/manage/Blocks/SiteTableau/index.js
@@ -0,0 +1,28 @@
+import sliderSVG from '@plone/volto/icons/slider.svg';
+import TableauEdit from './Edit';
+import TableauView from './View';
+
+export default (config) => {
+ config.blocks.blocksConfig.site_tableau_block = {
+ id: 'site_tableau_block',
+ title: 'Site tableau',
+ icon: sliderSVG,
+ group: 'data_blocks',
+ edit: TableauEdit,
+ view: TableauView,
+ restricted: false,
+ mostUsed: false,
+ sidebarTab: 1,
+ blocks: {},
+ security: {
+ addPermission: [],
+ view: [],
+ },
+ breakpoints: {
+ desktop: [Infinity, 982],
+ tablet: [981, 768],
+ mobile: [767, 0],
+ },
+ };
+ return config;
+};
diff --git a/src/components/manage/Blocks/SiteTableau/schema.js b/src/components/manage/Blocks/SiteTableau/schema.js
new file mode 100644
index 00000000..23102b39
--- /dev/null
+++ b/src/components/manage/Blocks/SiteTableau/schema.js
@@ -0,0 +1,147 @@
+import { tableauVersions, getLatestTableauVersion } from 'tableau-api-js';
+
+const urlParametersSchema = {
+ title: 'Parameter',
+ fieldsets: [
+ {
+ id: 'default',
+ title: 'Default',
+ fields: ['field', 'urlParam'],
+ },
+ ],
+ properties: {
+ field: {
+ title: 'Tableau fieldname',
+ type: 'text',
+ },
+ urlParam: {
+ title: 'URL param',
+ type: 'text',
+ },
+ },
+ required: [],
+};
+
+const breakpointUrlSchema = (config) => {
+ const breakpoints = config.blocks.blocksConfig.tableau_block.breakpoints;
+
+ return {
+ title: 'URL',
+ fieldsets: [{ id: 'default', title: 'Default', fields: ['device', 'url'] }],
+ properties: {
+ device: {
+ title: 'Device',
+ type: 'array',
+ choices: Object.keys(breakpoints).map((breakpoint) => [
+ breakpoint,
+ breakpoint,
+ ]),
+ },
+ url: {
+ title: 'Url',
+ widget: 'textarea',
+ },
+ },
+ required: [],
+ };
+};
+
+export default (config, provider_keys = []) => ({
+ title: 'Tableau',
+ fieldsets: [
+ {
+ id: 'default',
+ title: 'Default',
+ fields: ['version', 'url', 'title', 'description'],
+ },
+ {
+ id: 'data_connector',
+ title: 'Data connector options',
+ fields: ['provider_url', 'allowedParams', 'disabledKey'],
+ },
+ {
+ id: 'options',
+ title: 'Options',
+ fields: ['sheetname', 'hideTabs', 'hideToolbar', 'toolbarPosition'],
+ },
+ {
+ id: 'extra_options',
+ title: 'Extra options',
+ fields: ['urlParameters', 'breakpointUrls'],
+ },
+ ],
+ properties: {
+ version: {
+ title: 'Version',
+ type: 'array',
+ choices: [
+ ...tableauVersions.map((version) => [version, `tableau-${version}`]),
+ ],
+ default: config.settings.tableauVersion || getLatestTableauVersion(),
+ },
+ url: {
+ title: 'Url',
+ widget: 'textarea',
+ },
+ provider_url: {
+ title: 'Data provider',
+ widget: 'object_by_path',
+ },
+ allowedParams: {
+ title: 'Allowed params',
+ type: 'array',
+ items: {
+ choices: [],
+ },
+ },
+ disabledKey: {
+ title: 'Disabled',
+ type: 'array',
+ choices: [...provider_keys.map((key) => [key, key])],
+ },
+ title: {
+ title: 'Title',
+ widget: 'textarea',
+ },
+ description: {
+ title: 'Description',
+ widget: 'textarea',
+ },
+ sheetname: {
+ title: 'Sheetname',
+ type: 'text',
+ },
+ hideTabs: {
+ title: 'Hide tabs',
+ type: 'boolean',
+ default: false,
+ },
+ hideToolbar: {
+ title: 'Hide toolbar',
+ type: 'boolean',
+ default: false,
+ },
+ toolbarPosition: {
+ title: 'Toolbar position',
+ type: 'array',
+ choices: [
+ ['Top', 'Top'],
+ ['Bottom', 'Bottom'],
+ ],
+ default: 'Top',
+ },
+ urlParameters: {
+ title: 'URL parameters',
+ widget: 'object_list',
+ schema: urlParametersSchema,
+ description: 'Set a list of url parameters to filter the tableau',
+ },
+ breakpointUrls: {
+ title: 'Breakpoint urls',
+ widget: 'object_list',
+ schema: breakpointUrlSchema(config),
+ description: 'Set different vizualization for specific breakpoint',
+ },
+ },
+ required: ['version', 'url'],
+});
diff --git a/src/components/theme/View/DefaultView.jsx b/src/components/theme/View/DefaultView.jsx
index 931850ce..9055fd8a 100644
--- a/src/components/theme/View/DefaultView.jsx
+++ b/src/components/theme/View/DefaultView.jsx
@@ -3,7 +3,7 @@
* @module components/theme/View/DefaultView
*/
-import React, { useEffect, useRef, useState } from 'react';
+import React, { useEffect, useState } from 'react';
import { compose } from 'redux';
import { connect } from 'react-redux';
import { useHistory } from 'react-router-dom';
@@ -13,7 +13,6 @@ import { defineMessages, injectIntl } from 'react-intl';
import { Container, Image } from 'semantic-ui-react';
import { map } from 'lodash';
import qs from 'query-string';
-import { setQueryParam } from 'volto-datablocks/actions';
import config from '@plone/volto/registry';
@@ -37,30 +36,17 @@ const messages = defineMessages({
* @param {Object} content Content object.
* @returns {string} Markup of the component.
*/
-const DefaultView = ({
- content,
- intl,
- location,
- discodata_query,
- query,
- setQueryParam,
-}) => {
+const DefaultView = ({ content, intl, location, query }) => {
const [mounted, setMounted] = useState(false);
const history = useHistory();
const blocksFieldname = getBlocksFieldname(content);
const blocksLayoutFieldname = getBlocksLayoutFieldname(content);
const contentTypeBlocks = content['@components']?.layout?.[blocksFieldname];
- const hash = location.hash.replace('#', '');
- const timer = useRef(null);
- const clock = useRef(0);
- const siteTemplateQuery = [
- 'siteInspireId',
- 'siteName',
- 'siteReportingYear',
- // 'facilityInspireId',
- // 'installationInspireId',
- // 'lcpInspireId',
- ];
+ const siteTemplateQuery = ['siteInspireId', 'siteName', 'siteReportingYear'];
+ const queryObj = { ...(query || {}) };
+
+ const hasRequiredQuery =
+ siteTemplateQuery.filter((key) => queryObj[key]).length !== 3;
useEffect(() => {
setMounted(true);
@@ -80,64 +66,17 @@ const DefaultView = ({
/* eslint-disable-next-line */
}, []);
- // useEffect(() => {
- // if (
- // content['layout'] === 'default_view' &&
- // content['@type'] === 'site_template' &&
- // !discodata_query.search.siteInspireId &&
- // !query.siteInspireId
- // ) {
- // history.push('/browse/explore-data-map/map');
- // return;
- // }
- // if (
- // content['layout'] === 'default_view' &&
- // content['@type'] === 'site_template' &&
- // mounted
- // ) {
- // const queryParams = { ...query };
- // const missingQueryParams = {};
-
- // Object.keys(discodata_query.search)
- // .filter((key) => siteTemplateQuery.includes(key))
- // .forEach((key) => {
- // queryParams[key] = discodata_query.search[key];
- // });
-
- // Object.keys(query)
- // .filter(
- // (key) =>
- // siteTemplateQuery.includes(key) && !discodata_query.search[key],
- // )
- // .forEach((key) => {
- // if (key === 'siteReportingYear') {
- // missingQueryParams[key] = parseInt(query[key]);
- // } else {
- // missingQueryParams[key] = query[key];
- // }
- // });
-
- // if (Object.keys(missingQueryParams).length) {
- // setQueryParam({
- // queryParam: { ...missingQueryParams },
- // });
- // }
-
- // if (
- // Object.keys(queryParams).filter(
- // (key) =>
- // JSON.stringify(queryParams[key]) !== JSON.stringify(query[key]),
- // ).length
- // ) {
- // history.push(
- // `${location.pathname.replace(/\/$/, '')}?${qs.stringify(
- // queryParams,
- // )}`,
- // );
- // }
- // }
- // /* eslint-disable-next-line */
- // }, [mounted, content?.['@id']]);
+ useEffect(() => {
+ if (
+ content['layout'] === 'default_view' &&
+ content['@type'] === 'site_template' &&
+ hasRequiredQuery
+ ) {
+ history.push('/browse/explore-data-map/map');
+ return;
+ }
+ /* eslint-disable-next-line */
+ }, [mounted, content?.['@id']]);
return hasBlocksData(content) ? (
@@ -229,11 +168,7 @@ DefaultView.propTypes = {
};
export default compose(
- connect(
- (state, props) => ({
- discodata_query: state.discodata_query,
- query: qs.parse(state.router.location.search),
- }),
- { setQueryParam },
- ),
+ connect((state, props) => ({
+ query: qs.parse(state.router.location.search.replace('?', '')),
+ })),
)(injectIntl(DefaultView));
diff --git a/src/config.js b/src/config.js
index 7b9f40cf..8e1be67b 100644
--- a/src/config.js
+++ b/src/config.js
@@ -70,8 +70,8 @@ import DummyBlockView from '~/components/manage/Blocks/DummyBlock/View';
import DiscodataTableBlockEdit from '~/components/manage/Blocks/DiscodataTableBlock/Edit';
import DiscodataTableBlockView from '~/components/manage/Blocks/DiscodataTableBlock/View';
-import DiscodataComponentsBlockEdit from '~/components/manage/Blocks/DiscodataComponentsBlock/Edit';
-import DiscodataComponentsBlockView from '~/components/manage/Blocks/DiscodataComponentsBlock/View';
+// import DiscodataComponentsBlockEdit from '~/components/manage/Blocks/DiscodataComponentsBlock/Edit';
+// import DiscodataComponentsBlockView from '~/components/manage/Blocks/DiscodataComponentsBlock/View';
import TextEdit from '~/components/manage/Blocks/DiscodataComponents/Text/Edit';
import TextView from '~/components/manage/Blocks/DiscodataComponents/Text/View';
@@ -91,6 +91,7 @@ import ListView from '~/components/manage/Blocks/DiscodataComponents/List/View';
import BlocksWidget from '~/components/manage/Widgets/BlocksWidget';
import QueryParametersListWidget from '~/components/manage/Blocks/DiscodataComponents/Widgets/QueryParametersListWidget';
+import installSiteTableau from '~/components/manage/Blocks/SiteTableau';
import installSiteStructureSidebar from '~/components/manage/Blocks/SiteStructureSidebar';
import installSiteHeader from '~/components/manage/Blocks/SiteBlocks/Header';
import installEnvironmentalSiteDetails from '~/components/manage/Blocks/SiteBlocks/EnvironmentalSiteDetails';
@@ -358,6 +359,7 @@ export default function applyConfig(config) {
excludeFromNavigation: ['/industrial-site'],
metaDescription: 'European Environment Agency',
matomoSiteId: 48,
+ tableauVersion: '2.3.0',
};
config.portlets = {
@@ -372,6 +374,7 @@ export default function applyConfig(config) {
];
return [
+ installSiteTableau,
installSiteStructureSidebar,
installSiteHeader,
installEnvironmentalSiteDetails,
diff --git a/src/customizations/volto/middleware/api.js b/src/customizations/volto/middleware/api.js
index 0108374f..0bae27b5 100644
--- a/src/customizations/volto/middleware/api.js
+++ b/src/customizations/volto/middleware/api.js
@@ -42,7 +42,7 @@ export function addExpandersToPath(path, type) {
}
const stringifiedQuery = qs.stringify(query, {
arrayFormat: 'comma',
- encode: false,
+ encode: true,
});
if (!stringifiedQuery) {
return pathPart;
diff --git a/yarn.lock b/yarn.lock
index eef07293..0747fdcb 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -19629,6 +19629,10 @@ table@^5.2.3, table@^5.4.6:
slice-ansi "^2.1.0"
string-width "^3.0.0"
+"tableau-api-js@github:eea/tableau-api-js#1.1.0":
+ version "1.1.0"
+ resolved "https://codeload.github.com/eea/tableau-api-js/tar.gz/ee6167de3663de7f6d2c010dd3208e8d5ed381ed"
+
tapable@^1.0.0, tapable@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"