@processmaker/modeler 1.30.1 → 1.30.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.30.1",
3
+ "version": "1.30.3",
4
4
  "scripts": {
5
5
  "serve": "vue-cli-service serve",
6
6
  "open-cypress": "TZ=UTC cypress open",
package/src/.DS_Store CHANGED
Binary file
@@ -35,6 +35,7 @@ import { id as messageFlowId } from '@/components/nodes/messageFlow/config';
35
35
  import { id as dataOutputAssociationFlowId } from '@/components/nodes/dataOutputAssociation/config';
36
36
  import { id as dataInputAssociationFlowId } from '@/components/nodes/dataInputAssociation/config';
37
37
  import { labelWidth, poolPadding } from '../nodes/pool/poolSizes';
38
+ import { invalidNodeColor, poolColor } from '@/components/nodeColors';
38
39
 
39
40
  export default {
40
41
  name: 'Selection',
@@ -80,6 +81,10 @@ export default {
80
81
  selectableBlackList:[
81
82
  genericFlowId,
82
83
  ],
84
+ newPool: null,
85
+ oldPool: null,
86
+ isValidSelectionLinks: true,
87
+ invalidPool: null,
83
88
  };
84
89
  },
85
90
  mounted(){
@@ -147,13 +152,21 @@ export default {
147
152
  return;
148
153
  }
149
154
  // validate if there is a lane previously selected
150
- let lane = this.selected.find(view => {
151
- return this.draggableBlackList.includes(view.model.component.node.type);
155
+ let lane = this.selected.find(shape => {
156
+ return this.draggableBlackList.includes(shape.model.component.node.type);
152
157
  });
153
158
  if (lane) {
154
159
  this.selected = [view];
155
160
  return;
156
- }
161
+ }
162
+ // validate if there is a lane previously selected
163
+ let pool = this.selected.find(shape => {
164
+ return shape.model.component.node.type === poolId;
165
+ });
166
+ if (pool && view.model.component.node.type !== poolId) {
167
+ this.selected = [view];
168
+ return;
169
+ }
157
170
  // validate if the current selection is a pool
158
171
  if (view.model.component && view.model.component.node.type === poolId) {
159
172
  //validate if previous selection are all pools
@@ -164,6 +177,14 @@ export default {
164
177
  }
165
178
  return;
166
179
  }
180
+ // prevent select out of the current pool container
181
+ if (view.model.component && view.model.component.node.pool){
182
+ pool = this.getPool(this.selected);
183
+ if (pool && view.model.component.node.pool.id !== pool.model.get('id')) {
184
+ this.selected = [view];
185
+ return;
186
+ }
187
+ }
167
188
  this.selectOrUnselectShape(view);
168
189
  },
169
190
  /**
@@ -296,6 +317,20 @@ export default {
296
317
  });
297
318
  return elements;
298
319
  },
320
+ /**
321
+ * Check if a point is into the area
322
+ * @param {Object} position
323
+ * @param {Object} area
324
+ */
325
+ isPositionWithinArea(position, area) {
326
+ const { x, y, width, height } = area;
327
+ return (
328
+ position.x >= x &&
329
+ position.x <= x + width &&
330
+ position.y >= y &&
331
+ position.y <= y + height
332
+ );
333
+ },
299
334
  /**
300
335
  * Prepare the conectedLinks collection
301
336
  * @param {Array} shapes
@@ -303,17 +338,52 @@ export default {
303
338
  prepareConectedLinks(shapes){
304
339
  const { paper } = this.paperManager;
305
340
  this.conectedLinks = [];
341
+ this.isValidSelectionLinks = true;
306
342
  shapes.forEach((shape) => {
307
- const conectedLinks = this.graph.getConnectedLinks(shape.model);
343
+ let conectedLinks = this.graph.getConnectedLinks(shape.model);
344
+ // if the shape is a container
345
+ if ( shape.model.component && shape.model.component.node.type === poolId) {
346
+ const area = shape.model.getBBox();
347
+ const linksInArea = paper.model.getLinks().filter((link) => {
348
+ const sourcePosition = link.getSourcePoint();
349
+ const targetPosition = link.getTargetPoint();
350
+ return (
351
+ this.isPositionWithinArea(sourcePosition, area) ||
352
+ this.isPositionWithinArea(targetPosition, area)
353
+ );
354
+ });
355
+ if (linksInArea) {
356
+ conectedLinks = [...conectedLinks, ...linksInArea];
357
+ }
358
+ }
308
359
  conectedLinks.forEach((link) => {
309
360
  const linkView = paper.findViewByModel(link);
310
361
  if (!this.conectedLinks.some(obj => obj.id === linkView.id)) {
311
362
  this.conectedLinks.push(linkView);
363
+ this.validateSelectionLinks(linkView);
312
364
  }
313
365
  });
314
-
315
366
  });
316
367
  },
368
+ /**
369
+ * Validate if the selection is valid to drag and drop in other container
370
+ * @param {Object} linkView
371
+ */
372
+ validateSelectionLinks(linkView){
373
+ if (this.isValidSelectionLinks) {
374
+ const source = this.selected.find(shape => {
375
+ return shape.model.get('id') === linkView.model.getSourceElement().get('id');
376
+ });
377
+ const target = this.selected.find(shape => {
378
+ return shape.model.get('id') === linkView.model.getTargetElement().get('id');
379
+ });
380
+ if (source && target) {
381
+ this.isValidSelectionLinks = true;
382
+ } else {
383
+ this.isValidSelectionLinks = false;
384
+ }
385
+ }
386
+ },
317
387
  /**
318
388
  * Return the bounding box of the selected elements,
319
389
  * @param {Array} selected
@@ -494,14 +564,15 @@ export default {
494
564
  * Stop drag procedure
495
565
  * @param {Object} event
496
566
  */
497
- stopDrag() {
567
+ async stopDrag() {
498
568
  this.dragging = false;
499
569
  this.stopForceMove = false;
500
570
  // Readjusts the selection box, taking into consideration elements
501
571
  // that are anchored and did not move, such as boundary events.
502
- this.updateSelectionBox();
503
- this.updateFlowsWaypoint();
572
+ await this.$nextTick();
573
+ await this.paperManager.awaitScheduledUpdates();
504
574
  this.overPoolStopDrag();
575
+ this.updateSelectionBox();
505
576
  },
506
577
  /**
507
578
  * Selector will update the waypoints of the related flows
@@ -534,10 +605,12 @@ export default {
534
605
  return drafRef.model.get('id') !== shape.model.get('id');
535
606
  });
536
607
  }
537
- // allow movement only if one lane boundary event is selected;
608
+ // allow movements only if one boundary event is selected;
538
609
  if (this.selected && this.selected.length === 1 &&
539
610
  this.selected[0].model.get('type') === 'processmaker.components.nodes.boundaryEvent.Shape') {
540
611
  this.selected[0].model.translate(x, y);
612
+ // validation about boundary event movements
613
+ this.selected[0].model.component.turnInvalidTargetRed();
541
614
  return;
542
615
  }
543
616
  shapes.forEach((shape)=> shape.model.translate(x, y));
@@ -623,6 +696,21 @@ export default {
623
696
  let selectedArea = g.rect(f.x, f.y, width, height);
624
697
  return this.getElementsInSelectedArea(selectedArea, { strict: false });
625
698
  },
699
+ getPool(elements){
700
+ const { paper } = this.paperManager;
701
+ let pool = null;
702
+ if (elements && elements.length > 0) {
703
+ elements.forEach(({ model }) => {
704
+ if (pool) {
705
+ return;
706
+ }
707
+ if (model.getParentCell() && model.getParentCell().component.node.type === poolId){
708
+ pool = model.getParentCell();
709
+ }
710
+ });
711
+ }
712
+ return paper.findViewByModel(pool);
713
+ },
626
714
  /**
627
715
  * Check that they are not in a pool
628
716
  * @param {Array} elements
@@ -647,18 +735,35 @@ export default {
647
735
  if (this.isNotPoolChilds(this.selected)) {
648
736
  return;
649
737
  }
738
+ const currentPool = this.getPool(this.selected);
650
739
  const elementsUnderDivArea = this.getShapesFromPoint(event);
651
740
  const pool = elementsUnderDivArea.find(item => {
652
741
  return item.model.component && item.model.component.node.type === poolId;
653
742
  });
743
+ this.newPool = null;
744
+ this.oldPool = null;
654
745
  if (!pool) {
655
746
  this.isOutOfThePool = true;
656
747
  store.commit('preventSavingElementPosition');
657
748
  this.paperManager.setStateInvalid();
658
749
  } else {
659
- this.isOutOfThePool = false;
660
- store.commit('preventSavingElementPosition');
661
750
  this.paperManager.setStateValid();
751
+
752
+ if (this.invalidPool) {
753
+ this.invalidPool.model.component.shape.attr('body/fill', poolColor);
754
+ this.invalidPool = null;
755
+ }
756
+ if (currentPool && currentPool.model.get('id') !== pool.model.get('id')) {
757
+ this.newPool = pool;
758
+ this.oldPool = currentPool;
759
+ this.isOutOfThePool = false;
760
+ if (!this.isValidSelectionLinks){
761
+ this.isOutOfThePool = true;
762
+ this.invalidPool = pool;
763
+ pool.model.component.shape.attr('body/fill', invalidNodeColor);
764
+ store.commit('preventSavingElementPosition');
765
+ }
766
+ }
662
767
  }
663
768
  },
664
769
  /**
@@ -666,14 +771,31 @@ export default {
666
771
  */
667
772
  overPoolStopDrag(){
668
773
  if (this.isNotPoolChilds(this.selected)) {
774
+ this.updateFlowsWaypoint();
669
775
  this.$emit('save-state');
670
776
  return;
671
777
  }
672
778
  if (this.isOutOfThePool) {
673
779
  this.rollbackSelection();
780
+ if (this.invalidPool) {
781
+ this.invalidPool.model.component.shape.attr('body/fill', poolColor);
782
+ this.invalidPool = null;
783
+ }
674
784
  } else {
675
- this.expandToFitElement(this.selected);
676
- this.$emit('save-state');
785
+ this.updateFlowsWaypoint();
786
+ if (this.newPool){
787
+ /* Remove the shape from its current pool */
788
+ this.moveElements(this.selected, this.oldPool, this.newPool);
789
+ this.newPool = null;
790
+ this.oldPool = null;
791
+ this.updateLaneChildren(this.selected);
792
+ this.$emit('save-state');
793
+ } else {
794
+ this.expandToFitElement(this.selected);
795
+ this.updateLaneChildren(this.selected);
796
+ this.$emit('save-state');
797
+ }
798
+
677
799
  }
678
800
  },
679
801
  /**
@@ -695,7 +817,6 @@ export default {
695
817
  shape.model.translate(deltaX/scale.sx, deltaY/scale.sy);
696
818
  });
697
819
  this.isOutOfThePool = false;
698
- this.updateFlowsWaypoint();
699
820
  await store.commit('allowSavingElementPosition');
700
821
  this.paperManager.setStateValid();
701
822
  await this.$nextTick();
@@ -774,6 +895,35 @@ export default {
774
895
  }
775
896
  }
776
897
  },
898
+ /**
899
+ * Updates the lane children when a element is moved into the pool
900
+ * @param {Array} selected
901
+ */
902
+ updateLaneChildren(selected){
903
+ if (!selected) {
904
+ return;
905
+ }
906
+ const pool = selected.find(({ model }) => {
907
+ if (model.getParentCell()) {
908
+ return model.getParentCell().component.node.type === poolId;
909
+ }
910
+ return false;
911
+ });
912
+ if (pool){
913
+ pool.model.getParentCell();
914
+ pool.model.component.laneSet && pool.component.updateLaneChildren();
915
+ }
916
+ },
917
+ moveElements(selected, oldPool, newPool){
918
+ const shapesToMove= [
919
+ 'PoolLane',
920
+ 'standard.Link',
921
+ ];
922
+ selected.filter(shape => !shapesToMove.includes(shape.model.get('type')))
923
+ .forEach(shape => {
924
+ oldPool.model.component.moveElement(shape.model, newPool.model);
925
+ });
926
+ },
777
927
  },
778
928
  };
779
929
  </script>
@@ -174,8 +174,6 @@ export default {
174
174
  this.shape.listenToOnce(this.paper, 'cell:pointerup blank:pointerup', () => {
175
175
  this.moveBoundaryEventIfOverTask();
176
176
  this.resetInvalidTarget();
177
- this.$emit('save-state');
178
-
179
177
  store.commit('allowSavingElementPosition');
180
178
  });
181
179
  },
@@ -216,8 +214,6 @@ export default {
216
214
  const task = this.getTaskUnderShape();
217
215
  this.attachBoundaryEventToTask(task);
218
216
  this.updateShapePosition(task);
219
-
220
- this.shape.on('change:position', this.turnInvalidTargetRed);
221
217
  },
222
218
  };
