Skip to content

Commit

Permalink
Set thumbnail from map inside datasets and maps detail panel (#364)
Browse files Browse the repository at this point in the history
  • Loading branch information
luorlandini authored Oct 13, 2021
1 parent 0a7f59b commit 1d896a3
Show file tree
Hide file tree
Showing 16 changed files with 274 additions and 21 deletions.
13 changes: 13 additions & 0 deletions geonode_mapstore_client/client/js/actions/gnresource.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const EDIT_TITLE_RESOURCE = 'GEONODE:EDIT_TITLE_RESOURCE';
export const EDIT_ABSTRACT_RESOURCE = 'GEONODE:EDIT_ABSTRACT_RESOURCE';
export const EDIT_THUMBNAIL_RESOURCE = 'GEONODE:EDIT_THUMBNAIL_RESOURCE';
export const SET_FAVORITE_RESOURCE = 'GEONODE:SET_FAVORITE_RESOURCE';
export const SET_MAP_THUMBNAIL = 'GEONODE:SET_MAP_THUMBNAIL';
export const SET_SELECTED_DATASET_PERMISSIONS = "GEONODE:SET_SELECTED_DATASET_PERMISSIONS";
export const REQUEST_RESOURCE_CONFIG = 'GEONODE:REQUEST_RESOURCE_CONFIG';
export const REQUEST_NEW_RESOURCE_CONFIG = 'GEONODE:REQUEST_NEW_RESOURCE_CONFIG';
Expand Down Expand Up @@ -197,6 +198,18 @@ export function setFavoriteResource(favorite) {
};
}


/**
* Set map like thumbnail to map or layer (trigger epic gnSaveDirectContent)
* @memberof actions.gnresource
*/

export function setMapThumbnail() {
return {
type: SET_MAP_THUMBNAIL
};
}

export function requestResourceConfig(resourceType, pk, options) {
return {
type: REQUEST_RESOURCE_CONFIG,
Expand Down
4 changes: 4 additions & 0 deletions geonode_mapstore_client/client/js/api/geonode/v2/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,10 @@ export const getDocumentsByDocType = (docType = 'image', {
}));
};

export const setMapThumbnail = (pk, body) => {
return axios.post(parseDevHostname(`${endpoints[RESOURCES]}/${pk}/set_thumbnail_from_bbox`), body)
.then(({ data }) => (data));
};

export const setFavoriteResource = (pk, favorite) => {
const request = favorite ? axios.post : axios.delete;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,48 @@
* LICENSE file in the root directory of this source tree.
*/

import React, { useState, useEffect } from 'react';
import React, { useState, useEffect, useRef } from 'react';
import Thumbnail from '@mapstore/framework/components/misc/Thumbnail';
import FaIcon from '@js/components/FaIcon';
import Button from '@js/components/Button';
import tooltip from '@mapstore/framework/components/misc/enhancers/tooltip';
import Message from '@mapstore/framework/components/I18N/Message';
const ButtonWithToolTip = tooltip(Button);

const ThumbnailEditable = ({
defaultImage,
onEdit = () => {}
}) => {

const thumbnailRef = useRef(null);
const [thumbnail, setThumbnail] = useState();
useEffect(() => {
setThumbnail(defaultImage);

}, [ ]);
}, [defaultImage]);

const handleDialaogWindowUpload = () => {
thumbnailRef?.current?.nextElementSibling.click();
};

