Skip to content

Commit

Permalink
✨ Add edit multi relation features (#140)
Browse files Browse the repository at this point in the history
* ✨ Start to develop edit multi relation feature from multi parent feature layer

* ✨ Start to develop edit multi relation feature from multi parent feature layer

* ✨ Add reset method step

* Clean code - spaces

* 🐛 Add user message to copy paste from other layer

* Clean code - spaces

* Use steps message to address user to follow right flow

* ♻️ Use class instead base or inherit

* Remove setModal false

* ✨ Show modal select window to choose whild features of select relation you want edit

* 🐛 get relation only editable, not also visible

* 🌐translation

* 💄 run Once

* Remove copy feature form external layer tool. Unused

* ♻️ Handle start toolbox session uniform

* Comment getEditingMediaFields to copy also attach (media, pdf,etcc.) of clone of feature

* 🐛 In case of no relations, show user message and stop

* ✨ Referred to  g3w-suite/g3w-admin#991

* 🐛 Unlock relations layers in case of editing relation by parent layer

* Remove return Promise.reject because cause a vue error

* Remove unusefull new
  • Loading branch information
volterra79 authored Dec 16, 2024
1 parent 45f9e28 commit 55afa24
Show file tree
Hide file tree
Showing 18 changed files with 354 additions and 179 deletions.
17 changes: 8 additions & 9 deletions components/FormRelation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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;
Expand Down Expand Up @@ -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,
});
}
Expand Down Expand Up @@ -572,14 +572,14 @@
*
* @since [email protected]
*/
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 }))
]
}
},
Expand Down Expand Up @@ -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);
}
},
Expand Down Expand Up @@ -1029,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();
Expand Down
2 changes: 1 addition & 1 deletion components/Toolbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@
<img
height = "25"
width = "25"
:src = "resourcesurl + 'images/' + tool.icon"
:src = "`${resourcesurl}images/${tool.icon}`"
:title = "get_tool_title(`${tool.name}`)"
/>
</div>
Expand Down
1 change: 1 addition & 0 deletions components/UserMessage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<button
@click = "completeStep(step)"
:class = "'btn btn-success' + (step.buttonnext.disabled ? ' g3w-disabled' : '' )"
style = "margin-left: 10px;"
v-t-plugin = "'editing.workflow.next'"
></button>
</span>
Expand Down
108 changes: 55 additions & 53 deletions deprecated.js
Original file line number Diff line number Diff line change
@@ -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/[email protected]
* ORIGINAL SOURCE: g3w-client/src/core/workflow/[email protected]
*/
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 {
Expand All @@ -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/[email protected]
Expand Down Expand Up @@ -812,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
});
}
Expand Down
37 changes: 33 additions & 4 deletions g3wsdk/editing/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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..)
Expand Down Expand Up @@ -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;
})
}

/**
Expand Down
6 changes: 3 additions & 3 deletions g3wsdk/workflow/workflow.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
1 change: 1 addition & 0 deletions i18n/de.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
1 change: 1 addition & 0 deletions i18n/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
1 change: 1 addition & 0 deletions i18n/fi.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
1 change: 1 addition & 0 deletions i18n/fr.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
1 change: 1 addition & 0 deletions i18n/it.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
1 change: 1 addition & 0 deletions i18n/pl.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
Loading

0 comments on commit 55afa24

Please sign in to comment.