Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A favorite icon will let the authenticated user add the resource to his favorites #214

Merged
merged 42 commits into from
Jun 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
39e4b7c
conf proxy
luorlandini Mar 24, 2021
0e14896
Merge remote-tracking branch 'upstream/master'
luorlandini Apr 1, 2021
a284a3c
Merge remote-tracking branch 'upstream/master'
luorlandini Apr 7, 2021
213a635
Merge remote-tracking branch 'upstream/master'
luorlandini Apr 12, 2021
42d8965
Merge remote-tracking branch 'upstream/master'
luorlandini Apr 15, 2021
2cb0c3a
Merge remote-tracking branch 'upstream/master'
luorlandini Apr 16, 2021
67fe726
Merge remote-tracking branch 'upstream/master'
luorlandini Apr 16, 2021
efc1bcd
Merge remote-tracking branch 'upstream/master'
luorlandini Apr 20, 2021
2e4ebe3
Merge remote-tracking branch 'upstream/master'
luorlandini Apr 20, 2021
37f6ae8
Merge remote-tracking branch 'upstream/master'
luorlandini Apr 26, 2021
e56da8b
Merge remote-tracking branch 'upstream/master'
luorlandini May 3, 2021
d384237
Merge remote-tracking branch 'upstream/master'
luorlandini May 3, 2021
8cfb1ca
Merge remote-tracking branch 'upstream/master'
luorlandini May 6, 2021
19be961
Merge remote-tracking branch 'upstream/master'
luorlandini May 10, 2021
7a646a3
Merge remote-tracking branch 'upstream/master'
luorlandini May 12, 2021
0ff1b62
Merge remote-tracking branch 'upstream/master'
luorlandini May 17, 2021
f328a01
Merge remote-tracking branch 'upstream/master'
luorlandini May 19, 2021
7ae2c74
Merge remote-tracking branch 'upstream/master'
luorlandini May 24, 2021
8381427
Merge remote-tracking branch 'upstream/master'
luorlandini May 24, 2021
73330c2
Merge remote-tracking branch 'upstream/master'
luorlandini May 25, 2021
2b7c30c
Merge remote-tracking branch 'upstream/master'
luorlandini May 25, 2021
de22dc1
add param style prefix
luorlandini May 26, 2021
eac72ed
set favorite in state
luorlandini May 26, 2021
936768e
Merge remote-tracking branch 'upstream/master'
luorlandini May 26, 2021
cb7dd17
replace favorite with favourite
luorlandini May 26, 2021
1fdfb9b
fix typo
luorlandini May 27, 2021
f87b58b
remove favorite reduce
luorlandini May 27, 2021
57911d6
rename in favorite and add http request
luorlandini May 27, 2021
a78df16
fix status
luorlandini May 27, 2021
e4439c3
fix action doc
luorlandini May 27, 2021
e300f1b
check user is logged
luorlandini May 27, 2021
92fee7e
debounce onClick
luorlandini May 27, 2021
cce793e
rename in favourite
luorlandini May 27, 2021
4697c3d
default host
luorlandini May 27, 2021
f6443b7
Merge branch 'master' into 196_favorite_icon
luorlandini May 27, 2021
516d982
update
luorlandini May 28, 2021
5c28cc5
pass favoriteas flag
luorlandini Jun 25, 2021
b4f5762
pass favoriteas flag
luorlandini Jun 25, 2021
3a3801c
Merge remote-tracking branch 'upstream/master' into 196_favorite_icon
luorlandini Jun 25, 2021
b5dbca9
delete method
luorlandini Jun 25, 2021
0e0f3ad
fix lint
luorlandini Jun 25, 2021
56f6592
enableFavourite
luorlandini Jun 25, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions geonode_mapstore_client/client/js/actions/gnresource.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ export const SET_RESOURCE_PERMISSIONS = 'GEONODE:SET_RESOURCE_PERMISSIONS';
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_FAVOURITE_RESOURCE = 'GEONODE:SET_FAVOURITE_RESOURCE';

