532c24f3b36851587216c80e1145e6b09292761d
[sdc/sdc-workflow-designer.git] /
1 import inherits from 'inherits';
2
3 import { pick, assign } from 'min-dash';
4
5 import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
6
7 import {
8     add as collectionAdd,
9     remove as collectionRemove
10 } from 'diagram-js/lib/util/Collections';
11
12 /**
13  * A handler responsible for updating the custom element's businessObject
14  * once changes on the diagram happen.
15  */
16 export default function CustomUpdater(eventBus, bpmnjs) {
17     CommandInterceptor.call(this, eventBus);
18
19     function updateCustomElement(e) {
20         var context = e.context,
21             shape = context.shape,
22             businessObject = shape.businessObject;
23
24         if (!isCustom(shape)) {
25             return;
26         }
27
28         var parent = shape.parent;
29
30         var customElements = bpmnjs._customElements;
31
32         // make sure element is added / removed from bpmnjs.customElements
33         if (!parent) {
34             collectionRemove(customElements, businessObject);
35         } else {
36             collectionAdd(customElements, businessObject);
37         }
38
39         // save custom element position
40         assign(businessObject, pick(shape, ['x', 'y']));
41     }
42
43     function updateCustomConnection(e) {
44         var context = e.context,
45             connection = context.connection,
46             source = connection.source,
47             target = connection.target,
48             businessObject = connection.businessObject;
49
50         var parent = connection.parent;
51
52         var customElements = bpmnjs._customElements;
53
54         // make sure element is added / removed from bpmnjs.customElements
55         if (!parent) {
56             collectionRemove(customElements, businessObject);
57         } else {
58             collectionAdd(customElements, businessObject);
59         }
60
61         // update waypoints
62         assign(businessObject, {
63             waypoints: copyWaypoints(connection)
64         });
65
66         if (source && target) {
67             assign(businessObject, {
68                 source: source.id,
69                 target: target.id
70             });
71         }
72     }
73
74     this.executed(
75         ['shape.create', 'shape.move', 'shape.delete'],
76         ifCustomElement(updateCustomElement)
77     );
78
79     this.reverted(
80         ['shape.create', 'shape.move', 'shape.delete'],
81         ifCustomElement(updateCustomElement)
82     );
83
84     this.executed(
85         [
86             'connection.create',
87             'connection.reconnectStart',
88             'connection.reconnectEnd',
89             'connection.updateWaypoints',
90             'connection.delete',
91             'connection.layout',
92             'connection.move'
93         ],
94         ifCustomElement(updateCustomConnection)
95     );
96
97     this.reverted(
98         [
99             'connection.create',
100             'connection.reconnectStart',
101             'connection.reconnectEnd',
102             'connection.updateWaypoints',
103             'connection.delete',
104             'connection.layout',
105             'connection.move'
106         ],
107         ifCustomElement(updateCustomConnection)
108     );
109 }
110
111 inherits(CustomUpdater, CommandInterceptor);
112
113 CustomUpdater.$inject = ['eventBus', 'bpmnjs'];
114
115 /////// helpers ///////////////////////////////////
116
117 function copyWaypoints(connection) {
118     return connection.waypoints.map(function(p) {
119         return { x: p.x, y: p.y };
120     });
121 }
122
123 function isCustom(element) {
124     return element && /custom:/.test(element.type);
125 }
126
127 function ifCustomElement(fn) {
128     return function(event) {
129         var context = event.context,
130             element = context.shape || context.connection;
131
132         if (isCustom(element)) {
133             fn(event);
134         }
135     };
136 }