diff --git a/CHANGELOG.md b/CHANGELOG.md index 56ff794a..9cfe1a92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,18 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +### [5.0.4](https://github.com/eea/volto-plotlycharts/compare/5.0.3...5.0.4) - 24 November 2022 + +#### :hammer_and_wrench: Others + +- block query schema updates [andreiggr - [`b29153f`](https://github.com/eea/volto-plotlycharts/commit/b29153fd60e52b9e3a42d204572f3db3015f79f4)] +- remove even out matrix [andreiggr - [`ee7dbf6`](https://github.com/eea/volto-plotlycharts/commit/ee7dbf678a7863aa852721c184ae6e1802a702ba)] +- include more coremetadata, update csv format [andreiggr - [`6311876`](https://github.com/eea/volto-plotlycharts/commit/6311876368639eb2178344c2c95e371fa402185a)] ### [5.0.3](https://github.com/eea/volto-plotlycharts/compare/5.0.2...5.0.3) - 16 November 2022 #### :hammer_and_wrench: Others - data query updates [andreiggr - [`db6a18c`](https://github.com/eea/volto-plotlycharts/commit/db6a18c5cc310877fdb589aef2a6ac84a35920c5)] -- have data query from context and custom on block [andreiggr - [`7224436`](https://github.com/eea/volto-plotlycharts/commit/72244367c71ce5534d3d21c18b0ee06bc8583194)] ### [5.0.2](https://github.com/eea/volto-plotlycharts/compare/5.0.1...5.0.2) - 10 November 2022 #### :hammer_and_wrench: Others diff --git a/package.json b/package.json index 4677e94b..dad2ad77 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@eeacms/volto-plotlycharts", - "version": "5.0.3", + "version": "5.0.4", "description": "Plotly Charts and Editor integration for Volto", "main": "src/index.js", "author": "European Environment Agency: IDM2 A-Team", diff --git a/src/Blocks/EmbedEEAVisualization/Edit.jsx b/src/Blocks/EmbedEEAVisualization/Edit.jsx index f5c6d5ce..57b3f017 100644 --- a/src/Blocks/EmbedEEAVisualization/Edit.jsx +++ b/src/Blocks/EmbedEEAVisualization/Edit.jsx @@ -53,10 +53,6 @@ const Edit = (props) => { has_data_query_by_context: data.has_data_query_by_context, vis_url: data.vis_url, with_sources: data.show_sources, - include_sources_download: data?.include_sources_download, - include_other_org_download: data?.include_other_org_download, - include_temporal_coverage_download: - data?.include_temporal_coverage_download, }} hoverFormatXY={data.hover_format_xy} withSources={data.show_sources} diff --git a/src/Blocks/EmbedEEAVisualization/View.jsx b/src/Blocks/EmbedEEAVisualization/View.jsx index 24dd9a28..a5c9a4aa 100644 --- a/src/Blocks/EmbedEEAVisualization/View.jsx +++ b/src/Blocks/EmbedEEAVisualization/View.jsx @@ -34,10 +34,6 @@ const View = (props) => { use_live_data: true, vis_url: data.vis_url, with_sources: data.show_sources, - include_sources_download: data?.include_sources_download, - include_other_org_download: data?.include_other_org_download, - include_temporal_coverage_download: - data?.include_temporal_coverage_download, }} hoverFormatXY={data.hover_format_xy} withSources={data.show_sources} diff --git a/src/Blocks/EmbedEEAVisualization/schema.js b/src/Blocks/EmbedEEAVisualization/schema.js index f0c28d33..8ec8a451 100644 --- a/src/Blocks/EmbedEEAVisualization/schema.js +++ b/src/Blocks/EmbedEEAVisualization/schema.js @@ -1,46 +1,6 @@ import React from 'react'; -const makeMetadataOptions = (data) => { - if (data && data.length > 0) { - return data - .map((item) => [...Object.keys(item)]) //get all keys, should be the same for all - .flat(1) // flatten all arrays - .reduce(function (a, b) { - if (a.indexOf(b) < 0) a.push(b); - return a; - }, []) //remove duplicates. We need only one set of keys - .map((item) => [item, item]); //map them for choices - } - return []; -}; - const Schema = (props) => { - const hasSources = - props.data_provenance && - props.data.download_button && - props.data_provenance.data && - props.data_provenance.data.length > 0; - const hasOtherOrg = - props.data.download_button && - props.other_organisations && - props.other_organisations.length > 0; - const hasTemporalCoverage = - props.data.download_button && - props.temporal_coverage && - props.temporal_coverage.temporal && - props.temporal_coverage.temporal.length > 0; - - const data_provenance_options = makeMetadataOptions( - props?.data_provenance?.data, - ); - - const temporal_coverage_options = makeMetadataOptions( - props?.temporal_coverage?.temporal, - ); - - const other_organisations_options = makeMetadataOptions( - props?.other_organisations, - ); return { title: 'Embed EEA visualization', @@ -53,14 +13,7 @@ const Schema = (props) => { { id: 'download', title: 'Download', - fields: [ - 'download_button', - ...(hasSources ? ['include_sources_download'] : []), - ...(hasOtherOrg ? ['include_other_org_download'] : []), - ...(hasTemporalCoverage - ? ['include_temporal_coverage_download'] - : []), - ], + fields: ['download_button'], }, { id: 'data_query', @@ -101,24 +54,6 @@ const Schema = (props) => { title: 'Toggle download', type: 'boolean', }, - include_sources_download: { - title: 'Download sources', - description: 'Include sources in the dowloaded CSV', - choices: data_provenance_options, - isMulti: true, - }, - include_other_org_download: { - title: 'Download other organisations', - description: 'Include other organisations in the dowloaded CSV', - choices: other_organisations_options, - isMulti: true, - }, - include_temporal_coverage_download: { - title: 'Download temporal coverage', - description: 'Include temporal coverage in the dowloaded CSV', - choices: temporal_coverage_options, - isMulti: true, - }, show_sources: { title: 'Toggle sources', type: 'boolean', @@ -129,9 +64,9 @@ const Schema = (props) => { type: 'boolean', }, data_query: { - title: 'Block Query', + title: 'Specific block criteria', description: - 'Query data on this block. If context queries are present, block queries will be overridden.', + 'Query data on this block. Predefined query criteria options are available only when the taxonomies are present in the site ', widget: 'data_query', }, }, diff --git a/src/ConnectedChart2/ConnectedChart2.jsx b/src/ConnectedChart2/ConnectedChart2.jsx index 0bcfed81..86948b41 100644 --- a/src/ConnectedChart2/ConnectedChart2.jsx +++ b/src/ConnectedChart2/ConnectedChart2.jsx @@ -3,6 +3,8 @@ import { compose } from 'redux'; import loadable from '@loadable/component'; import { connectToProviderData } from '@eeacms/volto-datablocks/hocs'; import { updateChartDataFromProvider } from '@eeacms/volto-datablocks/helpers'; +import { toPublicURL } from '@plone/volto/helpers'; + import { connect } from 'react-redux'; import { connectBlockToVisualization } from '@eeacms/volto-plotlycharts/hocs'; @@ -13,23 +15,6 @@ import { Download } from '../Download'; import { Sources } from '../Sources'; const LoadablePlotly = loadable(() => import('react-plotly.js')); - -const filterItemsIds = (items, allowedIds) => { - const newItems = - items && items.length > 0 - ? items - .map((item) => { - var newItem = {}; - allowedIds.forEach((id) => { - newItem[id] = item[id]; - }); - return newItem; - }) - .filter((value) => Object.keys(value).length !== 0) - : []; - return newItems; -}; - /* * ConnectedChart */ @@ -47,6 +32,8 @@ function ConnectedChart2(props) { data_provenance, other_organisations, temporal_coverage, + publisher, + geo_coverage, } = props; const with_sources = props?.withSources ?? false; @@ -100,9 +87,6 @@ function ConnectedChart2(props) { '', }; } - // console.log(provider_data, ' provider_data'); - // console.log(props.data.data_query, ' props.data.data_query'); - // console.log(chartData, ' chartData'); let data = provider_data ? updateChartDataFromProvider(chartData.data || [], provider_data) : chartData.data || []; @@ -147,29 +131,13 @@ function ConnectedChart2(props) { } provider_data={provider_data} provider_metadata={provider_metadata} + url_source={toPublicURL(props?.location?.pathname)} core_metadata={{ - data_provenance: props.data?.include_sources_download - ? filterItemsIds( - data_provenance?.data, - props.data?.include_sources_download, - ) - : '', - other_organisations: props.data?.include_other_org_download - ? filterItemsIds( - other_organisations, - props.data?.include_other_org_download, - ) - : '', - temporal_coverage: - props.data?.include_temporal_coverage_download && - props.data?.include_temporal_coverage_download.length > 0 && - temporal_coverage?.temporal && - temporal_coverage?.temporal?.length > 0 - ? filterItemsIds( - temporal_coverage?.temporal, - props.data?.include_temporal_coverage_download, - ) - : '', + data_provenance: data_provenance?.data, + other_organisations: other_organisations, + temporal_coverage: temporal_coverage?.temporal, + publisher: publisher, + geo_coverage: geo_coverage?.geolocation, }} /> )} @@ -191,10 +159,11 @@ function ConnectedChart2(props) { export default compose( connect( (state, props) => ({ - //mapped core metadata data to props. Include more if needed - subreq: state.content.subrequests?.[props.id]?.data, visualization: state.content.subrequests?.[props.id]?.data?.visualization?.chartData, + //mapped core metadata data to props. Include more if needed + publisher: state.content.subrequests?.[props.id]?.data?.publisher, + geo_coverage: state.content.subrequests?.[props.id]?.data?.geo_coverage, temporal_coverage: state.content.subrequests?.[props.id]?.data?.temporal_coverage, other_organisations: diff --git a/src/Download/Download.jsx b/src/Download/Download.jsx index 74eff96e..f8a65d46 100644 --- a/src/Download/Download.jsx +++ b/src/Download/Download.jsx @@ -5,17 +5,22 @@ import downloadSVG from '../static/download-cloud-fill.svg'; import { trackLink } from '@eeacms/volto-matomo/utils'; -function getHeaders(headers) { +function getHeaders(headers, onlySectionHeader = false) { let str = ''; - headers.forEach((header) => { - if (str !== '') str += ','; - if (header.includes(',')) { - str += `"${header}"`; - } else { - str += header; - } - }); - return str + '\r\n'; + if (!onlySectionHeader) { + headers.forEach((header) => { + if (str !== '') str += ','; + if (header.includes(',')) { + str += `"${header}"`; + } else { + str += header; + } + }); + return str + '\r\n'; + } else { + str += headers[0]; + return str; + } } function getData(array) { @@ -41,19 +46,28 @@ function getData(array) { return str; } -function convertToCSV(array, readme = []) { +const insertEmptyRows = (matrix, rows) => { + for (let i = 0; i < rows; i++) { + matrix += '\r\n'; + } + return matrix; +}; + +function convertToCSV(array, readme = [], noHeaders = false) { const headers = Object.keys(array[0]); - let str = getHeaders(headers); + let str = getHeaders(headers, noHeaders); str += getData(array); - for (let i = 0; i < 5; i++) { - str += '\r\n'; - } + str = insertEmptyRows(str, 1); - readme.forEach((text) => { - str += text + '\r\n'; - }); + if (readme && readme.length > 0) { + readme.forEach((text) => { + str += text + '\r\n'; + }); + + str = insertEmptyRows(str, 1); + } return str; } @@ -64,14 +78,11 @@ function convertMatrixToCSV(matrix, readme = []) { matrix.forEach((array) => { str += getHeaders(Object.keys(array[0])); str += getData(array); - for (let i = 0; i < 2; i++) { - str += '\r\n'; - } + + str = insertEmptyRows(str, 1); }); - for (let i = 0; i < 3; i++) { - str += '\r\n'; - } + str = insertEmptyRows(str, 1); readme.forEach((text) => { str += text + '\r\n'; @@ -112,57 +123,70 @@ function exportCSVFile(csv, title = 'data') { } } +const renameKey = (key) => { + switch (key) { + case 'data_provenance': + return 'Sources'; + case 'other_organisations': + return 'Other organisations involved'; + case 'temporal_coverage': + return 'Temporal coverage'; + case 'geo_coverage': + return 'Geographical coverage'; + case 'publisher': + return 'Publisher'; + default: + return key; + } +}; + const spreadCoreMetadata = (core_metadata) => { + //filter requested metadata and insert head titles let spread_metadata = {}; Object.keys(core_metadata).forEach((key) => { if (core_metadata[key].length > 0) { core_metadata[key].forEach((item) => { Object.keys(item).forEach((subkey) => { - if (!spread_metadata['EEA Core Metadata']) { - spread_metadata['EEA Core Metadata'] = [' ']; - } else { - spread_metadata['EEA Core Metadata'].push(' '); - } - if (!spread_metadata[`${key}_${subkey}`]) { - spread_metadata[`${key}_${subkey}`] = [item[subkey]]; - } else { - spread_metadata[`${key}_${subkey}`].push(item[subkey]); + if (subkey !== '@id' && subkey !== 'value') { + if (!spread_metadata[`${renameKey(key)}`]) { + spread_metadata[`${renameKey(key)}`] = [' ']; + } else { + spread_metadata[`${renameKey(key)}`].push(' '); + } + + if (!spread_metadata[`${key}_${subkey}`]) { + spread_metadata[`${key}_${subkey}`] = [item[subkey]]; + } else { + spread_metadata[`${key}_${subkey}`].push(item[subkey]); + } } }); }); } }); - const coreMaxRows = Object.values(spread_metadata).reduce((a, b) => - a.length > b.length ? a : b, - ).length; - - let evenMatrix = spread_metadata; - Object.entries(evenMatrix).forEach(([key, items]) => { - if (items.length < coreMaxRows) { - for (let i = items.length; i < coreMaxRows; i++) { - items.push(''); - } - } - }); - return evenMatrix; + return spread_metadata; }; const Download = (props) => { const { - // sources, - // className, title, provider_data, provider_metadata, providers_data, providers_metadata, core_metadata, + url_source, } = props; const handleDownloadData = () => { let array = []; - let core_metadata_array = []; + let data_provenance_array = []; + let other_organisation_array = []; + let temporal_coverage_array = []; + let geo_coverage_array = []; + let publisher_array = []; + let readme = provider_metadata?.readme ? [provider_metadata?.readme] : []; const mappedData = { ...provider_data, @@ -173,27 +197,92 @@ const Download = (props) => { array[index][key] = item; }); }); - const hasCoreMetadata = - core_metadata?.data_provenance?.length > 0 || - core_metadata?.other_organisation?.length > 0 || - core_metadata?.temporal_coverage?.length > 0; - if (hasCoreMetadata) { + const hasDataProvenance = core_metadata?.data_provenance?.length > 0; + const hasOtherOrganisation = core_metadata?.other_organisations?.length > 0; + const hasTemporalCoverage = core_metadata?.temporal_coverage?.length > 0; + const hasGeoCoverage = core_metadata?.geo_coverage?.length > 0; + const hasPublisher = core_metadata?.publisher?.length > 0; + + if ( + hasDataProvenance || + hasOtherOrganisation || + hasTemporalCoverage || + hasGeoCoverage || + hasPublisher + ) { Object.entries(spreadCoreMetadata(core_metadata)).forEach( ([key, items]) => { items.forEach((item, index) => { - if (!core_metadata_array[index]) core_metadata_array[index] = {}; - core_metadata_array[index][key] = item; + if (key.includes('data_provenance') || key.includes('Sources')) { + if (!data_provenance_array[index]) + data_provenance_array[index] = {}; + data_provenance_array[index][key] = item; + } + if ( + key.includes('other_organisation') || + key.includes('Other organisations involved') + ) { + if (!other_organisation_array[index]) + other_organisation_array[index] = {}; + other_organisation_array[index][key] = item; + } + if ( + key.includes('temporal_coverage') || + key.includes('Temporal coverage') + ) { + if (!temporal_coverage_array[index]) + temporal_coverage_array[index] = {}; + temporal_coverage_array[index][key] = item; + } + if ( + key.includes('geo_coverage') || + key.includes('Geographical coverage') + ) { + if (!geo_coverage_array[index]) geo_coverage_array[index] = {}; + geo_coverage_array[index][key] = item; + } + if (key.includes('publisher') || key.includes('Publisher')) { + if (!publisher_array[index]) publisher_array[index] = {}; + publisher_array[index][key] = item; + } }); }, ); } const data_csv = convertToCSV(array, readme); - const core_metadata_csv = hasCoreMetadata - ? convertToCSV(core_metadata_array, readme) + + const data_provenance_csv = hasDataProvenance + ? convertToCSV(data_provenance_array, [], true) + : ''; + const other_organisation_csv = hasOtherOrganisation + ? convertToCSV(other_organisation_array, [], true) + : ''; + const temporal_coverage_csv = hasTemporalCoverage + ? convertToCSV(temporal_coverage_array, [], true) : ''; - const csv = hasCoreMetadata ? data_csv + core_metadata_csv : data_csv; + const geo_coverage_csv = hasGeoCoverage + ? convertToCSV(geo_coverage_array, [], true) + : ''; + const publisher_csv = hasPublisher + ? convertToCSV(publisher_array, [], true) + : ''; + + const download_source_csv = convertToCSV( + [{ 'Downloaded from :': ' ', url: url_source }], + [], + true, + ); + + const csv = + data_csv + + download_source_csv + + data_provenance_csv + + publisher_csv + + other_organisation_csv + + geo_coverage_csv + + temporal_coverage_csv; exportCSVFile(csv, title); };