From 330a7669a0e80b403463a6e200d7eb6b860dd7e3 Mon Sep 17 00:00:00 2001 From: Suren Date: Fri, 31 Oct 2025 13:36:01 +0530 Subject: [PATCH 1/2] #1893 - Fix: Changing settings of a 3D Tiles resource throws an error --- .../client/js/api/geonode/v2/index.js | 10 ++++++++-- geonode_mapstore_client/client/js/epics/gnsave.js | 14 ++++++++------ .../client/js/selectors/resource.js | 6 +++++- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/geonode_mapstore_client/client/js/api/geonode/v2/index.js b/geonode_mapstore_client/client/js/api/geonode/v2/index.js index 80828435f7..37ea19f15a 100644 --- a/geonode_mapstore_client/client/js/api/geonode/v2/index.js +++ b/geonode_mapstore_client/client/js/api/geonode/v2/index.js @@ -374,6 +374,11 @@ export const updateDataset = (pk, body) => { .then(({ data }) => (data.dataset)); }; +export const updateResource = (pk, body) => { + return axios.patch(getEndpointUrl(RESOURCES, `/${pk}`), body) + .then(({ data }) => (data.resource)); +}; + export const updateDocument = (pk, body) => { return axios.patch(getEndpointUrl(DOCUMENTS, `/${pk}`), body) .then(({ data }) => data.document); @@ -731,7 +736,7 @@ export const createDataset = (body) => { export const getMetadataDownloadLinkByPk = (pk) => { return getEndpointUrl(RESOURCES, `/${pk}/iso_metadata_xml`); -} +}; export default { getEndpoints, @@ -771,5 +776,6 @@ export default { deleteExecutionRequest, getResourceByTypeAndByPk, createDataset, - getMetadataDownloadLinkByPk + getMetadataDownloadLinkByPk, + updateResource }; diff --git a/geonode_mapstore_client/client/js/epics/gnsave.js b/geonode_mapstore_client/client/js/epics/gnsave.js index 8c8399a784..84595f1cde 100644 --- a/geonode_mapstore_client/client/js/epics/gnsave.js +++ b/geonode_mapstore_client/client/js/epics/gnsave.js @@ -51,7 +51,9 @@ import { updateDocument, setMapThumbnail, updateCompactPermissionsByPk, - getResourceByUuid + getResourceByUuid, + updateDatasetTimeSeries, + updateResource as updateResourceAPI } from '@js/api/geonode/v2'; import { parseDevHostname } from '@js/utils/APIUtils'; import uuid from 'uuid'; @@ -79,13 +81,13 @@ import { cleanCompactPermissions, toGeoNodeMapConfig, RESOURCE_MANAGEMENT_PROPERTIES, - getDimensions + getDimensions, + isDefaultDatasetSubtype } from '@js/utils/ResourceUtils'; import { ProcessTypes, ProcessStatus } from '@js/utils/ResourceServiceUtils'; -import { updateDatasetTimeSeries } from '@js/api/geonode/v2/index'; import { updateNode, updateSettingsParams } from '@mapstore/framework/actions/layers'; import { layersSelector, getSelectedLayer as getSelectedNode } from '@mapstore/framework/selectors/layers'; import { styleServiceSelector, getUpdatedLayer, selectedStyleSelector } from '@mapstore/framework/selectors/styleeditor'; @@ -170,11 +172,11 @@ const SaveAPI = { ...(timeseries && { has_time: timeseries?.has_time }) }; const { request, actions } = setDefaultStyle(state, id); // set default style, if modified - + const requestDataset = !isDefaultDatasetSubtype(currentResource?.subtype) ? updateResourceAPI : updateDataset; return request().then(() => (id // perform dataset and timeseries updates sequentially to avoid race conditions - ? updateDataset(id, updatedBody).then((resource) => - updateDatasetTimeSeries(id, timeseries).then(() => resource) + ? requestDataset(id, updatedBody).then((resource) => + timeseries ? updateDatasetTimeSeries(id, timeseries).then(() => resource) : Promise.resolve(resource) ) : Promise.resolve()) .then((_resource) => { let resource = omit(_resource, 'default_style'); diff --git a/geonode_mapstore_client/client/js/selectors/resource.js b/geonode_mapstore_client/client/js/selectors/resource.js index 114c0509f9..f19f719c2f 100644 --- a/geonode_mapstore_client/client/js/selectors/resource.js +++ b/geonode_mapstore_client/client/js/selectors/resource.js @@ -313,7 +313,11 @@ function isResourceDataEqual(state, initialData = {}, currentData = {}) { omit(initialLayerData, ['style', 'fields', 'extendedParams', 'pk', '_v_', 'isDataset', 'perms'])); const isStyleEqual = isEmpty(selectedLayer?.availableStyles) || isEmpty(selectedLayer?.style) ? true : selectedLayer?.style === selectedLayer?.availableStyles?.[0]?.name; - const isAttributesEqual = isEmpty(selectedLayer) ? true : !isEmpty(initialLayerData) && isEqual(initialLayerData?.fields, selectedLayer.fields); + const isAttributesEqual = isEmpty(selectedLayer) ? true + : !isEmpty(initialLayerData) && isEqual( + isEmpty(initialLayerData?.fields) ? {} : initialLayerData?.fields, + isEmpty(selectedLayer?.fields) ? {} : selectedLayer?.fields + ); return isSettingsEqual && isAttributesEqual && isStyleEqual; } From 463df2f5f8efc20b1c3e7feb01603cf27ef5731f Mon Sep 17 00:00:00 2001 From: Suren Date: Fri, 31 Oct 2025 14:22:08 +0530 Subject: [PATCH 2/2] code refactor --- .../client/js/epics/gnsave.js | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/geonode_mapstore_client/client/js/epics/gnsave.js b/geonode_mapstore_client/client/js/epics/gnsave.js index 84595f1cde..471c1ff17b 100644 --- a/geonode_mapstore_client/client/js/epics/gnsave.js +++ b/geonode_mapstore_client/client/js/epics/gnsave.js @@ -172,21 +172,23 @@ const SaveAPI = { ...(timeseries && { has_time: timeseries?.has_time }) }; const { request, actions } = setDefaultStyle(state, id); // set default style, if modified - const requestDataset = !isDefaultDatasetSubtype(currentResource?.subtype) ? updateResourceAPI : updateDataset; - return request().then(() => (id + return request().then(() => { + const patchResource = !isDefaultDatasetSubtype(currentResource?.subtype) ? updateResourceAPI : updateDataset; + return (id // perform dataset and timeseries updates sequentially to avoid race conditions - ? requestDataset(id, updatedBody).then((resource) => - timeseries ? updateDatasetTimeSeries(id, timeseries).then(() => resource) : Promise.resolve(resource) - ) : Promise.resolve()) - .then((_resource) => { - let resource = omit(_resource, 'default_style'); - if (timeseries) { - const layerId = layersSelector(state)?.find((l) => l.pk === resource?.pk)?.id; - // actions to be dispacted are added to response array - return [resource, updateNode(layerId, 'layers', { dimensions: get(resource, 'data.dimensions', []) }), ...actions]; - } - return [resource, ...actions]; - })); + ? patchResource(id, updatedBody).then((resource) => + timeseries ? updateDatasetTimeSeries(id, timeseries).then(() => resource) : Promise.resolve(resource) + ) : Promise.resolve()) + .then((_resource) => { + let resource = omit(_resource, 'default_style'); + if (timeseries) { + const layerId = layersSelector(state)?.find((l) => l.pk === resource?.pk)?.id; + // actions to be dispacted are added to response array + return [resource, updateNode(layerId, 'layers', { dimensions: get(resource, 'data.dimensions', []) }), ...actions]; + } + return [resource, ...actions]; + }); + }); }, [ResourceTypes.VIEWER]: (state, id, body) => { const user = userSelector(state);