Skip to content

Commit

Permalink
#1947: Harmonization of download actions inside the GeoNode client
Browse files Browse the repository at this point in the history
  • Loading branch information
dsuren1 committed Jan 30, 2025
1 parent c0f8177 commit f825b9d
Show file tree
Hide file tree
Showing 23 changed files with 196 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ const itemElement = ({ labelId, href, badge, target }) => (

const itemsList = (items) => (items && items.map((item) => {

const { labelId, href, badge, target, type, Component, className } = item;
const { labelId, href, badge, target, type, Component, className, cfg } = item;

if (type === 'plugin' && Component) {
return (<li><Component variant="default" className={className} showMessage /></li>);
return (<li><Component {...cfg} variant="default" className={className} showMessage /></li>);
}

return itemElement({ labelId, href, badge, target });
Expand Down Expand Up @@ -97,7 +97,7 @@ const DropdownList = ({
.map((itm, idx) => {

if (itm.type === 'plugin' && itm.Component) {
return (<li><itm.Component variant="default" className={itm.className} showMessage /></li>);
return (<li><itm.Component {...itm.cfg} variant="default" className={itm.className} showMessage /></li>);
}
if (itm.type === 'divider') {
return <Dropdown.Divider key={idx} />;
Expand Down
28 changes: 14 additions & 14 deletions geonode_mapstore_client/client/js/epics/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,23 +68,23 @@ export const gnFetchMissingLayerData = (action$, { getState } = {}) =>
const layerResourceId = layer?.extendedParams?.pk;
const layerResourceDataset = state.gnresource.data?.maplayers?.find(mapLayer => mapLayer.dataset?.pk === parseInt(layerResourceId, 10))?.dataset;
return layerResourceDataset
? isEmpty(layerResourceDataset?.linkedResources)
? Rx.Observable.defer(() =>
getDatasetByPk(layerResourceId)
.then((layerDataset) => layerDataset)
.catch(() => [])
).switchMap((layerDataset) =>
Rx.Observable.of(
updateLayerDataset(layerDataset),
? isEmpty(layerResourceDataset?.linkedResources)
? Rx.Observable.defer(() =>
getDatasetByPk(layerResourceId)
.then((layerDataset) => layerDataset)
.catch(() => [])
).switchMap((layerDataset) =>
Rx.Observable.of(
updateLayerDataset(layerDataset),
setLayerDataset(layerResourceId)
)
).startWith(setLayerDataset())
: Rx.Observable.of(
setLayerDataset(layerResourceId)
)
)
: Rx.Observable.of(
setLayerDataset(layerResourceId)
)
: Rx.Observable.of(
setLayerDataset()
)
setLayerDataset()
);
});


Expand Down
87 changes: 87 additions & 0 deletions geonode_mapstore_client/client/js/plugins/DatasetDownload.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright 2025, 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 Dropdown from '@js/components/Dropdown';
import FaIcon from '@js/components/FaIcon/FaIcon';
import { getSelectedLayerDataset } from '@js/selectors/resource';
import { SOURCE_TYPES } from "@js/utils/ResourceUtils";

const DatasetDownload = connect(
createSelector([
getSelectedLayerDataset
], (resource) => ({
resource
}))
)(({
items,
selectedNodes,
status,
statusTypes,
resource, // the selected layer's dataset resource
allowedSources = [SOURCE_TYPES.LOCAL] // allowed sources for download
}) => {
const toolbarItems = items?.filter(item => item.target === "toolbar");
const layer = selectedNodes?.[0]?.node;
if ([statusTypes?.LAYER].includes(status) && layer && !layer?.error && toolbarItems.length > 0) {
return (
<div className="gn-layer-download">
<Dropdown className={"download-dropdown"}>
<Dropdown.Toggle
id={ `gn-toggle-dropdown-layer-download`}
bsStyle={"primary"}
noCaret
>
<FaIcon name={"download"} />
</Dropdown.Toggle>
<Dropdown.Menu>
{toolbarItems.map(({Component, name}, idx) => (
<Dropdown.Item eventKey={idx}>
<Component
key={`${name}-item-${idx}`}
resource={resource}
allowedSources={allowedSources}
variant="default"
/>
</Dropdown.Item>
))}
</Dropdown.Menu>
</Dropdown>
</div>
);
}
return null;
});

/**
* Plugin for downloading the dataset resource
* via direct download or export the data associated
* @name DatasetDownload
* @example
* {
* "name": "DatasetDownload"
* }
*/
export default createPlugin('DatasetDownload', {
component: DatasetDownload,
containers: {
TOC: {
doNotHide: true,
name: "DatasetDownload",
target: 'toolbar',
Component: DatasetDownload,
position: 11
}
},
epics: {},
reducers: {}
});
19 changes: 14 additions & 5 deletions geonode_mapstore_client/client/js/plugins/DownloadResource.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import isEmpty from 'lodash/isEmpty';
import { createPlugin } from '@mapstore/framework/utils/PluginsUtils';
import { getDownloadUrlInfo, isDocumentExternalSource, GXP_PTYPES } from '@js/utils/ResourceUtils';
import { getDownloadUrlInfo, isDocumentExternalSource, GXP_PTYPES, SOURCE_TYPES } from '@js/utils/ResourceUtils';
import Message from '@mapstore/framework/components/I18N/Message';
import Button from '@js/components/Button';
import tooltip from '@mapstore/framework/components/misc/enhancers/tooltip';
Expand All @@ -38,6 +38,8 @@ const DownloadButton = ({
onAction = () => {},
renderType = "button",
showIcon,
downloadMsgId = "gnviewer.download",
allowedSources = [SOURCE_TYPES.LOCAL, SOURCE_TYPES.REMOTE],
downloading
}) => {
const Component = RENDER_TYPE[renderType];
Expand All @@ -51,6 +53,7 @@ const DownloadButton = ({
|| !_resource?.perms?.includes('download_resourcebase')
|| (!isButton && isNotAjaxSafe)
|| [GXP_PTYPES.REST_MAP, GXP_PTYPES.REST_IMG].includes(_resource?.ptype) // exclude arcgis remote layers from direct download
|| !allowedSources.includes(_resource?.sourcetype)
) {
return null;
}
Expand All @@ -59,15 +62,15 @@ const DownloadButton = ({
return downloadInfo.url ? (
<Component
{...isButton && { variant, size }}
{...showIcon && { tooltipId: "gnviewer.download" }}
{...showIcon && { tooltipId: downloadMsgId }}
download
href={ downloadInfo.url }
target="_blank"
rel="noopener noreferrer"
>
{showIcon
? <FaIcon name={isExternal ? "external-link" : "download"} />
: <Message msgId="gnviewer.download" />
: <Message msgId={downloadMsgId} />
}
</Component>
) : null;
Expand All @@ -78,11 +81,11 @@ const DownloadButton = ({
disabled={!!downloading}
onClick={() => downloading ? null : onAction(_resource)}
{...isButton && { variant, size}}
{...showIcon && { tooltipId: "gnviewer.download" }}
{...showIcon && { tooltipId: downloadMsgId }}
>
{showIcon
? <FaIcon name="download" />
: <Message msgId="gnviewer.download" />
: <Message msgId={downloadMsgId} />
}
</Component>
);
Expand Down Expand Up @@ -133,6 +136,12 @@ export default createPlugin('DownloadResource', {
target: 'toolbar',
Component: DownloadResource,
priority: 1
},
DatasetDownload: {
name: 'DownloadResource',
target: 'toolbar',
Component: DownloadResource,
priority: 1
}
},
epics: {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ import tooltip from '@mapstore/framework/components/misc/enhancers/tooltip';
import { getSelectedLayer, layersSelector } from '@mapstore/framework/selectors/layers';
import useLocalStorage from '@js/hooks/useLocalStorage';
import TemplateSelector from '@js/plugins/visualstyleeditor/TemplateSelector';
import { isDefaultDatasetSubtype } from '@js/utils/ResourceUtils';
import { isDefaultDatasetSubtype, SOURCE_TYPES } from '@js/utils/ResourceUtils';

const Button = tooltip(GNButton);

Expand Down Expand Up @@ -318,7 +318,7 @@ function StyleEditorTocButton({
if (hide
|| status !== statusTypes.LAYER
|| !mapLayer?.dataset
|| mapLayer?.dataset?.sourcetype === 'REMOTE'
|| mapLayer?.dataset?.sourcetype === SOURCE_TYPES.REMOTE
|| !changeResource
|| isNew
|| !isDefaultDatasetSubtype(mapLayer?.dataset?.subtype)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export const LayerDownloadActionButton = connect(
size={size}
onClick={() => onClick()}
>
<Message msgId="gnhome.dataset" />
<Message msgId="gnviewer.exportData" />
</Button>
);
});
Expand Down
10 changes: 10 additions & 0 deletions geonode_mapstore_client/client/js/plugins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,25 @@ export const plugins = {
OperationPlugin,
MetadataEditorPlugin,
MetadataViewerPlugin,
DatasetDownloadPlugin: toModulePlugin(
'DatasetDownload',
() => import(/* webpackChunkName: 'plugins/dataset-download' */ '@js/plugins/DatasetDownload')
),
LayerDownloadPlugin: toModulePlugin(
'LayerDownload',
() => import(/* webpackChunkName: 'plugins/layer-download' */ '@mapstore/framework/plugins/LayerDownload'),
{
overrides: {
containers: {
TOC: {},
ActionNavbar: {
name: 'LayerDownload',
Component: LayerDownloadActionButton
},
DatasetDownload: {
name: 'LayerDownload',
Component: LayerDownloadActionButton,
target: 'toolbar'
}
}
}
Expand Down
9 changes: 7 additions & 2 deletions geonode_mapstore_client/client/js/utils/ResourceUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ export const isDefaultDatasetSubtype = (subtype) => !subtype || ['vector', 'rast

export const FEATURE_INFO_FORMAT = 'TEMPLATE';

export const SOURCE_TYPES = {
LOCAL: 'LOCAL',
REMOTE: 'REMOTE'
};

const datasetAttributeSetToFields = ({ attribute_set: attributeSet = [] }) => {
return attributeSet
.filter(({ attribute_type: type }) => !type.includes('gml:'))
Expand Down Expand Up @@ -221,7 +226,7 @@ export const resourceToLayerConfig = (resource) => {
...(dimensions.length > 0 && ({ dimensions })),
extendedParams,
...(fields && { fields }),
...(sourcetype === 'REMOTE' && !wmsUrl.includes('/geoserver/') && {
...(sourcetype === SOURCE_TYPES.REMOTE && !wmsUrl.includes('/geoserver/') && {
serverType: ServerTypes.NO_VENDOR
})
};
Expand Down Expand Up @@ -327,7 +332,7 @@ export const ResourceTypes = {
};

export const isDocumentExternalSource = (resource) => {
return resource && resource.resource_type === ResourceTypes.DOCUMENT && resource.sourcetype === 'REMOTE';
return resource && resource.resource_type === ResourceTypes.DOCUMENT && resource.sourcetype === SOURCE_TYPES.REMOTE;
};

export const getResourceTypesInfo = () => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,31 @@
}

}

.ms-toc-container {
.ms-toc-toolbar-content {
.gn-layer-download {
width: 30px;
.download-dropdown {
position: absolute;
top: 0;
width: inherit;
button.dropdown-toggle{
width: inherit;
}
ul.dropdown-menu {
width: 120px;
li {
a[role="menuitem"] {
padding: 0;
}
button {
width: 100%;
text-align: left;
}
}
}
}
}
}
}
16 changes: 16 additions & 0 deletions geonode_mapstore_client/static/mapstore/configs/localConfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,14 @@
"disableIf": "{!state('selectedLayerPermissions').includes('download_resourcebase') || context.isDocumentExternalSource(state('gnResourceData'))}",
"type": "dropdown",
"items": [
{
"type": "plugin",
"name": "DownloadResource",
"cfg": {
"downloadMsgId": "gnhome.dataset",
"allowedSources": ["LOCAL"]
}
},
{
"type": "plugin",
"name": "LayerDownload"
Expand Down Expand Up @@ -1610,6 +1618,14 @@
}
}
},
{
"name": "DatasetDownload",
"mandatory": true
},
{
"name": "DownloadResource",
"mandatory": true
},
{
"name": "MapThumbnail"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,8 @@
},
"gnviewer": {
"edit": "Bearbeiten",
"export": "Export",
"export": "Exportieren",
"exportData": "Daten exportieren",
"editInfo": "Informationen anzeigen",
"editMetadata": "Metadaten bearbeiten",
"editStyle": "Stil bearbeiten",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@
"gnviewer": {
"edit": "Edit",
"export": "Export",
"exportData": "Export Data",
"editInfo": "Edit Info",
"editMetadata": "Edit Metadata",
"editStyle": "Edit Style",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@
"gnviewer": {
"edit": "Editar",
"export": "Exportar",
"exportData": "Exportar datos",
"editInfo": "Editar información",
"editMetadata": "Editar Metadatos",
"editStyle": "Editar Estilo",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@
"gnviewer": {
"edit": "Edit",
"export": "Export",
"exportData": "Export Data",
"editInfo": "Edit Info",
"editMetadata": "Edit Metadata",
"editStyle": "Edit Style",
Expand Down
Loading

0 comments on commit f825b9d

Please sign in to comment.