Skip to content

Commit

Permalink
Notify user when editor has pending changes (#435)
Browse files Browse the repository at this point in the history
  • Loading branch information
allyoucanmap authored Aug 18, 2021
1 parent e01e44a commit 1a1f2e3
Show file tree
Hide file tree
Showing 19 changed files with 438 additions and 165 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ const DropdownList = ({
.map((itm, idx) => {

if (itm.type === 'plugin' && itm.Component) {
return (<li><itm.Component variant="default" /></li>);
return (<li><itm.Component variant="default" className={itm.className}/></li>);
}
if (itm.type === 'divider') {
return <Dropdown.Divider key={idx} />;
Expand All @@ -97,6 +97,7 @@ const DropdownList = ({
style={itm.style}
as={itm?.items ? 'span' : 'a' }
target={itm.target}
className={itm.className}
>
{itm.labelId && <Message msgId={itm.labelId} /> || itm.label}
{isValidBadgeValue(itm.badge) && <Badge>{itm.badge}</Badge>}
Expand Down
10 changes: 5 additions & 5 deletions geonode_mapstore_client/client/js/components/Menu/MenuItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ import {
*
*/

const MenuItem = ({ item, menuItemsProps, containerNode, tabIndex, classItem, size, alignRight, variant }) => {
const MenuItem = ({ item, menuItemsProps, containerNode, tabIndex, classItem = '', size, alignRight, variant }) => {

const { formatHref, query } = menuItemsProps;
const { id, type, label, labelId = '', items = [], href, style, badge = '', image, Component, target } = item;
const btnClassName = `btn${variant && ` btn-${variant}` || ''}${size && ` btn-${size}` || ''}`;
const { id, type, label, labelId = '', items = [], href, style, badge = '', image, Component, target, className } = item;
const btnClassName = `btn${variant && ` btn-${variant}` || ''}${size && ` btn-${size}` || ''}${className ? ` ${className}` : ''}`;

const badgeValue = badge;
if (type === 'dropdown') {
Expand All @@ -54,7 +54,7 @@ const MenuItem = ({ item, menuItemsProps, containerNode, tabIndex, classItem, si
labelId={labelId}
toogleStyle={style}
toogleImage={image}
dropdownClass={classItem}
dropdownClass={`${classItem}${className ? ` ${className}` : ''}`}
tabIndex={tabIndex}
badgeValue={badgeValue}
containerNode={containerNode}
Expand All @@ -65,7 +65,7 @@ const MenuItem = ({ item, menuItemsProps, containerNode, tabIndex, classItem, si
}

if ((type === 'custom' || type === 'plugin') && Component) {
return <Component variant={variant} size={size}/>;
return <Component variant={variant} size={size} className={className}/>;
}

if (type === 'link') {
Expand Down
24 changes: 16 additions & 8 deletions geonode_mapstore_client/client/js/epics/__tests__/gnsave-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ import {
SAVE_ERROR,
saveContent,
updateResourceBeforeSave,
saveDirectContent
saveDirectContent,
SAVE_CONTENT
} from '@js/actions/gnsave';
import { SET_CONTROL_PROPERTY } from '@mapstore/framework/actions/controls';
import {
UPDATE_RESOURCE_PROPERTIES,
RESET_GEO_LIMITS,
RESOURCE_LOADING,
SET_RESOURCE,
RESOURCE_ERROR,
Expand Down Expand Up @@ -52,7 +54,7 @@ describe('gnsave epics', () => {
setTimeout(done);
});
it('should create new map with success (gnSaveContent)', (done) => {
const NUM_ACTIONS = 3;
const NUM_ACTIONS = 4;
const metadata = {
title: 'Title',
description: 'Description',
Expand All @@ -68,8 +70,9 @@ describe('gnsave epics', () => {
expect(actions.map(({ type }) => type))
.toEqual([
SAVING_RESOURCE,
SET_CONTROL_PROPERTY,
SAVE_SUCCESS,
UPDATE_RESOURCE_PROPERTIES
SET_RESOURCE
]);
} catch (e) {
done(e);
Expand All @@ -80,7 +83,7 @@ describe('gnsave epics', () => {
);
});
it('should update existing map with success (gnSaveContent)', (done) => {
const NUM_ACTIONS = 3;
const NUM_ACTIONS = 4;
const id = 1;
const metadata = {
title: 'Title',
Expand All @@ -97,8 +100,9 @@ describe('gnsave epics', () => {
expect(actions.map(({ type }) => type))
.toEqual([
SAVING_RESOURCE,
SET_CONTROL_PROPERTY,
SAVE_SUCCESS,
UPDATE_RESOURCE_PROPERTIES
SET_RESOURCE
]);
} catch (e) {
done(e);
Expand Down Expand Up @@ -226,7 +230,7 @@ describe('gnsave epics', () => {
});

it('should trigger saveResource (gnSaveDirectContent)', (done) => {
const NUM_ACTIONS = 2;
const NUM_ACTIONS = 3;
const pk = 1;
const resource = {
'id': pk,
Expand All @@ -243,7 +247,11 @@ describe('gnsave epics', () => {
(actions) => {
try {
expect(actions.map(({ type }) => type))
.toEqual([SAVING_RESOURCE, SET_RESOURCE]);
.toEqual([
SAVING_RESOURCE,
SAVE_CONTENT,
RESET_GEO_LIMITS
]);
} catch (e) {
done(e);
}
Expand Down
64 changes: 44 additions & 20 deletions geonode_mapstore_client/client/js/epics/gnresource.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ import {
resetResourceState,
loadingResourceConfig,
resourceConfigError,
setResourceCompactPermissions
setResourceCompactPermissions,
updateResourceProperties
} from '@js/actions/gnresource';

import {
Expand Down Expand Up @@ -109,45 +110,43 @@ const resourceTypes = {
}
},
[ResourceTypes.MAP]: {
resourceObservable: (pk) =>
resourceObservable: (pk, options) =>
Observable.defer(() => getMapByPk(pk))
.switchMap((response) => {
const { data, ...resource } = response;
.switchMap((resource) => {
return Observable.of(
configureMap(data),
configureMap(options.data || resource.data),
setControlProperty('toolbar', 'expanded', false),
setResource(resource),
setResourceId(pk)
);
}),
newResourceObservable: () =>
newResourceObservable: (options) =>
Observable.defer(() => getNewMapConfiguration())
.switchMap((response) => {
return Observable.of(
configureMap(response),
configureMap(options.data || response),
setControlProperty('toolbar', 'expanded', false)
);
})
},
[ResourceTypes.GEOSTORY]: {
resourceObservable: (pk) =>
resourceObservable: (pk, options) =>
Observable.defer(() => getGeoAppByPk(pk))
.switchMap((gnGeoStory) => {
const { data, ...resource } = gnGeoStory;
.switchMap((resource) => {
return Observable.of(
setCurrentStory(data),
setCurrentStory(options.data || resource.data),
setResource(resource),
setResourceId(pk),
setGeoStoryResource({
canEdit: resource?.perms?.includes('change_resourcebase')
})
);
}),
newResourceObservable: () =>
newResourceObservable: (options) =>
Observable.defer(() => getNewGeoStoryConfig())
.switchMap((gnGeoStory) => {
return Observable.of(
setCurrentStory({...gnGeoStory, sections: [{...gnGeoStory.sections[0], id: uuid(),
setCurrentStory(options.data || {...gnGeoStory, sections: [{...gnGeoStory.sections[0], id: uuid(),
contents: [{...gnGeoStory.sections[0].contents[0], id: uuid()}]}]}),
setEditing(true),
setGeoStoryResource({
Expand All @@ -169,8 +168,7 @@ const resourceTypes = {
[ResourceTypes.DASHBOARD]: {
resourceObservable: (pk, options) =>
Observable.defer(() => getGeoAppByPk(pk))
.switchMap(( gnDashboard ) => {
const { data, ...resource } = gnDashboard;
.switchMap(( resource ) => {
const { readOnly } = options || {};
const canEdit = !readOnly && resource?.perms?.includes('change_resourcebase') ? true : false;
const canDelete = !readOnly && resource?.perms?.includes('delete_resourcebase') ? true : false;
Expand All @@ -185,16 +183,25 @@ const resourceTypes = {
lastUpdate: resource.last_updated,
name: resource.title
},
data
options.data || resource.data
),
setResource(resource),
setResourceId(pk)
);
})
.startWith(dashboardLoading(false)),
newResourceObservable: () =>
newResourceObservable: (options) =>
Observable.of(
resetDashboard(),
...(options.data ? [
dashboardLoaded(
{
canDelete: true,
canEdit: true
},
options.data
)
] : []),
dashboardLoading(false)
)
}
Expand Down Expand Up @@ -237,8 +244,9 @@ export const gnViewerRequestNewResourceConfig = (action$, store) =>
setNewResource(),
setResourceType(action.resourceType)
),
newResourceObservable(),
newResourceObservable({}),
Observable.of(
setControlProperty('pendingChanges', 'value', null),
loadingResourceConfig(false)
)
)
Expand All @@ -250,10 +258,19 @@ export const gnViewerRequestNewResourceConfig = (action$, store) =>
});
});

export const gnViewerRequestResourceConfig = (action$) =>
export const gnViewerRequestResourceConfig = (action$, store) =>
action$.ofType(REQUEST_RESOURCE_CONFIG)
.switchMap((action) => {

const state = store.getState();

const currentPendingChanges = state?.controls?.pendingChanges?.value;
const pendingChanges = currentPendingChanges
&& currentPendingChanges.pk === action.pk
&& currentPendingChanges.resourceType === action.resourceType
? currentPendingChanges
: {};

const { resourceObservable } = resourceTypes[action.resourceType] || {};

if (!resourceObservable) {
Expand All @@ -276,8 +293,15 @@ export const gnViewerRequestResourceConfig = (action$) =>
.catch(() => {
return Observable.empty();
}),
resourceObservable(action.pk, action.options),
resourceObservable(action.pk, {
...action.options,
// set the pending changes as the new data fro maps, dashboards and geostories
// if undefined the returned data will be used
data: pendingChanges?.data
}),
Observable.of(
...(pendingChanges?.resource ? [updateResourceProperties(pendingChanges.resource)] : []),
setControlProperty('pendingChanges', 'value', null),
loadingResourceConfig(false)
)
)
Expand Down
Loading

0 comments on commit 1a1f2e3

Please sign in to comment.