@processmaker/modeler 1.27.0 → 1.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,8 +12,60 @@ export default class DataOutputAssociation extends DataAssociation {
12
12
  return false;
13
13
  }
14
14
 
15
- return DataAssociation.isADataNode(targetNode) &&
16
- DataOutputAssociation.isValidSourceNode(sourceNode);
15
+ const dataStoreValidSources = [
16
+ 'bpmn:Task',
17
+ 'bpmn:SubProcess',
18
+ 'bpmn:CallActivity',
19
+ 'bpmn:ManualTask',
20
+ 'bpmn:ScriptTask',
21
+ 'bpmn:ServiceTask',
22
+ ];
23
+ const dataStoreValidTargets = [
24
+ 'bpmn:Task',
25
+ 'bpmn:SubProcess',
26
+ 'bpmn:CallActivity',
27
+ 'bpmn:ManualTask',
28
+ 'bpmn:ScriptTask',
29
+ 'bpmn:ServiceTask',
30
+ ];
31
+ const dataObjectValidSources = [
32
+ 'bpmn:Task',
33
+ 'bpmn:SubProcess',
34
+ 'bpmn:CallActivity',
35
+ 'bpmn:ManualTask',
36
+ 'bpmn:ScriptTask',
37
+ 'bpmn:ServiceTask',
38
+ 'bpmn:IntermediateCatchEvent',
39
+ 'bpmn:StartEvent',
40
+ ];
41
+ const dataObjectValidTargets = [
42
+ 'bpmn:Task',
43
+ 'bpmn:SubProcess',
44
+ 'bpmn:CallActivity',
45
+ 'bpmn:ManualTask',
46
+ 'bpmn:ScriptTask',
47
+ 'bpmn:ServiceTask',
48
+ 'bpmn:IntermediateThrowEvent',
49
+ 'bpmn:EndEvent',
50
+ ];
51
+
52
+ const sourceType = sourceNode.definition.$type;
53
+ const targetType = targetNode.definition.$type;
54
+ const sourceIsDataStore = sourceNode.definition.$type === 'bpmn:DataStoreReference';
55
+ const sourceIsDataObject = sourceNode.definition.$type === 'bpmn:DataObjectReference';
56
+ const targetIsDataStore = targetNode.definition.$type === 'bpmn:DataStoreReference';
57
+ const targetIsDataObject = targetNode.definition.$type === 'bpmn:DataObjectReference';
58
+
59
+ if (sourceIsDataStore && dataStoreValidTargets.includes(targetType)) {
60
+ return true;
61
+ }
62
+ if (sourceIsDataObject && dataObjectValidTargets.includes(targetType)) {
63
+ return true;
64
+ }
65
+ if (targetIsDataStore && dataStoreValidSources.includes(sourceType)) {
66
+ return true;
67
+ }
68
+ return (targetIsDataObject && dataObjectValidSources.includes(sourceType));
17
69
  }
18
70
 
19
71
  makeFlowNode(sourceShape, targetShape, genericLink) {
@@ -86,23 +86,6 @@ export default {
86
86
  },
87
87
  },
88
88
  watch: {
89
- 'node.definition': {
90
- handler() {
91
- const newNameLabel = this.shapeName;
92
-
93
- if (newNameLabel !== this.nameLabel) {
94
- this.nameLabel = newNameLabel;
95
- }
96
- this.setDefaultMarker(this.isDefaultFlow());
97
- },
98
- deep: true,
99
- },
100
- 'node.definition.sourceRef': {
101
- handler() {
102
- this.setDefaultMarker(this.isDefaultFlow());
103
- },
104
- deep: true,
105
- },
106
89
  },
