From bfc17c4971baf09abaec9f79762349f84618cfbc Mon Sep 17 00:00:00 2001 From: Cyrus Hiatt Date: Tue, 16 Apr 2019 12:55:50 -0700 Subject: [PATCH] Prevents extra constraint records from getting saved to the database. re #4375 --- arches/app/media/js/models/card.js | 21 +++++----- arches/app/media/js/viewmodels/card.js | 13 ++++++- .../views/graph/graph-designer/card-tree.js | 38 +++++++++---------- arches/app/models/card.py | 32 ++++++++-------- 4 files changed, 56 insertions(+), 48 deletions(-) diff --git a/arches/app/media/js/models/card.js b/arches/app/media/js/models/card.js index 06e02a7c23e..e9495295fcd 100644 --- a/arches/app/media/js/models/card.js +++ b/arches/app/media/js/models/card.js @@ -72,7 +72,6 @@ define([ this.set('component_id', this.component_id); this.set('config', {}); this.set('constraints', this.constraints); - this.cardComponentLookup = cardComponentLookup; this.configKeys = ko.observableArray(); this.disposables = []; @@ -126,16 +125,18 @@ define([ this.setConstraints = function(arr) { var self = this; - arr.forEach(function(constraint){ - var constraintViewModel = new CardConstraintsViewModel({ - constraint: koMapping.fromJS(constraint), - widgets: self.widgets() + if (arr) { + arr.forEach(function(constraint){ + var constraintViewModel = new CardConstraintsViewModel({ + constraint: koMapping.fromJS(constraint), + widgets: self.widgets() + }); + constraintViewModel.constraint.nodes.subscribe(function(){ + self.toJSON(); + }, self); + self.constraints.push(constraintViewModel); }); - constraintViewModel.constraint.nodes.subscribe(function(){ - self.toJSON(); - }, self); - self.constraints.push(constraintViewModel); - }); + } }; this.sourceData = attributes; diff --git a/arches/app/media/js/viewmodels/card.js b/arches/app/media/js/viewmodels/card.js index 4b3760f785e..6173fe8f209 100644 --- a/arches/app/media/js/viewmodels/card.js +++ b/arches/app/media/js/viewmodels/card.js @@ -7,9 +7,10 @@ define([ 'models/card-widget', 'arches', 'require', + 'uuid', 'utils/dispose', 'viewmodels/tile' -], function($, _, ko, koMapping, CardModel, CardWidgetModel, arches, require, dispose) { +], function($, _, ko, koMapping, CardModel, CardWidgetModel, arches, require, uuid, dispose) { /** * A viewmodel used for generic cards * @@ -71,6 +72,12 @@ define([ var multiselect = params.multiselect || false; var isWritable = params.card.is_writable || false; var selection; + var emptyConstraint = [{ + uniquetoallinstances: false, + nodes:[], + cardid: self.cardid, + constraintid: uuid.generate() + }]; if (params.multiselect) { selection = params.selection || ko.observableArray([]); } else { @@ -83,7 +90,8 @@ define([ data: _.extend(params.card, { widgets: params.cardwidgets, nodes: params.graphModel.get('nodes'), - nodegroup: nodegroup + nodegroup: nodegroup, + constraints: params.constraints }), datatypelookup: params.graphModel.get('datatypelookup'), }); @@ -134,6 +142,7 @@ define([ parentCard: params.parentCard, expanded: ko.observable(false), perms: perms, + constraints: params.constraints || emptyConstraint, permsLiteral: permsLiteral, scrollTo: ko.pureComputed(function() { return scrollTo() === this; diff --git a/arches/app/media/js/views/graph/graph-designer/card-tree.js b/arches/app/media/js/views/graph/graph-designer/card-tree.js index bcf8577ce19..0a9d895bcad 100644 --- a/arches/app/media/js/views/graph/graph-designer/card-tree.js +++ b/arches/app/media/js/views/graph/graph-designer/card-tree.js @@ -5,12 +5,13 @@ define([ 'viewmodels/card', 'models/card-widget', 'arches', + 'uuid', 'graph-designer-data', 'bindings/sortable', 'bindings/scrollTo', 'widgets', 'card-components' -], function($, _, ko, CardViewModel, CardWidgetModel, arches, data) { +], function($, _, ko, CardViewModel, CardWidgetModel, arches, uuid, data) { var CardTreeViewModel = function(params) { var self = this; var filter = ko.observable(''); @@ -26,23 +27,16 @@ define([ var scrollTo = ko.observable(); var cachedFlatTree; var cardList = data.cards; - data.cards.forEach(function(card){ - var cardConstraints = []; - data.constraints.forEach(function(constraint){ - if (card.cardid === constraint.card_id) { - cardConstraints.push(constraint); - } - }); - if (cardConstraints.length === 0) { - cardConstraints.push({ - uniquetoallinstances: false, - nodes:[], - cardid: undefined, - constraintid: undefined - }); - } - card.constraints = cardConstraints; - }); + + var getBlankConstraint = function(card){ + return [{ + uniquetoallinstances: false, + nodes: [], + cardid: card.cardid, + constraintid: uuid.generate() + }] + }; + this.flattenTree = function(parents, flatList) { _.each(ko.unwrap(parents), function(parent) { flatList.push(parent); @@ -170,6 +164,10 @@ define([ }); return !nodegroup || !ko.unwrap(nodegroup.parentnodegroup_id); }).map(function(card) { + var constraints = data.constraints.filter(function(ct){return ct.card_id === card.cardid;}); + if (constraints.length === 0) { + constraints = getBlankConstraint(card); + } return new CardViewModel({ card: card, graphModel: params.graphModel, @@ -178,6 +176,7 @@ define([ displayname: ko.observable(), handlers: {}, cards: data.cards, + constraints: constraints, tiles: [], selection: selection, hover: hover, @@ -317,7 +316,8 @@ define([ userisreviewer: true, perms: ko.observableArray(), permsLiteral: ko.observableArray(), - parentCard: parent + parentCard: parent, + constraints: getBlankConstraint(data.card) }); parentcards.push(newCardViewModel); diff --git a/arches/app/models/card.py b/arches/app/models/card.py index 374468f2104..43a1c717165 100644 --- a/arches/app/models/card.py +++ b/arches/app/models/card.py @@ -46,29 +46,27 @@ def add_nodeconstraints(nodeids, constraint_model): constraintid = constraint.get('constraintid', None) unique_to_all = constraint.get('uniquetoallinstances', False) nodeids = constraint.get('nodes', []) - if constraintid is None: + try: + constraint_model = models.ConstraintModel.objects.get(pk=constraintid) + constraint_model.uniquetoallinstances = unique_to_all + current_nodeids = {str(i.nodeid) for i in constraint_model.nodes.all()} + future_nodeids = set(nodeids) + nodes_to_remove = current_nodeids - future_nodeids + nodes_to_add = future_nodeids - current_nodeids + add_nodeconstraints(nodes_to_add, constraint_model) + models.ConstraintXNode.objects.filter( + Q(constraint=constraint_model) & + Q(node__in=nodes_to_remove) + ).delete() + constraint_model.save() + except ObjectDoesNotExist as e: constraint_model = models.ConstraintModel() constraint_model.card = self + constraint_model.constraintid = constraintid constraint_model.uniquetoallinstances = unique_to_all constraint_model.save() add_nodeconstraints(nodeids, constraint_model) constraint_model.save() - else: - try: - constraint_model = models.ConstraintModel.objects.get(pk=constraintid) - constraint_model.uniquetoallinstances = unique_to_all - current_nodeids = {str(i.nodeid) for i in constraint_model.nodes.all()} - future_nodeids = set(nodeids) - nodes_to_remove = current_nodeids - future_nodeids - nodes_to_add = future_nodeids - current_nodeids - add_nodeconstraints(nodes_to_add, constraint_model) - models.ConstraintXNode.objects.filter( - Q(constraint=constraint_model) & - Q(node__in=nodes_to_remove) - ).delete() - constraint_model.save() - except ObjectDoesNotExist as e: - print e constraint_models.append(constraint_model) self.constraints = constraint_models