export const SET_SELECTED_LAYER_PERMISSIONS = "GEONODE:SET_SELECTED_LAYER_PERMISSIONS";


/**
* Actions for GeoNode resource
* store information of the resource in use
Expand Down Expand Up @@ -174,3 +176,16 @@ export function setSelectedLayerPermissions(permissions) {
permissions
};
}

/**
* Set the resource favourite field (trigger epic gnSaveFavouriteContent)
* @memberof actions.gnresource
* @param {bool} favourite resource data field
*/
export function setFavouriteResource(favourite) {

return {
type: SET_FAVOURITE_RESOURCE,
favourite
};
}
7 changes: 7 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,13 @@ export const getDocumentsByDocType = (docType = 'image', {
}));
};


export const setFavouriteResource = (pk, favourite) => {
const request = favourite ? axios.post : axios.delete;
return request(parseDevHostname(`${endpoints[RESOURCES]}/${pk}/favorite`))
.then(({ data }) => data );
};

export const getResourceByPk = (pk) => {
return axios.get(parseDevHostname(`${endpoints[RESOURCES]}/${pk}`))
.then(({ data }) => data.resource);
Expand Down
4 changes: 3 additions & 1 deletion geonode_mapstore_client/client/js/apps/gn-home.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import gnsearch from '@js/reducers/gnsearch';
import gnresource from '@js/reducers/gnresource';
import gnsearchEpics from '@js/epics/gnsearch';
import gnlocaleEpics from '@js/epics/gnlocale';
import gnsaveEpics from '@js/epics/gnsave';

import {
getConfiguration,
Expand Down Expand Up @@ -108,7 +109,8 @@ Promise.all([
},
appEpics: {
...gnsearchEpics,
...gnlocaleEpics
...gnlocaleEpics,
...gnsaveEpics
},
geoNodeConfiguration
});
Expand Down
58 changes: 36 additions & 22 deletions geonode_mapstore_client/client/js/components/home/DetailsPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,29 @@ import {
getUserName,
getResourceTypesInfo
} from '@js/utils/GNSearchUtils';

import debounce from 'lodash/debounce';
import CopyToClipboardCmp from 'react-copy-to-clipboard';
import url from 'url';
import {TextEditable, ThumbnailEditable} from '@js/components/ContentsEditable/';
import { TextEditable, ThumbnailEditable } from '@js/components/ContentsEditable/';

const CopyToClipboard = tooltip(CopyToClipboardCmp);

const EditTitle = ({title, onEdit}) => {
const EditTitle = ({ title, onEdit }) => {
return (
<div className="editContainer">
<h1><TextEditable onEdit={ onEdit } text={title} /></h1>
<h1><TextEditable onEdit={onEdit} text={title} /></h1>
</div>);
};

const EditAbstract = ({abstract, onEdit}) => (
const EditAbstract = ({ abstract, onEdit }) => (
<div className="editContainer">
<TextEditable onEdit={ onEdit } text={abstract} />
<TextEditable onEdit={onEdit} text={abstract} />
</div>

);


const EditThumbnail = ({image, onEdit}) => (
const EditThumbnail = ({ image, onEdit }) => (
<div className="editContainer imagepreview">
<ThumbnailEditable onEdit={onEdit} defaultImage={image} />
</div>
Expand Down Expand Up @@ -99,10 +99,12 @@ function DetailsPanel({
editAbstract,
editThumbnail,
activeEditMode,
closePanel
closePanel,
favourite,
onFavourite,
enableFavourite
}) {


const [editModeTitle, setEditModeTitle] = useState(false);
const [editModeAbstract, setEditModeAbstract] = useState(false);

Expand Down Expand Up @@ -137,6 +139,9 @@ function DetailsPanel({
}, 700);
};

const handleFavourite = () => {
onFavourite(!favourite);
};

const types = getTypesInfo();
const {
Expand All @@ -147,7 +152,6 @@ function DetailsPanel({
} = resource && (types[resource.doc_type] || types[resource.resource_type]) || {};
const embedUrl = resource?.embed_url && formatEmbedUrl(resource);
const detailUrl = resource?.pk && formatDetailUrl(resource);

return (
<div
ref={detailsContainerNode}
Expand Down Expand Up @@ -176,7 +180,7 @@ function DetailsPanel({
alignItems: 'center',
justifyContent: 'center'
}}>
<FaIcon name={icon}/>
<FaIcon name={icon} />
</div>
{embedUrl && !editThumbnail
? <iframe
Expand All @@ -198,7 +202,7 @@ function DetailsPanel({
top: 0,
left: 0,
backgroundColor: 'inherit'
}}/> )
}} />)
}
{loading && <div
className="gn-details-panel-preview-loader"
Expand All @@ -216,7 +220,7 @@ function DetailsPanel({
<span className="sr-only">Loading resource detail...</span>
</Spinner>
</div>}
</div> }
</div>}

{activeEditMode && editThumbnail && <div className="gn-details-panel-preview inediting"> <EditThumbnail onEdit={editThumbnail} image={resource?.thumbnail_url} /> </div>}

Expand All @@ -225,19 +229,29 @@ function DetailsPanel({
<div className="gn-details-panel-title" >

{!editModeTitle && <h1>
{ icon && <><FaIcon name={icon}/></>}
{ resource?.title }
{icon && <><FaIcon name={icon} /></>}
{resource?.title}
</h1>
}
{ activeEditMode && !editModeTitle && <span className="inEdit" onClick={handleEditModeTitle} ><FaIcon name={'edit'}/></span>}
{activeEditMode && !editModeTitle && <span className="inEdit" onClick={handleEditModeTitle} ><FaIcon name={'edit'} /></span>}


{editModeTitle && <><h1><EditTitle title={resource?.title} onEdit={editTitle} />
</h1>
<span className="inEdit" onClick={handleEditModeTitle} ><FaIcon name={'check-circle'}/></span></>
<span className="inEdit" onClick={handleEditModeTitle} ><FaIcon name={'check-circle'} /></span></>
}
{
<div className="gn-details-panel-tools">
{
enableFavourite &&
<Button
variant="default"
onClick={debounce(handleFavourite, 500)}>
<FaIcon stylePrefix={favourite ? `fa` : `far`} name="star" />
</Button>
}


{detailUrl && <CopyToClipboard
tooltipPosition="top"
tooltipId={
Expand All @@ -257,7 +271,7 @@ function DetailsPanel({
variant="default"
href={detailUrl}
rel="noopener noreferrer">
<Message msgId={`gnhome.view${name || ''}`}/>
<Message msgId={`gnhome.view${name || ''}`} />
</Button>}
</div>
}
Expand All @@ -273,14 +287,14 @@ function DetailsPanel({
}
})}>{getUserName(resource.owner)}</a></>}
{(resource?.date_type && resource?.date)
&& <>{' '}/{' '}{ moment(resource.date).format('MMMM Do YYYY')}</>}
&& <>{' '}/{' '}{moment(resource.date).format('MMMM Do YYYY')}</>}
</p>
}
<p>
{ activeEditMode && !editModeAbstract && <span className="inEdit" onClick={handleEditModeAbstract} ><FaIcon name={'edit'}/></span>}
{activeEditMode && !editModeAbstract && <span className="inEdit" onClick={handleEditModeAbstract} ><FaIcon name={'edit'} /></span>}
<div className="gn-details-panel-description">
{editModeAbstract && <>
<span className="inEdit" onClick={handleEditModeAbstract} ><FaIcon name={'check-circle'}/></span>
<span className="inEdit" onClick={handleEditModeAbstract} ><FaIcon name={'check-circle'} /></span>
<EditAbstract abstract={resource?.abstract} onEdit={editAbstract} />
</>
}
Expand All @@ -294,7 +308,7 @@ function DetailsPanel({

<p>
{resource?.category?.identifier && <div>
<Message msgId="gnhome.category"/>:{' '}
<Message msgId="gnhome.category" />:{' '}
<a href={formatHref({
query: {
'filter{category.identifier.in}': resource.category.identifier
Expand Down
5 changes: 3 additions & 2 deletions geonode_mapstore_client/client/js/components/home/FaIcon.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import React from 'react';
function FaIcon({
name,
className,
style
style,
stylePrefix = 'fa'
}) {
return <i className={`fa fa-${name}${className ? ` ${className}` : ''}`} style={style}/>;
return <i className={`${stylePrefix} fa-${name}${className ? ` ${className}` : ''}`} style={style}/>;
}

FaIcon.defaultProps = {};
Expand Down
31 changes: 28 additions & 3 deletions geonode_mapstore_client/client/js/epics/gnsave.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,14 @@ import {
resourceLoading,
setResource,
resourceError,
updateResourceProperties
updateResourceProperties,
SET_FAVOURITE_RESOURCE
} from '@js/actions/gnresource';
import {
getResourceByPk,
createGeoStory,
updateGeoStory
updateGeoStory,
setFavouriteResource
} from '@js/api/geonode/v2';
import { parseDevHostname } from '@js/utils/APIUtils';
import uuid from 'uuid';
Expand Down Expand Up @@ -207,8 +209,31 @@ export const gnUpdateResource = (action$, store) =>
.startWith(resourceLoading());
});

export const gnSaveFavouriteContent = (action$, store) =>
action$.ofType(SET_FAVOURITE_RESOURCE)
.switchMap((action) => {
const state = store.getState();
const pk = state?.gnresource?.data.pk;
const favourite = action.favourite;
return Observable
.defer(() => setFavouriteResource(pk, favourite))
.switchMap(() => {
return Observable.of(
updateResourceProperties({
'favourite': favourite
})
);
})
.catch((error) => {
return Observable.of(resourceError(error.data || error.message));
});

});


export default {
gnSaveContent,
gnUpdateResource,
gnSaveDirectContent
gnSaveDirectContent,
gnSaveFavouriteContent
};
1 change: 0 additions & 1 deletion geonode_mapstore_client/client/js/reducers/gnresource.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ function gnresource(state = {selectedLayerPermissions: [], data: {}}, action) {
};
}


case SET_SELECTED_LAYER_PERMISSIONS:
return {
...state,
Expand Down
19 changes: 15 additions & 4 deletions geonode_mapstore_client/client/js/routes/Home.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ import {
loadFeaturedResources
} from '@js/actions/gnsearch';

import { setFavouriteResource
} from '@js/actions/gnresource';

import {
hashLocationToHref,
getFilterById
Expand Down Expand Up @@ -119,10 +122,15 @@ const ConnectedFeatureList = connect(

const ConnectedDetailsPanel = connect(
createSelector([
state => state?.gnresource?.loading || false
], (loading) => ({
loading
}))
state => state?.gnresource?.loading || false,
state => state?.gnresource?.data?.favourite || false
], (loading, favourite) => ({
loading,
favourite
})),
{
onFavourite: setFavouriteResource
}
)(DetailsPanel);

const suggestionsRequestTypes = {
Expand Down Expand Up @@ -380,6 +388,8 @@ function Home({
const isHeroVisible = !hideHero && inView;
const stickyFiltersMaxHeight = (window.innerHeight - dimensions.brandNavbarHeight - dimensions.actionNavbarNodeHeight - dimensions.footerNodeHeight);
const filterFormTop = dimensions.brandNavbarHeight + dimensions.actionNavbarNodeHeight;


return (
<div className={`gn-home`}>
<MetaTags
Expand Down Expand Up @@ -489,6 +499,7 @@ function Home({
: undefined}
column={ hideHero &&
<ConnectedDetailsPanel
enableFavourite={!!user}
resource={resource}
linkHref={hrefDetailPanel}
formatHref={handleFormatHref}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,8 @@
},
{
"type": "link",
"href": "/favorite/list/",
"labelId": "gnhome.favorites"
"href": "/favourite/list/",
"labelId": "gnhome.favourites"
},
{
"type": "link",
Expand Down