Skip to content

Commit

Permalink
Fix #1825 Implement Assets tab (#1826)
Browse files Browse the repository at this point in the history
* Fix #1825 Implement Assets tab

* get filename download from content disposition header
  • Loading branch information
allyoucanmap authored Jul 30, 2024
1 parent 1f60436 commit 0021085
Show file tree
Hide file tree
Showing 23 changed files with 252 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';
import FaIcon from '@js/components/FaIcon';

function DetailsAssets({ fields }) {
return (
<div className="gn-details-assets">
{fields.map((field, idx) => {
const asset = field?.extras?.content || {};
return (
<div key={idx} className="gn-details-info-fields">
<div className="gn-details-info-row linked-resources">
<FaIcon name="file" />
{asset.download_url ? <a
download
href={asset.download_url}
>
{asset.title}{' '}<FaIcon name="download" />
</a> : asset.title}
</div>
</div>
);
})}
</div>
);
}

export default DetailsAssets;
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import DetailsAttributeTable from '@js/components/DetailsPanel/DetailsAttributeT
import DetailsLinkedResources from '@js/components/DetailsPanel/DetailsLinkedResources';
import Message from '@mapstore/framework/components/I18N/Message';
import DetailsLocations from '@js/components/DetailsPanel/DetailsLocations';
import DetailsAssets from '@js/components/DetailsPanel/DetailsAssets';

