Skip to content

Commit 9fb24f5

Browse files
anup39allyoucanmap
andauthored
Fix #2288 Added Update Bounding Box button to trigger recalculation of extent of the dataset. (#2293)
--------- Co-authored-by: allyoucanmap <[email protected]>
1 parent 868e883 commit 9fb24f5

File tree

21 files changed

+238
-25
lines changed

21 files changed

+238
-25
lines changed

geonode_mapstore_client/client/js/actions/gnresource.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ export const DOWNLOAD_RESOURCE = 'GEONODE_DOWNLOAD_RESOURCE';
3535
export const DOWNLOAD_COMPLETE = 'GEONODE_DOWNLOAD_COMPLETE';
3636
export const UPDATE_SINGLE_RESOURCE = 'GEONODE_UPDATE_SINGLE_RESOURCE';
3737
export const SET_RESOURCE_EXTENT = 'GEONODE_SET_RESOURCE_EXTENT';
38+
export const UPDATE_RESOURCE_EXTENT = 'GEONODE_UPDATE_RESOURCE_EXTENT';
39+
export const UPDATE_RESOURCE_EXTENT_LOADING = 'GEONODE_UPDATE_RESOURCE_EXTENT_LOADING';
3840
export const SET_RESOURCE_PATH_PARAMETERS = 'GEONODE:SET_RESOURCE_PATH_PARAMETERS';
3941
export const SET_MAP_VIEWER_LINKED_RESOURCE = 'GEONODE:SET_MAP_VIEWER_LINKED_RESOURCE';
4042
export const MANAGE_LINKED_RESOURCE = 'GEONODE:MANAGE_LINKED_RESOURCE';
@@ -328,6 +330,19 @@ export function setResourceExtent(coords) {
328330
};
329331
}
330332

333+
export function updateResourceExtent() {
334+
return {
335+
type: UPDATE_RESOURCE_EXTENT,
336+
};
337+
}
338+
339+
export function updateResourceExtentLoading(loading) {
340+
return {
341+
type: UPDATE_RESOURCE_EXTENT_LOADING,
342+
loading
343+
};
344+
}
345+
331346
export function setResourcePathParameters(params) {
332347
return {
333348
type: SET_RESOURCE_PATH_PARAMETERS,

geonode_mapstore_client/client/js/api/geonode/v2/index.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,11 @@ export const getMetadataDownloadLinkByPk = (pk) => {
739739
return getEndpointUrl(RESOURCES, `/${pk}/iso_metadata_xml`);
740740
};
741741

742+
export const updateResourceExtent = (pk) => {
743+
return axios.put(getEndpointUrl(DATASETS, `/${pk}/recalc-bbox`))
744+
.then(({ data }) => data);
745+
}
746+
742747
export default {
743748
getEndpoints,
744749
getResources,
@@ -778,5 +783,6 @@ export default {
778783
getResourceByTypeAndByPk,
779784
createDataset,
780785
getMetadataDownloadLinkByPk,
781-
updateResource
786+
updateResource,
787+
updateResourceExtent
782788
};

geonode_mapstore_client/client/js/epics/__tests__/gnresource-test.js

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,16 @@ import {
1515
closeInfoPanelOnMapClick,
1616
closeDatasetCatalogPanel,
1717
gnZoomToFitBounds,
18-
closeResourceDetailsOnMapInfoOpen
18+
closeResourceDetailsOnMapInfoOpen,
19+
gnUpdateResourceExtent
1920
} from '@js/epics/gnresource';
21+
import { SAVE_SUCCESS } from '@mapstore/framework/actions/featuregrid';
2022
import {
2123
setResourceThumbnail,
2224
UPDATE_RESOURCE_PROPERTIES,
23-
UPDATE_SINGLE_RESOURCE
25+
UPDATE_SINGLE_RESOURCE,
26+
UPDATE_RESOURCE_EXTENT_LOADING,
27+
updateResourceExtent
2428
} from '@js/actions/gnresource';
2529
import { clickOnMap, changeMapView, ZOOM_TO_EXTENT } from '@mapstore/framework/actions/map';
2630
import { SET_CONTROL_PROPERTY, setControlProperty } from '@mapstore/framework/actions/controls';
@@ -269,4 +273,76 @@ describe('gnresource epics', () => {
269273
);
270274

271275
});
276+
it('should update resource extent on UPDATE_RESOURCE_EXTENT action', (done) => {
277+
const NUM_ACTIONS = 3;
278+
const pk = 1;
279+
const testState = {
280+
gnresource: {
281+
data: {
282+
pk: pk,
283+
'title': 'Map'
284+
}
285+
}
286+
};
287+
mockAxios.onPut(new RegExp(`datasets/${pk}/bbox_recalc`))
288+
.reply(() => [200, { success: true }]);
289+
290+
testEpic(
291+
gnUpdateResourceExtent,
292+
NUM_ACTIONS,
293+
updateResourceExtent(),
294+
(actions) => {
295+
try {
296+
expect(actions.map(({ type }) => type))
297+
.toEqual([
298+
UPDATE_RESOURCE_EXTENT_LOADING,
299+
UPDATE_RESOURCE_EXTENT_LOADING,
300+
SHOW_NOTIFICATION
301+
]);
302+
expect(actions[0].loading).toBe(true);
303+
expect(actions[1].loading).toBe(false);
304+
} catch (e) {
305+
done(e);
306+
}
307+
done();
308+
},
309+
testState
310+
);
311+
});
312+
313+
it('should update resource extent on SAVE_SUCCESS without notification', (done) => {
314+
const NUM_ACTIONS = 2;
315+
const pk = 1;
316+
const testState = {
317+
gnresource: {
318+
data: {
319+
pk: pk,
320+
'title': 'Map'
321+
}
322+
}
323+
};
324+
mockAxios.onPut(new RegExp(`datasets/${pk}/bbox_recalc`))
325+
.reply(() => [200, { success: true }]);
326+
327+
testEpic(
328+
gnUpdateResourceExtent,
329+
NUM_ACTIONS,
330+
{ type: SAVE_SUCCESS },
331+
(actions) => {
332+
try {
333+
expect(actions.map(({ type }) => type))
334+
.toEqual([
335+
UPDATE_RESOURCE_EXTENT_LOADING,
336+
UPDATE_RESOURCE_EXTENT_LOADING
337+
]);
338+
expect(actions[0].loading).toBe(true);
339+
expect(actions[1].loading).toBe(false);
340+
} catch (e) {
341+
done(e);
342+
}
343+
done();
344+
},
345+
testState
346+
);
347+
});
272348
});

