Skip to content

Commit 5404b13

Browse files
#1947: Harmonization of download actions inside the GeoNode client (#1948)
--------- Co-authored-by: stefano bovio <[email protected]>
1 parent e6b79ae commit 5404b13

26 files changed

+151
-79
lines changed

geonode_mapstore_client/client/js/epics/index.js

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -68,23 +68,23 @@ export const gnFetchMissingLayerData = (action$, { getState } = {}) =>
6868
const layerResourceId = layer?.extendedParams?.pk;
6969
const layerResourceDataset = state.gnresource.data?.maplayers?.find(mapLayer => mapLayer.dataset?.pk === parseInt(layerResourceId, 10))?.dataset;
7070
return layerResourceDataset
71-
? isEmpty(layerResourceDataset?.linkedResources)
72-
? Rx.Observable.defer(() =>
73-
getDatasetByPk(layerResourceId)
74-
.then((layerDataset) => layerDataset)
75-
.catch(() => [])
76-
).switchMap((layerDataset) =>
77-
Rx.Observable.of(
78-
updateLayerDataset(layerDataset),
71+
? isEmpty(layerResourceDataset?.linkedResources)
72+
? Rx.Observable.defer(() =>
73+
getDatasetByPk(layerResourceId)
74+
.then((layerDataset) => layerDataset)
75+
.catch(() => [])
76+
).switchMap((layerDataset) =>
77+
Rx.Observable.of(
78+
updateLayerDataset(layerDataset),
79+
setLayerDataset(layerResourceId)
80+
)
81+
).startWith(setLayerDataset())
82+
: Rx.Observable.of(
7983
setLayerDataset(layerResourceId)
8084
)
81-
)
8285
: Rx.Observable.of(
83-
setLayerDataset(layerResourceId)
84-
)
85-
: Rx.Observable.of(
86-
setLayerDataset()
87-
)
86+
setLayerDataset()
87+
);
8888
});
8989

9090

geonode_mapstore_client/client/js/hooks/usePluginItems.js

Lines changed: 0 additions & 37 deletions
This file was deleted.

geonode_mapstore_client/client/js/plugins/DetailViewer.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ import Message from '@mapstore/framework/components/I18N/Message';
4545
import { layersSelector } from '@mapstore/framework/selectors/layers';
4646
import { mapSelector } from '@mapstore/framework/selectors/map';
4747
import { parsePluginConfigExpressions } from '@js/utils/MenuUtils';
48-
import usePluginItems from '@js/hooks/usePluginItems';
48+
import usePluginItems from '@mapstore/framework/hooks/usePluginItems';
4949
import { getResourceTypesInfo } from '@js/utils/ResourceUtils';
5050
import tabComponents from '@js/plugins/detailviewer/tabComponents';
5151