const replaceTemplateString = (properties, str) => {
return Object.keys(properties).reduce((updatedStr, key) => {
Expand Down Expand Up @@ -146,7 +147,8 @@ const tabTypes = {
'attribute-table': DetailsAttributeTable,
'linked-resources': DetailsLinkedResources,
'locations': DetailsLocations,
'tab': DetailsInfoFields
'tab': DetailsInfoFields,
'assets': DetailsAssets
};

const parseTabItems = (items) => {
Expand Down
5 changes: 4 additions & 1 deletion geonode_mapstore_client/client/js/epics/resourceservice.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { push } from 'connected-react-router';
import {
error as errorNotification
} from '@mapstore/framework/actions/notifications';
import { getFilenameFromContentDispositionHeader } from '@js/utils/FileUtils';

export const gnMonitorAsyncProcesses = (action$, store) => {
return action$.ofType(START_ASYNC_PROCESS)
Expand Down Expand Up @@ -105,7 +106,9 @@ export const gnDownloadResource = (action$) =>
const resource = action?.resource;
return Observable.defer(() => downloadResource(resource)
.then(({ output, headers }) => {
saveAs(new Blob([output], { type: headers?.['content-type'] }), resource.title);
const filename = getFilenameFromContentDispositionHeader(headers?.['content-disposition'])
|| resource.title;
saveAs(new Blob([output], { type: headers?.['content-type'] }), filename);
return { resource };
})
.catch((error) => ({ resource, error: error?.data?.detail || error?.statusText || error?.message || true }))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const DownloadButton = ({
<Component
{...isButton && { variant, size }}
{...showIcon && { tooltipId: "gnviewer.download" }}
download={`${_resource?.title}.${_resource?.extension}`}
download
href={ downloadInfo.url }
target="_blank"
rel="noopener noreferrer"
Expand Down
6 changes: 3 additions & 3 deletions geonode_mapstore_client/client/js/reducers/gnresource.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import {
import {
cleanCompactPermissions,
getGeoLimitsFromCompactPermissions,
getResourceWithLinkedResources
getResourceAdditionalProperties
} from '@js/utils/ResourceUtils';

const defaultState = {
Expand Down Expand Up @@ -75,7 +75,7 @@ function gnresource(state = defaultState, action) {
};
}
case SET_RESOURCE: {
const actionData = getResourceWithLinkedResources(action.data || {});
const actionData = getResourceAdditionalProperties(action.data || {});
const { data, ...resource } = actionData;
let updatedResource = {...resource};
const linkedResources = state.data?.linkedResources;
Expand Down Expand Up @@ -241,7 +241,7 @@ function gnresource(state = defaultState, action) {
case SET_MAP_VIEWER_LINKED_RESOURCE:
return {
...state,
viewerLinkedResource: { ...getResourceWithLinkedResources(omit(action.resource, ['data'])) }
viewerLinkedResource: { ...getResourceAdditionalProperties(omit(action.resource, ['data'])) }
};
case SET_DEFAULT_VIEWER_PLUGINS:
return {
Expand Down
14 changes: 14 additions & 0 deletions geonode_mapstore_client/client/js/utils/FileUtils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import axios from '@mapstore/framework/libs/ajax';
import isEmpty from "lodash/isEmpty";
import trim from 'lodash/trim';

/**
* @module utils/FileUtils
Expand Down Expand Up @@ -94,3 +95,16 @@ export const getFileNameAndExtensionFromUrl = (url) => {
ext = period !== -1 ? parsedName.substring(period + 1) : "";
return { fileName, ext: !isEmpty(ext) ? "." + ext : ext };
};
/**
* Get file name from Content-Disposition header
* @param {string} contentDisposition
* @return {string}
*/
export const getFilenameFromContentDispositionHeader = (contentDisposition) => {
if ((contentDisposition || '').includes('attachment')) {
// regex from https://stackoverflow.com/a/23054920
const matches = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/.exec(contentDisposition) || [];
return trim(trim(matches?.[1] || '', '"'), "'");
}
return '';
};
10 changes: 10 additions & 0 deletions geonode_mapstore_client/client/js/utils/ResourceUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,16 @@ export const getResourceWithLinkedResources = (resource = {}) => {
return resource;
};

export const getResourceAdditionalProperties = (_resource = {}) => {
const resource = getResourceWithLinkedResources(_resource);
const links = resource?.links || [];
const assets = links.filter(link => link?.extras?.type === 'asset' && link?.extras?.content?.title);
return {
...resource,
...(assets?.length && { assets })
};
};

export const onDeleteRedirectTo = (resources = []) => {
let redirectUrl = '/';
if (!isEmpty(resources) && resources?.length === 1) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import expect from 'expect';
import {
determineResourceType,
getFileNameAndExtensionFromUrl,
getFileNameParts
getFileNameParts,
getFilenameFromContentDispositionHeader
} from '@js/utils/FileUtils';

describe('FileUtils', () => {
Expand Down Expand Up @@ -65,5 +66,11 @@ describe('FileUtils', () => {
expect(fileName).toBe('');
});
});
it('getFilenameFromContentDispositionHeader', () => {
expect(getFilenameFromContentDispositionHeader()).toBe('');
expect(getFilenameFromContentDispositionHeader('attachment; filename="tileset.json"')).toBe('tileset.json');
expect(getFilenameFromContentDispositionHeader('attachment; filename*="filename.jpg"')).toBe('filename.jpg');
expect(getFilenameFromContentDispositionHeader('attachment')).toBe('');
});
});

Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ import {
isDocumentExternalSource,
getDownloadUrlInfo,
getCataloguePath,
getResourceWithLinkedResources
getResourceWithLinkedResources,
getResourceAdditionalProperties
} from '../ResourceUtils';

describe('Test Resource Utils', () => {
Expand Down Expand Up @@ -1048,4 +1049,116 @@ describe('Test Resource Utils', () => {
expect(getResourceWithLinkedResources({linked_resources: {linked_to: ["1"], linked_by: ["1"]}}))
.toEqual({linkedResources: {linkedBy: ["1"], linkedTo: ["1"]}});
});
it('getResourceAdditionalProperties', () => {
expect(getResourceAdditionalProperties({})).toEqual({});
expect(getResourceAdditionalProperties()).toEqual({});
expect(getResourceAdditionalProperties({pk: 1, linked_resources: {linked_to: ["1"], linked_by: ["1"]}}))
.toEqual({pk: 1, linkedResources: {linkedBy: ["1"], linkedTo: ["1"]}});
expect(getResourceAdditionalProperties({
pk: 1,
links: [
{
extension: '3dtiles',
extras: {
type: 'asset',
content: {
title: 'Original',
description: null,
type: '3dtiles',
download_url: '/api/v2/assets/12/download'
}
},
link_type: 'uploaded',
mime: '',
name: 'tileset',
url: '/path'
},
{
extension: '3dtiles',
extras: {
type: 'asset',
content: {
title: null,
description: null,
type: '3dtiles',
download_url: '/api/v2/assets/12/download'
}
},
link_type: 'uploaded',
mime: '',
name: 'tileset',
url: '/path'
},
{
extension: 'xml',
link_type: 'metadata',
mime: 'text/xml',
name: 'ISO',
url: '/path'
}
]
}))
.toEqual({
pk: 1,
assets: [
{
extension: '3dtiles',
extras: {
type: 'asset',
content: {
title: 'Original',
description: null,
type: '3dtiles',
download_url: '/api/v2/assets/12/download'
}
},
link_type: 'uploaded',
mime: '',
name: 'tileset',
url: '/path'
}
],
links: [
{
extension: '3dtiles',
extras: {
type: 'asset',
content: {
title: 'Original',
description: null,
type: '3dtiles',
download_url: '/api/v2/assets/12/download'
}
},
link_type: 'uploaded',
mime: '',
name: 'tileset',
url: '/path'
},
{
extension: '3dtiles',
extras: {
type: 'asset',
content: {
title: null,
description: null,
type: '3dtiles',
download_url: '/api/v2/assets/12/download'
}
},
link_type: 'uploaded',
mime: '',
name: 'tileset',
url: '/path'
},
{
extension: 'xml',
link_type: 'metadata',
mime: 'text/xml',
name: 'ISO',
url: '/path'
}
]
});
});
});
42 changes: 42 additions & 0 deletions geonode_mapstore_client/static/mapstore/configs/localConfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,12 @@
"id": "related",
"labelId": "gnviewer.linkedResources.label",
"items": "{context.get(state('gnResourceData'), 'linkedResources')}"
},
{
"type": "assets",
"id": "assets",
"labelId": "gnviewer.assets",
"items": "{context.get(state('gnResourceData'), 'assets')}"
}
]
}
Expand Down Expand Up @@ -1722,6 +1728,12 @@
"id": "related",
"labelId": "gnviewer.linkedResources.label",
"items": "{context.get(state('gnResourceData'), 'linkedResources')}"
},
{
"type": "assets",
"id": "assets",
"labelId": "gnviewer.assets",
"items": "{context.get(state('gnResourceData'), 'assets')}"
}
]
}
Expand Down Expand Up @@ -2418,6 +2430,12 @@
"id": "related",
"labelId": "gnviewer.linkedResources.label",
"items": "{context.get(state('gnResourceData'), 'linkedResources')}"
},
{
"type": "assets",
"id": "assets",
"labelId": "gnviewer.assets",
"items": "{context.get(state('gnResourceData'), 'assets')}"
}
]
}
Expand Down Expand Up @@ -2753,6 +2771,12 @@
"id": "related",
"labelId": "gnviewer.linkedResources.label",
"items": "{context.get(state('gnResourceData'), 'linkedResources')}"
},
{
"type": "assets",
"id": "assets",
"labelId": "gnviewer.assets",
"items": "{context.get(state('gnResourceData'), 'assets')}"
}
]
}
Expand Down Expand Up @@ -3017,6 +3041,12 @@
"id": "related",
"labelId": "gnviewer.linkedResources.label",
"items": "{context.get(state('gnResourceData'), 'linkedResources')}"
},
{
"type": "assets",
"id": "assets",
"labelId": "gnviewer.assets",
"items": "{context.get(state('gnResourceData'), 'assets')}"
}
]
}
Expand Down Expand Up @@ -3551,6 +3581,12 @@
"id": "related",
"labelId": "gnviewer.linkedResources.label",
"items": "{context.get(state('gnResourceData'), 'linkedResources')}"
},
{
"type": "assets",
"id": "assets",
"labelId": "gnviewer.assets",
"items": "{context.get(state('gnResourceData'), 'assets')}"
}
],
"allPage": {},
Expand Down Expand Up @@ -4322,6 +4358,12 @@
"id": "related",
"labelId": "gnviewer.linkedResources.label",
"items": "{context.get(state('gnResourceData'), 'linkedResources')}"
},
{
"type": "assets",
"id": "assets",
"labelId": "gnviewer.assets",
"items": "{context.get(state('gnResourceData'), 'assets')}"
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,8 @@
}
}
},
"allResources": "All resources"
"allResources": "All resources",
"assets": "Assets"
}
}
}
Loading

0 comments on commit 0021085

Please sign in to comment.