@processmaker/modeler 1.39.8 → 1.39.9

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,8 +1,8 @@
1
1
  {
2
2
  "name": "@processmaker/modeler",
3
- "version": "1.39.8",
3
+ "version": "1.39.9",
4
4
  "scripts": {
5
- "serve": "vue-cli-service serve",
5
+ "serve": "vue-cli-service serve --mode development",
6
6
  "test:unit": "vue-cli-service test:unit",
7
7
  "lint": "vue-cli-service lint --no-fix",
8
8
  "build-bundle": "vue-cli-service build --target lib --name modeler ./src/components/nodes/index.js",
@@ -56,6 +56,7 @@
56
56
  "jointjs": "^3.1.1",
57
57
  "js-yaml-loader": "^1.2.2",
58
58
  "lodash": "^4.17.21",
59
+ "lodash-contrib": "^4.1200.1",
59
60
  "luxon": "^1.21.1",
60
61
  "mocha-junit-reporter": "^2.0.0",
61
62
  "mustache": "^3.2.1",
@@ -77,7 +78,7 @@
77
78
  "@babel/eslint-parser": "^7.12.16",
78
79
  "@cypress/code-coverage": "^3.11.0",
79
80
  "@panter/vue-i18next": "^0.15.2",
80
- "@processmaker/processmaker-bpmn-moddle": "0.14.0",
81
+ "@processmaker/processmaker-bpmn-moddle": "0.14.1",
81
82
  "@types/jest": "^24.9.1",
82
83
  "@vue/babel-preset-app": "^5.0.4",
83
84
  "@vue/cli-plugin-babel": "~5.0.0",
@@ -152,6 +152,7 @@
152
152
  @remove-nodes="removeNodes"
153
153
  :processNode="processNode"
154
154
  @save-state="pushToUndoStack"
155
+ :isMultiplayer="isMultiplayer"
155
156
  />
156
157
  </b-row>
157
158
 
@@ -173,6 +174,7 @@ import { dia } from 'jointjs';
173
174
  import boundaryEventConfig from '../nodes/boundaryEvent';
174
175
  import BpmnModdle from 'bpmn-moddle';
175
176
  import ExplorerRail from '../rails/explorer-rail/explorer';
177
+ import { isJSON } from 'lodash-contrib';
176
178
  import pull from 'lodash/pull';
177
179
  import remove from 'lodash/remove';
178
180
  import store from '@/store';
@@ -334,7 +336,6 @@ export default {
334
336
  watch: {
335
337
  isRendering() {
336
338
  const loadingMessage = 'Loading process, please be patient.';
337
-
338
339
  if (this.isRendering) {
339
340
  window.ProcessMaker.alert(loadingMessage, 'warning');
340
341
  document.body.style.cursor = 'wait !important';
@@ -919,7 +920,7 @@ export default {
919
920
 
920
921
  this.removeUnsupportedElementAttributes(definition);
921
922
 
922
- const config = definition.config ? JSON.parse(definition.config) : {};
923
+ const config = definition.config && isJSON(definition.config) ? JSON.parse(definition.config) : {};
923
924
  const type = config?.processKey || parser(definition, this.moddle);
924
925
 
925
926
  const unnamedElements = ['bpmn:TextAnnotation', 'bpmn:Association', 'bpmn:DataOutputAssociation', 'bpmn:DataInputAssociation'];
@@ -1144,7 +1145,14 @@ export default {
1144
1145
  this.poolTarget = null;
1145
1146
  });
1146
1147
  },
1147
- async removeNode(node, { removeRelationships = true } = {}) {
1148
+ async removeNode(node, options) {
1149
+ if (this.isMultiplayer) {
1150
+ window.ProcessMaker.EventBus.$emit('multiplayer-removeNode', node);
1151
+ } else {
1152
+ this.removeNodeProcedure(node, options);
1153
+ }
1154
+ },
1155
+ async removeNodeProcedure(node, { removeRelationships = true } = {}) {
1148
1156
  if (!node) {
1149
1157
  // already removed
1150
1158
  return;
@@ -1388,7 +1396,7 @@ export default {
1388
1396
  if (this.isSelecting) {
1389
1397
  this.$refs.selector.endSelection(this.paperManager.paper);
1390
1398
  } else {
1391
- this.$refs.selector.stopDrag(event);
1399
+ this.$refs.selector.stopDrag();
1392
1400
  }
1393
1401
  }
1394
1402
  window.ProcessMaker.EventBus.$emit('custom-pointerclick', event);
@@ -48,6 +48,7 @@ export default {
48
48
  paperManager: Object,
49
49
  useModelGeometry: Boolean,
50
50
  processNode: Object,
51
+ isMultiplayer: Boolean,
51
52
  },
52
53
  data() {
53
54
  return {
@@ -576,6 +577,24 @@ export default {
576
577
  await this.paperManager.awaitScheduledUpdates();
577
578
  this.overPoolStopDrag();
578
579
  this.updateSelectionBox();
580
+ if (this.isMultiplayer) {
581
+ window.ProcessMaker.EventBus.$emit('multiplayer-updateNodes', this.getProperties());
582
+ }
583
+
584
+
585
+ },
586
+ getProperties() {
587
+ const changed = [];
588
+ this.selected.forEach(function(item) {
589
+ changed.push({
590
+ id: item.model.component.node.definition.id,
591
+ properties: {
592
+ clientX: item.model.get('position').x,
593
+ clientY: item.model.get('position').y,
594
+ },
595
+ });
596
+ });
597
+ return changed;
579
598
  },
580
599
  /**
581
600
  * Selector will update the waypoints of the related flows
@@ -71,7 +71,7 @@ export default class Node {
71
71
  }
72
72
 
73
73
  setIds(nodeIdGenerator, id) {
74
- const [nodeId, diagramId] = id ? [ id + '_di'] : nodeIdGenerator.generate();
74
+ const [nodeId, diagramId] = id ? [ id, id + '_di'] : nodeIdGenerator.generate();
75
75
  if (!this.id) {
76
76
  this.id = nodeId;
77
77
  }
@@ -8,6 +8,7 @@ export default class Multiplayer {
8
8
  modeler = null;
9
9
  #nodeIdGenerator = null;
10
10
  room = null;
11
+ deletedItem = null;
11
12
  constructor(modeler) {
12
13
  // define document
13
14
  this.ydoc = new Y.Doc();
@@ -16,8 +17,8 @@ export default class Multiplayer {
16
17
  init() {
17
18
  this.#nodeIdGenerator = getNodeIdGenerator(this.modeler.definitions);
18
19
 
19
- this.room = new Room('room-' + window.ProcessMaker.modeler.process.id);
20
- const wsProvider = new WebsocketProvider('ws://localhost:1234', this.room.getRoom(), this.ydoc);
20
+ this.room = new Room(`room-${window.ProcessMaker.modeler.process.id}`);
21
+ const wsProvider = new WebsocketProvider(process.env.VUE_APP_WEBSOCKET_PROVIDER, this.room.getRoom(), this.ydoc);
21
22
  wsProvider.on('status', () => {
22
23
  // todo status handler
23
24
  });
@@ -25,24 +26,114 @@ export default class Multiplayer {
25
26
  this.yarray = this.ydoc.getArray('modeler');
26
27
  // observe changes of the diagram
27
28
  this.yarray.observe(event => {
28
- event.changes.delta.forEach((value) =>{
29
+ event.changes.delta.forEach((value) => {
29
30
  if (value.insert) {
30
31
  value.insert.forEach((value) => {
31
- this.createShape(value);
32
+ this.createShape(value.toJSON());
32
33
  this.#nodeIdGenerator.updateCounters();
33
34
  });
34
35
  }
35
36
  });
37
+ // remove nodes observer
38
+ if (event.changes.deleted && event.changes.deleted.size > 0) {
39
+ this.removeShape();
40
+ }
41
+ });
42
+ this.yarray.observeDeep(ymapEventArray => {
43
+ ymapEventArray.forEach((ymap) => {
44
+ const ymapNested = ymap.target ;
45
+ const newProperties = {};
46
+ ymap.changes.keys.forEach((change, key) => {
47
+ if (change.action === 'add') {
48
+ // TODO add new properties
49
+ } else if (change.action === 'update') {
50
+ newProperties[key] = ymapNested.get(key);
51
+ } else if (change.action === 'delete') {
52
+ // TODO delete propertiees
53
+ }
54
+ });
55
+ if (Object.keys(newProperties).length > 0 ) {
56
+ newProperties['id'] = ymapNested.get('id');
57
+ this.updateShapes(newProperties);
58
+ }
59
+ });
36
60
  });
37
61
  window.ProcessMaker.EventBus.$on('multiplayer-addNode', ( data ) => {
38
62
  this.addNode(data);
39
63
  });
64
+ window.ProcessMaker.EventBus.$on('multiplayer-removeNode', ( data ) => {
65
+ this.removeNode(data);
66
+ });
67
+ window.ProcessMaker.EventBus.$on('multiplayer-updateNodes', ( data ) => {
68
+ this.updateNodes(data);
69
+ });
40
70
  }
41
71
  addNode(data) {
42
- this.yarray.push([data]);
43
-
72
+ const ymapNested = new Y.Map();
73
+ this.doTransact(ymapNested, data);
74
+ this.yarray.push([ymapNested]);
44
75
  }
45
76
  createShape(value) {
46
77
  this.modeler.handleDropProcedure(value, false);
47
78
  }
79
+ removeNode(data) {
80
+ const index = this.getIndex(data.definition.id);
81
+ this.yarray.delete(index, 1); // delete one element
82
+ }
83
+ getIndex(id) {
84
+ let index = -1;
85
+ for (const value of this.yarray) {
86
+ index ++;
87
+ if (value.get('id') === id) {
88
+ break ;
89
+ }
90
+ }
91
+ return index;
92
+ }
93
+ removeShape() {
94
+ const nodes = this.getRemovedNodes(this.modeler.nodes, this.yarray.toArray());
95
+ nodes.forEach((value) => {
96
+ this.modeler.removeNodeProcedure(value, true);
97
+ });
98
+ }
99
+ getRemovedNodes(array1, array2) {
100
+ return array1.filter(object1 => {
101
+ return !array2.some(object2 => {
102
+ return object1.definition.id === object2.get('id');
103
+ });
104
+ });
105
+ }
106
+ updateNodes(data) {
107
+ data.forEach((value) => {
108
+ const index = this.getIndex(value.id);
109
+ const nodeToUpdate = this.yarray.get(index);
110
+ this.doTransact(nodeToUpdate, value.properties);
111
+ });
112
+ }
113
+ doTransact(ymapNested, data) {
114
+ this.ydoc.transact(() => {
115
+ for (const key in data) {
116
+ if (Object.prototype.hasOwnProperty.call(data, key)) {
117
+ ymapNested.set(key, data[key]);
118
+ }
119
+ }
120
+ });
121
+ }
122
+ updateShapes(data) {
123
+ const { paper } = this.modeler;
124
+ const element = this.getJointElement(paper.model, data.id);
125
+ // Update the element's position attribute
126
+ element.set('position', { x:data.clientX, y:data.clientY });
127
+ // Trigger a rendering of the element on the paper
128
+ paper.findViewByModel(element).update();
129
+ }
130
+ getJointElement(graph, targetValue) {
131
+ const cells = graph.getCells();
132
+ for (const cell of cells) {
133
+ if (cell.component.id === targetValue) {
134
+ return cell;
135
+ }
136
+ }
137
+ return null; // Return null if no matching element is found
138
+ }
48
139
  }
@@ -1,4 +1,3 @@
1
-
2
1
  export default class Room {
3
2
  #room ='';
4
3
  constructor(name) {
@@ -7,4 +6,4 @@ export default class Room {
7
6
  getRoom() {
8
7
  return this.#room;
9
8
  }
10
- }
9
+ }
@@ -51,7 +51,7 @@ window.ProcessMaker = {
51
51
  },
52
52
  modeler: {
53
53
  process: {
54
- id: 3,
54
+ id: 1,
55
55
  },
56
56
  },
57
57
  };