@processmaker/modeler 1.40.1 → 1.40.3

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@processmaker/modeler",
3
- "version": "1.40.1",
3
+ "version": "1.40.3",
4
4
  "scripts": {
5
5
  "serve": "vue-cli-service serve --mode development",
6
6
  "test:unit": "vue-cli-service test:unit",
@@ -102,6 +102,8 @@ export default {
102
102
  'highlightedNode.definition.assignedUsers'(current, previous) { this.handleAssignmentChanges(current, previous); },
103
103
  'highlightedNode.definition.assignedGroups'(current, previous) { this.handleAssignmentChanges(current, previous); },
104
104
  'highlightedNode.definition.assignmentRules'(current, previous) { this.handleAssignmentChanges(current, previous); },
105
+ 'highlightedNode.definition.allowInterstitial'(current, previous) { this.handleAssignmentChanges(current, previous); },
106
+ 'highlightedNode.definition.interstitialScreenRef'(current, previous) { this.handleAssignmentChanges(current, previous); },
105
107
  },
106
108
  computed: {
107
109
  inspectorHeaderTitle() {
@@ -254,7 +256,7 @@ export default {
254
256
  defaultInspectorHandler(value, isMultiplayer) {
255
257
  /* Go through each property and rebind it to our data */
256
258
  for (const key in omit(value, ['$type', 'eventDefinitions'])) {
257
- if (this.highlightedNode.definition.get(key) !== value[key]) {
259
+ if (this.highlightedNode.definition.get(key) !== value[key]) {
258
260
  this.multiplayerHook(key, value[key], isMultiplayer);
259
261
  this.setNodeProp(this.highlightedNode, key, value[key]);
260
262
  }
@@ -56,7 +56,7 @@
56
56
 
57
57
  <iframe
58
58
  title="Preview"
59
- v-show="!!previewUrl && !showSpinner"
59
+ :style="{visibility: displayPreviewIframe}"
60
60
  :src="previewUrl"
61
61
  class="preview-iframe"
62
62
  @load="loading"
@@ -95,20 +95,26 @@ export default {
95
95
  }
96
96
  },
97
97
  highlightedNode() {
98
+ // If there isn't preview configuration hide the panel
99
+ const nodeConfig = this.getConfig(this.data);
100
+ if (!nodeConfig) {
101
+ this.$emit('togglePreview', false);
102
+ return;
103
+ }
104
+
98
105
  document.activeElement.blur();
99
- this.prepareData();
106
+ this.previewNode();
100
107
  },
101
- 'highlightedNode.definition'(current, previous) { this.handleAssignmentChanges(current, previous); },
102
- 'highlightedNode.definition.assignmentLock'(current, previous) { this.handleAssignmentChanges(current, previous); },
103
- 'highlightedNode.definition.allowReassignment'(current, previous) { this.handleAssignmentChanges(current, previous); },
104
- 'highlightedNode.definition.assignedUsers'(current, previous) { this.handleAssignmentChanges(current, previous); },
105
- 'highlightedNode.definition.assignedGroups'(current, previous) { this.handleAssignmentChanges(current, previous); },
106
- 'highlightedNode.definition.assignmentRules'(current, previous) { this.handleAssignmentChanges(current, previous); },
107
108
  },
108
109
  computed: {
109
110
  highlightedNode() {
110
111
  return store.getters.highlightedNodes[0];
111
112
  },
113
+ displayPreviewIframe() {
114
+ const result = !!this.previewUrl && !this.showSpinner;
115
+ console.log('mostrar iframe', result);
116
+ return result ? 'visible' : 'hidden';
117
+ },
112
118
  },
113
119
  methods: {
114
120
  loading() {
@@ -137,21 +143,6 @@ export default {
137
143
  this.taskTitle = this.data?.name;
138
144
 
139
145
  this.taskTitle = this?.highlightedNode?.definition?.name;
140
- this.previewNode();
141
- },
142
-
143
- handleAssignmentChanges(currentValue, previousValue) {
144
- if (currentValue === previousValue) {
145
- return;
146
- }
147
-
148
- const nodeConfig = this.getConfig(this.data);
149
-
150
- if (nodeConfig) {
151
- this.prepareData();
152
- } else {
153
- this.$emit('togglePreview', false);
154
- }
155
146
  },
156
147
  onSelectedPreview(item) {
157
148
  this.selectedPreview = item;
@@ -160,7 +151,7 @@ export default {
160
151
  if (!this.highlightedNode || (!this.visible && !force)) {
161
152
  return;
162
153
  }
163
-
154
+ this.prepareData();
164
155
  const previewConfig = this.getConfig(this.data);
165
156
 
166
157
  let clone = {};
@@ -179,7 +170,6 @@ export default {
179
170
  this.previewUrl = nodeHasConfiguredAssets && previewConfig && nodeHasConfigParams
180
171
  ? `${previewConfig.url}?node=${nodeData}`
181
172
  : null;
182
-
183
173
  this.taskTitle = this.highlightedNode?.definition?.name;
184
174
  },
185
175
  onClose() {
@@ -139,6 +139,7 @@
139
139
  @clone-selection="cloneSelection"
140
140
  @default-flow="toggleDefaultFlow"
141
141
  @shape-resize="shapeResize"
142
+ @definition-changed="onNodeDefinitionChanged"
142
143
  />
143
144
 
144
145
  <RailBottom
@@ -237,6 +238,7 @@ import ProcessmakerModelerGenericFlow from '@/components/nodes/genericFlow/gener
237
238
  import Selection from './Selection';
238
239
  import RemoteCursor from '@/components/multiplayer/remoteCursor/RemoteCursor.vue';
239
240
  import Multiplayer from '@/multiplayer/multiplayer';
241
+ import { getBoundaryEventData } from '../nodes/boundaryEvent/boundaryEventUtils';
240
242
 
241
243
  export default {
242
244
  components: {
@@ -353,6 +355,13 @@ export default {
353
355
  'processmaker-modeler-data-output-association',
354
356
  'processmaker-modeler-association',
355
357
  ],
358
+ boundaryEventTypes: [
359
+ 'processmaker-modeler-boundary-timer-event',
360
+ 'processmaker-modeler-boundary-error-event',
361
+ 'processmaker-modeler-boundary-signal-event',
362
+ 'processmaker-modeler-boundary-conditional-event',
363
+ 'processmaker-modeler-boundary-message-event',
364
+ ],
356
365
  };
357
366
  },
358
367
  watch: {
@@ -420,6 +429,12 @@ export default {
420
429
  isMultiplayer: () => store.getters.isMultiplayer,
421
430
  },
422
431
  methods: {
432
+ onNodeDefinitionChanged() {
433
+ // re-render the preview just if the preview pane is open
434
+ if (this.isOpenPreview) {
435
+ this.handlePreview();
436
+ }
437
+ },
423
438
  onStartPreviewResize(event) {
424
439
  this.isResizingPreview = true;
425
440
  this.currentCursorPosition = event.x;
@@ -1177,12 +1192,7 @@ export default {
1177
1192
  'processmaker-modeler-sequence-flow',
1178
1193
  'processmaker-modeler-association',
1179
1194
  'processmaker-modeler-data-input-association',
1180
- 'processmaker-modeler-data-input-association',
1181
- 'processmaker-modeler-boundary-timer-event',
1182
- 'processmaker-modeler-boundary-error-event',
1183
- 'processmaker-modeler-boundary-signal-event',
1184
- 'processmaker-modeler-boundary-conditional-even',
1185
- 'processmaker-modeler-boundary-message-event',
1195
+ ...this.boundaryEventTypes,
1186
1196
  ];
1187
1197
  if (!this.isMultiplayer) {
1188
1198
  return;
@@ -1299,6 +1309,8 @@ export default {
1299
1309
  });
1300
1310
  },
1301
1311
  async addClonedNodes(nodes) {
1312
+ const flowNodes = [];
1313
+
1302
1314
  nodes.forEach(node => {
1303
1315
  if (!node.pool) {
1304
1316
  node.pool = this.poolTarget;
@@ -1308,10 +1320,24 @@ export default {
1308
1320
  addNodeToProcess(node, targetProcess);
1309
1321
 
1310
1322
  this.planeElements.push(node.diagram);
1311
- this.multiplayerHook(node, false);
1323
+
1324
+ if (this.flowTypes.includes(node.type)) {
1325
+ // Add flow to array to render after
1326
+ flowNodes.push(node);
1327
+ } else if (this.boundaryEventTypes.includes(node.type)) {
1328
+ // Get boundary event data
1329
+ const defaultData = getBoundaryEventData(node);
1330
+ window.ProcessMaker.EventBus.$emit('multiplayer-addBoundaryEvent', defaultData);
1331
+ } else {
1332
+ this.multiplayerHook(node, false);
1333
+ }
1334
+
1312
1335
  store.commit('addNode', node);
1313
1336
  this.poolTarget = null;
1314
1337
  });
1338
+
1339
+ // Render flows after all nodes have been added
1340
+ flowNodes.forEach(node => this.multiplayerHook(node, false));
1315
1341
  },
1316
1342
  async removeNode(node, options) {
1317
1343
  // Check if the node is not replaced
@@ -347,7 +347,7 @@ export default {
347
347
  */
348
348
  prepareConectedLinks(shapes){
349
349
  const { paper } = this.paperManager;
350
- this.conectedLinks = [];
350
+ this.connectedLinks = [];
351
351
  this.isValidSelectionLinks = true;
352
352
  shapes.forEach((shape) => {
353
353
  let conectedLinks = this.graph.getConnectedLinks(shape.model);
@@ -368,8 +368,8 @@ export default {
368
368
  }
369
369
  conectedLinks.forEach((link) => {
370
370
  const linkView = paper.findViewByModel(link);
371
- if (!this.conectedLinks.some(obj => obj.id === linkView.id)) {
372
- this.conectedLinks.push(linkView);
371
+ if (!this.connectedLinks.some(obj => obj.id === linkView.id)) {
372
+ this.connectedLinks.push(linkView);
373
373
  this.validateSelectionLinks(linkView);
374
374
  }
375
375
  });
@@ -585,6 +585,7 @@ export default {
585
585
  this.updateSelectionBox();
586
586
  if (this.isMultiplayer) {
587
587
  window.ProcessMaker.EventBus.$emit('multiplayer-updateNodes', this.getProperties(this.selected));
588
+ window.ProcessMaker.EventBus.$emit('multiplayer-updateNodes', this.getConnectedLinkProperties(this.connectedLinks));
588
589
  }
589
590
  },
590
591
 
@@ -600,7 +601,6 @@ export default {
600
601
  if (shape.model.get('type') === 'processmaker.modeler.bpmn.pool') {
601
602
  const childrens = shape.model.component.getElementsUnderArea(shape.model, this.graph)
602
603
  .filter((element) => element.component);
603
-
604
604
  changed = [...changed, ...this.getContainerProperties(childrens, changed)];
605
605
  } else {
606
606
  const { node } = shape.model.component;
@@ -626,6 +626,38 @@ export default {
626
626
 
627
627
  return changed;
628
628
  },
629
+ /**
630
+ * Get connected link properties
631
+ * @param {Array} links
632
+ */
633
+ getConnectedLinkProperties(links) {
634
+ let changed = [];
635
+ links.forEach((linkView) => {
636
+ const waypoint = [];
637
+ const { node } = linkView.model.component;
638
+ node.diagram.waypoint?.forEach(point => {
639
+ waypoint.push({
640
+ x: point.x,
641
+ y: point.y,
642
+ });
643
+ });
644
+ const sourceRefId = linkView.sourceView.model.component.node.definition.id;
645
+ const targetRefId = linkView.targetView.model.component.node.definition.id;
646
+ const nodeType = linkView.model.component.node.type;
647
+ changed.push(
648
+ {
649
+ id: node.definition.id,
650
+ properties: {
651
+ type: nodeType,
652
+ waypoint,
653
+ sourceRefId,
654
+ targetRefId,
655
+ },
656
+ });
657
+
658
+ });
659
+ return changed;
660
+ },
629
661
  /**
630
662
  * Get properties for each boundary inside a shape
631
663
  */
@@ -677,7 +709,7 @@ export default {
677
709
  * Selector will update the waypoints of the related flows
678
710
  */
679
711
  updateFlowsWaypoint(){
680
- this.conectedLinks.forEach((link)=> {
712
+ this.connectedLinks.forEach((link)=> {
681
713
  if (link.model.component && link.model.get('type') === 'standard.Link'){
682
714
  const start = link.sourceAnchor;
683
715
  const end = link.targetAnchor;
@@ -885,7 +917,7 @@ export default {
885
917
  if (this.newPool){
886
918
  /* Remove the shape from its current pool */
887
919
  this.moveElements(this.selected, this.oldPool, this.newPool);
888
- this.moveConectedLinks(this.conectedLinks, this.oldPool, this.newPool);
920
+ this.moveConnectedLinks(this.connectedLinks, this.oldPool, this.newPool);
889
921
  this.newPool = null;
890
922
  this.oldPool = null;
891
923
  this.updateLaneChildren(this.selected);
@@ -1025,7 +1057,7 @@ export default {
1025
1057
  oldPool.model.component.moveElement(shape.model, newPool.model);
1026
1058
  });
1027
1059
  },
1028
- moveConectedLinks(links, oldPool, newPool){
1060
+ moveConnectedLinks(links, oldPool, newPool){
1029
1061
  links.forEach(link => {
1030
1062
  oldPool.model.component.moveFlow(link.model, newPool.model);
1031
1063
  });
@@ -27,6 +27,7 @@ import CrownConfig from '@/components/crown/crownConfig/crownConfig';
27
27
  import highlightConfig from '@/mixins/highlightConfig';
28
28
  import store from '@/store';
29
29
  import { canAddBoundaryEventToTarget } from '@/boundaryEventValidation';
30
+ import { getBoundaryEventData } from '@/components/nodes/boundaryEvent/boundaryEventUtils';
30
31
 
31
32
  export default {
32
33
  components: {
@@ -203,24 +204,9 @@ export default {
203
204
  this.invalidTargetElement = targetElement;
204
205
  },
205
206
  addMultiplayerBoundaryEvent() {
206
- const control = {
207
- bpmnType: this.node.diagram.$type,
208
- id: this.node.diagram.id,
209
- type: this.node.type,
210
- attachedToRef: this.node.definition.get('attachedToRef'),
211
- };
207
+ const defaultData = getBoundaryEventData(this.node);
212
208
 
213
- window.ProcessMaker.EventBus.$emit('multiplayer-addBoundaryEvent', {
214
- x: this.node.diagram.bounds.x,
215
- y: this.node.diagram.bounds.y,
216
- height: this.node.diagram.bounds.height,
217
- width: this.node.diagram.bounds.width,
218
- attachedToRefId: this.node.definition.get('attachedToRef')?.id,
219
- control,
220
- type: this.node.type,
221
- id: this.node.definition.id,
222
- color: this.node.definition.get('color'),
223
- });
209
+ window.ProcessMaker.EventBus.$emit('multiplayer-addBoundaryEvent', defaultData);
224
210
  },
225
211
  },
226
212
  async mounted() {
@@ -234,9 +220,9 @@ export default {
234
220
  const task = this.getTaskUnderShape();
235
221
  this.attachBoundaryEventToTask(task);
236
222
  this.updateShapePosition(task);
237
-
223
+
238
224
  if (this.node.fromCrown) {
239
- this.addMultiplayerBoundaryEvent();
225
+ this.addMultiplayerBoundaryEvent();
240
226
  }
241
227
  },
242
228
  };
@@ -0,0 +1,35 @@
1
+ export const getBoundaryEventData = (node) => {
2
+ const control = {
3
+ bpmnType: node.diagram.$type,
4
+ id: node.diagram.id,
5
+ type: node.type,
6
+ attachedToRef: node.definition.get('attachedToRef'),
7
+ };
8
+
9
+ const eventDefinition = node.definition.get('eventDefinitions')[0];
10
+ const eventDefinitionType = Object.keys(eventDefinition).reduce((acc, key) => {
11
+ if (key.startsWith('time')) {
12
+ acc[key] = eventDefinition[key];
13
+ }
14
+ return acc;
15
+ }, {});
16
+
17
+ const type = Object.keys(eventDefinitionType)[0];
18
+
19
+ return {
20
+ x: node.diagram.bounds.x,
21
+ y: node.diagram.bounds.y,
22
+ height: node.diagram.bounds.height,
23
+ width: node.diagram.bounds.width,
24
+ attachedToRefId: node.definition.get('attachedToRef')?.id,
25
+ control,
26
+ type: node.type,
27
+ id: node.definition.id,
28
+ color: node.definition.get('color'),
29
+ cancelActivity: node.definition.get('cancelActivity'),
30
+ eventTimerDefinition: {
31
+ type,
32
+ body: eventDefinitionType[type]?.body,
33
+ },
34
+ };
35
+ };
@@ -10,6 +10,16 @@ import { defaultDurationTimerEvent } from '@/constants';
10
10
 
11
11
  export const id = 'processmaker-modeler-boundary-timer-event';
12
12
 
13
+ export const setEventTimerDefinition = (moddle, node, type, body) => {
14
+ const eventDefinition = {
15
+ [type]: moddle.create('bpmn:Expression', { body }),
16
+ };
17
+
18
+ return [
19
+ moddle.create('bpmn:TimerEventDefinition', eventDefinition),
20
+ ];
21
+ };
22
+
13
23
  export default merge(cloneDeep(boundaryEventConfig), {
14
24
  id,
15
25
  component,
@@ -58,17 +68,16 @@ export default merge(cloneDeep(boundaryEventConfig), {
58
68
  continue;
59
69
  }
60
70
 
61
- const eventDefinition = {
62
- [type]: moddle.create('bpmn:Expression', { body }),
63
- };
64
-
65
- const eventDefinitions = [
66
- moddle.create('bpmn:TimerEventDefinition', eventDefinition),
67
- ];
68
-
69
- eventDefinitions[0].id = node.definition.get('eventDefinitions')[0].id;
70
-
71
+ const eventDefinitions = setEventTimerDefinition(moddle, node, type, body);
71
72
  setNodeProp(node, 'eventDefinitions', eventDefinitions);
73
+ window.ProcessMaker.EventBus.$emit('multiplayer-updateInspectorProperty', {
74
+ id: node.definition.id,
75
+ key: 'eventTimerDefinition',
76
+ value: {
77
+ type,
78
+ body,
79
+ },
80
+ });
72
81
  } else {
73
82
  window.ProcessMaker.EventBus.$emit('multiplayer-updateInspectorProperty', {
74
83
  id: node.definition.id , key, value: value[key],
@@ -5,6 +5,7 @@ import { taskHeight, taskWidth } from '@/components/nodes/task/taskConfig';
5
5
  import advancedAccordionConfig from '@/components/inspectors/advancedAccordionConfig';
6
6
  import documentationAccordionConfig from '@/components/inspectors/documentationAccordionConfig';
7
7
  import defaultNames from '@/components/nodes/task/defaultNames';
8
+ import { loopCharacteristicsHandler } from '@/components/inspectors/LoopCharacteristics';
8
9
 
9
10
  export const id = 'processmaker-modeler-call-activity';
10
11
 
@@ -86,4 +87,5 @@ export default {
86
87
  ],
87
88
  },
88
89
  ],
90
+ loopCharacteristicsHandler,
89
91
  };
@@ -118,6 +118,7 @@ export default {
118
118
  deep: true,
119
119
  handler() {
120
120
  setupLoopCharacteristicsMarkers(this.node.definition, this.markers, this.$set, this.$delete);
121
+ this.$emit('definition-changed', this.node.definition);
121
122
  },
122
123
  },
123
124
  },
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <b-avatar-group class="container" v-show="!isMultiplayer">
2
+ <b-avatar-group class="container" v-show="isMultiplayer">
3
3
  <template v-for="item in filteredPlayers" >
4
4
  <Avatar :badgeBackgroundColor="item.color" :imgSrc="item.avatar" :userName="item.name" :key="item.key"/>
5
5
  </template>
@@ -128,7 +128,7 @@ export default {
128
128
  const originalTargetElement = this.getDataInputOutputAssociationTargetRef(originalAssociation.definition);
129
129
  const clonedElement = clonedNodes.find(node => node.cloneOf === originalTargetElement.id);
130
130
  const clonedDataInput = getOrFindDataInput(this.moddle, clonedElement, srcClone.definition);
131
-
131
+ clonedDataInput.$parent.$parent = clonedElement.definition;
132
132
  clonedAssociation.definition.set('sourceRef', [srcClone.definition]);
133
133
  clonedAssociation.definition.set('targetRef', clonedDataInput);
134
134
  clonedElement.definition.set('dataInputAssociations', [clonedAssociation.definition]);
@@ -4,6 +4,8 @@ import { getNodeIdGenerator } from '../NodeIdGenerator';
4
4
  import { getDefaultAnchorPoint } from '@/portsUtils';
5
5
  import Room from './room';
6
6
  import store from '@/store';
7
+ import { setEventTimerDefinition } from '@/components/nodes/boundaryTimerEvent';
8
+ import { getBoundaryEventData } from '@/components/nodes/boundaryEvent/boundaryEventUtils';
7
9
 
8
10
  export default class Multiplayer {
9
11
  clientIO = null;
@@ -199,7 +201,13 @@ export default class Multiplayer {
199
201
  */
200
202
  syncLocalNodes(clientId){
201
203
  // Get the process definition
202
- const nodes = this.modeler.nodes.map((node) => this.modeler.multiplayerHook(node, false, true));
204
+ const nodes = this.modeler.nodes.map((node) => {
205
+ if (node.definition.$type === 'bpmn:BoundaryEvent') {
206
+ return getBoundaryEventData(node);
207
+ }
208
+
209
+ return this.modeler.multiplayerHook(node, false, true);
210
+ });
203
211
 
204
212
  nodes.forEach((node) => {
205
213
  const yMapNested = new Y.Map();
@@ -227,7 +235,7 @@ export default class Multiplayer {
227
235
  if (node) {
228
236
  return;
229
237
  }
230
- if (this.modeler.nodeRegistry[value.type] && this.modeler.nodeRegistry[value.type].multiplayerClient) {
238
+ if (this.modeler.nodeRegistry[value.type]?.multiplayerClient) {
231
239
  this.modeler.nodeRegistry[value.type].multiplayerClient(this.modeler, value);
232
240
  } else {
233
241
  this.modeler.addRemoteNode(value);
@@ -559,8 +567,8 @@ export default class Multiplayer {
559
567
  return;
560
568
  }
561
569
  const keys = Object.keys(data).filter((key) => key !== 'id');
562
- const key = keys[0];
563
- const value = data[key];
570
+ let key = keys[0];
571
+ let value = data[key];
564
572
 
565
573
  if (key === 'condition') {
566
574
  node.definition.get('eventDefinitions')[0].get('condition').body = value;
@@ -606,6 +614,15 @@ export default class Multiplayer {
606
614
  node.definition.get('eventDefinitions')[0].signalRef = signal;
607
615
  }
608
616
 
617
+ if (key === 'eventTimerDefinition') {
618
+ const { type, body } = value;
619
+
620
+ const eventDefinitions = setEventTimerDefinition(this.modeler.moddle, node, type, body);
621
+
622
+ key = 'eventDefinitions';
623
+ value = eventDefinitions;
624
+ }
625
+
609
626
  const specialProperties = [
610
627
  'messageRef', 'signalRef', 'gatewayDirection', 'condition', 'allowedUsers', 'allowedGroups',
611
628
  ];
@@ -28,10 +28,10 @@ export default (node) => {
28
28
  const originalInspectorData = node.inspectorData || null;
29
29
 
30
30
  // Override the inspector handler to add loop props
31
- node.inspectorHandler = (value, node, setNodeProp, moddle, definitions, defaultInspectorHandler) => {
31
+ node.inspectorHandler = (value, node, setNodeProp, moddle, definitions, defaultInspectorHandler, isMultiplayer) => {
32
32
  originalInspectorHandler(value, node, setNodeProp, moddle, definitions, defaultInspectorHandler);
33
- value = loopCharacteristicsHandler(value, node, setNodeProp, moddle, definitions);
34
- defaultInspectorHandler(value);
33
+ value = loopCharacteristicsHandler(value, node, setNodeProp, moddle, definitions, isMultiplayer);
34
+ defaultInspectorHandler(value, isMultiplayer);
35
35
  };
36
36
 
37
37
  // Override the data handler to load loop config into the inspector