Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for multi fields relations #53

Merged
merged 17 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
801 changes: 504 additions & 297 deletions components/FormRelation.vue

Large diffs are not rendered by default.

360 changes: 272 additions & 88 deletions components/Table.vue

Large diffs are not rendered by default.

67 changes: 42 additions & 25 deletions form/editingform.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,54 @@
const {base, inherit} = g3wsdk.core.utils;
const {GUI} = g3wsdk.gui;
const {FormComponent} = g3wsdk.gui.vue;
const { base, inherit } = g3wsdk.core.utils;
const { GUI } = g3wsdk.gui;
const { FormComponent } = g3wsdk.gui.vue;
const EditingFormService = require('./editingformservice');

function EditingFormComponent(options={}) {
function EditingFormComponent(options = {}) {

base(this, options);
const EditingService = require('../services/editingservice');

const EditingService = require('../services/editingservice');
const relationsOptions = options.context_inputs || null;
const {layer} = options;
const layerId = layer.getId();
if (relationsOptions) {
const feature = relationsOptions.inputs.features[relationsOptions.inputs.features.length-1];
const promise = feature.isNew() ? Promise.resolve() : EditingService.getLayersDependencyFeatures(layerId, {
feature,
filterType: 'fid'
});
promise.then(()=> {
const layerId = options.layer.getId();
const feature = (
relationsOptions &&
relationsOptions.inputs &&
relationsOptions.inputs.features &&
relationsOptions.inputs.features[relationsOptions.inputs.features.length - 1]
);

if (feature) {
(
feature.isNew()
? Promise.resolve()
: EditingService.getLayersDependencyFeatures(layerId, { feature, filterType: 'fid' })
).then(() => {

relationsOptions.formEventBus = this.getService().getEventBus();
const service = new EditingFormService(relationsOptions);
const RelationComponents = service.buildRelationComponents();
const customFormComponents = EditingService.getFormComponentsById(layerId);
//check if add components to add
customFormComponents.length && this.addFormComponents(customFormComponents);

const service = new EditingFormService(relationsOptions);
const RelationComponents = service.buildRelationComponents();
const customFormComponents = EditingService.getFormComponentsById(layerId);

// check if add components to add
if (customFormComponents.length > 0) {
this.addFormComponents(customFormComponents);
}

// add relation component
RelationComponents.length && this.addFormComponents(RelationComponents);
this.getService().handleRelation = async function({relation, layerId, feature}){
if (RelationComponents.length > 0) {
this.addFormComponents(RelationComponents);
}

// overwrite click on relation handler
this.getService().handleRelation = async function({ relation }) {
GUI.setLoadingContent(true);
const {name: relationId} = relation;
await EditingService.setLayerUniqueFieldValues(layer.getRelationById(relationId).getChild());
this.setCurrentComponentById(relationId);
await EditingService.setLayerUniqueFieldValues(options.layer.getRelationById(relation.name).getChild());
this.setCurrentComponentById(relation.name);
GUI.setLoadingContent(false);
};
})

});
}
}

Expand Down
60 changes: 39 additions & 21 deletions form/editingformservice.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,44 @@
const {GUI} = g3wsdk.gui;
const RelationComponent = require('../components/FormRelation.vue');
const EditingFormService = function(options={}) {
const { GUI } = g3wsdk.gui;
const RelationComponent = require('../components/FormRelation.vue');

const EditingFormService = function(options = {}) {

const EditingService = require('../services/editingservice');

this.state = {
relations: []
};
const {layer, features} = options.inputs || {};
// get back to Father function

const { layer, features } = options.inputs || {};

/**
* get back to Father function
*/
this._formEventBus = options.formEventBus || null;

const layerId = layer.getId();
// get feature
const feature = features[features.length - 1];

// get only relation with type not ONE and layer is the father
let relations = layer.getRelations().getArray().filter(relation => relation.getType() !== 'ONE' && relation.getFather() === layerId);
/**
* get relation layers that set in editing on g3w-admin
*/
relations = EditingService.getRelationsInEditing({layerId, relations , feature});
this.hasRelations = () => !!relations.length;

// get relation layers that set in editing on g3w-admin
relations = EditingService.getRelationsInEditing({
layerId,
relations ,
feature: features[features.length - 1],
});

this.hasRelations = () => relations.length > 0;

this.buildRelationComponents = function() {

const self = this;

const relationComponents = [];
relations.forEach(relation => {

relations.forEach(({ relation, relations }) => {
const relationComponent = Vue.extend({
mixins: [RelationComponent],
mixins: [ RelationComponent ],
name: `relation_${Date.now()}`,
methods: {
getService() {
Expand All @@ -33,23 +48,26 @@ const EditingFormService = function(options={}) {
data() {
return {
layerId,
relation: relation.relation,
relations: relation.relations,
relation,
relations,
resourcesurl: GUI.getResourcesUrl(),
formeventbus: self._formEventBus
}
};
},
});
relationComponents.push({
title: "plugins.editing.edit_relation",
name: relation.relation.name,
id: relation.relation.id,
header: false, // not show to header form
title: "plugins.editing.edit_relation",
name: relation.name,
id: relation.id,
header: false, // hide header form
component: relationComponent
})
});

return relationComponents;

};

};

module.exports = EditingFormService;
72 changes: 54 additions & 18 deletions services/editingservice.js
Original file line number Diff line number Diff line change
Expand Up @@ -908,14 +908,29 @@ proto._getRelationLayerId = function({layerId, relation}={}){
return relation.getChild() === layerId ? relation.getFather() : relation.getChild();
};

/**
*
* @param layerId
* @param relation
* @param feature
* @param layerType
*/
proto.getRelationsByFeature = function({layerId, relation, feature, layerType}={}) {
//ownField and relationField are Array @since v3.7.0
const {ownField, relationField} = this._getRelationFieldsFromRelation({
layerId,
relation
});
const featureValue = feature.get(relationField);
//get features of relation child layers
const features = this._getFeaturesByLayerId(layerId);
return features.filter(feature => feature.get(ownField) == featureValue);
//Loop relation fields
const featuresValues = relationField.map(rField => feature.get(rField));
return features.filter(feature => {
return ownField.reduce((bool, oField, index) => {
return bool && feature.get(oField) == featuresValues[index]
}, true)
});

};

proto.registerLeavePage = function(bool){
Expand Down Expand Up @@ -1118,16 +1133,26 @@ proto.fatherInEditing = function(layerId) {
return inEditing;
};

/**
*
* @param layerId
* @param relation
* @returns {{ownField: *, relationField: *}}
* @private
*/
proto._getRelationFieldsFromRelation = function({layerId, relation} = {}) {
const childId = relation.getChild ? relation.getChild() : relation.child;
const isChild = childId !== layerId;
const _fatherField = relation.getFatherField ? relation.getFatherField() : relation.fatherField;
const _childField = relation.getChildField ? relation.getChildField() : relation.childField;
const ownField = isChild ? _fatherField : _childField;
const relationField = isChild ? _childField : _fatherField;
const _fatherField = relation.getFatherField ?
relation.getFatherField() :
relation.fatherField;
const _childField = relation.getChildField ?
relation.getChildField() :
relation.childField;

return {
ownField,
relationField
ownField: isChild ? _fatherField : _childField,
relationField: isChild ? _childField : _fatherField
}
};

Expand Down Expand Up @@ -1185,11 +1210,18 @@ proto.getLayersDependencyFeaturesFromSource = function({layerId, relation, featu
layerId,
relation
});
const featureValue = feature.get(relationField);
const find = operator === 'eq' ? features.find(featureSource => {
const featureSourceValue = featureSource.get(ownField) ;
return featureSourceValue == featureValue;
}): false;
//get features Values
const featureValues = relationField.map(rField => feature.get(rField));
const find = operator === 'eq' ?

ownField.reduce((bool, oField, index) => {
return features.find(featureSource => {
return bool && featureSource.get(oField) == featureValues[index];
})
}, true) :

false;

resolve(find);
})
};
Expand Down Expand Up @@ -1757,12 +1789,16 @@ proto.getExternalLayersWithSameGeometryOfLayer = function(layer){
const geometryType = layer.getGeometryType();
return this._mapService.getExternalLayers().filter(externalLayer => {
const features = externalLayer.getSource().getFeatures();
if (features && features.length) {
if (features && features.length > 0) {
return features[0].getGeometry() ?
(geometryType === features[0].getGeometry().getType())
||
isSameBaseGeometryType(geometryType, features[0].getGeometry().getType()) : false;
} else return false;
(
(geometryType === features[0].getGeometry().getType()) ||
isSameBaseGeometryType(geometryType, features[0].getGeometry().getType())
) :
false;
} else {
return false;
}
});
};

Expand Down
Loading