return (
<>
<Thumbnail
ref={thumbnailRef}
thumbnail={thumbnail}
onUpdate={(data) => {
setThumbnail(data);
onEdit(data);
}}
message={<Message msgId="gnviewer.uploadImage"/>}
/>
<div className={`icon-image-preview`} >
<ButtonWithToolTip
variant="default"
className="upload-thumbnail"
onClick={ () => handleDialaogWindowUpload()}
tooltip={ <Message msgId="gnviewer.uploadImage"/> }
tooltipPosition={"top"}
>
<FaIcon name="upload" />
</div>
</ButtonWithToolTip>
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,8 @@ function DetailsPanel({
closePanel,
favorite,
onFavorite,
enableFavorite
enableFavorite,
buttonSaveThumbnailMap
}) {
const detailsContainerNode = useRef();
const isMounted = useRef();
Expand Down Expand Up @@ -411,7 +412,13 @@ function DetailsPanel({
<div className="gn-details-panel-content">
{editThumbnail && <div className="gn-details-panel-content-img">
{!activeEditMode && <ThumbnailPreview src={resource?.thumbnail_url} />}
{activeEditMode && <div className="gn-details-panel-preview inediting"> <EditThumbnail onEdit={editThumbnail} image={resource?.thumbnail_url} /> </div>}
{activeEditMode && <div className="gn-details-panel-preview inediting">
<EditThumbnail
onEdit={editThumbnail}
image={resource?.thumbnail_url}
/>
{ buttonSaveThumbnailMap }
</div>}
</div>
}

Expand Down
39 changes: 38 additions & 1 deletion geonode_mapstore_client/client/js/epics/gnsave.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import axios from '@mapstore/framework/libs/ajax';
import { Observable } from 'rxjs';
import { mapInfoSelector } from '@mapstore/framework/selectors/map';
import { mapInfoSelector, mapSelector } from '@mapstore/framework/selectors/map';
import { userSelector } from '@mapstore/framework/selectors/security';
import {
error as errorNotification,
Expand All @@ -21,12 +21,15 @@ import {
saveError,
savingResource,
SAVE_DIRECT_CONTENT,
clearSave,
saveContent
} from '@js/actions/gnsave';
import {
setResource,
SET_MAP_THUMBNAIL,
resetGeoLimits,
setResourceCompactPermissions,
updateResourceProperties,
loadingResourceConfig
} from '@js/actions/gnresource';
import {
Expand All @@ -37,6 +40,7 @@ import {
createMap,
updateMap,
updateDocument,
setMapThumbnail,
updateCompactPermissionsByPk,
getResourceByUuid
} from '@js/api/geonode/v2';
Expand Down Expand Up @@ -155,7 +159,39 @@ export const gnSaveContent = (action$, store) =>
.startWith(savingResource());

});
export const gnSetMapThumbnail = (action$, store) =>
action$.ofType(SET_MAP_THUMBNAIL)
.switchMap(() => {
const state = store.getState();
const contentType = state.gnresource?.data?.resource_type || 'map';
const resourceIDThumbnail = state?.gnresource?.id;
const currentResource = state.gnresource?.data || {};
const map = mapSelector(state) || {};
const body = {
srid: map.bbox.crs,
bbox: [ Object.values(map.bbox.bounds)[2],
Object.values(map.bbox.bounds)[0],
Object.values(map.bbox.bounds)[3],
Object.values(map.bbox.bounds)[1]
]
};
return Observable.defer(() => setMapThumbnail(resourceIDThumbnail, body, contentType))
.switchMap((res) => {
return Observable.of(
updateResourceProperties({...currentResource, thumbnail_url: `${res.thumbnail_url}?${Math.random()}`}),
clearSave(),
...([successNotification({title: "gnviewer.thumbnailsaved", message: "gnviewer.thumbnailsaved"})])

);
})
.catch((error) => {
return Observable.of(
saveError(error.data),
errorNotification({title: "gnviewer.thumbnailnotsaved", message: "gnviewer.thumbnailnotsaved"})
);
})
.startWith(savingResource());
});
export const gnSaveDirectContent = (action$, store) =>
action$.ofType(SAVE_DIRECT_CONTENT)
.switchMap(() => {
Expand Down Expand Up @@ -277,6 +313,7 @@ export const gnWatchStopCopyProcessOnSave = (action$, store) =>
export default {
gnSaveContent,
gnSaveDirectContent,
gnSetMapThumbnail,
gnWatchStopPermissionsProcess,
gnWatchStopCopyProcessOnSave
};
10 changes: 9 additions & 1 deletion geonode_mapstore_client/client/js/plugins/DetailViewer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import DetailsPanel from '@js/components/DetailsPanel';
import { userSelector } from '@mapstore/framework/selectors/security';
import usePluginItems from '@js/hooks/usePluginItems';
import {
editTitleResource,
editAbstractResource,
Expand Down Expand Up @@ -89,6 +90,7 @@ const ConnectedButton = connect(


function DetailViewer({
items,
location,
enabled,
onEditResource,
Expand All @@ -99,7 +101,12 @@ function DetailViewer({
hide,
user,
onClose
}) {
}, context) {

const { loadedPlugins } = context;
const configuredItems = usePluginItems({ items, loadedPlugins });
const buttonSaveThumbnailMap = configuredItems.filter(({ name }) => name === "MapThumbnail")
.map(({ Component, name }) => <Component key={name} />);

const handleTitleValue = (val) => {
onEditResource(val);
Expand Down Expand Up @@ -143,6 +150,7 @@ function DetailViewer({
editAbstract={handleAbstractValue}
editThumbnail={handleEditThumbnail}
activeEditMode={enabled && canEdit}
buttonSaveThumbnailMap={buttonSaveThumbnailMap}
enableFavorite={!!user}
formatHref={handleFormatHref}
/>
Expand Down
108 changes: 108 additions & 0 deletions geonode_mapstore_client/client/js/plugins/MapThumbnail.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Copyright 2021, 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 FaIcon from '@js/components/FaIcon';
import { mapInfoSelector } from '@mapstore/framework/selectors/map';
import Loader from '@mapstore/framework/components/misc/Loader';
import Button from '@js/components/Button';
import { isLoggedIn } from '@mapstore/framework/selectors/security';
import controls from '@mapstore/framework/reducers/controls';
import gnresource from '@js/reducers/gnresource';
import gnsave from '@js/reducers/gnsave';
import gnsaveEpics from '@js/epics/gnsave';
import { setMapThumbnail } from '@js/actions/gnresource';
import Message from '@mapstore/framework/components/I18N/Message';
import tooltip from '@mapstore/framework/components/misc/enhancers/tooltip';
const MapThumbnailButtonToolTip = tooltip(Button);

import {
isNewResource,
canEditResource
} from '@js/selectors/resource';


function MapThumbnail(props) {
return props.saving ? (<div
style={{ position: 'absolute', width: '100%',
height: '100%', backgroundColor: 'rgba(255, 255, 255, 0.75)',
top: '0px', zIndex: 1000, display: 'flex',
alignItems: 'center', justifyContent: 'center', right: '0px'}}>
<Loader size={150}/>
</div>) : null

;
}

const MapThumbnailPlugin = connect(
createSelector([
state => state?.gnsave?.saving
], (saving) => ({
saving
}))
)(MapThumbnail);

function MapThumbnailButton({
enabled,
onClick
}) {
return enabled
?
<MapThumbnailButtonToolTip
variant="default"
onClick={() => onClick()}
className={"map-thumbnail"}
tooltip={ <Message msgId="gnviewer.saveMapThumbnail"/> }
tooltipPosition={"top"}

>
<FaIcon name="map" />

</MapThumbnailButtonToolTip>

: null
;
}


const ConnectedMapThumbnailButton = connect(
createSelector(
isLoggedIn,
isNewResource,
canEditResource,
mapInfoSelector,
(loggedIn, isNew, canEdit, mapInfo) => ({
enabled: loggedIn && !isNew && (canEdit || mapInfo?.canEdit)
})
),
{
onClick: setMapThumbnail
}
)((MapThumbnailButton));

export default createPlugin('MapThumbnail', {
component: MapThumbnailPlugin,
containers: {
DetailViewer: {
name: 'MapThumbnail',
target: 'saveThumbnailMap',
Component: ConnectedMapThumbnailButton
}
},
epics: {
...gnsaveEpics
},
reducers: {
gnresource,
gnsave,
controls
}
});
4 changes: 4 additions & 0 deletions geonode_mapstore_client/client/js/plugins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,10 @@ export const plugins = {
'SaveAs',
() => import(/* webpackChunkName: 'plugins/save-as-plugin' */ '@js/plugins/SaveAs')
),
MapThumbnailPlugin: toLazyPlugin(
'MapThumbnail',
() => import(/* webpackChunkName: 'plugins/map-thumbnail-plugin' */ '@js/plugins/MapThumbnail')
),
SearchPlugin: toLazyPlugin(
'Search',
() => import(/* webpackChunkName: 'plugins/search-plugin' */ '@mapstore/framework/plugins/Search')
Expand Down
2 changes: 1 addition & 1 deletion geonode_mapstore_client/client/js/selectors/resource.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const getResourcePerms = (state) => {
};

export const getResourceName = (state) => {
return state?.gnresource?.data?.name || false;
return state?.gnresource?.data?.title || false;
};

export const getResourceDescription = (state) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,9 @@
"disablePermission": true
}
},
{
"name": "MapThumbnail"
},
{
"name": "Share",
"cfg": {
Expand Down Expand Up @@ -1388,6 +1391,9 @@
{
"name": "ViewerLayout"
},
{
"name": "MapThumbnail"
},
{
"name": "ActionNavbar",
"cfg": {
Expand Down
Loading

0 comments on commit 1d896a3

Please sign in to comment.