From c01882f8677a9d02681df3446d7d28df1fe7727f Mon Sep 17 00:00:00 2001 From: mahmoud adel <58145645+mahmoudadel54@users.noreply.github.com> Date: Wed, 6 Nov 2024 13:35:46 +0200 Subject: [PATCH] [Backport 2024.02.xx] - #10648: Issue editing multiple fields in MapStore Attribute Table (#10651) (#10653) * #10648: Issue editing multiple fields in MapStore Attribute Table (#10651) * #10648: Issue editing multiple fields in MapStore Attribute Table Description: - edit in update wfs-t xml payload in case of multi-edit in each sigle row - add unit test for 'savePendingFeatureGridChanges' * #10648: move 'createChangesTransaction' util function from epics/featuregrid to FeatureGridUtils file and a unit test is added for it. * #10648: handle unit test for 'savePendingFeatureGridChanges' * #10648: edit jsdoc for util 'createChangesTransaction' * #10648: fix FE test failure for - Issue editing multiple fields in MapStore Attribute Table (#10654) * #10648: fix FE tests failure for savePendingFeatureGridChanges * #10648: remove unit test of 'savePendingFeatureGridChanges' --- web/client/epics/featuregrid.js | 12 +--- web/client/utils/FeatureGridUtils.js | 15 +++++ .../utils/__tests__/FeatureGridUtils-test.js | 57 ++++++++++++++++++- 3 files changed, 72 insertions(+), 12 deletions(-) diff --git a/web/client/epics/featuregrid.js b/web/client/epics/featuregrid.js index 16b9a27a94..a8738f19f9 100644 --- a/web/client/epics/featuregrid.js +++ b/web/client/epics/featuregrid.js @@ -11,8 +11,7 @@ import {get, head, isEmpty, find, castArray, includes, reduce} from 'lodash'; import { LOCATION_CHANGE } from 'connected-react-router'; import axios from '../libs/ajax'; import bbox from '@turf/bbox'; -import { fidFilter } from '../utils/ogc/Filter/filter'; -import { getDefaultFeatureProjection, getPagesToLoad, gridUpdateToQueryUpdate, updatePages } from '../utils/FeatureGridUtils'; +import { createChangesTransaction, getDefaultFeatureProjection, getPagesToLoad, gridUpdateToQueryUpdate, updatePages } from '../utils/FeatureGridUtils'; import assign from 'object-assign'; import { @@ -232,15 +231,6 @@ const addPagination = (filterObj, pagination) => ({ pagination }); -const createChangesTransaction = (changes, newFeatures, {insert, update, propertyChange, getPropertyName, transaction})=> - transaction( - newFeatures.map(f => insert(f)), - Object.keys(changes).map( id => - Object.keys(changes[id]).map(name => - update([propertyChange(getPropertyName(name), changes[id][name]), fidFilter("ogc", id)]) - ) - ) - ); const createDeleteTransaction = (features, {transaction, deleteFeature}) => transaction( features.map(deleteFeature) ); diff --git a/web/client/utils/FeatureGridUtils.js b/web/client/utils/FeatureGridUtils.js index b5406acd93..b35c34341f 100644 --- a/web/client/utils/FeatureGridUtils.js +++ b/web/client/utils/FeatureGridUtils.js @@ -18,6 +18,7 @@ import { } from './ogc/WFS/base'; import { applyDefaultToLocalizedString } from '../components/I18N/LocalizedString'; +import { fidFilter } from './ogc/Filter/filter'; const getGeometryName = (describe) => get(findGeometryProperty(describe), "name"); const getPropertyName = (name, describe) => name === "geometry" ? getGeometryName(describe) : name; @@ -392,3 +393,17 @@ export const supportsFeatureEditing = (layer) => includes(supportedEditLayerType * @returns {boolean} flag */ export const areLayerFeaturesEditable = (layer) => !layer?.disableFeaturesEditing && supportsFeatureEditing(layer); +/** + * Create wfs-t xml payload for insert/edit features in featuregrid + * @param {object} changes object that contains updates e.g: {LAYER_NAME.id: {"FIELD1": 55, "FIELD2":"edit 02"}} + * @param {object[]} newFeatures array of new inserted features + * @param {object} wfsutils object of wfs utils that includes insert/update/propertyChange/getPropertyName/transaction + * @returns {string} wfs-transaction xml payload + */ +export const createChangesTransaction = (changes, newFeatures, {insert, update, propertyChange, getPropertyName: getPropertyNameFunc, transaction})=> + transaction( + newFeatures.map(f => insert(f)), + Object.keys(changes).map( id =>{ + return update(Object.keys(changes[id]).map(prop => propertyChange(getPropertyNameFunc(prop), changes[id][prop])), fidFilter("ogc", id)); + }) + ); diff --git a/web/client/utils/__tests__/FeatureGridUtils-test.js b/web/client/utils/__tests__/FeatureGridUtils-test.js index 53f140dcd3..5609f2b76d 100644 --- a/web/client/utils/__tests__/FeatureGridUtils-test.js +++ b/web/client/utils/__tests__/FeatureGridUtils-test.js @@ -16,8 +16,10 @@ import { getAttributesNames, featureTypeToGridColumns, supportsFeatureEditing, - areLayerFeaturesEditable + areLayerFeaturesEditable, + createChangesTransaction } from '../FeatureGridUtils'; +import requestBuilder from "../ogc/WFST/RequestBuilder"; describe('FeatureGridUtils', () => { @@ -447,4 +449,57 @@ describe('FeatureGridUtils', () => { expect(areLayerFeaturesEditable({type: "wmts"})).toBeFalsy(); }); }); + describe('test featuregrid transactions utils', ()=>{ + const describeFeatureType = { + "elementFormDefault": "qualified", + "targetNamespace": "http://localhost:8080/geoserver/mapstore", + "targetPrefix": "mapstore", + "featureTypes": [ + { + "typeName": "TEST_LAYER", + "properties": [ + { + "name": "Integer", + "maxOccurs": 1, + "minOccurs": 0, + "nillable": true, + "type": "xsd:int", + "localType": "int" + }, + { + "name": "Long", + "maxOccurs": 1, + "minOccurs": 0, + "nillable": true, + "type": "xsd:int", + "localType": "int" + }, + { + "name": "Point", + "maxOccurs": 1, + "minOccurs": 0, + "nillable": true, + "type": "gml:Point", + "localType": "Point" + } + ] + } + ] + + }; + it('test createChangesTransaction for single edit', (done) => { + const singleChanges = {"TEST_LAYER.13": { "Integer": 50}}; + const transactionPayload = createChangesTransaction(singleChanges, [], requestBuilder(describeFeatureType)); + const samplePayload = `Integer50`; + expect(transactionPayload).toEqual(samplePayload); + done(); + }); + it('test createChangesTransaction for multi-edit', (done) => { + const multiChanges = {"TEST_LAYER.13": { "Integer": 50, "Long": 55 }}; + const transactionPayload = createChangesTransaction(multiChanges, [], requestBuilder(describeFeatureType)); + const multieditPayload = `Integer50,Long55`; + expect(transactionPayload).toEqual(multieditPayload); + done(); + }); + }); });