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 36 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
};
}
6 changes: 6 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,12 @@ export const getDocumentsByDocType = (docType = 'image', {
}));
};

export const setFavouriteResource = (pk, method) => {
// eslint-disable-next-line dot-notation
return axios[method](parseDevHostname(`${endpoints[RESOURCES]}/${pk}/favorite`))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to pass the method?
I would prefer to have to separated function if they are needed

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to have one function, instead of 2 similar function, in this case change only the CRUD method

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the aim is to use a single function I propose a different approach and do not expose the method.
Now we have here:

  • setFavouriteResource(pk, 'post') // set favourite to true
  • setFavouriteResource(pk, 'delete') // set favourite to false

My proposal is to make this more explicit:

  • setFavouriteResource(pk, true) // set favourite to true
  • setFavouriteResource(pk, false) // set favourite to false

Another proposal is to avoid as much as possible eslint-disable. We should try to follow the eslint rules:

const setFavouriteResource = (pk, favourite) => {
    const request = favourite ? axios.post : axios.get;
    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 @@ -107,7 +108,8 @@ Promise.all([
},
appEpics: {
...gnsearchEpics,
...gnlocaleEpics
...gnlocaleEpics,
...gnsaveEpics
},
geoNodeConfiguration
});
Expand Down
20 changes: 17 additions & 3 deletions geonode_mapstore_client/client/js/components/home/DetailsPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
getUserName,
getResourceTypesInfo
} from '@js/utils/GNSearchUtils';

import debounce from 'lodash/debounce';
import CopyToClipboard from 'react-copy-to-clipboard';
import url from 'url';
import {TextEditable, ThumbnailEditable} from '@js/components/ContentsEditable/';
Expand Down Expand Up @@ -95,10 +95,12 @@ function DetailsPanel({
editAbstract,
editThumbnail,
activeEditMode,
closePanel
closePanel,
favourite,
onFavourite,
isLogged
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should use something more related to favourite instead of isLogged. isLogged is related to the user and the DetailsPanel component should not be aware of the user state

maybe enableFavourite?

}) {


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

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

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

const types = getTypesInfo();
const {
Expand Down Expand Up @@ -234,6 +239,15 @@ function DetailsPanel({
}
{
<div className="gn-details-panel-tools">
{
isLogged &&
<Button
variant="default"
onClick={debounce(handleFavourite, 500)}>
<FaIcon stylePrefix={ favourite ? `fa` : `far`} name="star" />
</Button>
}

{detailUrl && <OverlayTrigger
placement="top"
overlay={(props) =>
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
33 changes: 30 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,33 @@ 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;
const method = (favourite) ? 'post' : 'delete';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should have setFavouriteResource and deleteFavouriteResource

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably is better removeFavouriteResource instead of delete


return Observable
.defer(() => setFavouriteResource(pk, method))
.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 @@ -110,7 +110,6 @@ function gnresource(state = {selectedLayerPermissions: []}, action) {
};
}


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

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

import {
hashLocationToHref,
getFilterById
Expand Down Expand Up @@ -100,10 +103,15 @@ const ConnectedCardGrid = 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 @@ -369,7 +377,6 @@ function Home({
const filterFormTop = dimensions.brandNavbarHeight + dimensions.actionNavbarNodeHeight;



return (
<div className={`gn-home gn-theme-${theme?.variant || 'light'}`}>
<BrandNavbar
Expand Down Expand Up @@ -456,6 +463,7 @@ function Home({
: undefined}
column={ hideHero &&
<ConnectedDetailsPanel
isLogged={!!user}
resource={resource}
filters={queryFilters}
linkHref={hrefDetailPanel}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -387,8 +387,8 @@
},
{
"type": "link",
"href": "/favorite/list/",
"labelId": "gnhome.favorites"
"href": "/favourite/list/",
"labelId": "gnhome.favourites"
},
{
"type": "link",
Expand Down