geonode_mapstore_client/client/js/plugins/DownloadResource.jsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { connect } from 'react-redux';
1111
import { createSelector } from 'reselect';
1212
import isEmpty from 'lodash/isEmpty';
1313
import { createPlugin } from '@mapstore/framework/utils/PluginsUtils';
14-
import { getDownloadUrlInfo, isDocumentExternalSource, GXP_PTYPES } from '@js/utils/ResourceUtils';
14+
import { getDownloadUrlInfo, isDocumentExternalSource, GXP_PTYPES, SOURCE_TYPES } from '@js/utils/ResourceUtils';
1515
import Message from '@mapstore/framework/components/I18N/Message';
1616
import Button from '@js/components/Button';
1717
import tooltip from '@mapstore/framework/components/misc/enhancers/tooltip';
@@ -38,6 +38,8 @@ const DownloadButton = ({
3838
onAction = () => {},
3939
renderType = "button",
4040
showIcon,
41+
downloadMsgId = "gnviewer.download",
42+
allowedSources = [SOURCE_TYPES.LOCAL, SOURCE_TYPES.REMOTE],
4143
downloading
4244
}) => {
4345
const Component = RENDER_TYPE[renderType];
@@ -51,6 +53,7 @@ const DownloadButton = ({
5153
|| !_resource?.perms?.includes('download_resourcebase')
5254
|| (!isButton && isNotAjaxSafe)
5355
|| [GXP_PTYPES.REST_MAP, GXP_PTYPES.REST_IMG].includes(_resource?.ptype) // exclude arcgis remote layers from direct download
56+
|| !allowedSources.includes(_resource?.sourcetype)
5457
) {
5558
return null;
5659
}
@@ -59,15 +62,15 @@ const DownloadButton = ({
5962
return downloadInfo.url ? (
6063
<Component
6164
{...isButton && { variant, size }}
62-
{...showIcon && { tooltipId: "gnviewer.download" }}
65+
{...showIcon && { tooltipId: downloadMsgId }}
6366
download
6467
href={ downloadInfo.url }
6568
target="_blank"
6669
rel="noopener noreferrer"
6770
>
6871
{showIcon
6972
? <FaIcon name={isExternal ? "external-link" : "download"} />
70-
: <Message msgId="gnviewer.download" />
73+
: <Message msgId={downloadMsgId} />
7174
}
7275
</Component>
7376
) : null;
@@ -78,11 +81,11 @@ const DownloadButton = ({
7881
disabled={!!downloading}
7982
onClick={() => downloading ? null : onAction(_resource)}
8083
{...isButton && { variant, size}}
81-
{...showIcon && { tooltipId: "gnviewer.download" }}
84+
{...showIcon && { tooltipId: downloadMsgId }}
8285
>
8386
{showIcon
8487
? <FaIcon name="download" />
85-
: <Message msgId="gnviewer.download" />
88+
: <Message msgId={downloadMsgId} />
8689
}
8790
</Component>
8891
);
@@ -133,6 +136,11 @@ export default createPlugin('DownloadResource', {
133136
target: 'toolbar',
134137
Component: DownloadResource,
135138
priority: 1
139+
},
140+
LayerDownload: {
141+
name: 'DownloadResource',
142+
Component: DownloadResource,
143+
priority: 1
136144
}
137145
},
138146
epics: {},

geonode_mapstore_client/client/js/plugins/LayerSettings.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import GroupSettings from '@js/plugins/layersettings/GroupSettings';
2424
import BaseLayerSettings from '@js/plugins/layersettings/BaseLayerSettings';
2525
import WMSLayerSettings from '@js/plugins/layersettings/WMSLayerSettings';
2626
import GeoNodeStyleSelector from '@js/plugins/layersettings/GeoNodeStyleSelector';
27-
import usePluginItems from '@js/hooks/usePluginItems';
27+
import usePluginItems from '@mapstore/framework/hooks/usePluginItems';
2828
import layersettingsEpics from '@js/epics/layersettings';
2929
import tooltip from '@mapstore/framework/components/misc/enhancers/tooltip';
3030
import { isAnnotationLayer } from '@mapstore/framework/plugins/Annotations/utils/AnnotationsUtils';

geonode_mapstore_client/client/js/plugins/ResourcesGrid.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ import { processingDownload } from '@js/selectors/resourceservice';
4646
import { resourceHasPermission, getCataloguePath } from '@js/utils/ResourceUtils';
4747
import {downloadResource, setFavoriteResource} from '@js/actions/gnresource';
4848
import FiltersForm from '@js/components/FiltersForm';
49-
import usePluginItems from '@js/hooks/usePluginItems';
49+
import usePluginItems from '@mapstore/framework/hooks/usePluginItems';
5050
import { ProcessTypes } from '@js/utils/ResourceServiceUtils';
5151
import { replace } from 'connected-react-router';
5252
import FaIcon from '@js/components/FaIcon';

geonode_mapstore_client/client/js/plugins/VisualStyleEditor.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ import tooltip from '@mapstore/framework/components/misc/enhancers/tooltip';
5252
import { getSelectedLayer, layersSelector } from '@mapstore/framework/selectors/layers';
5353
import useLocalStorage from '@js/hooks/useLocalStorage';
5454
import TemplateSelector from '@js/plugins/visualstyleeditor/TemplateSelector';
55-
import { isDefaultDatasetSubtype } from '@js/utils/ResourceUtils';
55+
import { isDefaultDatasetSubtype, SOURCE_TYPES } from '@js/utils/ResourceUtils';
5656

5757
const Button = tooltip(GNButton);
5858

@@ -318,7 +318,7 @@ function StyleEditorTocButton({
318318
if (hide
319319
|| status !== statusTypes.LAYER
320320
|| !mapLayer?.dataset
321-
|| mapLayer?.dataset?.sourcetype === 'REMOTE'
321+
|| mapLayer?.dataset?.sourcetype === SOURCE_TYPES.REMOTE
322322
|| !changeResource
323323
|| isNew
324324
|| !isDefaultDatasetSubtype(mapLayer?.dataset?.subtype)) {

geonode_mapstore_client/client/js/plugins/actionnavbar/buttons.jsx

Lines changed: 59 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,18 @@
55
* This source code is licensed under the BSD-style license found in the
66
* LICENSE file in the root directory of this source tree.
77
*/
8-
import React from 'react';
8+
import React, { useRef } from 'react';
9+
import { PropTypes } from 'prop-types';
910
import { connect } from 'react-redux';
1011
import { createSelector } from 'reselect';
12+
import usePluginItems from '@mapstore/framework/hooks/usePluginItems';
1113
import {
1214
setControlProperty
1315
} from '@mapstore/framework/actions/controls';
1416
import {
1517
toggleFullscreen
1618
} from '@mapstore/framework/actions/fullscreen';
17-
19+
import { Dropdown, MenuItem, Glyphicon } from 'react-bootstrap';
1820
import Message from '@mapstore/framework/components/I18N/Message';
1921
import Button from '@js/components/Button';
2022
import FaIcon from '@js/components/FaIcon';
@@ -23,7 +25,7 @@ import { openQueryBuilder } from '@mapstore/framework/actions/layerFilter';
2325
import { getSelectedLayer } from '@mapstore/framework/selectors/layers';
2426
import { isDashboardEditing } from '@mapstore/framework/selectors/dashboard';
2527
import { createWidget } from '@mapstore/framework/actions/widgets';
26-
import { getResourceData } from '@js/selectors/resource';
28+
import { getResourceData, getSelectedLayerDataset } from '@js/selectors/resource';
2729
import { GXP_PTYPES } from '@js/utils/ResourceUtils';
2830

2931
// buttons override to use in ActionNavbar for plugin imported from mapstore
@@ -57,31 +59,75 @@ export const FullScreenActionButton = connect(createSelector([
5759
);
5860
});
5961

60-
export const LayerDownloadActionButton = connect(
61-
(state) => ({
62-
data: getResourceData(state)
63-
}),
64-
{ onClick: setControlProperty.bind(null, 'layerdownload', 'enabled', true, true) }
65-
)(({
62+
const LayerDownloadActionButtonComponent = ({
6663
onClick,
6764
variant,
6865
size,
69-
data
70-
}) => {
66+
data,
67+
nodeTypes,
68+
items,
69+
status,
70+
statusTypes
71+
}, context) => {
72+
const node = useRef();
73+
const { loadedPlugins } = context;
74+
const configuredItems = usePluginItems({ items, loadedPlugins });
75+
// nodeTypes is included in the TOC plugin as additional prop
76+
const isTOCItem = !!nodeTypes;
7177
// hide button for arcgis sources
7278
if ([GXP_PTYPES.REST_MAP, GXP_PTYPES.REST_IMG].includes(data?.ptype)) {
7379
return null;
7480
}
81+
if (isTOCItem) {
82+
return status === statusTypes.LAYER ? (
83+
<>
84+
<Dropdown
85+
style={{ position: 'absolute' }}
86+
>
87+
<Dropdown.Toggle
88+
noCaret
89+
bsStyle="primary"
90+
className="square-button-md"
91+
>
92+
<Glyphicon glyph="download" />
93+
</Dropdown.Toggle>
94+
<Dropdown.Menu style={{ width: 'auto', minWidth: 'max-content' }}>
95+
{configuredItems.map(({ Component, name }) => {
96+
return (<Component key={name} renderType="menuItem" resource={data} />);
97+
})}
98+
<MenuItem onClick={() => onClick()}>
99+
<Message msgId="gnviewer.exportData" />
100+
</MenuItem>
101+
</Dropdown.Menu>
102+
</Dropdown>
103+
{/* include a placeholder to compute the space */}
104+
<div ref={node} className="square-button-md" style={{ display: 'inline-block', verticalAlign: 'middle' }} />
105+
</>
106+
) : null;
107+
}
75108
return (
76109
<Button
77110
variant={variant}
78111
size={size}
79112
onClick={() => onClick()}
80113
>
81-
<Message msgId="gnhome.dataset" />
114+
<Message msgId="gnviewer.exportData" />
82115
</Button>
83116
);
84-
});
117+
};
118+
119+
LayerDownloadActionButtonComponent.contextTypes = {
120+
loadedPlugins: PropTypes.object
121+
};
122+
123+
export const LayerDownloadActionButton = connect(
124+
createSelector([getResourceData, getSelectedLayerDataset],
125+
(resourceData, selectedLayerDataset) => ({
126+
data: selectedLayerDataset ? selectedLayerDataset : resourceData
127+
})
128+
),
129+
{ onClick: setControlProperty.bind(null, 'layerdownload', 'enabled', true, true) }
130+
)(LayerDownloadActionButtonComponent);
85131

86132
export const FilterLayerActionButton = connect(
87133
(state) => ({

geonode_mapstore_client/client/js/plugins/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ export const plugins = {
7575
{
7676
overrides: {
7777
containers: {
78+
TOC: {
79+
name: 'LayerDownload',
80+
target: 'toolbar',
81+
Component: LayerDownloadActionButton
82+
},
7883
ActionNavbar: {
7984
name: 'LayerDownload',
8085
Component: LayerDownloadActionButton

geonode_mapstore_client/client/js/selectors/__tests__/resourceservice-test.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import expect from 'expect';
1010
import { getCurrentProcesses, processingDownload, generalResourceDownload, featuredResourceDownload } from '../resourceservice';
11+
import { ResourceTypes } from '@js/utils/ResourceUtils';
1112

1213

1314
describe('resourceservice selector', () => {
@@ -34,6 +35,21 @@ describe('resourceservice selector', () => {
3435
};
3536
expect(processingDownload(testState)).toEqual(true);
3637
});
38+
it('test processingDownload when downloding dataset in the maplayers', () => {
39+
const testState = {
40+
gnresource: {
41+
data: {
42+
pk: 1,
43+
resource_type: ResourceTypes.MAP,
44+
maplayers: [{dataset: {pk: 2}}]
45+
}
46+
},
47+
resourceservice: {
48+
downloads: [{ pk: 2 }]
49+
}
50+
};
51+
expect(processingDownload(testState)).toEqual(true);
52+
});
3753

3854
it('test featuredResourceDownload', () => {
3955
const testState = {

0 commit comments

Comments
 (0)