Skip to content

Commit

Permalink
Adds backend constraint CRUD and serialization of constraints. re #4375
Browse files Browse the repository at this point in the history
  • Loading branch information
chiatt committed Mar 27, 2019
1 parent c0fb11b commit 34df626
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 37 deletions.
52 changes: 26 additions & 26 deletions arches/app/media/js/models/card.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,8 @@ define([
this.sortorder = ko.observable();
this.disabled = ko.observable();
this.component_id = ko.observable();
this.constraints = ko.observableArray([
{
uniqueToAllInstances: false,
nodeIds: []
}
]);
this.constraints = ko.observableArray();
this.uniqueConstraints = ko.observableArray();

this.set('cards', this.cards);
this.set('nodes', this.nodes);
Expand Down Expand Up @@ -152,25 +148,33 @@ define([
this.updateConstraints = function(){
var self = this;
return function(){
console.log(self.constraints());
var updatedConstraints = self.uniqueConstraints().map(function(c){
return {
nodeIds: ko.unwrap(c.nodeIds),
uniqueToAllInstances: ko.unwrap(c.uniqueToAllInstances)
uniquetoallinstances: ko.unwrap(c.uniqueToAllInstances),
constraintid: c.constraintid,
cardid: c.cardid
};
});
self.constraints(updatedConstraints);
self.set('constraints', updatedConstraints);
self.constraints.valueHasMutated();
};
};

this.uniqueConstraints = ko.observableArray();
this.constraints().forEach(function(constraint){
constraint.widgets = self.widgets();
var constraintViewModel = new CardConstraintsViewModel(constraint);
constraintViewModel.nodeIds.subscribe(self.updateConstraints());
constraintViewModel.uniqueToAllInstances.subscribe(self.updateConstraints());
self.uniqueConstraints.push(constraintViewModel);
});
this.setConstraints = function(arr) {
var self = this;
self.uniqueConstraints.removeAll();
arr.forEach(function(constraint){
constraint.widgets = self.widgets();
var constraintViewModel = new CardConstraintsViewModel(constraint);
constraintViewModel.nodeIds.subscribe(self.updateConstraints());
constraintViewModel.uniqueToAllInstances.subscribe(self.updateConstraints());
self.uniqueConstraints.push(constraintViewModel);
});
}

this.setConstraints(this.constraints());

this.disposables.push(componentIdSubscription);
this.disposables.push(cardSubscription);
Expand Down Expand Up @@ -233,6 +237,10 @@ define([
this.set('id', value);
this.get(key)(value);
break;
case 'constraints':
// this.set(key, koMapping.fromJS(value));
this.get(key)(value);
break;
case 'name':
case 'nodegroup_id':
case 'instructions':
Expand All @@ -256,7 +264,6 @@ define([
this.set(key, value);
}
}, this);

this._card(JSON.stringify(this.toJSON()));
},

Expand Down Expand Up @@ -314,16 +321,8 @@ define([
widget.label(originalWidgetData.label);
widget.widget_id(originalWidgetData.widget_id);
}
this._attributes.data.constraints.forEach(function(constraint){
constraint.widgets = this.widgets();
var constraintViewModel = new CardConstraintsViewModel(constraint);
constraintViewModel.nodeIds.subscribe(this.updateConstraints());
constraintViewModel.uniqueToAllInstances.subscribe(this.updateConstraints());
this.uniqueConstraints.push(constraintViewModel);
});
// this.setConstraints(this._attributes.data.constraints);
}, this);


this.parse(this._attributes);
},

Expand Down Expand Up @@ -367,6 +366,7 @@ define([
},

save: function(callback) {
console.log(this);
AbstractModel.prototype.save.call(this, function(request, status, self) {
if (status === 'success') {
this._card(JSON.stringify(this.toJSON()));
Expand Down
10 changes: 6 additions & 4 deletions arches/app/media/js/viewmodels/card-constraints.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@ define([
], function(ko) {
var ConstraintViewModel = function(params) {

this.uniqueToAllInstances = ko.observable(params.uniqueToAllInstances || false);
this.uniqueToAllInstances = ko.observable(params.uniquetoallinstances || false);
this.widgets = params.widgets || [];
this.nodeIds = ko.observableArray();

this.nodeIds = ko.observableArray(params.nodes);
this.cardid = params.card_id;
this.constraintid = params.constraintid;
this.getSelect2ConstraintConfig = function(placeholder){
var nodeOptions = this.widgets.map(function(c){return {text: c.label(), id: c.node.nodeid};});
return {
clickBubble: true,
disabled: false,
data: {results: this.widgets.map(function(c){return {text: c.label(), id: c.node.nodeid};})},
data: {results: nodeOptions},
value: this.nodeIds,
multiple: params.multiple || true,
closeOnSelect: false,
Expand Down
1 change: 0 additions & 1 deletion arches/app/media/js/viewmodels/card.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ define([
var nodegroup = _.find(ko.unwrap(nodegroups), function(group) {
return ko.unwrap(group.nodegroupid) === ko.unwrap(params.card.nodegroup_id);
});

var cardModel = new CardModel({
data: _.extend(params.card, {
widgets: params.cardwidgets,
Expand Down
1 change: 0 additions & 1 deletion arches/app/media/js/views/graph-designer.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ define([
'views/components/simple-switch'
], function($, _, ko, koMapping, BaseManagerView, AlertViewModel, GraphModel, ReportModel, GraphView, GraphTree, NodeFormView, BranchListView, CardTreeViewModel, PermissionDesigner, data, arches, GraphSettingsViewModel, CardViewModel, viewData, reportLookup) {
var GraphDesignerView = BaseManagerView.extend({

initialize: function(options) {
var viewModel = options.viewModel;
viewModel.graphid = ko.observable(data.graphid);
Expand Down
18 changes: 17 additions & 1 deletion arches/app/media/js/views/graph/graph-designer/card-tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,23 @@ 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,
nodeIds:[],
cardid: undefined,
constraintid: undefined
});
}
card.constraints = cardConstraints;
});
this.flattenTree = function(parents, flatList) {
_.each(ko.unwrap(parents), function(parent) {
flatList.push(parent);
Expand Down
54 changes: 50 additions & 4 deletions arches/app/models/card.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@
'''

from django.db import transaction
from django.db.models import Q
from django.core.exceptions import ObjectDoesNotExist
from django.forms import ModelForm
from arches.app.models import models
from arches.app.utils.betterJSONSerializer import JSONSerializer
from django.forms import ModelForm


class Card(models.CardModel):
"""
Expand All @@ -31,6 +32,46 @@ class Card(models.CardModel):
class Meta:
proxy = True

def update_constraints(self, constraints):

def add_nodeconstraints(nodeids, constraint_model):
for nodeid in nodeids:
print('adding nodes', nodeid)
node_constraint = models.ConstraintXNode()
node_constraint.node = models.Node.objects.get(pk=nodeid)
node_constraint.constraint = constraint_model
node_constraint.save()

for constraint in constraints:
constraintid = constraint.get('constraintid', None)
unique_to_all = constraint.get('uniquetoallinstances', False)
nodeids = constraint.get('nodeIds', [])
if constraintid is None:
constraint_model = models.ConstraintModel()
constraint_model.card = self
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()
print(models.ConstraintXNode.objects.filter(Q(constraint=constraint_model)))
constraint_model.save()
except ObjectDoesNotExist as e:
print e
self.constraints = constraint_model

def __init__(self, *args, **kwargs):
"""
Init a Card from a dictionary representation of from a model method call
Expand Down Expand Up @@ -79,16 +120,21 @@ def __init__(self, *args, **kwargs):
self.widgets = []
self.nodes = []
self.ontologyproperty = None
self.constraints = []

if args:
if isinstance(args[0], dict):
for key, value in args[0].iteritems():
if key not in ('cards', 'widgets', 'nodes', 'is_editable', 'nodegroup'):
if key not in ('cards', 'widgets', 'nodes', 'is_editable', 'nodegroup', 'constraints'):
setattr(self, key, value)

if 'cards' in args[0]:
for card in args[0]["cards"]:
self.cards.append(Card(card))

if 'constraints':
self.update_constraints(args[0]["constraints"])

if 'widgets' in args[0]:
for widget in args[0]["widgets"]:
cardxnodexwidgetid = widget.get('id', None)
Expand Down Expand Up @@ -208,7 +254,7 @@ def serialize(self, fields=None, exclude=None):
ret['ontologyproperty'] = self.ontologyproperty if 'ontologyproperty' not in exclude else ret.pop(
'ontologyproperty', None)
ret['disabled'] = self.disabled if 'disabled' not in exclude else ret.pop('disabled', None)

ret['constraints'] = self.constraints if 'constraints' not in exclude else ret.pop('constraints', None)
if self.graph and self.graph.ontology and self.graph.isresource:
edge = self.get_edge_to_parent()
ret['ontologyproperty'] = edge.ontologyproperty
Expand Down
1 change: 1 addition & 0 deletions arches/app/templates/views/graph-designer.htm
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ <h4 class="ep-form-toolbar-title">
ontology_namespaces: {{ontology_namespaces}},
branches: {{branches}},
cards: {{cards}},
constraints: {{constraints}},
cardwidgets: {{cardwidgets}},
widgets: {{widgets_json}},
cardComponents: {{card_components_json}},
Expand Down
7 changes: 7 additions & 0 deletions arches/app/views/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,12 @@ def get(self, request, graphid):
datatypes_json = JSONSerializer().serialize(datatypes, exclude=['modulename', 'isgeometric'])
branch_graphs = Graph.objects.exclude(pk=graphid).exclude(isresource=True)
cards = self.graph.cardmodel_set.order_by('sortorder').prefetch_related('cardxnodexwidget_set')
models.ConstraintModel.objects.filter(card=cards[0].cardid)
constraints = []
for card in cards:
if models.ConstraintModel.objects.filter(card=card).count() > 0:
constraints += models.ConstraintModel.objects.filter(card=card)

cardwidgets = [widget for widgets in [card.cardxnodexwidget_set.order_by(
'sortorder').all() for card in cards] for widget in widgets]
widgets = models.Widget.objects.all()
Expand Down Expand Up @@ -232,6 +238,7 @@ def get(self, request, graphid):
'title': help_title,
'template': 'graph-tab-help',
}
context['constraints'] = JSONSerializer().serialize(constraints)

return render(request, 'views/graph-designer.htm', context)

Expand Down

0 comments on commit 34df626

Please sign in to comment.