geonode_mapstore_client/client/js/epics/gnresource.js

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ import {
3030
removeLinkedResourcesByPk,
3131
getDatasetTimeSettingsByPk,
3232
getResourceByTypeAndByPk,
33-
deleteResourceThumbnail
33+
deleteResourceThumbnail,
34+
updateResourceExtent
3435
} from '@js/api/geonode/v2';
3536
import { configureMap } from '@mapstore/framework/actions/config';
3637
import { isMapInfoOpen } from '@mapstore/framework/selectors/mapInfo';
@@ -67,7 +68,9 @@ import {
6768
REQUEST_RESOURCE,
6869
resourceLoading,
6970
resourceError,
70-
setSelectedLayer
71+
setSelectedLayer,
72+
UPDATE_RESOURCE_EXTENT,
73+
updateResourceExtentLoading
7174
} from '@js/actions/gnresource';
7275

7376
import {
@@ -81,6 +84,8 @@ import {
8184
resetDashboard
8285
} from '@mapstore/framework/actions/dashboard';
8386

87+
import { SAVE_SUCCESS } from '@mapstore/framework/actions/featuregrid';
88+
8489
import {
8590
setControlProperty,
8691
resetControls,
@@ -788,6 +793,48 @@ export const gnSelectResourceEpic = (action$, store) =>
788793
);
789794
});
790795

