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 ? ( - <> -
-
- -
- - ) : ( - '' - )} -
- ) : ( -

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"