223
219
  </script>
@@ -6,9 +6,10 @@ import DataAssociation from '@/components/nodes/genericFlow/DataAssociation';
6
6
 
7
7
  export default class SequenceFlow extends Flow {
8
8
  static isValid({ sourceShape, targetShape, targetConfig }) {
9
+
9
10
  const targetNode = get(targetShape, 'component.node');
10
11
  const sourceNode = get(sourceShape, 'component.node');
11
-
12
+
12
13
  return Flow.hasTargetType(targetShape) &&
13
14
  Flow.targetIsNotSource(sourceNode, targetNode) &&
14
15
  SequenceFlow.targetIsNotALane(targetNode) &&
@@ -42,7 +42,6 @@ import highlightConfig from '@/mixins/highlightConfig';
42
42
  import AddLaneAboveButton from '@/components/crown/crownButtons/addLaneAboveButton';
43
43
  import AddLaneBelowButton from '@/components/crown/crownButtons/addLaneBelowButton';
44
44
  import { configurePool, elementShouldHaveFlowNodeRef } from '@/components/nodes/pool/poolUtils';
45
- import PoolEventHandlers from '@/components/nodes/pool/poolEventHandlers';
46
45
  import Node from '@/components/nodes/node';
47
46
  import { aPortEveryXPixels } from '@/portsUtils';
48
47
 
@@ -500,13 +499,6 @@ export default {
500
499
  }
501
500
  this.setPoolSize(this.shape);
502
501
  this.$emit('set-shape-stacking', this.shape);
503
-
504
- this.$nextTick(() => {
505
- const handler = new PoolEventHandlers(this.graph, this.paper, this.paperManager, this.shape, this);
506
- this.shape.listenTo(this.graph, 'change:position', (element, newPosition) => handler.onChangePosition(element, newPosition));
507
- this.shape.listenTo(this.paper, 'cell:pointerdown', (cellView) => handler.onPointerDown(cellView));
508
- this.shape.listenTo(this.paper, 'cell:pointerup', (cellView) => handler.onPointerUp(cellView));
509
- });
510
502
  },
511
503
  beforeDestroy() {
512
504
  const participants = this.collaboration.get('participants');
@@ -125,11 +125,11 @@ export default {
125
125
  this.$emit('set-shape-stacking', sourceShape);
126
126
  },
127
127
  /**
128
- * On Change vertices handler
129
- * @param {Object} link
130
- * @param {Array} vertices
131
- * @param {Object} options
132
- */
128
+ * On Change vertices handler
129
+ * @param {Object} link
130
+ * @param {Array} vertices
131
+ * @param {Object} options
132
+ */
133
133
  onChangeVertices(link, vertices, options){
134
134
  if (options && options.ui) {
135
135
  this.updateWaypoints();
@@ -305,7 +305,6 @@ export default {
305
305
  this.paper.el.addEventListener('mousemove', this.updateLinkTarget);
306
306
 
307
307
  this.$emit('set-cursor', 'not-allowed');
308
-
309
308
  if (this.isValidConnection) {
310
309
  this.shape.stopListening(this.paper, 'blank:pointerdown link:pointerdown element:pointerdown', this.removeLink);
311
310
  } else {