diff --git a/components/FormRelation.vue b/components/FormRelation.vue index 7c8f9fb8..ca1b6406 100644 --- a/components/FormRelation.vue +++ b/components/FormRelation.vue @@ -721,22 +721,13 @@ const unique_fields = g3wsdk.core.plugin.PluginsRegistry.getPlugin('editing').state.uniqueFieldsValues[this._relationLayerId]; //check if relation layer has unique values stored if (undefined !== unique_fields) { - //get parent layer unique fields - const parent_relation_unique_fields = ( - g3wsdk.core.plugin.PluginsRegistry.getPlugin('editing').state.uniqueFieldsValues[this.layerId] - && g3wsdk.core.plugin.PluginsRegistry.getPlugin('editing').state.uniqueFieldsValues[this.layerId].__uniqueFieldsValuesRelations - && g3wsdk.core.plugin.PluginsRegistry.getPlugin('editing').state.uniqueFieldsValues[this.layerId].__uniqueFieldsValuesRelations[this._relationLayerId] - ) Object .keys(relationfeature.getProperties()) .filter(p => undefined !== unique_fields[p]) .forEach(p => { const values = new Set(unique_fields[p]); + //@TODO Check if we need remove values.delete(relationfeature.get(p)); - //In the case of parent store unique values field of relation, update values of this field - if (parent_relation_unique_fields) { - parent_relation_unique_fields.__uniqueFieldsValuesRelations[this._relationLayerId][p] = values; - } }) } diff --git a/index.js b/index.js index 95255594..6301d0d3 100644 --- a/index.js +++ b/index.js @@ -216,6 +216,9 @@ new (class extends Plugin { this.state.editableLayers[layer.getId()] = layer; + //set default empty object + this.state.uniqueFieldsValues[layer.getId()] = {} + /** * attach layer widgets event: get data from api when a field of a layer * is related to a wgis form widget (ex. relation reference, value map, etc..) @@ -851,6 +854,9 @@ new (class extends Plugin { this.state.toolboxselected = null; this.state.message = null; + //reset unique values + Object.keys(this.state.uniqueFieldsValues).forEach(id => this.state.uniqueFieldsValue[id] = {}); + GUI.getService('map').refreshMap(); } diff --git a/toolboxes/toolbox.js b/toolboxes/toolbox.js index 3a446d36..dedcb149 100644 --- a/toolboxes/toolbox.js +++ b/toolboxes/toolbox.js @@ -92,15 +92,6 @@ export class ToolBox extends G3WObject { this._start = false; - const uniqueFields = layer.getEditingFields() - .filter(f => f.input && 'unique' === f.input.type) - .reduce((fields, f) => { fields[f.name] = f; return fields; }, {}); - - /** - * unique fields type - */ - this.uniqueFields = Object.keys(uniqueFields).length ? uniqueFields : null; - /** constraint loading features to a filter set */ this.constraints = { filter: null, show: null, tools: [] }; @@ -1216,12 +1207,6 @@ export class ToolBox extends G3WObject { // BACKOMP v3.x this.originalState = this.state.originalState; - // get informed when save on server - if (this.uniqueFields) { - this.getFieldUniqueValuesFromServer(); - this._resetOnSaveChangesOnServer = true; - } - //event features this._getFeaturesEvent = { event: null, fnc: null }; @@ -1308,30 +1293,6 @@ export class ToolBox extends G3WObject { return this.state.editing.dependencies.length > 0; } - /** - * Set unique value to filed unique - * @param reset - */ - getFieldUniqueValuesFromServer({ - reset = false - } = {}) { - this.state.layer.getWidgetData({ - type: 'unique', - fields: Object.values(this.uniqueFields).map(field => field.name).join() - }) - .then((response) => { - Object - .entries(response.data || []) - .forEach(([fieldName, values]) => { - if (reset) { - this.uniqueFields[fieldName].input.options.values.splice(0); - } - values.forEach(value => this.uniqueFields[fieldName].input.options.values.push(value)); - }) - }) - .fail(console.warn) - } - /** * Create getFeatures options * @@ -1690,10 +1651,6 @@ export class ToolBox extends G3WObject { response: new_relations[id], result: true }); - - //@since 3.9.0 - toolbox._session.saveChangesOnServer(); // dispatch setter event. - } this.__clearHistory(); @@ -1702,7 +1659,7 @@ export class ToolBox extends G3WObject { * @since v3.9.0 * After commit get new unique values */ - this._session.saveChangesOnServer(); + this._session.saveChangesOnServer(commit); // ES6 promises only accept a single response @@ -2853,11 +2810,21 @@ export class ToolBox extends G3WObject { /** * Hook to get informed that are saved on server - */ - __saveChangesOnServer() { - if (this._resetOnSaveChangesOnServer) { - this.getFieldUniqueValuesFromServer({ reset: true }); + * Get unique id for each commited layer/relation + */ + async __saveChangesOnServer(commit) { + const promises = [ setLayerUniqueFieldValues(this.getId()) ]; + const relationsId = []; + const addRelationId = (relations = {}) => { + Object.entries(relations).forEach(([id, commit]) => { + relationsId.push(id); + addRelationId(commit.relations); + }) } + addRelationId(commit.relations); + relationsId.forEach(id => promises.push(setLayerUniqueFieldValues(id))); + + await Promise.allSettled(promises); } /** diff --git a/utils/getFormFields.js b/utils/getFormFields.js index 462325d4..eb33c33f 100644 --- a/utils/getFormFields.js +++ b/utils/getFormFields.js @@ -1,5 +1,4 @@ -import { Workflow } from '../g3wsdk/workflow/workflow'; - +const {sortAlphabeticallyArray, sortNumericArray} = g3wsdk.core.utils; /** * ORIGINAL SOURCE: g3w-client-plugin-editing/workflows/tasks/editingtask.js@v3.7.1 * @@ -18,14 +17,11 @@ export function getFormFields({ inputs, context, feature, //current feature - isChild = false, //true -> relation form multi, // true -> multi features (e.g edit multi features attributes form) } = {}) { //editing service const service = g3wsdk.core.plugin.PluginsRegistry.getPlugin('editing'); - // root layerId (in case of child edit relation) - const relationLayerId = Workflow.Stack.getFirst().getInputs().layer.getId(); // current form layerId// unique values by feature field const layerId = inputs.layer.getId(); @@ -39,55 +35,27 @@ export function getFormFields({ //Loop through fields const unique_values = fields - //check if field is a unique widget type - .filter(f => f.validate.unique && f.editable) + //check if field is a unique field. Exclude pk not edittable + .filter(f => !(f.pk && false === f.editable) && ('unique' === f.input.type || f.validate.unique)) .map(field => ({ field, // feature field _value: feature.get(field.name), // feature current field value })) - //Loop through uniq value field + //Loop through unique fields unique_values.forEach(({ _value, field }) => { - // current editing feature adds to - let current_values; - //get relations - const relations = isChild && ( - service.state.uniqueFieldsValues[relationLayerId] - && service.state.uniqueFieldsValues[relationLayerId].__uniqueFieldsValuesRelations - && service.state.uniqueFieldsValues[relationLayerId].__uniqueFieldsValuesRelations[layerId] - ); - - //check if relation field has values - const has_values = relations && (undefined !== (relations[layerId] || {})[field.name]); - // child form --> belongs to relation (get child layer unique field values) - if (isChild && has_values) { - current_values = relations[layerId][field.name]; - } + //get current stored unique values for field + const current_values = service.state.uniqueFieldsValues[layerId][field.name] || new Set([]); - // root layer --> get current values of unique field - if (!isChild || !has_values) { - current_values = (service.state.uniqueFieldsValues[layerId] || {})[field.name] || []; - //check if temporary value is not added to values - // @since 3.9.0 - if (!field.input.options.values.includes(field.value)) { - field.input.options.values.push(field.value); - } - } + //NEED TO ADD ALWAYS CURRENT VALUE + field.input.options.values = (['integer', 'float', 'bigint'].includes(field.type) ? sortNumericArray: sortAlphabeticallyArray)(Array.from(current_values)); // convert "current" values to string (when not null or undefined) current_values.forEach(v => field.validate.exclude_values.add(![null, undefined].includes(v)? `${v}` : v ) ); - // convert "inputs" values to string (when not null or undefined) - inputs.features.forEach(f => { - const value = f.get(field.name); - if (![null, undefined].includes(value)) { - field.validate.exclude_values.add(`${value}`); - } - }); - // remove current value from exclude_values - field.validate.exclude_values.delete(_value); + field.validate.exclude_values.delete(`${_value}`); }); // skip when no fields are unique in multi features change form attribute @@ -100,53 +68,17 @@ export function getFormFields({ unique_values.forEach(({ _value, field }) => { // initial value is the same that current field vale (no changed) if (_value === field.value) { return } - //get - const layer = isChild && service.state.uniqueFieldsValues[relationLayerId]; - - // relation form - if (layer) { - // change relation layer unique field values - layer.__uniqueFieldsValuesRelations = layer.__uniqueFieldsValuesRelations || {}; - layer.__uniqueFieldsValuesRelations[layerId] = layer.__uniqueFieldsValuesRelations[layerId] || {}; - const values = new Set(layer.__uniqueFieldsValuesRelations[layerId][field.name]); - values.delete(_value); - values.add(field.value); - layer.__uniqueFieldsValuesRelations[layerId][field.name] = values; - } - - // root layer form (no relation) - if (!layer && service.state.uniqueFieldsValues[layerId] && service.state.uniqueFieldsValues[layerId][field.name]) { + // layer form + if (service.state.uniqueFieldsValues[layerId][field.name]) { // change layer unique field values const values = service.state.uniqueFieldsValues[layerId][field.name]; + //If changed, delete it from _value values.delete(_value); + //aff new one to value list unique field values.add(field.value); } - }); - // Save temporary relation feature changes on father (root) layer feature - const relations = false === isChild && ( - service.state.uniqueFieldsValues[layerId] - && service.state.uniqueFieldsValues[layerId].__uniqueFieldsValuesRelations - ); - - // skip when no relation unique fields values is stored - if (relations) { - Object - .keys(relations) - .forEach(id => { - Object - .entries(relations[id]) - .forEach(([name, values]) => { - service.state.uniqueFieldsValues[id][name] = values; - }) - }); - // clear temporary relations unique fields values - if (service.state.uniqueFieldsValues[layerId]) { - delete service.state.uniqueFieldsValues[layerId].__uniqueFieldsValuesRelations; - } - } - return { once: true }; }; @@ -156,10 +88,6 @@ export function getFormFields({ service.subscribe(`closeform_${layerId}`, () => { //unsubscribe event service.unsubscribe(`savedfeature_${layerId}`, savedfeatureFnc); - // clear temporary relations unique fields values - if (service.state.uniqueFieldsValues[layerId] && service.state.uniqueFieldsValues[layerId].__uniqueFieldsValuesRelations) { - delete service.state.uniqueFieldsValues[layerId].__uniqueFieldsValuesRelations; - } return { once: true }; }); diff --git a/utils/setLayerUniqueFieldValues.js b/utils/setLayerUniqueFieldValues.js index e05a8a66..66f85cab 100644 --- a/utils/setLayerUniqueFieldValues.js +++ b/utils/setLayerUniqueFieldValues.js @@ -4,8 +4,8 @@ const { CatalogLayersStoresRegistry } = g3wsdk.core.catalog; * ORIGINAL SOURCE: g3w-client-plugin-editing/services/editingservice.js@v3.7.8 * Method to get unique values of unique input values from server * It's called - * - When toolbox start - * - Open a relation from OpenFormStep + * - When toolbox start (parent layer and relation) + * - After commit to server (to get fresh new data) * * @param { string } layerId * @@ -15,29 +15,26 @@ const { CatalogLayersStoresRegistry } = g3wsdk.core.catalog; */ export async function setLayerUniqueFieldValues(layerId) { const service = g3wsdk.core.plugin.PluginsRegistry.getPlugin('editing'); //get editing service - - const promises = []; - const layer = CatalogLayersStoresRegistry.getLayerById(layerId); - layer - .getEditingFields() - //filter field that is unique and not yet set unique values - .filter(field => field.validate.unique && undefined === (service.state.uniqueFieldsValues[layerId] && service.state.uniqueFieldsValues[layerId][field.name])) - .forEach((field => { - promises.push(new Promise((resolve, reject) => { - layer - .getFilterData({ unique: field.name }) - .then((values = []) => { - //check if not yet create - if (undefined === service.state.uniqueFieldsValues[layerId]) { - service.state.uniqueFieldsValues[layerId] = {}; - } - //set unique values for the field - service.state.uniqueFieldsValues[layerId][field.name] = new Set(values); - resolve(); + await new Promise((resolve, reject) => { + const layer = g3wsdk.core.plugin.PluginsRegistry.getPlugin('editing').getLayerById(layerId); + //get all values for unique field + layer.getWidgetData({ + type: 'unique', + fields: Object.values(layer + .getEditingFields() + //filter field that is unique and not yet set unique values + .filter(f => !(f.pk && false === f.editable) && ('unique' === f.input.type || f.validate.unique))) + .map(f => f.name).join() + }).then((response) => { + Object + .entries(response.data || []) + .forEach(([name, values]) => { + service.state.uniqueFieldsValues[layerId][name] = new Set(values) }) - .fail(e => { console.warn(e); reject(e); }) - })) - })) - await Promise.allSettled(promises); + + resolve(service.state.uniqueFieldsValues[layerId][name]) + }) + .fail(e => { console.warn(e); reject(e); }) + }) return service.state.uniqueFieldsValues[layerId]; } \ No newline at end of file