796+
export const gnUpdateResourceExtent = (action$, store) =>
797+
action$.ofType(UPDATE_RESOURCE_EXTENT, SAVE_SUCCESS)
798+
.switchMap((action) => {
799+
const state = store.getState();
800+
const currentResource = state.gnresource?.data || {};
801+
const shouldNotify = action.type === UPDATE_RESOURCE_EXTENT;
802+
return Observable.concat(
803+
Observable.of(updateResourceExtentLoading(true)),
804+
Observable.defer(() =>
805+
updateResourceExtent(currentResource?.pk)
806+
.then(() => getResourceByPk(currentResource?.pk))
807+
.then((updatedResource) => {
808+
const { extent } = updatedResource || {};
809+
return extent;
810+
})
811+
)
812+
.switchMap((extent) =>
813+
Observable.of(
814+
updateResourceExtentLoading(false),
815+
...(shouldNotify ? [successNotification({
816+
title: "gnviewer.updateBoundingBox",
817+
message: "gnviewer.updateBoundingBoxSuccess"
818+
})] : []),
819+
...(extent ? [
820+
updateResourceProperties({
821+
extent
822+
})
823+
] : [])
824+
)
825+
)
826+
.catch(() =>
827+
Observable.of(
828+
updateResourceExtentLoading(false),
829+
...(shouldNotify ? [errorNotification({
830+
title: "gnviewer.updateBoundingBox",
831+
message: "gnviewer.updateBoundingBoxError"
832+
})] : [])
833+
)
834+
)
835+
);
836+
});
837+
791838
export default {
792839
gnViewerRequestNewResourceConfig,
793840
gnViewerRequestResourceConfig,
@@ -798,5 +845,6 @@ export default {
798845
closeResourceDetailsOnMapInfoOpen,
799846
gnManageLinkedResource,
800847
gnZoomToFitBounds,
801-
gnSelectResourceEpic
848+
gnSelectResourceEpic,
849+
gnUpdateResourceExtent
802850
};

geonode_mapstore_client/client/js/plugins/ResourceDetails/components/DetailsLocations.jsx

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import CopyToClipboardCmp from 'react-copy-to-clipboard';
2525
import Button from "@mapstore/framework/components/layout/Button";
2626
import FlexBox from "@mapstore/framework/components/layout/FlexBox";
2727
import Text from "@mapstore/framework/components/layout/Text";
28+
import Spinner from "@mapstore/framework/components/layout/Spinner";
2829

2930
const Map = mapTypeHOC(BaseMap);
3031
Map.displayName = "Map";
@@ -160,8 +161,7 @@ const defaultInteractions = {
160161
pinchZoom: true
161162
};
162163

163-
const DetailsLocations = ({ onSetExtent, fields, editing: allowEditProp, resource } = {}) => {
164-
164+
const DetailsLocations = ({loadingUpdateResourceExtent, onSetExtent, onUpdateExtent, fields, editing: allowEditProp, resource } = {}) => {
165165
const extent = get(fields, 'extent.coords');
166166
const initialExtent = get(fields, 'initialExtent.coords');
167167

@@ -170,6 +170,7 @@ const DetailsLocations = ({ onSetExtent, fields, editing: allowEditProp, resourc
170170
const isDrawn = initialExtent !== undefined && !isEqual(initialExtent, extent);
171171

172172
const allowEdit = !!(onSetExtent && !['map', 'dataset'].includes(resource?.resource_type) && allowEditProp);
173+
const allowRecalcBbox = !!(onUpdateExtent && resource?.resource_type === 'dataset');
173174

174175
return (
175176
<div>
@@ -232,6 +233,19 @@ const DetailsLocations = ({ onSetExtent, fields, editing: allowEditProp, resourc
232233
</FlexBox.Fill>
233234
</FlexBox>
234235
{allowEdit && <Text fontSize="sm"><HTML msgId="gnviewer.mapExtentHelpText"/></Text>}
236+
{allowRecalcBbox && (
237+
<FlexBox centerChildrenVertically gap="lg" classNames={['_padding-b-md']}>
238+
<Button
239+
disabled={loadingUpdateResourceExtent}
240+
variant="primary"
241+
onClick={() => onUpdateExtent()}>
242+
<Message msgId="gnviewer.updateBoundingBox"/>
243+
</Button>
244+
{
245+
loadingUpdateResourceExtent ? <Spinner/> : null
246+
}
247+
</FlexBox>
248+
)}
235249
</div>
236250
);
237251
};

geonode_mapstore_client/client/js/plugins/ResourceDetails/containers/tabComponents.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,16 @@ import DetailsData from '../components/DetailsData';
1313
import DetailsLinkedResources from '../components/DetailsLinkedResources';
1414
import DetailsSettings from '../components/DetailsSettings';
1515
import DetailsShare from '../components/DetailsShare';
16-
import { setResourceExtent, updateResourceProperties } from '@js/actions/gnresource';
16+
import { setResourceExtent, updateResourceProperties, updateResourceExtent } from '@js/actions/gnresource';
1717
import { show } from '@mapstore/framework/actions/notifications';
18+
import { createSelector } from 'reselect';
1819

1920
const tabComponents = {
20-
'locations': connect(() => ({}), { onSetExtent: setResourceExtent })(DetailsLocations),
21+
'locations': connect( createSelector([
22+
state => state?.gnresource?.loadingUpdateResourceExtent,
23+
], (loadingUpdateResourceExtent) => ({
24+
loadingUpdateResourceExtent,
25+
})), { onSetExtent: setResourceExtent , onUpdateExtent: updateResourceExtent })(DetailsLocations),
2126
'relations': DetailsLinkedResources,
2227
'assets': connect(() => ({}), { onNotify: show, onChange: updateResourceProperties })(DetailsAssets),
2328
'data': connect(() => ({}), { onChange: updateResourceProperties })(DetailsData),

geonode_mapstore_client/client/js/reducers/gnresource.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ import {
3737
SET_DEFAULT_VIEWER_PLUGINS,
3838
SET_SELECTED_LAYER,
3939
UPDATE_LAYER_DATASET,
40-
SET_SELECTED_LAYER_DATASET
40+
SET_SELECTED_LAYER_DATASET,
41+
UPDATE_RESOURCE_EXTENT_LOADING
4142
} from '@js/actions/gnresource';
4243
import {
4344
cleanCompactPermissions,
@@ -178,6 +179,12 @@ function gnresource(state = defaultState, action) {
178179
};
179180
}
180181

182+
case UPDATE_RESOURCE_EXTENT_LOADING: {
183+
return {
184+
...state,
185+
loadingUpdateResourceExtent: action.loading
186+
};
187+
}
181188
case ENABLE_MAP_THUMBNAIL_VIEWER: {
182189
return {
183190
...state,

geonode_mapstore_client/static/mapstore/gn-translations/data.de-DE.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,10 @@
547547
"assetUploadUnsupportedFormatError": "Nicht unterstützter Dateityp(s) '{ext}', kann die Datei(en) nicht hochladen",
548548
"assetDelete": "Asset löschen",
549549
"assetDeleteErrorMessage": "Fehler beim Löschen des Assets",
550-
"noAssets": "Keine Assets gefunden"
550+
"noAssets": "Keine Assets gefunden",
551+
"updateBoundingBox": "Begrenzungsrahmen aktualisieren",
552+
"updateBoundingBoxSuccess": "Begrenzungsrahmen erfolgreich aktualisiert",
553+
"updateBoundingBoxError": "Fehler beim Aktualisieren des Begrenzungsrahmens"
551554
},
552555
"resourcesCatalog": {
553556
"anonymous": "Jeder",

geonode_mapstore_client/static/mapstore/gn-translations/data.en-US.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,10 @@
547547
"assetUploadUnsupportedFormatError": "Unsupported file format(s) '{ext}', cannot upload the file(s)",
548548
"assetDelete": "Asset delete",
549549
"assetDeleteErrorMessage": "Failed to delete asset",
550-
"noAssets": "No assets found"
550+
"noAssets": "No assets found",
551+
"updateBoundingBox": "Update bounding box",
552+
"updateBoundingBoxSuccess": "Bounding box updated successfully",
553+
"updateBoundingBoxError": "Error updating bounding box"
551554
},
552555
"resourcesCatalog": {
553556
"anonymous": "Anyone",

geonode_mapstore_client/static/mapstore/gn-translations/data.es-ES.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,10 @@
546546
"assetUploadUnsupportedFormatError": "Tipo de archivo no admitido(s) '{ext}', no se puede cargar el archivo(s)",
547547
"assetDelete": "Eliminar Asset",
548548
"assetDeleteErrorMessage": "Error al eliminar el Asset",
549-
"noAssets": "No se encontraron assets"
549+
"noAssets": "No se encontraron assets",
550+
"updateBoundingBox": "Actualizar caja delimitadora",
551+
"updateBoundingBoxSuccess": "Caja delimitadora actualizada con éxito",
552+
"updateBoundingBoxError": "Error al actualizar la caja delimitadora"
550553
},
551554
"resourcesCatalog": {
552555
"anonymous": "Cualquiera",

0 commit comments

Comments
 (0)