From efae975a1ab8af978c6b1f3e526f6dd8a7fa6d67 Mon Sep 17 00:00:00 2001 From: DavidQuartz Date: Wed, 10 Aug 2022 16:07:33 +0000 Subject: [PATCH] Added Metadata downloads --- .../client/js/actions/gndownload.js | 29 +++++++++ .../js/epics/__tests__/gndownload-test.js | 41 +++++++++++++ .../client/js/epics/gndownload.js | 46 ++++++++++++++ .../plugins/downloads/DublinCoreDownload.jsx | 59 ++++++++++++++++++ .../js/plugins/downloads/IsoDownload.jsx | 60 +++++++++++++++++++ .../client/js/plugins/index.js | 8 +++ .../js/reducers/__tests__/gndownload-test.js | 37 ++++++++++++ .../client/js/reducers/gndownload.js | 53 ++++++++++++++++ .../static/mapstore/configs/localConfig.json | 24 +++++++- .../mapstore/translations/data.de-DE.json | 4 +- .../mapstore/translations/data.en-US.json | 4 +- .../mapstore/translations/data.es-ES.json | 4 +- .../mapstore/translations/data.fr-FR.json | 4 +- .../mapstore/translations/data.it-IT.json | 4 +- 14 files changed, 370 insertions(+), 7 deletions(-) create mode 100644 geonode_mapstore_client/client/js/actions/gndownload.js create mode 100644 geonode_mapstore_client/client/js/epics/__tests__/gndownload-test.js create mode 100644 geonode_mapstore_client/client/js/epics/gndownload.js create mode 100644 geonode_mapstore_client/client/js/plugins/downloads/DublinCoreDownload.jsx create mode 100644 geonode_mapstore_client/client/js/plugins/downloads/IsoDownload.jsx create mode 100644 geonode_mapstore_client/client/js/reducers/__tests__/gndownload-test.js create mode 100644 geonode_mapstore_client/client/js/reducers/gndownload.js diff --git a/geonode_mapstore_client/client/js/actions/gndownload.js b/geonode_mapstore_client/client/js/actions/gndownload.js new file mode 100644 index 0000000000..dd9168e001 --- /dev/null +++ b/geonode_mapstore_client/client/js/actions/gndownload.js @@ -0,0 +1,29 @@ +/* + * Copyright 2022, GeoSolutions Sas. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. +*/ + +/** +* Sync geostory components with their live resources on geonode +*/ +export const DOWNLOAD_METADATA = 'GEONODE:DOWNLOAD_METADATA'; +export const DOWNLOAD_METADATA_COMPLETE = 'GEONODE:DOWNLOAD_METADATA_COMPLETE'; + +export function downloadMetaData(linkType, pk) { + return { + type: DOWNLOAD_METADATA, + link: linkType, + pk + }; +} + +export function downloadMetaDataComplete(linkType, pk) { + return { + type: DOWNLOAD_METADATA_COMPLETE, + link: linkType, + pk + }; +} diff --git a/geonode_mapstore_client/client/js/epics/__tests__/gndownload-test.js b/geonode_mapstore_client/client/js/epics/__tests__/gndownload-test.js new file mode 100644 index 0000000000..ec9602ef23 --- /dev/null +++ b/geonode_mapstore_client/client/js/epics/__tests__/gndownload-test.js @@ -0,0 +1,41 @@ +/* + * Copyright 2022, GeoSolutions Sas. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +import expect from 'expect'; +import { testEpic } from '@mapstore/framework/epics/__tests__/epicTestUtils'; +import { downloadMetaData, DOWNLOAD_METADATA_COMPLETE } from '@js/actions/gndownload'; +import { gnDownloadMetaData } from '@js/epics/gndownload'; + +describe('gnDownloadMetaData epic', () => { + beforeEach(done => { + setTimeout(done); + }); + afterEach(done => { + setTimeout(done); + }); + it('should download metadata', (done) => { + const NUM_ACTIONS = 1; + + testEpic( + gnDownloadMetaData, + NUM_ACTIONS, + downloadMetaData('ISO', 1), + (actions) => { + try { + expect(actions.map(({type}) => type)).toEqual([ DOWNLOAD_METADATA_COMPLETE ]); + done(); + } catch (e) { + done(e); + } + }, + {}, + done + ); + }); + +}); diff --git a/geonode_mapstore_client/client/js/epics/gndownload.js b/geonode_mapstore_client/client/js/epics/gndownload.js new file mode 100644 index 0000000000..f42774c76c --- /dev/null +++ b/geonode_mapstore_client/client/js/epics/gndownload.js @@ -0,0 +1,46 @@ +/* + * Copyright 2022, GeoSolutions Sas. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { Observable } from 'rxjs'; +import axios from '@mapstore/framework/libs/ajax'; +import { saveAs } from 'file-saver'; +import { DOWNLOAD_METADATA, downloadMetaDataComplete } from '@js/actions/gndownload'; +import { + error as errorNotification +} from '@mapstore/framework/actions/notifications'; + +export const gnDownloadMetaData = (action$, store) => + action$.ofType(DOWNLOAD_METADATA) + .switchMap((action) => { + const state = store.getState(); + const url = state.gnresource?.data?.links?.find((link) => link.name === action.link).url; + const resourceTitle = state.gnresource?.data?.title; + + return Observable + .defer(() => axios.get(url).then((data) => data)) + .switchMap(({ data, headers }) => { + if (headers["content-type"] === "application/xml" || headers["content-type"] === "application/xml; charset=UTF-8") { + let xml = String.fromCharCode.apply(null, new Uint8Array(data)); + if (xml.indexOf(" { + return Observable.of( + downloadMetaDataComplete(action.link, action.pk), + errorNotification({ title: "gnviewer.cannotPerfomAction", message: error?.data?.message || error?.data?.detail || error?.originalError?.message || "gnviewer.syncErrorDefault" })); + }); + + }); + +export default { + gnDownloadMetaData +}; diff --git a/geonode_mapstore_client/client/js/plugins/downloads/DublinCoreDownload.jsx b/geonode_mapstore_client/client/js/plugins/downloads/DublinCoreDownload.jsx new file mode 100644 index 0000000000..7165a02ab4 --- /dev/null +++ b/geonode_mapstore_client/client/js/plugins/downloads/DublinCoreDownload.jsx @@ -0,0 +1,59 @@ +/* + * Copyright 2022, GeoSolutions Sas. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. +*/ + +import React from 'react'; +import { connect } from 'react-redux'; +import { createSelector } from 'reselect'; +import { createPlugin } from '@mapstore/framework/utils/PluginsUtils'; +import Message from '@mapstore/framework/components/I18N/Message'; +import Button from '@js/components/Button'; +import { downloadMetaData } from '@js/actions/gndownload'; +import { gnDownloadMetaData } from '@js/epics/gndownload'; +import Spinner from '@js/components/Spinner'; +import gnDownload from '@js/reducers/gndownload'; + +function DublinCoreDownload({ onDownload, resourcePk, isDownloading }) { + return ( + + ); +} + +const DublinCoreDownloadPlugin = connect( + createSelector([ + state => state?.gnresource?.data.pk || null, + state => state?.gnDownload?.downloads?.DublinCore || {} + ], (resourcePk, downloadingResources) => ({ + resourcePk, + isDownloading: downloadingResources[resourcePk] + })), + { + onDownload: downloadMetaData + } +)(DublinCoreDownload); + +DublinCoreDownload.defaultProps = { + onDownload: () => { }, + resourcePk: null, + isDownloading: false +}; + +export default createPlugin('DublinCoreDownload', { + component: () => null, + containers: { + ActionNavbar: { + name: 'DublinCoreDownload', + Component: DublinCoreDownloadPlugin + } + }, + epics: { gnDownloadMetaData }, + reducers: { gnDownload } +}); diff --git a/geonode_mapstore_client/client/js/plugins/downloads/IsoDownload.jsx b/geonode_mapstore_client/client/js/plugins/downloads/IsoDownload.jsx new file mode 100644 index 0000000000..2467c496ce --- /dev/null +++ b/geonode_mapstore_client/client/js/plugins/downloads/IsoDownload.jsx @@ -0,0 +1,60 @@ +/* + * Copyright 2022, GeoSolutions Sas. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. +*/ + +import React from 'react'; +import { connect } from 'react-redux'; +import { createSelector } from 'reselect'; +import { createPlugin } from '@mapstore/framework/utils/PluginsUtils'; +import Message from '@mapstore/framework/components/I18N/Message'; +import Button from '@js/components/Button'; +import { downloadMetaData } from '@js/actions/gndownload'; +import { gnDownloadMetaData } from '@js/epics/gndownload'; +import Spinner from '@js/components/Spinner'; +import gnDownload from '@js/reducers/gndownload'; + +function IsoDownload({ onDownload, resourcePk, isDownloading }) { + return ( + + ); +} + +const IsoDownloadPlugin = connect( + createSelector([ + state => state?.gnresource?.data.pk || null, + state => state?.gnDownload?.downloads?.ISO || {} + ], (resourcePk, downloadingResources) => ({ + resourcePk, + isDownloading: downloadingResources[resourcePk] + })), + { + onDownload: downloadMetaData + } +)(IsoDownload); + +IsoDownload.defaultProps = { + onDownload: () => { }, + resourcePk: null, + isDownloading: false +}; + + +export default createPlugin('IsoDownload', { + component: () => null, + containers: { + ActionNavbar: { + name: 'IsoDownload', + Component: IsoDownloadPlugin + } + }, + epics: { gnDownloadMetaData }, + reducers: { gnDownload } +}); diff --git a/geonode_mapstore_client/client/js/plugins/index.js b/geonode_mapstore_client/client/js/plugins/index.js index b5010d9724..d6d37a8059 100644 --- a/geonode_mapstore_client/client/js/plugins/index.js +++ b/geonode_mapstore_client/client/js/plugins/index.js @@ -427,6 +427,14 @@ export const plugins = { SyncPlugin: toLazyPlugin( 'Sync', () => import(/* webpackChunkName: 'plugins/sync-plugin' */ '@js/plugins/Sync') + ), + IsoDownloadPlugin: toLazyPlugin( + 'IsoDownload', + () => import(/* webpackChunkName: 'plugins/iso-download-plugin' */ '@js/plugins/downloads/IsoDownload') + ), + DublinCoreDownloadPlugin: toLazyPlugin( + 'DublinCoreDownload', + () => import(/* webpackChunkName: 'plugins/iso-download-plugin' */ '@js/plugins/downloads/DublinCoreDownload') ) }; diff --git a/geonode_mapstore_client/client/js/reducers/__tests__/gndownload-test.js b/geonode_mapstore_client/client/js/reducers/__tests__/gndownload-test.js new file mode 100644 index 0000000000..34b34b2612 --- /dev/null +++ b/geonode_mapstore_client/client/js/reducers/__tests__/gndownload-test.js @@ -0,0 +1,37 @@ +/* + * Copyright 2022, GeoSolutions Sas. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +import expect from 'expect'; +import gndownload from '@js/reducers/gndownload'; +import { + downloadMetaData, + downloadMetaDataComplete +} from '@js/actions/gndownload'; + +describe('gndownload reducer', () => { + it('should test downloadMetaData', () => { + const state = gndownload({downloads: {ISO: {}, DublinCore: {}}}, downloadMetaData('ISO', 1)); + expect(state).toEqual({ + downloads: { + DublinCore: {}, + ISO: { + 1: true + } + } + }); + }); + it('should test downloadMetaDataComplete', () => { + const state = gndownload({downloads: {ISO: {}, DublinCore: {}}}, downloadMetaDataComplete('ISO', 1)); + expect(state).toEqual({ + downloads: { + DublinCore: {}, + ISO: {} + } + }); + }); +}); diff --git a/geonode_mapstore_client/client/js/reducers/gndownload.js b/geonode_mapstore_client/client/js/reducers/gndownload.js new file mode 100644 index 0000000000..5883b0ec66 --- /dev/null +++ b/geonode_mapstore_client/client/js/reducers/gndownload.js @@ -0,0 +1,53 @@ +/* + * Copyright 2022s, GeoSolutions Sas. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. +*/ + +import { DOWNLOAD_METADATA, DOWNLOAD_METADATA_COMPLETE } from '@js/actions/gndownload'; + +const defaultState = { + downloads: { + ISO: {}, + DublinCore: {} + } +}; + +function gnDownload(state = defaultState, action) { + + switch (action.type) { + case DOWNLOAD_METADATA: { + const linkType = action?.link?.split(' ').join(''); + return { + ...state, + downloads: { + ...state.downloads, + [linkType]: { + [action.pk]: true + } + } + }; + } + case DOWNLOAD_METADATA_COMPLETE: { + const newState = { ...state }; + const linkType = action?.link?.split(' ').join(''); + const downloads = newState.downloads[linkType]; + delete downloads[action.pk]; + return { + ...newState, + downloads: { + ...newState.downloads, + [linkType]: { + ...downloads + } + } + }; + } + default: + return state; + } +} + +export default gnDownload; diff --git a/geonode_mapstore_client/client/static/mapstore/configs/localConfig.json b/geonode_mapstore_client/client/static/mapstore/configs/localConfig.json index c0179461af..3a08407821 100644 --- a/geonode_mapstore_client/client/static/mapstore/configs/localConfig.json +++ b/geonode_mapstore_client/client/static/mapstore/configs/localConfig.json @@ -929,8 +929,22 @@ "name": "FilterLayer" }, { - "type": "plugin", - "name": "LayerDownload" + "labelId": "gnviewer.download", + "type": "dropdown", + "items": [ + { + "type": "plugin", + "name": "IsoDownload" + }, + { + "type": "plugin", + "name": "DublinCoreDownload" + }, + { + "type": "plugin", + "name": "LayerDownload" + } + ] }, { "type": "plugin", @@ -1153,6 +1167,12 @@ { "name": "Playback" }, + { + "name": "IsoDownload" + }, + { + "name": "DublinCoreDownload" + }, { "name": "LayerDownload", "cfg": { diff --git a/geonode_mapstore_client/client/static/mapstore/translations/data.de-DE.json b/geonode_mapstore_client/client/static/mapstore/translations/data.de-DE.json index 32699b8028..9e5bbc6fc3 100644 --- a/geonode_mapstore_client/client/static/mapstore/translations/data.de-DE.json +++ b/geonode_mapstore_client/client/static/mapstore/translations/data.de-DE.json @@ -292,7 +292,9 @@ "embedgeostory": "Betten Sie diese Geostory ein", "embeddocument": "Betten Sie dieses Dokument ein", "embeddashboard": "Betten Sie dieses Dashboard ein", - "directLink": "Direkte Verbindung" + "directLink": "Direkte Verbindung", + "iso": "ISO -Metadaten", + "dublinCore": "Dublin Core Metadaten" } } } diff --git a/geonode_mapstore_client/client/static/mapstore/translations/data.en-US.json b/geonode_mapstore_client/client/static/mapstore/translations/data.en-US.json index 17efaf0b22..d06927faa5 100644 --- a/geonode_mapstore_client/client/static/mapstore/translations/data.en-US.json +++ b/geonode_mapstore_client/client/static/mapstore/translations/data.en-US.json @@ -292,7 +292,9 @@ "embedgeostory": "Embed this Geostory", "embeddocument": "Embed this Document", "embeddashboard": "Embed this Dashboard", - "directLink": "Direct Link" + "directLink": "Direct Link", + "iso": "ISO Metadata", + "dublinCore": "Dublin Core Metadata" } } } diff --git a/geonode_mapstore_client/client/static/mapstore/translations/data.es-ES.json b/geonode_mapstore_client/client/static/mapstore/translations/data.es-ES.json index efb1f2c798..48d227403d 100644 --- a/geonode_mapstore_client/client/static/mapstore/translations/data.es-ES.json +++ b/geonode_mapstore_client/client/static/mapstore/translations/data.es-ES.json @@ -291,7 +291,9 @@ "embedgeostory": "Insertar esta Geohistoria", "embeddocument": "Inserta éste Documento", "embeddashboard": "Insertar este Panel", - "directLink": "Enlace Directo" + "directLink": "Enlace Directo", + "iso": "Metadatos iso", + "dublinCore": "Metadatos de Dublin Core" } } } diff --git a/geonode_mapstore_client/client/static/mapstore/translations/data.fr-FR.json b/geonode_mapstore_client/client/static/mapstore/translations/data.fr-FR.json index 8c670984ca..6e6cd3c80a 100644 --- a/geonode_mapstore_client/client/static/mapstore/translations/data.fr-FR.json +++ b/geonode_mapstore_client/client/static/mapstore/translations/data.fr-FR.json @@ -292,7 +292,9 @@ "embedgeostory": "Intégrer cette Geostory", "embeddocument": "Intégrer ce document", "embeddashboard": "Intégrer ce Tableau de bord", - "directLink": "BLien direct" + "directLink": "BLien direct", + "iso": "Métadonnées ISO", + "dublinCore": "Métadonnées de Dublin Core" } } } diff --git a/geonode_mapstore_client/client/static/mapstore/translations/data.it-IT.json b/geonode_mapstore_client/client/static/mapstore/translations/data.it-IT.json index 0bcfb1091e..a93512ce0a 100644 --- a/geonode_mapstore_client/client/static/mapstore/translations/data.it-IT.json +++ b/geonode_mapstore_client/client/static/mapstore/translations/data.it-IT.json @@ -294,7 +294,9 @@ "embedgeostory": "Incorpora questa Geostoria", "embeddocument": "Incorpora questo Documento", "embeddashboard": "Incorpora questo Dashboard", - "directLink": "Collegamento Diretto" + "directLink": "Collegamento Diretto", + "iso": "Metadati ISO", + "dublinCore": "Metadati di Dublin Core" } } }