107
90
  methods: {
108
91
  completeLink() {
@@ -10,7 +10,7 @@ import cloneDeep from 'lodash/cloneDeep';
10
10
 
11
11
  export default class Node {
12
12
  static diagramPropertiesToCopy = ['x', 'y', 'width', 'height'];
13
- static definitionPropertiesToNotCopy = ['$type', 'id'];
13
+ static definitionPropertiesToNotCopy = ['$type', 'id', 'dataOutputAssociations'];
14
14
  static flowDefinitionPropertiesToNotCopy = ['$type', 'id', 'sourceRef', 'targetRef'];
15
15
  static eventDefinitionPropertiesToNotCopy = ['errorRef', 'messageRef'];
16
16
 
@@ -81,6 +81,70 @@ export default class Node {
81
81
  this.diagram.id = diagramId;
82
82
  this.diagram.bpmnElement = this.definition;
83
83
  }
84
+ if (this.definition.loopCharacteristics && this.definition.loopCharacteristics.$type === 'bpmn:StandardLoopCharacteristics') {
85
+ this.definition.loopCharacteristics.set('id', nodeIdGenerator.generate()[0]);
86
+ if (this.definition.loopCharacteristics.loopCondition) {
87
+ this.definition.loopCharacteristics.get('loopCondition').set('id', nodeIdGenerator.generate()[0]);
88
+ }
89
+ }
90
+ let dataInputRef, dataOutputRef;
91
+ if (this.definition.ioSpecification) {
92
+ this.definition.ioSpecification.set('id', nodeIdGenerator.generate()[0]);
93
+ const taskId = this.definition.id;
94
+ if (this.definition.ioSpecification.get('dataInputs')) {
95
+ this.definition.ioSpecification.get('dataInputs').forEach(dataInput => {
96
+ const id = dataInput.get('id');
97
+ if (id.substring(0, this.cloneOf.length) === this.cloneOf) {
98
+ dataInput.set('id', id.replace(this.cloneOf + '_', taskId + '_'));
99
+ dataInputRef = dataInput;
100
+ } else {
101
+ dataInput.set('id', nodeIdGenerator.generate()[0]);
102
+ }
103
+ });
104
+ }
105
+ if (this.definition.ioSpecification.get('dataOutputs')) {
106
+ this.definition.ioSpecification.get('dataOutputs').forEach(dataOutput => {
107
+ const id = dataOutput.get('id');
108
+ if (id.substring(0, this.cloneOf.length) === this.cloneOf) {
109
+ dataOutput.set('id', id.replace(this.cloneOf + '_', taskId + '_'));
110
+ dataOutputRef = dataOutput;
111
+ } else {
112
+ dataOutput.set('id', nodeIdGenerator.generate()[0]);
113
+ }
114
+ });
115
+ }
116
+ if (this.definition.ioSpecification.get('inputSets')) {
117
+ this.definition.ioSpecification.get('inputSets').forEach(inputSet => {
118
+ inputSet.set('id', nodeIdGenerator.generate()[0]);
119
+ });
120
+ }
121
+ if (this.definition.ioSpecification.get('outputSets')) {
122
+ this.definition.ioSpecification.get('outputSets').forEach(outputSet => {
123
+ outputSet.set('id', nodeIdGenerator.generate()[0]);
124
+ });
125
+ }
126
+ }
127
+ if (this.definition.loopCharacteristics && this.definition.loopCharacteristics.$type === 'bpmn:MultiInstanceLoopCharacteristics') {
128
+ this.definition.loopCharacteristics.set('id', nodeIdGenerator.generate()[0]);
129
+ if (this.definition.loopCharacteristics.loopCardinality) {
130
+ this.definition.loopCharacteristics.get('loopCardinality').set('id', nodeIdGenerator.generate()[0]);
131
+ }
132
+ if (this.definition.loopCharacteristics.loopDataInputRef && dataInputRef) {
133
+ this.definition.loopCharacteristics.set('loopDataInputRef', dataInputRef);
134
+ }
135
+ if (this.definition.loopCharacteristics.loopDataOutputRef && dataOutputRef) {
136
+ this.definition.loopCharacteristics.set('loopDataOutputRef', dataOutputRef);
137
+ }
138
+ if (this.definition.loopCharacteristics.inputDataItem) {
139
+ this.definition.loopCharacteristics.get('inputDataItem').set('id', nodeIdGenerator.generate()[0]);
140
+ }
141
+ if (this.definition.loopCharacteristics.outputDataItem) {
142
+ this.definition.loopCharacteristics.get('outputDataItem').set('id', nodeIdGenerator.generate()[0]);
143
+ }
144
+ if (this.definition.loopCharacteristics.completionCondition) {
145
+ this.definition.loopCharacteristics.get('completionCondition').set('id', nodeIdGenerator.generate()[0]);
146
+ }
147
+ }
84
148
  }
85
149
 
86
150
  clone(nodeRegistry, moddle, $t) {
@@ -90,7 +154,7 @@ export default class Node {
90
154
 
91
155
  clonedNode.id = null;
92
156
  clonedNode.pool = this.pool;
93
- clonedNode.definition.cloneOf = this.id;
157
+ clonedNode.cloneOf = this.id;
94
158
 
95
159
  Node.diagramPropertiesToCopy.forEach(prop => clonedNode.diagram.bounds[prop] = this.diagram.bounds[prop]);
96
160
  Object.keys(this.definition).filter(key => !Node.definitionPropertiesToNotCopy.includes(key)).forEach(key => {
@@ -99,7 +163,7 @@ export default class Node {
99
163
  if (key === 'eventDefinitions') {
100
164
  for (var i in clonedDefinition) {
101
165
  if (definition[i].signalRef && !clonedDefinition[i].signalRef) {
102
- clonedDefinition[i].signalRef = { ...definition[i].signalRef };
166
+ clonedDefinition[i].set('signalRef', { ...definition[i].signalRef });
103
167
  }
104
168
  }
105
169
  }
@@ -122,7 +186,7 @@ export default class Node {
122
186
 
123
187
  clonedFlow.id = null;
124
188
  clonedFlow.pool = this.pool;
125
- clonedFlow.definition.cloneOf = this.id;
189
+ clonedFlow.cloneOf = this.id;
126
190
  clonedFlow.diagram.waypoint = [];
127
191
 
128
192
  this.diagram.waypoint.forEach(point => clonedFlow.diagram.waypoint.push(point));
@@ -133,12 +197,13 @@ export default class Node {
133
197
  if (key === 'eventDefinitions') {
134
198
  for (var i in clonedDefinition) {
135
199
  if (definition[i].signalRef && !clonedDefinition[i].signalRef) {
136
- clonedDefinition[i].signalRef = { ...definition[i].signalRef };
200
+ clonedDefinition[i].set('signalRef', { ...definition[i].signalRef });
137
201
  }
138
202
  }
139
203
  }
140
204
  clonedFlow.definition.set(key, clonedDefinition);
141
- clonedFlow.definition.sourceRef = clonedFlow.definition.targetRef = null;
205
+ clonedFlow.definition.set('sourceRef', null);
206
+ clonedFlow.definition.set('targetRef', null);
142
207
  });
143
208
 
144
209
  Node.eventDefinitionPropertiesToNotCopy.forEach(
@@ -0,0 +1,145 @@
1
+ import { id as laneId } from '../components/nodes/poolLane/config';
2
+ import { id as sequenceFlowId } from '../components/nodes/sequenceFlow';
3
+ import { id as associationId } from '../components/nodes/association';
4
+ import { id as messageFlowId } from '../components/nodes/messageFlow/config';
5
+ import { id as dataOutputAssociationFlowId } from '../components/nodes/dataOutputAssociation/config';
6
+ import { id as dataInputAssociationFlowId } from '../components/nodes/dataInputAssociation/config';
7
+ import { id as genericFlowId } from '../components/nodes/genericFlow/config';
8
+ import { getOrFindDataInput, findIOSpecificationOwner } from '../components/crown/utils';
9
+
10
+ export default {
11
+ methods: {
12
+ cloneSelection() {
13
+ let clonedNodes = [], clonedFlows = [], clonedDataInputAssociations = [], clonedDataOutputAssociations = [];
14
+ const nodes = this.highlightedNodes;
15
+ const selector = this.$refs.selector.$el;
16
+ const flowNodeTypes = [
17
+ sequenceFlowId,
18
+ laneId,
19
+ associationId,
20
+ messageFlowId,
21
+ genericFlowId,
22
+ ];
23
+ const dataInputAssociationNodeTypes = [
24
+ dataInputAssociationFlowId,
25
+ ];
26
+ const dataOutputAssociationNodeTypes = [
27
+ dataOutputAssociationFlowId,
28
+ ];
29
+
30
+ if (typeof selector.getBoundingClientRect === 'function') {
31
+ nodes.forEach(node => {
32
+ if (flowNodeTypes.includes(node.type)) {
33
+ const clonedFlow = this.cloneFlowAndSetNewId(node);
34
+ clonedFlows.push(clonedFlow);
35
+ clonedNodes.push(clonedFlow);
36
+ } else if (dataInputAssociationNodeTypes.includes(node.type)) {
37
+ const clonedFlow = this.cloneFlowAndSetNewId(node);
38
+ clonedDataInputAssociations.push(clonedFlow);
39
+ clonedNodes.push(clonedFlow);
40
+ } else if (dataOutputAssociationNodeTypes.includes(node.type)) {
41
+ const clonedFlow = this.cloneFlowAndSetNewId(node);
42
+ clonedDataOutputAssociations.push(clonedFlow);
43
+ clonedNodes.push(clonedFlow);
44
+ } else {
45
+ const clonedElement = this.cloneElementAndCalculateOffset(node);
46
+ clonedNodes.push(clonedElement);
47
+ }
48
+ });
49
+ }
50
+
51
+ this.connectClonedFlows(clonedFlows, clonedNodes);
52
+ this.connectClonedDataInputAssociations(clonedDataInputAssociations, clonedNodes);
53
+ this.connectClonedDataOutputAssociations(clonedDataOutputAssociations, clonedNodes);
54
+
55
+ return clonedNodes;
56
+ },
57
+ // Returns the Flow Element (Task| DataStore| DataObject) that is the target of the association
58
+ getDataInputOutputAssociationTargetRef(association) {
59
+ if (association.targetRef.$type === 'bpmn:DataInput') {
60
+ const ioSpec = association.targetRef.$parent;
61
+ return findIOSpecificationOwner(ioSpec, this);
62
+ }
63
+ if (association.targetRef.$type === 'bpmn:DataInputAssociation') {
64
+ const ioSpec = association.targetRef.$parent;
65
+ return findIOSpecificationOwner(ioSpec, this);
66
+ }
67
+ return association.targetRef;
68
+ },
69
+ cloneFlowAndSetNewId(node) {
70
+ const clonedFlow = node.cloneFlow(this.nodeRegistry, this.moddle, this.$t);
71
+ clonedFlow.setIds(this.nodeIdGenerator);
72
+ return clonedFlow;
73
+ },
74
+ cloneElementAndCalculateOffset(node) {
75
+ const clonedElement = node.clone(this.nodeRegistry, this.moddle, this.$t);
76
+ const { height: selectorHeight } = this.$refs.selector.$el.getBoundingClientRect();
77
+ const { sy } = this.paper.scale();
78
+ const yOffset = selectorHeight / sy;
79
+ clonedElement.diagram.bounds.y += yOffset;
80
+ clonedElement.setIds(this.nodeIdGenerator);
81
+ return clonedElement;
82
+ },
83
+ connectClonedFlows(clonedFlows, clonedNodes) {
84
+ clonedFlows.forEach(clonedFlow => {
85
+ const originalFlow = this.nodes.find(node => node.definition.id === clonedFlow.cloneOf);
86
+ const src = originalFlow.definition.sourceRef;
87
+ const target = originalFlow.definition.targetRef;
88
+ const srcClone = clonedNodes.find(node => node.cloneOf === src.id);
89
+ const targetClone = clonedNodes.find(node => node.cloneOf === target.id);
90
+ if (!srcClone || !targetClone) {
91
+ clonedNodes.splice(clonedNodes.indexOf(clonedFlow), 1);
92
+ return;
93
+ }
94
+ clonedFlow.definition.set('sourceRef', srcClone.definition);
95
+ clonedFlow.definition.set('targetRef', targetClone.definition);
96
+
97
+ if (srcClone.definition.outgoing) {
98
+ srcClone.definition.outgoing.push(clonedFlow.definition);
99
+ } else {
100
+ srcClone.definition.set('outgoing', [clonedFlow.definition]);
101
+ }
102
+
103
+ if (targetClone.definition.incoming) {
104
+ targetClone.definition.incoming.push(clonedFlow.definition);
105
+ } else {
106
+ targetClone.definition.set('incoming', [clonedFlow.definition]);
107
+ }
108
+
109
+ clonedFlow.diagram.waypoint.forEach(point => {
110
+ const { height: selectorHeight } = this.$refs.selector.$el.getBoundingClientRect();
111
+ point.y += selectorHeight;
112
+ });
113
+ });
114
+ },
115
+ connectClonedDataInputAssociations(clonedDataInputAssociations, clonedNodes) {
116
+ clonedDataInputAssociations.forEach(clonedAssociation => {
117
+ const originalAssociation = this.nodes.find(node => node.definition.id === clonedAssociation.cloneOf);
118
+ const src = originalAssociation.definition.sourceRef[0];
119
+ const srcClone = clonedNodes.find(node => node.cloneOf === src.id);
120
+ const originalTargetElement = this.getDataInputOutputAssociationTargetRef(originalAssociation.definition);
121
+ const clonedElement = clonedNodes.find(node => node.cloneOf === originalTargetElement.id);
122
+ const clonedDataInput = getOrFindDataInput(this.moddle, clonedElement, srcClone.definition);
123
+
124
+ clonedAssociation.definition.set('sourceRef', [srcClone.definition]);
125
+ clonedAssociation.definition.set('targetRef', clonedDataInput);
126
+ clonedElement.definition.set('dataInputAssociations', [clonedAssociation.definition]);
127
+ });
128
+ },
129
+ connectClonedDataOutputAssociations(clonedDataOutputAssociations, clonedNodes) {
130
+ clonedDataOutputAssociations.forEach(clonedAssociation => {
131
+ const originalAssociation = this.nodes.find(node => node.definition.id === clonedAssociation.cloneOf);
132
+ const src = originalAssociation.definition.sourceRef || originalAssociation.definition.$parent;
133
+ const target = originalAssociation.definition.targetRef;
134
+ const srcClone = clonedNodes.find(node => node.cloneOf === src.id);
135
+ const targetClone = clonedNodes.find(node => node.cloneOf === target.id);
136
+
137
+ clonedAssociation.definition.set('targetRef', targetClone.definition);
138
+ clonedAssociation.definition.set('sourceRef', srcClone.definition);
139
+
140
+ const existingOutputAssociations = srcClone.definition.get('dataOutputAssociations') || [];
141
+ srcClone.definition.set('dataOutputAssociations', [...existingOutputAssociations, clonedAssociation.definition]);
142
+ });
143
+ },
144
+ },
145
+ };
@@ -78,7 +78,7 @@ export default {
78
78
  });
79
79
  },
80
80
  setEndpoint(shape, endpoint, connectionOffset) {
81
- if (isPoint(shape)) {
81
+ if (shape && isPoint(shape)) {
82
82
  return this.shape[endpoint](shape, {
83
83
  anchor: {
84
84
  name: 'modelCenter',
@@ -253,6 +253,9 @@ export default {
253
253
  ? this.getTargetRef()
254
254
  : this.node.definition.get('targetRef');
255
255
 
256
+ // if flow doesn't have a targetRef such as incomplete node, return
257
+ if (!targetRef) return;
258
+
256
259
  if (targetRef.id) {
257
260
  const targetShape = this.graph.getElements().find(element => {
258
261
  return element.component && element.component.node.definition === targetRef;
package/src/store.js CHANGED
@@ -36,8 +36,7 @@ export default new Vuex.Store({
36
36
  globalProcesses: [],
37
37
  allowSavingElementPosition: true,
38
38
  copiedElements: [],
39
- clientX: null,
40
- clientY: null,
39
+ clientLeftPaper: false,
41
40
  },
42
41
  getters: {
43
42
  nodes: state => state.nodes,
@@ -56,8 +55,7 @@ export default new Vuex.Store({
56
55
  globalProcessEvents: (state, getters) => flatten(getters.globalProcesses.map(process => process.events)),
57
56
  allowSavingElementPosition: state => state.allowSavingElementPosition,
58
57
  copiedElements: state => state.copiedElements,
59
- clientX: state => state.clientX,
60
- clientY: state => state.clientY,
58
+ clientLeftPaper: state => state.clientLeftPaper,
61
59
  },
62
60
  mutations: {
63
61
  preventSavingElementPosition(state) {
@@ -148,13 +146,8 @@ export default new Vuex.Store({
148
146
  setCopiedElements(state, elements) {
149
147
  state.copiedElements = elements;
150
148
  },
151
- setClientMousePosition(state, position) {
152
- const { clientX, clientY } = position;
153
- state = { clientX, clientY };
154
- },
155
- clientLeftPaper(state) {
156
- state.clientX = null;
157
- state.clientY = null;
149
+ setClientLeftPaper(state, status) {
150
+ state.clientLeftPaper = status;
158
151
  },
159
152
  },
160
153
  actions: {