From 3cc12d6d42279d7d3b374e868c82979ba966d920 Mon Sep 17 00:00:00 2001 From: volterra79 Date: Fri, 22 Nov 2024 17:29:51 +0100 Subject: [PATCH 01/21] :sparkles: Start to develop edit multi relation feature from multi parent feature layer --- icons/EditMultiRelationFeatures.png | Bin 0 -> 999 bytes toolboxes/toolbox.js | 57 ++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 icons/EditMultiRelationFeatures.png diff --git a/icons/EditMultiRelationFeatures.png b/icons/EditMultiRelationFeatures.png new file mode 100644 index 0000000000000000000000000000000000000000..d521c4ab900f39c349fb558c2d6e584f1e567e70 GIT binary patch literal 999 zcmV`=k4}3#OFEh)9PA(KOA_b-nB4@zXtC?7t>lT2|-bpN{H6 zh`a|xWS^Z!I{iK{m>M_(VEIrY(uEMXk?h07L>g70DkS0^P)ecq>SfH%&f3OnYSv=Q zcXc2|f#m`LfafmS;~jQ1N+|%qfgca$MF{|tlaqdUb5J5;J(vDm(jbkokS{1>jE?;L z3oDGMa4vJYOeTY&)W8Q{PykR$EeLe#zu5A1-?!8jI(zYS@HqhT4857`!%TJtRiP@h zwnSlB7LvDbz%b?usitNPYBz3%VOkZ6^h^1!Xj3AQ5XofH@(kUxyWNf`S4eS(E*J6C z)D(gNo__i4-nULi-)w0!7K6ET=W2>uJayqAEGLz6WW&ptN-RHV2OP*IsuC8`_|H`yTDOvB;%SZW% zu2Y==I=uj0jzNNRj)%kl;`N(X2n2#Sxc?AzUB{ifw=h0FX4{sPm7zVp4@9K%1$=sz zhHxXo6v^9MqK?&2xas(UN-0Cvu3uT|Fy;%&IsXug#%s#U%RO}{BEsK&z2rN+N~tAn zqkzx!=Ac8V`*{2AKLmq8B=&TGF@~Yk0MZj_+it~*GPJcs{X`GJ=mE=RX=t zN=gt3H~WWb8Z!)I7C+Q&bES7{UA?PAnWhN features.length < 2, + done: () => { Workflow.Stack.getCurrent().clearUserMessagesSteps(); } + }, + dynamic: 0, + done: false + } + } + }), + new Step({ run: async (inputs, context) => { + const relations = Array.from( + new Set( + (await Promise.allSettled(inputs.features.map(feature => { + return getLayersDependencyFeatures(inputs.layer.getId(), { + // @since g3w-client-plugin-editin@v3.7.0 + relations: inputs.layer.getRelations().getArray().filter(r => + inputs.layer.getId() === r.getFather() && // get only child relation features of current editing layer + getEditingLayerById(r.getChild()) && // child layer is in editing + 'ONE' !== r.getType() // exclude ONE relation (Join 1:1) + ), + feature, + filterType: 'fid', + }); + }))).filter(({status }) => 'fulfilled' === status).map(({ value }) => value).flat() + ) + ); + //In case of multi relation in editing + if (relations.length > 1) { + alert('Choose relations') + } + + return $promisify(Promise.resolve(inputs, context)); + }}), + new OpenFormStep({ multi: true }), + ], + }), + }, // Move Feature (is_vector) && capabilities.includes('change_feature') && { id: 'movefeature', From f60d8c589b9de3fbd22b2f88d777f515da789ba6 Mon Sep 17 00:00:00 2001 From: volterra79 Date: Mon, 25 Nov 2024 12:19:31 +0100 Subject: [PATCH 02/21] :sparkles: Start to develop edit multi relation feature from multi parent feature layer --- components/Toolbox.vue | 2 +- components/UserMessage.vue | 1 + toolboxes/toolbox.js | 116 +++++++++++++++++++++++-------------- workflows/index.js | 6 +- 4 files changed, 79 insertions(+), 46 deletions(-) diff --git a/components/Toolbox.vue b/components/Toolbox.vue index 5e1fd24b..2f1441e9 100644 --- a/components/Toolbox.vue +++ b/components/Toolbox.vue @@ -98,7 +98,7 @@ diff --git a/components/UserMessage.vue b/components/UserMessage.vue index 65c8e88f..ef14f92c 100644 --- a/components/UserMessage.vue +++ b/components/UserMessage.vue @@ -24,6 +24,7 @@ diff --git a/toolboxes/toolbox.js b/toolboxes/toolbox.js index ebc190bf..bd8754ab 100644 --- a/toolboxes/toolbox.js +++ b/toolboxes/toolbox.js @@ -80,15 +80,21 @@ export class ToolBox extends G3WObject { constructor(layer, dependencies = []) { super(); - const is_vector = [undefined, Layer.LayerTypes.VECTOR].includes(layer.getType()); - const geometryType = is_vector && layer.getGeometryType(); - const is_point = is_vector && Geometry.isPointGeometryType(geometryType); - const is_line = is_vector && Geometry.isLineGeometryType(geometryType); - const is_poly = is_vector && Geometry.isPolygonGeometryType(geometryType); - const is_table = Layer.LayerTypes.TABLE === layer.getType(); - const isMultiGeometry = geometryType && Geometry.isMultiGeometry(geometryType); - const iconGeometry = is_vector && (is_point ? 'Point' : is_line ? 'Line' : 'Polygon'); - + const is_vector = [undefined, Layer.LayerTypes.VECTOR].includes(layer.getType()); + const geometryType = is_vector && layer.getGeometryType(); + const is_point = is_vector && Geometry.isPointGeometryType(geometryType); + const is_line = is_vector && Geometry.isLineGeometryType(geometryType); + const is_poly = is_vector && Geometry.isPolygonGeometryType(geometryType); + const is_table = Layer.LayerTypes.TABLE === layer.getType(); + const isMultiGeometry = geometryType && Geometry.isMultiGeometry(geometryType); + const iconGeometry = is_vector && (is_point ? 'Point' : is_line ? 'Line' : 'Polygon'); + //@since 3.9.0 Check if layer has relation layers editable + const editable_relations = layer.getRelations().getArray() + .filter(relation => { + const l = CatalogLayersStoresRegistry.getLayerById(getRelationId({ layerId: layer.getId(), relation })); + return l.isEditable() && l.config.editing.visible; + }) + .map(r => r); this._start = false; /** constraint loading features to a filter set */ @@ -103,7 +109,7 @@ export class ToolBox extends G3WObject { * _states: [ * { * id: unique key - * state: [state] // example: history contsins features state + * state: [state] // example: history contains features state * // array because a tool can apply changes to more than one features at time (split di una feature) * }, * { @@ -409,7 +415,7 @@ export class ToolBox extends G3WObject { }), }, // @since 3.9.0 Edit Attributes of relations features to Multi features - (is_vector) && capabilities.includes('change_attr_feature') && { + (is_vector) && capabilities.includes('change_attr_feature') && editable_relations.filter(r => 'ONE' !== r.getType()).length > 0 && { id: 'editmultiattributesrelationfeatures', type: ['change_attr_feature'], name: "editing.tools.update_multi_features", @@ -429,39 +435,65 @@ export class ToolBox extends G3WObject { description: `editing.workflow.steps.${ApplicationState.ismobile ? 'selectDrawBoxAtLeast2Feature' : 'selectMultiPointSHIFTAtLeast2Feature'}`, buttonnext: { disabled: true, - condition:({ features=[] }) => features.length < 2, - done: () => { Workflow.Stack.getCurrent().clearUserMessagesSteps(); } + condition: ({ features = [] }) => features.length < 2, + done: () => { Workflow.Stack.getCurrent().clearUserMessagesSteps(); } }, dynamic: 0, - done: false + done: false } } }), new Step({ run: async (inputs, context) => { - const relations = Array.from( - new Set( - (await Promise.allSettled(inputs.features.map(feature => { - return getLayersDependencyFeatures(inputs.layer.getId(), { - // @since g3w-client-plugin-editin@v3.7.0 - relations: inputs.layer.getRelations().getArray().filter(r => - inputs.layer.getId() === r.getFather() && // get only child relation features of current editing layer - getEditingLayerById(r.getChild()) && // child layer is in editing - 'ONE' !== r.getType() // exclude ONE relation (Join 1:1) - ), - feature, - filterType: 'fid', - }); - }))).filter(({status }) => 'fulfilled' === status).map(({ value }) => value).flat() - ) - ); + GUI.setModal(true); + const relations = editable_relations.filter(r => 'ONE' !== r.getType()); + //get relation features from feature parent layer + await Promise.allSettled(inputs.features.map(feature => getLayersDependencyFeatures(inputs.layer.getId(), { + relations, + feature, + filterType: 'fid', + }))) + //In case of multi relation in editing if (relations.length > 1) { alert('Choose relations') } + //start child workflow + const workflow = new Workflow({ + type: 'editmultiattributes', + steps: [ + new OpenFormStep({ multi: true }), + ], + }); + //Relations layer + const rLayer = getEditingLayerById(relations[0].getChild()); + + const fields = getRelationFieldsFromRelation({ + layerId: relations[0].getChild(), + relation: relations[0] + }); + + const options = { + context: { + session: Workflow.Stack.getCurrent().getSession(), // get parent workflow + excludeFields: fields.ownField, // array of fields to be excluded + }, + inputs: { + features: rLayer.readFeatures(), + layer: rLayer + } + }; + try { + await promisify(workflow.start(options)); + } catch(e) { + console.warn(e); + } + + workflow.stop(); + + GUI.setModal(false); return $promisify(Promise.resolve(inputs, context)); }}), - new OpenFormStep({ multi: true }), ], }), }, @@ -1254,7 +1286,7 @@ export class ToolBox extends G3WObject { this.state._tools.forEach(tool => { Object.assign(tool, { disabledtoolsoftools: [], - enabled: false, + enabled: !!tool.enabled, active: false, message: null, messages: tool.op.getMessages(), @@ -1828,7 +1860,7 @@ export class ToolBox extends G3WObject { * * @param bool */ - setEditing(bool=true) { + setEditing(bool = true) { this.setEnable(bool); this.state.editing.on = bool; this.enableTools(bool); @@ -1853,7 +1885,7 @@ export class ToolBox extends G3WObject { * * @returns {boolean} */ - setEnable(bool=false) { + setEnable(bool = false) { this.state.enabled = bool; return this.state.enabled; } @@ -2056,9 +2088,9 @@ export class ToolBox extends G3WObject { const disabledtools = this.state._disabledtools || []; tools .forEach(tool => { - const enabled = undefined !== tool.enable ? tool.enable : bool; - tool.enabled = (bool && disabledtools.length) - ? disabledtools.indexOf(tool.getId()) === -1 + const enabled = undefined === tool.enable ? bool : tool.enable; + tool.enabled = (bool && disabledtools.length > 0) + ? !disabledtools.includes(tool.getId()) : toRawType(enabled) === 'Boolean' ? enabled : enabled({ bool, tool }); @@ -2823,11 +2855,11 @@ export class ToolBox extends G3WObject { if ((Layer.LayerTypes.VECTOR === this.state._layerType) && this.state._getFeaturesOption.filter.bbox) { const fnc = () => { if ( - //added ApplicationState.online - ApplicationState.online - && this.state.editing.canEdit - && this.state.selected //need to be selected - && 0 === GUI.getContentLength() + //added ApplicationState.online + ApplicationState.online + && this.state.editing.canEdit + && this.state.selected //need to be selected + && 0 === GUI.getContentLength() ) { this.state._getFeaturesOption.filter.bbox = GUI.getService('map').getMapBBOX(); this.state.loading = true; diff --git a/workflows/index.js b/workflows/index.js index 2ebb81b3..a281dbc8 100644 --- a/workflows/index.js +++ b/workflows/index.js @@ -479,7 +479,7 @@ export class OpenFormStep extends Step { formStructure: inputs.layer.hasFormStructure() && inputs.layer.getLayerEditingFormStructure() || undefined, modal: true, push: this._options.push || this._isContentChild, /** @since v3.7 force push content on top without clear previous content */ - showgoback: undefined !== this._options.showgoback ? this._options.showgoback : !this._isContentChild, /** @since v3.7 force show back button */ + showgoback: undefined === this._options.showgoback ? !this._isContentChild : this._options.showgoback, /** @since v3.7 force show back button */ /** @TODO make it straightforward: `headerComponent` vs `buttons` ? */ headerComponent: this._saveAll && { template: /* html */ ` @@ -775,8 +775,8 @@ export class OpenFormStep extends Step { if (contextService && false === this._isContentChild) { contextService.setUpdate(false, { force: false }); } - - GUI.closeForm({ pop: this.push || this._isContentChild }); + //@since 3.9.0 add GUI.getContentLength() in case of edit multi relationfeatures tool + GUI.closeForm({ pop: this.push || this._isContentChild && GUI.getContentLength() > 1 }); g3wsdk.core.plugin.PluginsRegistry.getPlugin('editing').resetCurrentLayout(); From 14406e18226591f8cf12ec8f7204a1f308471eed Mon Sep 17 00:00:00 2001 From: volterra79 Date: Mon, 25 Nov 2024 14:21:48 +0100 Subject: [PATCH 03/21] :sparkles: Add reset method step --- toolboxes/toolbox.js | 10 ++++++---- workflows/index.js | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/toolboxes/toolbox.js b/toolboxes/toolbox.js index bd8754ab..744ec738 100644 --- a/toolboxes/toolbox.js +++ b/toolboxes/toolbox.js @@ -402,11 +402,12 @@ export class ToolBox extends G3WObject { description: `editing.workflow.steps.${ApplicationState.ismobile ? 'selectDrawBoxAtLeast2Feature' : 'selectMultiPointSHIFTAtLeast2Feature'}`, buttonnext: { disabled: true, - condition:({ features=[] }) => features.length < 2, - done: () => { Workflow.Stack.getCurrent().clearUserMessagesSteps(); } + condition:({ features = [] }) => features.length < 2, + done: () => { Workflow.Stack.getCurrent().clearUserMessagesSteps(); }, }, dynamic: 0, - done: false + done: false, + reset() { this.dynamic = 0; }, } } }), @@ -439,7 +440,8 @@ export class ToolBox extends G3WObject { done: () => { Workflow.Stack.getCurrent().clearUserMessagesSteps(); } }, dynamic: 0, - done: false + done: false, + reset() { this.dynamic = 0; }, } } }), diff --git a/workflows/index.js b/workflows/index.js index a281dbc8..9f96a2f8 100644 --- a/workflows/index.js +++ b/workflows/index.js @@ -1092,6 +1092,7 @@ export class SelectElementsStep extends Step { } stop() { + Object.values(this.getSteps() || {}).forEach(s => s.reset && s.reset() ); this._selectInteractions.forEach(i => this.removeInteraction(i)); if (this._vectorLayer) { From d695f3f8be9eedfc6149553eeb71091f89237aae Mon Sep 17 00:00:00 2001 From: volterra79 Date: Mon, 25 Nov 2024 15:50:05 +0100 Subject: [PATCH 04/21] Clean code - spaces --- g3wsdk/workflow/workflow.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/g3wsdk/workflow/workflow.js b/g3wsdk/workflow/workflow.js index 32e5a525..bd4a9c21 100644 --- a/g3wsdk/workflow/workflow.js +++ b/g3wsdk/workflow/workflow.js @@ -368,10 +368,10 @@ export class Workflow extends G3WObject { if (showUserMessage) { GUI.showUserMessage({ - title: 'plugins.editing.workflow.title.steps', - type: 'tool', + title: 'plugins.editing.workflow.title.steps', + type: 'tool', position: 'left', - size: 'small', + size: 'small', closable: false, hooks: { body: { From 1286a0c0c12d4e00f9285f35c4756475bf7dd1cd Mon Sep 17 00:00:00 2001 From: volterra79 Date: Mon, 25 Nov 2024 15:55:09 +0100 Subject: [PATCH 05/21] :bug: Add user message to copy paste from other layer --- toolboxes/toolbox.js | 55 ++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/toolboxes/toolbox.js b/toolboxes/toolbox.js index 744ec738..5253cfe7 100644 --- a/toolboxes/toolbox.js +++ b/toolboxes/toolbox.js @@ -580,7 +580,6 @@ export class ToolBox extends G3WObject { steps: [ new Step({ layer, - help: 'editing.steps.help.draw_new_feature', run(inputs, context) { return $promisify(new Promise((resolve, reject) => { const originalLayer = inputs.layer; @@ -610,35 +609,42 @@ export class ToolBox extends G3WObject { className: 'btn-success', callback: async () => { try { + const feature = await $promisify(async () => { + GUI.showUserMessage({ + type: 'tool', + message: 'plugins.editing.workflow.steps.selectPoint', + size: 'small', + autoclose: false, + closable: false + }); //get selected layer const layer = layers.find(l => l.selected); - const feature = await $promisify(async () => { const features = await (new Promise(async resolve => { this.addInteraction( layer.external - ? new PickFeaturesInteraction({ layer: GUI.getService('map').getLayerById(layer.id) }) - : new g3wsdk.ol.interactions.PickCoordinatesInteraction(), { - 'picked': async e => { - try { - resolve(convertToGeometry( - layer.external - ? e.features // external layer - : ((await DataRouterService.getData('query:coordinates', { // TOC/PROJECT layer - inputs: { - coordinates: e.coordinate, - query_point_tolerance: ProjectsRegistry.getCurrentProject().getQueryPointTolerance(), - layerIds: [layer.id], - multilayers: false - }, - outputs: null - })).data[0] || { features: [] }).features, - geometryType, - )) - } catch(e) { - console.warn(e); - } + ? new PickFeaturesInteraction({ layer: GUI.getService('map').getLayerById(layer.id) }) + : new g3wsdk.ol.interactions.PickCoordinatesInteraction(), { + 'picked': async e => { + try { + resolve(convertToGeometry( + layer.external + ? e.features // external layer + : ((await DataRouterService.getData('query:coordinates', { // TOC/PROJECT layer + inputs: { + coordinates: e.coordinate, + query_point_tolerance: ProjectsRegistry.getCurrentProject().getQueryPointTolerance(), + layerIds: [layer.id], + multilayers: false + }, + outputs: null + })).data[0] || { features: [] }).features, + geometryType, + )) + } catch(e) { + console.warn(e); } } + } ); })); @@ -703,6 +709,9 @@ export class ToolBox extends G3WObject { //hide user message step })); }, + stop() { + GUI.closeUserMessage(); + } }), openFormStep, ], From d2f36cbe8480af04ae4f44d55aa67d2d1f0ce6bd Mon Sep 17 00:00:00 2001 From: volterra79 Date: Tue, 26 Nov 2024 08:54:27 +0100 Subject: [PATCH 06/21] Clean code - spaces --- toolboxes/toolbox.js | 96 ++++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 47 deletions(-) diff --git a/toolboxes/toolbox.js b/toolboxes/toolbox.js index 5253cfe7..2e0a89bb 100644 --- a/toolboxes/toolbox.js +++ b/toolboxes/toolbox.js @@ -445,57 +445,59 @@ export class ToolBox extends G3WObject { } } }), - new Step({ run: async (inputs, context) => { - GUI.setModal(true); - const relations = editable_relations.filter(r => 'ONE' !== r.getType()); - //get relation features from feature parent layer - await Promise.allSettled(inputs.features.map(feature => getLayersDependencyFeatures(inputs.layer.getId(), { - relations, - feature, - filterType: 'fid', - }))) - - //In case of multi relation in editing - if (relations.length > 1) { - alert('Choose relations') - } - //start child workflow - const workflow = new Workflow({ - type: 'editmultiattributes', - steps: [ - new OpenFormStep({ multi: true }), - ], - }); - //Relations layer - const rLayer = getEditingLayerById(relations[0].getChild()); - - const fields = getRelationFieldsFromRelation({ - layerId: relations[0].getChild(), - relation: relations[0] - }); - - const options = { - context: { - session: Workflow.Stack.getCurrent().getSession(), // get parent workflow - excludeFields: fields.ownField, // array of fields to be excluded - }, - inputs: { - features: rLayer.readFeatures(), - layer: rLayer + new Step({ + run: async (inputs, context) => { + GUI.setModal(true); + const relations = editable_relations.filter(r => 'ONE' !== r.getType()); + //get relation features from feature parent layer + await Promise.allSettled(inputs.features.map(feature => getLayersDependencyFeatures(inputs.layer.getId(), { + relations, + feature, + filterType: 'fid', + }))) + + //In case of multi relation in editing + if (relations.length > 1) { + alert('Choose relations') } - }; + //start child workflow + const workflow = new Workflow({ + type: 'editmultiattributes', + steps: [ + new OpenFormStep({ multi: true }), + ], + }); + //Relations layer + const rLayer = getEditingLayerById(relations[0].getChild()); - try { - await promisify(workflow.start(options)); - } catch(e) { - console.warn(e); - } + const fields = getRelationFieldsFromRelation({ + layerId: relations[0].getChild(), + relation: relations[0] + }); + + const options = { + context: { + session: Workflow.Stack.getCurrent().getSession(), // get parent workflow + excludeFields: fields.ownField, // array of fields to be excluded + }, + inputs: { + features: rLayer.readFeatures(), + layer: rLayer + } + }; + + try { + await promisify(workflow.start(options)); + } catch(e) { + console.warn(e); + } - workflow.stop(); + workflow.stop(); - GUI.setModal(false); - return $promisify(Promise.resolve(inputs, context)); - }}), + GUI.setModal(false); + return $promisify(Promise.resolve(inputs, context)); + } + }), ], }), }, From 7e7da7e6257a15471a006b96fcc6982e2570b63b Mon Sep 17 00:00:00 2001 From: volterra79 Date: Tue, 26 Nov 2024 15:01:52 +0100 Subject: [PATCH 07/21] Use steps message to address user to follow right flow --- toolboxes/toolbox.js | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/toolboxes/toolbox.js b/toolboxes/toolbox.js index 2e0a89bb..9606106a 100644 --- a/toolboxes/toolbox.js +++ b/toolboxes/toolbox.js @@ -582,6 +582,17 @@ export class ToolBox extends G3WObject { steps: [ new Step({ layer, + //@since 3.9.0 to show user message steps + steps: { + chooselayer: { + description: `editing.modal.tools.copyfeaturefromotherlayer.title`, + done: false, + }, + selectgeometry: { + description: `editing.workflow.steps.selectPoint`, + done: false, + } + }, run(inputs, context) { return $promisify(new Promise((resolve, reject) => { const originalLayer = inputs.layer; @@ -610,15 +621,10 @@ export class ToolBox extends G3WObject { label: 'Ok', className: 'btn-success', callback: async () => { + //set choose layer step done + this.setUserMessageStepDone('chooselayer'); try { const feature = await $promisify(async () => { - GUI.showUserMessage({ - type: 'tool', - message: 'plugins.editing.workflow.steps.selectPoint', - size: 'small', - autoclose: false, - closable: false - }); //get selected layer const layer = layers.find(l => l.selected); const features = await (new Promise(async resolve => { @@ -711,9 +717,6 @@ export class ToolBox extends G3WObject { //hide user message step })); }, - stop() { - GUI.closeUserMessage(); - } }), openFormStep, ], From 51c3e1af31b1829b9acb0a02eb5007274a36762c Mon Sep 17 00:00:00 2001 From: volterra79 Date: Tue, 26 Nov 2024 15:45:45 +0100 Subject: [PATCH 08/21] :recycle: Use class instead base or inherit --- deprecated.js | 102 +++++++++++++++++++++++++------------------------- 1 file changed, 52 insertions(+), 50 deletions(-) diff --git a/deprecated.js b/deprecated.js index 8d47e8f9..9ce6c95f 100644 --- a/deprecated.js +++ b/deprecated.js @@ -1,93 +1,97 @@ import { promisify } from '../../utils/promisify'; +class Queque { + constructor() { this.tasks = []; } + addTask(task) { this.tasks.push(task); } + run(reverse = false) { while (this.tasks.length) { const task = reverse ? this.tasks.pop() : this.tasks.shift(); task(); } } + flush() { return this.tasks.splice(0); } + getLength() { return this.tasks.length; } + clear() { this.run(); this.tasks = []; } +} + + /** * Class Flow of workflow step by step * * ORIGINAL SOURCE: g3w-client/src/core/workflow/flow.js@v3.9.1 * ORIGINAL SOURCE: g3w-client/src/core/workflow/queque.js@v3.9.1 */ -export function Flow() { - console.warn('[G3W-CLIENT] g3wsdk.core.workflow.Flow is deprecated'); - - class Queque { - constructor() { this.tasks = []; } - addTask(task) { this.tasks.push(task); } - run(reverse = false) { while (this.tasks.length) { const task = reverse ? this.tasks.pop() : this.tasks.shift(); task(); } } - flush() { return this.tasks.splice(0); } - getLength() { return this.tasks.length; } - clear() { this.run(); this.tasks = []; } +export class Flow extends g3wsdk.core.G3WObject { + constructor() { + super(); + console.warn('[G3W-CLIENT] g3wsdk.core.workflow.Flow is deprecated'); + this.steps = []; + this.counter = 0; + this.context = null; + this.queques = { + end: new Queque(), + micro: new Queque() + }; + this.inputs; + this.d; + this._workflow; } - let steps = []; - let inputs; - let counter = 0; - let context = null; - let d; - let _workflow; - this.queques = { - end: new Queque(), - micro: new Queque() - }; //start workflow - this.start = function(workflow) { - d = $.Deferred(); - if (counter > 0) { + start(workflow) { + this.d = $.Deferred(); + if (this.counter > 0) { console.log("reset workflow before restarting"); } - _workflow = workflow; - inputs = workflow.getInputs(); - context = workflow.getContext(); - steps = workflow.getSteps(); + this._workflow = workflow; + this.inputs = workflow.getInputs(); + this.context = workflow.getContext(); + this.steps = workflow.getSteps(); // check if there are steps - if (steps && steps.length) { + if (this.steps && this.steps.length) { //run step (first) - this.runStep(steps[0], inputs, context); + this.runStep(this.steps[0], this.inputs, this.context); } // return a promise that will be reolved if all step go right - return d.promise(); + return this.d.promise(); }; //run step - this.runStep = function(step, inputs) { + runStep(step, inputs) { //run step that run task - _workflow.setMessages({ + this._workflow.setMessages({ help: step.state.help }); const runMicroTasks = this.queques.micro.getLength(); - step.run(inputs, context, this.queques) + step.run(inputs, this.context, this.queques) .then(outputs => { runMicroTasks && this.queques.micro.run(); this.onDone(outputs); }) - .fail(error => this.onError(error)); + .fail(e => this.onError(e)); }; //check if all step are resolved - this.onDone = function(outputs) { - counter++; - if (counter === steps.length) { - counter = 0; - d.resolve(outputs); + onDone(outputs) { + this.counter++; + if (this.counter === this.steps.length) { + this.counter = 0; + this.d.resolve(outputs); return; } - this.runStep(steps[counter], outputs); + this.runStep(this.steps[this.counter], outputs); }; // in case of error - this.onError = function(err) { - counter = 0; + onError(e) { + this.counter = 0; this.clearQueques(); - d.reject(err); + this.d.reject(e); }; // stop flow - this.stop = function() { + stop() { const d = $.Deferred(); - steps[counter].isRunning() ? steps[counter].stop() : null; + this.steps[counter].isRunning() ? this.steps[this.counter].stop() : null; this.clearQueques(); - if (counter > 0) { + if (this.counter > 0) { // set counter to 0 - counter = 0; + this.counter = 0; // reject flow d.reject(); } else { @@ -97,15 +101,13 @@ export function Flow() { return d.promise(); }; - this.clearQueques = function(){ + clearQueques(){ this.queques.micro.clear(); this.queques.end.clear(); } - g3wsdk.core.utils.base(this) } -g3wsdk.core.utils.inherit(Flow, g3wsdk.core.G3WObject); /** * ORIGINAL SOURCE: g3w-client/src/services/editing.js@v3.9.1 From fec6b77e2780dd3df41417b175154289a1cb2fc3 Mon Sep 17 00:00:00 2001 From: volterra79 Date: Tue, 3 Dec 2024 09:48:02 +0100 Subject: [PATCH 09/21] Remove setModal false --- workflows/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/workflows/index.js b/workflows/index.js index 9f96a2f8..23f935b0 100644 --- a/workflows/index.js +++ b/workflows/index.js @@ -603,7 +603,6 @@ export class OpenFormStep extends Step { // skip when no fields if (0 === fields.length) { - GUI.setModal(false); resolve(inputs); return; } From daf91d9bd2dd098d07db8525bcac70f8ae10d389 Mon Sep 17 00:00:00 2001 From: volterra79 Date: Thu, 5 Dec 2024 15:26:44 +0100 Subject: [PATCH 10/21] :sparkles: Show modal select window to choose whild features of select relation you want edit --- toolboxes/toolbox.js | 73 +++++++++++++++++++++++++++++++++++++++----- workflows/index.js | 10 ++++-- 2 files changed, 72 insertions(+), 11 deletions(-) diff --git a/toolboxes/toolbox.js b/toolboxes/toolbox.js index 9606106a..22f6ea51 100644 --- a/toolboxes/toolbox.js +++ b/toolboxes/toolbox.js @@ -424,10 +424,10 @@ export class ToolBox extends G3WObject { /** ORIGINAL SOURCE: g3w-client-plugin-editing/workflows/editmultifeatureattributesworkflow.js@v3.7.1 */ op: new Workflow({ layer, - type: 'editmultiattributesrelationfeatures', - helpMessage: 'editing.tools.update_multi_features', + type: 'editmultiattributesrelationfeatures', + helpMessage: 'editing.tools.update_multi_features', registerEscKeyEvent: true, - runOnce: true, + runOnce: false, steps: [ new SelectElementsStep({ type: 'multiple', @@ -455,11 +455,65 @@ export class ToolBox extends G3WObject { feature, filterType: 'fid', }))) + //get first relation layer id + let relationLayerId = relations[0].getChild(); //In case of multi relation in editing if (relations.length > 1) { - alert('Choose relations') + //ser relation layer id + try { + await new Promise((resolve, reject) => { + const vueInstance = new (Vue.extend({ + name: 'multi-relations-fetures', + template: `
+ +
+ `, + data() { + return { + relations: this.$options.relations, + relationId: this.$options.relationId + } + } + }))({ relations, relationId: relations[0].state.id }) + + GUI.showModalDialog({ + title: tPlugin('editing.relations'), + className: 'modal-left', + closeButton: false, + message: vueInstance.$mount().$el, + buttons: { + cancel: { + label: 'Cancel', + className: 'btn-danger', + callback() { reject(); } + }, + ok: { + label: 'Ok', + className: 'btn-success', + callback: async () => { + //set relation layer id to editin + relationLayerId = relations.find(r => vueInstance.relationId === r.state.id).getChild(); + resolve(); + } + } + } + }).on('hide.bs.modal', () => vueInstance.$destroy()); //destroy vue instance after dialog is a closed + //hide user message step + }) + } catch(e) { + console.warn(e); + GUI.setModal(false); + return $promisify(Promise.reject(e)); + } } + //start child workflow const workflow = new Workflow({ type: 'editmultiattributes', @@ -468,7 +522,7 @@ export class ToolBox extends G3WObject { ], }); //Relations layer - const rLayer = getEditingLayerById(relations[0].getChild()); + const rLayer = getEditingLayerById(relationLayerId); const fields = getRelationFieldsFromRelation({ layerId: relations[0].getChild(), @@ -477,16 +531,19 @@ export class ToolBox extends G3WObject { const options = { context: { - session: Workflow.Stack.getCurrent().getSession(), // get parent workflow - excludeFields: fields.ownField, // array of fields to be excluded + session: Workflow.Stack.getCurrent().getSession(), // get parent workflow + excludeFields: fields.ownField, // array of fields to be excluded + isContentChild: false, //@since 3.9.0 force child to flase }, inputs: { features: rLayer.readFeatures(), layer: rLayer } - }; + } try { + //set eventually unique values + await setLayerUniqueFieldValues(relationLayerId); await promisify(workflow.start(options)); } catch(e) { console.warn(e); diff --git a/workflows/index.js b/workflows/index.js index 23f935b0..ce07a906 100644 --- a/workflows/index.js +++ b/workflows/index.js @@ -403,7 +403,8 @@ export class OpenFormStep extends Step { */ run(inputs, context) { const promise = new Promise(async (resolve, reject) => { - this._isContentChild = Workflow.Stack.getLength() > 1; + //@since 3.9.0 can set isContentChild attribute to force it (case edit relation features from multi parent features) + this._isContentChild = undefined === context.isContentChild ? Workflow.Stack.getLength() > 1 : context.isContentChild; this.layerId = inputs.layer.getId(); GUI.setLoadingContent(false); @@ -648,7 +649,10 @@ export class OpenFormStep extends Step { this.fireEvent(`savedfeature_${this.layerId}`, newFeatures); // called after saved using layerId // In case of save of child it means that child is updated so also parent if (this._isContentChild) { - Workflow.Stack.getParents().forEach(w => w.getContextService().setUpdate(true, { force: true })); + Workflow.Stack.getParents() + //filter only with has getContextService to be sure + .filter(w => w.getContextService() && w.getContextService().setUpdate) + .forEach(w => w.getContextService().setUpdate(true, { force: true })); } //@TODO add field unique new value id not set resolve(inputs); @@ -771,7 +775,7 @@ export class OpenFormStep extends Step { const contextService = is_parent_table && Workflow.Stack.getCurrent().getContextService(); // force update parent form update - if (contextService && false === this._isContentChild) { + if (contextService && contextService.setUpdate && false === this._isContentChild) { contextService.setUpdate(false, { force: false }); } //@since 3.9.0 add GUI.getContentLength() in case of edit multi relationfeatures tool From 66822c83d69caa3db6aa0dddc32279b97a4a465a Mon Sep 17 00:00:00 2001 From: volterra79 Date: Fri, 6 Dec 2024 12:06:26 +0100 Subject: [PATCH 11/21] :bug: get relation only editable, not also visible --- toolboxes/toolbox.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolboxes/toolbox.js b/toolboxes/toolbox.js index 22f6ea51..2c5d0aee 100644 --- a/toolboxes/toolbox.js +++ b/toolboxes/toolbox.js @@ -92,7 +92,7 @@ export class ToolBox extends G3WObject { const editable_relations = layer.getRelations().getArray() .filter(relation => { const l = CatalogLayersStoresRegistry.getLayerById(getRelationId({ layerId: layer.getId(), relation })); - return l.isEditable() && l.config.editing.visible; + return l.isEditable(); }) .map(r => r); this._start = false; From 4dcfa5ac175e591dd12b75ef359106941dc6309c Mon Sep 17 00:00:00 2001 From: volterra79 Date: Fri, 6 Dec 2024 12:22:53 +0100 Subject: [PATCH 12/21] :globe_with_meridians:translation --- i18n/de.js | 1 + i18n/en.js | 1 + i18n/fi.js | 1 + i18n/fr.js | 1 + i18n/it.js | 1 + i18n/pl.js | 1 + i18n/ro.js | 1 + i18n/se.js | 1 + toolboxes/toolbox.js | 4 ++-- 9 files changed, 10 insertions(+), 2 deletions(-) diff --git a/i18n/de.js b/i18n/de.js index de265b8d..d7ad6480 100644 --- a/i18n/de.js +++ b/i18n/de.js @@ -42,6 +42,7 @@ export default { update_feature: "Feature-Attribut aktualisieren", update_multi_features: "Attribute ausgewählter Features aktualisieren", update_multi_features_relations: "Update attributes of all selected relations", + update_multi_features_relations_from_parents : "Bearbeiten Sie Beziehungsdatensätze von einem oder mehreren übergeordneten features", copyfeaturefromexternallayer: "Create Feature from added layer" }, toolsoftool: { diff --git a/i18n/en.js b/i18n/en.js index 2b72cc7b..5f5a6cae 100644 --- a/i18n/en.js +++ b/i18n/en.js @@ -44,6 +44,7 @@ export default { update_feature: "Update feature attribute", update_multi_features: "Update attributes of selected features", update_multi_features_relations: "Update attributes of all selected relations", + update_multi_features_relations_from_parents : "Edit relations records from one or mode parent features", copyfeaturefromexternallayer: "Create Feature from added layer" }, toolsoftool: { diff --git a/i18n/fi.js b/i18n/fi.js index f1fd6af5..486a5126 100644 --- a/i18n/fi.js +++ b/i18n/fi.js @@ -42,6 +42,7 @@ export default { update_feature: "Päivitä ominaisuus", update_multi_features: "Muokkaa valittujen ominaisuuksien attribuutteja", update_multi_features_relations: "Update attributes of all selected relations", + update_multi_features_relations_from_parents : "Edit relations records from one or mode parent features", copyfeaturefromexternallayer: "Create Feature from added layer" }, toolsoftool: { diff --git a/i18n/fr.js b/i18n/fr.js index e495c1e9..4990dbd3 100644 --- a/i18n/fr.js +++ b/i18n/fr.js @@ -42,6 +42,7 @@ export default { update_feature: "Modifier les attributs des fonctionnalités", update_multi_features: "Modifier les attributs des fonctionnalités sélectionnées", update_multi_features_relations: "Update attributes of all selected relations", + update_multi_features_relations_from_parents : "Modifier les enregistrements de relation à partir d'une ou plusieurs entités parents", copyfeaturefromexternallayer: "Create Feature from added layer" }, toolsoftool: { diff --git a/i18n/it.js b/i18n/it.js index 9bffae24..6681e9fe 100644 --- a/i18n/it.js +++ b/i18n/it.js @@ -44,6 +44,7 @@ export default { update_feature: "Modifica attributi elemento", update_multi_features: "Modifica gli attributi degli elementi selezionati", update_multi_features_relations: "Modifica gli attributi di tutte le relazioni selezionate", + update_multi_features_relations_from_parents : "Edita i record relazionati di uno o più padri", copyfeaturefromexternallayer: "Crea elemento da un livello esterno" }, toolsoftool: { diff --git a/i18n/pl.js b/i18n/pl.js index 65f2b92c..e61416b0 100644 --- a/i18n/pl.js +++ b/i18n/pl.js @@ -39,6 +39,7 @@ export default { update_feature: "Update feature attribute", update_multi_features: "Update attributes of selected features", update_multi_features_relations: "Update attributes of all selected relations", + update_multi_features_relations_from_parents : "Edit relations records from one or mode parent features", copyfeaturefromexternallayer: "Create Feature from added layer" }, toolsoftool: { diff --git a/i18n/ro.js b/i18n/ro.js index 5a2a092d..3555cc26 100644 --- a/i18n/ro.js +++ b/i18n/ro.js @@ -42,6 +42,7 @@ export default { update_feature: "Actualizează atributul entității", update_multi_features: "Actualizează atributele entităților selectate", update_multi_features_relations: "Update attributes of all selected relations", + update_multi_features_relations_from_parents : "Editați înregistrările relațiilor de la una sau mai multe caracteristici părinte", copyfeaturefromexternallayer: "Create Feature from added layer" }, toolsoftool: { diff --git a/i18n/se.js b/i18n/se.js index 43b60a11..48663441 100644 --- a/i18n/se.js +++ b/i18n/se.js @@ -42,6 +42,7 @@ export default { update_feature: "Uppdatera egenskap", update_multi_features: "Ändra attributen för de valda funktionerna", update_multi_features_relations: "Update attributes of all selected relations", + update_multi_features_relations_from_parents : "Edit relations records from one or mode parent features", copyfeaturefromexternallayer: "Create Feature from added layer" }, toolsoftool: { diff --git a/toolboxes/toolbox.js b/toolboxes/toolbox.js index 2c5d0aee..19f7b59e 100644 --- a/toolboxes/toolbox.js +++ b/toolboxes/toolbox.js @@ -419,13 +419,13 @@ export class ToolBox extends G3WObject { (is_vector) && capabilities.includes('change_attr_feature') && editable_relations.filter(r => 'ONE' !== r.getType()).length > 0 && { id: 'editmultiattributesrelationfeatures', type: ['change_attr_feature'], - name: "editing.tools.update_multi_features", + name: "editing.tools.update_multi_features_relations_from_parents", icon: "EditMultiRelationFeatures.png", /** ORIGINAL SOURCE: g3w-client-plugin-editing/workflows/editmultifeatureattributesworkflow.js@v3.7.1 */ op: new Workflow({ layer, type: 'editmultiattributesrelationfeatures', - helpMessage: 'editing.tools.update_multi_features', + helpMessage: 'editing.tools.update_multi_features_relations_from_parents', registerEscKeyEvent: true, runOnce: false, steps: [ From 7b9a44aa7cc951c704a1b31823c1744449fdd2b1 Mon Sep 17 00:00:00 2001 From: volterra79 Date: Fri, 6 Dec 2024 12:42:49 +0100 Subject: [PATCH 13/21] :lipstick: run Once --- toolboxes/toolbox.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolboxes/toolbox.js b/toolboxes/toolbox.js index 19f7b59e..073758a8 100644 --- a/toolboxes/toolbox.js +++ b/toolboxes/toolbox.js @@ -427,7 +427,7 @@ export class ToolBox extends G3WObject { type: 'editmultiattributesrelationfeatures', helpMessage: 'editing.tools.update_multi_features_relations_from_parents', registerEscKeyEvent: true, - runOnce: false, + runOnce: true, steps: [ new SelectElementsStep({ type: 'multiple', From f015f978697d171e960b7dc63a8bf128f267a254 Mon Sep 17 00:00:00 2001 From: volterra79 Date: Tue, 10 Dec 2024 10:37:34 +0100 Subject: [PATCH 14/21] Remove copy feature form external layer tool. Unused --- toolboxes/toolbox.js | 42 ------------------------------------------ 1 file changed, 42 deletions(-) diff --git a/toolboxes/toolbox.js b/toolboxes/toolbox.js index 073758a8..4d0f83c1 100644 --- a/toolboxes/toolbox.js +++ b/toolboxes/toolbox.js @@ -1277,48 +1277,6 @@ export class ToolBox extends G3WObject { registerEscKeyEvent: true }), }, - // Copy Features from external layer - (is_line || is_poly) && capabilities.includes('add_feature') && { - id: 'copyfeaturefromexternallayer', - type: ['add_feature'], - name: "editing.tools.copyfeaturefromexternallayer", - icon: "copyPolygonFromFeature.png", - visible: tool => { - const map = GUI.getService('map'); - const type = this.getLayer().getGeometryType(); - const has_same_geom = layer => { - // check if tool is visible and the layer is a Vector - const features = 'VECTOR' === layer.getType() && layer.getSource().getFeatures(); - return features && features.length ? isSameBaseGeometryType(features[0].getGeometry().getType(), type) : true; - }; - map.onbefore('loadExternalLayer', layer => !tool.visible && (tool.visible = has_same_geom(layer))); - map.onafter('unloadExternalLayer', layer => { - const features = tool.visible && 'VECTOR' === layer.getType() && layer.getSource().getFeatures(); - if (features && features.length && isSameBaseGeometryType(features[0].getGeometry().getType(), type)) { - tool.visible = map.getExternalLayers().find(l => undefined !== has_same_geom(l)); - } - }); - return false; - }, - /** ORIGINAL SOURCE: g3w-client-plugin-editing/workflows/addfeaturefrommapvectorlayersworkflow.js@v3.7.1 */ - op: new Workflow({ - layer, - type: 'addfeaturefrommapvectorlayers', - runOnce: true, - steps: [ - new SelectElementsStep({ - layer, - type: 'external', - help: 'editing.steps.help.copy' - }, false), - new OpenFormStep({ - layer, - help: 'editing.steps.help.copy' - }), - ], - registerEscKeyEvent: true - }), - }, // Add Table feature (alphanumerical layer - No geometry) is_table && capabilities.includes('add_feature') && { id: 'addfeature', From 77381c152dcece37c3d48ac2ccfced8d48fb0677 Mon Sep 17 00:00:00 2001 From: volterra79 Date: Tue, 10 Dec 2024 10:41:05 +0100 Subject: [PATCH 15/21] :recycle: Handle start toolbox session uniform --- toolboxes/toolbox.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/toolboxes/toolbox.js b/toolboxes/toolbox.js index 4d0f83c1..e612d3f4 100644 --- a/toolboxes/toolbox.js +++ b/toolboxes/toolbox.js @@ -1616,7 +1616,7 @@ export class ToolBox extends G3WObject { this.startLoading(); this.setFeaturesOptions({ filter }); try { - handlerAfterSessionGetFeatures(await promisify(this._session.start(this.state._getFeaturesOption))) + await handlerAfterSessionGetFeatures(promisify(this._session.start(this.state._getFeaturesOption))) } catch(e) { console.warn(e); this.setEditing(false); @@ -1629,12 +1629,12 @@ export class ToolBox extends G3WObject { if (!is_started && !GIVE_ME_A_NAME) { this._start = true; this.startLoading(); - this._session.start(this.state._getFeaturesOption).then(handlerAfterSessionGetFeatures) + await handlerAfterSessionGetFeatures(promisify(this._session.start(this.state._getFeaturesOption))) } if (is_started && !this._start) { this.startLoading(); - this._session.getFeatures(this.state._getFeaturesOption).then(handlerAfterSessionGetFeatures); + await handlerAfterSessionGetFeatures(promisify(this._session.getFeatures(this.state._getFeaturesOption))) this._start = true; } From 96bbe9bb7554b32cd128effa0412ccd0636e45aa Mon Sep 17 00:00:00 2001 From: volterra79 Date: Wed, 11 Dec 2024 10:56:47 +0100 Subject: [PATCH 16/21] Comment getEditingMediaFields to copy also attach (media, pdf,etcc.) of clone of feature --- toolboxes/toolbox.js | 3 ++- utils/handleSplitFeature.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/toolboxes/toolbox.js b/toolboxes/toolbox.js index e612d3f4..58f03a11 100644 --- a/toolboxes/toolbox.js +++ b/toolboxes/toolbox.js @@ -887,7 +887,8 @@ export class ToolBox extends G3WObject { feature.getGeometry().translate(deltaXY.x, deltaXY.y) } // set media fields to null - layer.getEditingMediaFields({}).forEach(f => feature.set(f, null)); + //@since 3.9.0 Comment + //layer.getEditingMediaFields({}).forEach(f => feature.set(f, null)); /** * evaluated geometry expression */ diff --git a/utils/handleSplitFeature.js b/utils/handleSplitFeature.js index 84e2a0fc..74362c30 100644 --- a/utils/handleSplitFeature.js +++ b/utils/handleSplitFeature.js @@ -52,7 +52,8 @@ export async function handleSplitFeature({ newFeature.setGeometry(splittedGeometry); // set media fields to null - layer.getEditingMediaFields({}).forEach(f => newFeature.set(f, null)); + //@since 3.9.0 Commented + //layer.getEditingMediaFields({}).forEach(f => newFeature.set(f, null)); feature = new Feature({ feature: newFeature }); From b733b10ee421786bfec14fb498143dcd5a5640a6 Mon Sep 17 00:00:00 2001 From: volterra79 Date: Wed, 11 Dec 2024 15:59:56 +0100 Subject: [PATCH 17/21] :bug: In case of no relations, show user message and stop --- toolboxes/toolbox.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/toolboxes/toolbox.js b/toolboxes/toolbox.js index 58f03a11..2103126d 100644 --- a/toolboxes/toolbox.js +++ b/toolboxes/toolbox.js @@ -524,6 +524,17 @@ export class ToolBox extends G3WObject { //Relations layer const rLayer = getEditingLayerById(relationLayerId); + if (0 === rLayer.readFeatures().length) { + GUI.setModal(false); + + GUI.showUserMessage({ + type: 'warning', + message: 'plugins.editing.no_relations_found', + autoclose: true, + }) + return $promisify(Promise.reject()); + } + const fields = getRelationFieldsFromRelation({ layerId: relations[0].getChild(), relation: relations[0] From 29fa953de03011428001b318a7a29f4467850be1 Mon Sep 17 00:00:00 2001 From: volterra79 Date: Thu, 12 Dec 2024 17:51:52 +0100 Subject: [PATCH 18/21] :sparkles: Referred to https://github.com/g3w-suite/g3w-admin/pull/991 --- components/FormRelation.vue | 6 +++--- deprecated.js | 6 +++--- g3wsdk/editing/editor.js | 37 +++++++++++++++++++++++++++++++++---- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/components/FormRelation.vue b/components/FormRelation.vue index 582afb10..3c85c584 100644 --- a/components/FormRelation.vue +++ b/components/FormRelation.vue @@ -572,14 +572,14 @@ * * @since g3w-client-plugin-editing@v3.7.4 */ - onCommit({ new_relations = {} }) { + onCommit({ relations = {} }) { const relationLayer = getEditingLayerById(this.relation.child); // there is a new relation saved on server - if (new_relations[relationLayer.getId()] && Array.isArray(new_relations[relationLayer.getId()].new)) { + if (relations[relationLayer.getId()] && Array.isArray(relations[relationLayer.getId()].new)) { this._new_relations_ids = [ ...(this._new_relations_ids || []), - ...new_relations[relationLayer.getId()].new.map(({ clientid, id }) => ({ clientid, id })) + ...relations[relationLayer.getId()].new.map(({ clientid, id }) => ({ clientid, id })) ] } }, diff --git a/deprecated.js b/deprecated.js index 9ce6c95f..21bc13c0 100644 --- a/deprecated.js +++ b/deprecated.js @@ -814,15 +814,15 @@ export class Session extends g3wsdk.core.G3WObject { return; } - const { new_relations = {} } = response.response; // check if new relations are saved on server + const { relations = {} } = response.response; // check if new relations are saved on server // sync server data with local data - for (const id in new_relations) { + for (const id in relations) { Session.Registry .getSession(id) // get session of relation by id .getEditor() .applyCommitResponse({ // apply commit response to current editing relation layer - response: new_relations[id], + response: relations[id], result: true }); } diff --git a/g3wsdk/editing/editor.js b/g3wsdk/editing/editor.js index af687128..a0f2cd07 100644 --- a/g3wsdk/editing/editor.js +++ b/g3wsdk/editing/editor.js @@ -8,6 +8,8 @@ import { ToolBox } from '../../toolboxes/toolbox'; import { promisify, $promisify } from '../../utils/promisify'; +import { getRelationsInEditing } from "../../utils/getRelationsInEditing"; +import {getRelationId} from "editing/utils/getRelationId"; const { ApplicationState, G3WObject } = g3wsdk.core; const { FeaturesStore } = g3wsdk.core.layer.features; @@ -320,7 +322,7 @@ export default class Editor extends G3WObject { // properties - properties of feature returned by server response.response.new.forEach(({ clientid, id, properties } = {}) => { //get feature from current layer in editing - const feature = this._featuresstore.getFeatureById(clientid); + const feature = this.getEditingSource().getFeatureById(clientid); // set new id feature.setId(id); //set properties @@ -346,6 +348,33 @@ export default class Editor extends G3WObject { }); + //@since 3.9.0 take in account update properties returned by server (Useful in case of media input changes) + (response.response.update || []).forEach(({ id, properties } = {}) => { + //get feature from current layer in editing + const feature = this.getEditingSource().getFeatureById(id); + //set properties + feature.setProperties(properties); + //Loop on eventual relation updated or created + relations.forEach(r => { // handle relations (if provided) + Object + .entries(r) + .forEach(([ id, opts = {}]) => { // id - relation layer id, opts - Object contain relation properties + //get the editing source of relation layer + const source = ToolBox.get(id).getSession().getEditor().getEditingSource(); + // handle value to relation field saved on server + (opts.ids || []).forEach(id => { + const rFeature = source.getFeatureById(id); + if (rFeature) { + opts.fatherField.forEach((ff, i) => {// loop relation ids + rFeature.set(opts.childField[i], feature.get(ff)) // set father feature `value` and `name` + }) + } + }) + }); + }); + + }); + const features = this.readEditingFeatures(); features.forEach(f => f.clearState()); // reset state of the editing features (update, new etc..) @@ -439,10 +468,10 @@ export default class Editor extends G3WObject { */ stop() { return $promisify(async () => { - const response = await promisify(this._layer.unlock()); + const { result } = await promisify(this._layer.unlock()); this.clear(); - return response; - }); + return result; + }) } /** From 2997529cf5a1d0c4f9371b22834c165407a595e0 Mon Sep 17 00:00:00 2001 From: volterra79 Date: Thu, 12 Dec 2024 17:53:11 +0100 Subject: [PATCH 19/21] :bug: Unlock relations layers in case of editing relation by parent layer --- toolboxes/toolbox.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/toolboxes/toolbox.js b/toolboxes/toolbox.js index 2103126d..847751a3 100644 --- a/toolboxes/toolbox.js +++ b/toolboxes/toolbox.js @@ -1686,9 +1686,6 @@ export class ToolBox extends G3WObject { //eventually reset start resolve feature waiting promise this.startResolve = null; - //set start to false - this._start = false - this.state.editing.on = false; if (this.state._constraints.scale) { this._handleScaleConstraint(true); @@ -1728,6 +1725,9 @@ export class ToolBox extends G3WObject { try { await promisify(this._session.stop()); + //set start to false + this._start = false + this.state.editing.on = false; this.state.enabled = false; this.stopLoading(); this.state._getFeaturesOption = {}; @@ -1738,7 +1738,7 @@ export class ToolBox extends G3WObject { // clear layer unique field values g3wsdk.core.plugin.PluginsRegistry.getPlugin('editing').state.uniqueFieldsValues[this.getId()] = {}; return true; - } catch (e) { + } catch(e) { console.warn(e); return Promise.reject(e); } @@ -1792,16 +1792,16 @@ export class ToolBox extends G3WObject { return; } - const { new_relations = {} } = response.response; // check if new relations are saved on server + const { relations = {} } = response.response; // check if relations are saved on server // sync server data with local data - for (const id in new_relations) { + for (const id in relations) { const toolbox = ToolBox.get(id) toolbox .getSession() .getEditor() .applyCommitResponse({ // apply commit response to current editing relation layer - response: new_relations[id], + response: relations[id], result: true }); } @@ -2937,7 +2937,6 @@ export class ToolBox extends G3WObject { console.warn(e); return Promise.reject(e); } finally { - if (!this.inEditing()) { return; } if (ApplicationState.online) { this._stopSessionChildren(this.state.id); } From 127b1c6441fa0c3ecc0ec3615d2bcb04b25af81e Mon Sep 17 00:00:00 2001 From: volterra79 Date: Fri, 13 Dec 2024 13:50:58 +0100 Subject: [PATCH 20/21] Remove return Promise.reject because cause a vue error --- components/FormRelation.vue | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/components/FormRelation.vue b/components/FormRelation.vue index 3c85c584..2d50d603 100644 --- a/components/FormRelation.vue +++ b/components/FormRelation.vue @@ -906,11 +906,10 @@ await promise; } catch (e) { console.trace('START TOOL FAILED', e); - return Promise.reject(e); } finally { relationtool.state.active = false; } - } catch (e) { + } catch(e) { console.warn(e); } }, From 2290dee494be9b87389a9aa7fffde0089e40f4f1 Mon Sep 17 00:00:00 2001 From: volterra79 Date: Fri, 13 Dec 2024 14:36:19 +0100 Subject: [PATCH 21/21] Remove unusefull new --- components/FormRelation.vue | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/FormRelation.vue b/components/FormRelation.vue index 2d50d603..c4beaf0f 100644 --- a/components/FormRelation.vue +++ b/components/FormRelation.vue @@ -396,7 +396,7 @@ const is_vector = (external || layer.isGeoLayer()) this.runAddRelationWorkflow({ workflow: is_vector - ? new this._add_link_workflow.selectandcopy({ + ? this._add_link_workflow.selectandcopy({ copyLayer: layer, isVector: true, help: 'editing.steps.help.copy', @@ -421,7 +421,7 @@ */ addVectorRelation() { this.runAddRelationWorkflow({ - workflow: new this._add_link_workflow.add(), + workflow: this._add_link_workflow.add(), isVector: Layer.LayerTypes.VECTOR === this._layerType, }); this.show_vector_tools = false; @@ -473,7 +473,7 @@ this.resize(); } else { this.runAddRelationWorkflow({ - workflow: new this._add_link_workflow.add(), + workflow: this._add_link_workflow.add(), isVector: Layer.LayerTypes.VECTOR === this._layerType, }); } @@ -1028,7 +1028,7 @@ this.disabled = true; const is_vector = Layer.LayerTypes.VECTOR === this._layerType; - const workflow = new this._add_link_workflow.link( is_vector ? { + const workflow = this._add_link_workflow.link( is_vector ? { selectStyle: SELECTED_STYLES[this.getLayer().getGeometryType()] } : {}); const options = this._createWorkflowOptions();