1
|
/**
|
2
|
* Class representing a change. In a single change, lists of components to be changed and proposals are stored.
|
3
|
* Changes can be postponed and back activated.
|
4
|
* @constructor
|
5
|
*/
|
6
|
function Change() {
|
7
|
var rootElement;
|
8
|
var buttonGroup;
|
9
|
var includeNotFoundCheckbox;
|
10
|
var replaceComponentsCheckbox;
|
11
|
var triggerChangeButton;
|
12
|
var oldVertexListComponent;
|
13
|
var newVertexListComponent;
|
14
|
|
15
|
var oldVertexList = [];
|
16
|
var newVertexList = [];
|
17
|
|
18
|
var postponed = false;
|
19
|
var triggered = false;
|
20
|
var detailsLoaded = false;
|
21
|
|
22
|
/* TODO: display change in modal window
|
23
|
app.changeModalWindow.setChange(this);
|
24
|
app.changeModalWindow.open();
|
25
|
*/
|
26
|
|
27
|
/**
|
28
|
* Adds a new vertex to the list of components to be changed. The vertex is set as excluded and its DOM element
|
29
|
* is removed from document. Its edges are moved so that they end at the group.
|
30
|
* @param {Vertex} vertex Vertex to be added to the change.
|
31
|
*/
|
32
|
this.addVertex = function(vertex) {
|
33
|
if (!(vertex instanceof Vertex)) {
|
34
|
throw new TypeError(vertex.toString() + 'is not instance of Vertex');
|
35
|
}
|
36
|
|
37
|
// set remove hook
|
38
|
vertex.removeFromSidebarList = this.removeVertex.bind(this, vertex);
|
39
|
|
40
|
oldVertexList.push(vertex);
|
41
|
oldVertexListComponent.appendChild(vertex);
|
42
|
|
43
|
app.redrawEdges();
|
44
|
|
45
|
// vertex list changed so different results could be retrieved when triggered again
|
46
|
this.setTriggered(false);
|
47
|
this.setDetailsLoaded(false);
|
48
|
|
49
|
toggleButtonGroup.call(this);
|
50
|
};
|
51
|
|
52
|
/**
|
53
|
* Removes a vertex from the list of component to be changed. The vertex is returned back to the viewport and
|
54
|
* its edges are moved to it.
|
55
|
* @param {Vertex} vertex Vertex to be removed from the change.
|
56
|
*/
|
57
|
this.removeVertex = function(vertex) {
|
58
|
if (!(vertex instanceof Vertex)) {
|
59
|
throw new TypeError(vertex.toString() + 'is not instance of Vertex');
|
60
|
}
|
61
|
|
62
|
// unset remove hook
|
63
|
vertex.removeFromSidebarList = app.utils.noop;
|
64
|
|
65
|
oldVertexList.splice(oldVertexList.indexOf(vertex), 1);
|
66
|
oldVertexListComponent.removeChild(vertex);
|
67
|
|
68
|
app.redrawEdges();
|
69
|
|
70
|
// vertex list changed so different results could be retrieved when triggered again
|
71
|
this.setTriggered(false);
|
72
|
this.setDetailsLoaded(false);
|
73
|
|
74
|
toggleButtonGroup.call(this);
|
75
|
};
|
76
|
|
77
|
/**
|
78
|
* @returns {array<Vertex>} List of components to be changed.
|
79
|
*/
|
80
|
this.getOldVertexList = function() {
|
81
|
return oldVertexList;
|
82
|
};
|
83
|
|
84
|
/**
|
85
|
* @returns {boolean} True if the change was already triggered, otherwise false.
|
86
|
*/
|
87
|
this.isTriggered = function() {
|
88
|
return triggered;
|
89
|
};
|
90
|
|
91
|
/**
|
92
|
* Sets the change as triggered.
|
93
|
* @param {boolean} newValue True to set the change as trigger, otherwise false.
|
94
|
*/
|
95
|
this.setTriggered = function(newValue) {
|
96
|
triggered = newValue;
|
97
|
|
98
|
if (newValue) {
|
99
|
rootElement.classList.add('change--triggered');
|
100
|
} else {
|
101
|
rootElement.classList.remove('change--triggered');
|
102
|
}
|
103
|
};
|
104
|
|
105
|
/**
|
106
|
* @returns {boolean} True if the details of proposed component were loaded, otherwise false.
|
107
|
*/
|
108
|
this.isDetailsLoaded = function() {
|
109
|
return detailsLoaded;
|
110
|
};
|
111
|
|
112
|
/**
|
113
|
* Sets the change details as loaded.
|
114
|
* @param {boolean} newValue True to set the change as it has details loaded, otherwise false.
|
115
|
*/
|
116
|
this.setDetailsLoaded = function(newValue) {
|
117
|
detailsLoaded = newValue;
|
118
|
|
119
|
if (newValue) {
|
120
|
rootElement.classList.add('change--details-loaded');
|
121
|
} else {
|
122
|
rootElement.classList.remove('change--details-loaded');
|
123
|
}
|
124
|
};
|
125
|
|
126
|
/**
|
127
|
* @returns {boolean} True if the change is currently postponed, otherwise false.
|
128
|
*/
|
129
|
this.isPostponed = function() {
|
130
|
return postponed;
|
131
|
};
|
132
|
|
133
|
/**
|
134
|
* Sets the change postponed.
|
135
|
* @param {boolean} newValue True to set the change as postponed, otherwise false.
|
136
|
*/
|
137
|
this.setPostponed = function(newValue) {
|
138
|
postponed = newValue;
|
139
|
|
140
|
if (newValue) {
|
141
|
rootElement.classList.add('change--postponed');
|
142
|
} else {
|
143
|
rootElement.classList.remove('change--postponed');
|
144
|
}
|
145
|
};
|
146
|
|
147
|
/**
|
148
|
* Postpones the change. Removes its current DOM element from document.
|
149
|
*/
|
150
|
this.postpone = function() {
|
151
|
this.setPostponed(true);
|
152
|
this.remove();
|
153
|
};
|
154
|
|
155
|
/**
|
156
|
* Activates the change. Removes its current DOM element from document.
|
157
|
*/
|
158
|
this.activate = function() {
|
159
|
this.setPostponed(false);
|
160
|
this.remove();
|
161
|
};
|
162
|
|
163
|
/**
|
164
|
* Creates a new DOM element representing the change in memory. The element being created depends on whether the change
|
165
|
* is postponed at the moment. Binds user interactions to local handler functions.
|
166
|
* @returns {Element} HTML or SVG DOM element depending on whether the change is postponed.
|
167
|
*/
|
168
|
this.render = function() {
|
169
|
rootElement = postponed ? renderPostponed.call(this) : renderActive.call(this);
|
170
|
|
171
|
this.setPostponed(postponed);
|
172
|
this.setDetailsLoaded(detailsLoaded);
|
173
|
this.setTriggered(triggered);
|
174
|
toggleButtonGroup.call(this);
|
175
|
|
176
|
return rootElement;
|
177
|
};
|
178
|
|
179
|
/**
|
180
|
* Removes the DOM element representing the change from document.
|
181
|
*/
|
182
|
this.remove = function() {
|
183
|
rootElement.remove();
|
184
|
};
|
185
|
|
186
|
function renderActive() {
|
187
|
rootElement = app.utils.createHtmlElement('div', {
|
188
|
'class': 'change',
|
189
|
});
|
190
|
|
191
|
// buttons
|
192
|
buttonGroup = app.utils.createHtmlElement('div', {
|
193
|
'class': 'button-group hidden',
|
194
|
});
|
195
|
rootElement.appendChild(buttonGroup);
|
196
|
|
197
|
// include not found classes checkbox
|
198
|
includeNotFoundCheckbox = app.utils.createHtmlElement('input', {
|
199
|
'type': 'checkbox',
|
200
|
'name': 'includeNotFoundClasses',
|
201
|
'class': 'include-not-found-checkbox',
|
202
|
'title': 'Include not found classes in the change',
|
203
|
'data-tooltip': 'left',
|
204
|
});
|
205
|
buttonGroup.appendChild(includeNotFoundCheckbox);
|
206
|
|
207
|
// trigger change button
|
208
|
triggerChangeButton = app.utils.createHtmlElement('button', {
|
209
|
'class': 'trigger-change-button button',
|
210
|
'title': 'Change components',
|
211
|
});
|
212
|
triggerChangeButton.appendChild(app.utils.createHtmlElement('img', {
|
213
|
'src': 'images/tochange/crce-call-trans.gif',
|
214
|
'alt': 'Icon of "change components" action',
|
215
|
}));
|
216
|
triggerChangeButton.addEventListener('click', triggerChange.bind(this));
|
217
|
buttonGroup.appendChild(triggerChangeButton);
|
218
|
|
219
|
// postpone button
|
220
|
var postponeButton = app.utils.createHtmlElement('button', {
|
221
|
'class': 'postpone-button button',
|
222
|
'title': 'Postpone change',
|
223
|
});
|
224
|
postponeButton.appendChild(app.utils.createHtmlElement('img', {
|
225
|
'src': 'images/tochange/postpone-trans.gif',
|
226
|
'alt': 'Icon of "postpone current change" action',
|
227
|
}));
|
228
|
postponeButton.addEventListener('click', moveToPostponed.bind(this));
|
229
|
buttonGroup.appendChild(postponeButton);
|
230
|
|
231
|
|
232
|
// old vertex list
|
233
|
oldVertexListComponent = new ChangeVertexList(this);
|
234
|
rootElement.appendChild(oldVertexListComponent.render());
|
235
|
|
236
|
oldVertexList.forEach(function(vertex) {
|
237
|
oldVertexListComponent.appendChild(vertex);
|
238
|
}, this);
|
239
|
|
240
|
|
241
|
// controls
|
242
|
var changeControls = app.utils.createHtmlElement('div', {
|
243
|
'class': 'change-controls',
|
244
|
});
|
245
|
rootElement.appendChild(changeControls);
|
246
|
|
247
|
// transition arrow
|
248
|
var arrow = app.utils.createHtmlElement('span', {
|
249
|
'class': 'transition-arrow',
|
250
|
});
|
251
|
arrow.appendChild(app.utils.createTextElement('🡻'));
|
252
|
changeControls.appendChild(arrow);
|
253
|
|
254
|
// control buttons
|
255
|
var controlButtonGroup = app.utils.createHtmlElement('div', {
|
256
|
'class': 'button-group',
|
257
|
});
|
258
|
changeControls.appendChild(controlButtonGroup);
|
259
|
|
260
|
// load change details button
|
261
|
var loadDetailsButton = app.utils.createHtmlElement('button', {
|
262
|
'class': 'load-details-button button',
|
263
|
'title': 'Load change details',
|
264
|
});
|
265
|
loadDetailsButton.appendChild(app.utils.createTextElement('…'));
|
266
|
loadDetailsButton.addEventListener('click', loadChangeDetails.bind(this));
|
267
|
controlButtonGroup.appendChild(loadDetailsButton);
|
268
|
|
269
|
// replace old components by new ones checkbox
|
270
|
replaceComponentsCheckbox = app.utils.createHtmlElement('input', {
|
271
|
'type': 'checkbox',
|
272
|
'name': 'replaceComponents',
|
273
|
'class': 'replace-components-checkbox',
|
274
|
'title': 'Replace old components by new ones',
|
275
|
'checked': 'checked',
|
276
|
'data-tooltip': 'left',
|
277
|
});
|
278
|
controlButtonGroup.appendChild(replaceComponentsCheckbox);
|
279
|
|
280
|
// accept change button
|
281
|
var acceptButton = app.utils.createHtmlElement('button', {
|
282
|
'class': 'accept-button button',
|
283
|
'title': 'Accept proposed change',
|
284
|
});
|
285
|
acceptButton.appendChild(app.utils.createHtmlElement('img', {
|
286
|
'src': 'images/tochange/accept-trans.gif',
|
287
|
'alt': 'Icon of "accept proposed change" action',
|
288
|
}));
|
289
|
acceptButton.addEventListener('click', acceptChange.bind(this));
|
290
|
controlButtonGroup.appendChild(acceptButton);
|
291
|
|
292
|
// revoke change button
|
293
|
var revokeButton = app.utils.createHtmlElement('button', {
|
294
|
'class': 'revoke-button button',
|
295
|
'title': 'Revoke proposed change',
|
296
|
});
|
297
|
revokeButton.appendChild(app.utils.createHtmlElement('img', {
|
298
|
'src': 'images/button_cancel.png',
|
299
|
'alt': 'Icon of "revoke proposed change" action',
|
300
|
}));
|
301
|
revokeButton.addEventListener('click', revokeChange.bind(this));
|
302
|
controlButtonGroup.appendChild(revokeButton);
|
303
|
|
304
|
|
305
|
// new vertex list
|
306
|
newVertexListComponent = new ChangeVertexList(this);
|
307
|
rootElement.appendChild(newVertexListComponent.render());
|
308
|
|
309
|
newVertexList.forEach(function(vertex) {
|
310
|
newVertexListComponent.appendChild(vertex);
|
311
|
}, this);
|
312
|
|
313
|
return rootElement;
|
314
|
}
|
315
|
|
316
|
function renderPostponed() {
|
317
|
rootElement = app.utils.createHtmlElement('li', {
|
318
|
'class': 'change',
|
319
|
});
|
320
|
|
321
|
|
322
|
// buttons
|
323
|
var buttonGroup = app.utils.createHtmlElement('div', {
|
324
|
'class': 'button-group',
|
325
|
});
|
326
|
rootElement.appendChild(buttonGroup);
|
327
|
|
328
|
// activate change button
|
329
|
var activateButton = app.utils.createHtmlElement('button', {
|
330
|
'class': 'activate-button button',
|
331
|
'title': 'Set change active',
|
332
|
});
|
333
|
activateButton.appendChild(app.utils.createHtmlElement('img', {
|
334
|
'src': 'images/tochange/tochange-trans.gif',
|
335
|
'alt': 'Icon of "set change active" action',
|
336
|
}));
|
337
|
activateButton.addEventListener('click', moveToActive.bind(this));
|
338
|
buttonGroup.appendChild(activateButton);
|
339
|
|
340
|
|
341
|
// original vertex list
|
342
|
oldVertexListComponent = new ChangeVertexList(this);
|
343
|
rootElement.appendChild(oldVertexListComponent.render());
|
344
|
|
345
|
oldVertexList.forEach(function(vertex) {
|
346
|
oldVertexListComponent.appendChild(vertex);
|
347
|
}, this);
|
348
|
|
349
|
|
350
|
// new vertex list
|
351
|
newVertexListComponent = new ChangeVertexList(this);
|
352
|
rootElement.appendChild(newVertexListComponent.render());
|
353
|
|
354
|
newVertexList.forEach(function(vertex) {
|
355
|
newVertexListComponent.appendChild(vertex);
|
356
|
}, this);
|
357
|
|
358
|
|
359
|
return rootElement;
|
360
|
}
|
361
|
|
362
|
function triggerChange() {
|
363
|
var self = this;
|
364
|
var includeNotFound = includeNotFoundCheckbox.checked;
|
365
|
|
366
|
app.loader.enable();
|
367
|
|
368
|
app.componentChanger.run(oldVertexList, includeNotFound).then(function(data) {
|
369
|
self.setTriggered(true);
|
370
|
|
371
|
data.forEach(function(component) {
|
372
|
var vertex = new VertexLight(component);
|
373
|
|
374
|
newVertexList.push(vertex);
|
375
|
newVertexListComponent.appendChild(vertex);
|
376
|
});
|
377
|
|
378
|
}, function(reason) {
|
379
|
if (typeof reason === 'string') {
|
380
|
alert(reason);
|
381
|
} else {
|
382
|
alert('Error occurred while querying CRCE. See JS console for more details.');
|
383
|
console.error(reason);
|
384
|
}
|
385
|
|
386
|
}).always(function() {
|
387
|
app.loader.disable();
|
388
|
});
|
389
|
}
|
390
|
|
391
|
function loadChangeDetails() {
|
392
|
var self = this;
|
393
|
var graphVersion = parseInt(app.cookies.get('graphVersion'));
|
394
|
var uuidToNameMap = {};
|
395
|
|
396
|
app.loader.enable();
|
397
|
|
398
|
downloadComponents(graphVersion + 1, newVertexList).then(function(responses) {
|
399
|
// get map with component's UUID as key and its filename as value
|
400
|
uuidToNameMap = responses.map(function(response) {
|
401
|
return response[0];
|
402
|
}).reduce(function(map, component) {
|
403
|
map[component.uuid] = component.name;
|
404
|
return map;
|
405
|
}, {});
|
406
|
|
407
|
return copyComponents(app.vertexList);
|
408
|
|
409
|
}).then(function() {
|
410
|
return loadGraphData(graphVersion + 1);
|
411
|
|
412
|
}).then(function(data) {
|
413
|
// vertices
|
414
|
data.vertices.forEach(function(component) {
|
415
|
var vertex = app.findVertexByName(component.name);
|
416
|
|
417
|
if (app.utils.isDefined(vertex)) {
|
418
|
// vertex already exists in graph
|
419
|
return;
|
420
|
|
421
|
} else {
|
422
|
// create a new vertex
|
423
|
var vertex = new Vertex(component);
|
424
|
vertex.setPosition(new Coordinates(0, 0));
|
425
|
|
426
|
app.nodeList.push(vertex);
|
427
|
app.vertexList.push(vertex);
|
428
|
|
429
|
app.viewportComponent.addVertex(vertex);
|
430
|
}
|
431
|
|
432
|
// replace light vertex placeholder by vertex component
|
433
|
var placeholdingVertex = newVertexList.find(function(newVertex) {
|
434
|
return uuidToNameMap[newVertex.id] == this.name;
|
435
|
}, vertex);
|
436
|
|
437
|
if (app.utils.isDefined(placeholdingVertex)) {
|
438
|
newVertexList.splice(newVertexList.indexOf(placeholdingVertex), 1);
|
439
|
newVertexListComponent.removeChild(placeholdingVertex);
|
440
|
}
|
441
|
|
442
|
newVertexList.push(vertex);
|
443
|
});
|
444
|
|
445
|
var newVertexNameList = newVertexList.map(function(vertex) {
|
446
|
return vertex.name;
|
447
|
});
|
448
|
|
449
|
// edges
|
450
|
data.edges.forEach(function(component) {
|
451
|
// vertex names are prefixed by "vertex_" string, cut it off
|
452
|
var fromNodeName = component.from.substring(7);
|
453
|
var toNodeName = component.to.substring(7);
|
454
|
|
455
|
// neither end of the edge is a newly added vertex
|
456
|
if (newVertexNameList.indexOf(fromNodeName) < 0 && newVertexNameList.indexOf(toNodeName) < 0) return;
|
457
|
|
458
|
var edge = new Edge(component);
|
459
|
|
460
|
var fromNode = app.findVertexByName(fromNodeName);
|
461
|
if (fromNode) {
|
462
|
fromNode.addOutEdge(edge);
|
463
|
}
|
464
|
|
465
|
var toNode = app.findVertexByName(toNodeName);
|
466
|
if (toNode) {
|
467
|
toNode.addInEdge(edge);
|
468
|
}
|
469
|
|
470
|
app.edgeList.push(edge);
|
471
|
|
472
|
app.viewportComponent.addEdge(edge);
|
473
|
});
|
474
|
|
475
|
|
476
|
newVertexList.forEach(function(vertex) {
|
477
|
vertex.exclude();
|
478
|
|
479
|
newVertexListComponent.appendChild(vertex);
|
480
|
});
|
481
|
|
482
|
app.redrawEdges();
|
483
|
|
484
|
self.setDetailsLoaded(true);
|
485
|
|
486
|
}).always(function() {
|
487
|
app.loader.disable();
|
488
|
});
|
489
|
}
|
490
|
|
491
|
function downloadComponents(graphVersion, vertexList) {
|
492
|
var downloadPromises = [];
|
493
|
vertexList.forEach(function(vertex) {
|
494
|
var downloadPromise = $.ajax({
|
495
|
type: 'POST',
|
496
|
url: 'api/download-component?graphVersion=' + graphVersion + '&uuid=' + encodeURIComponent(vertex.id),
|
497
|
contentType: 'application/json',
|
498
|
timeout: 180 * 1000, // in milliseconds
|
499
|
});
|
500
|
|
501
|
downloadPromises.push(downloadPromise);
|
502
|
});
|
503
|
|
504
|
return app.utils.promiseAll(downloadPromises);
|
505
|
}
|
506
|
|
507
|
function deleteComponents(graphVersion, vertexList) {
|
508
|
var deletePromises = [];
|
509
|
vertexList.forEach(function(vertex) {
|
510
|
var deletePromise = $.ajax({
|
511
|
type: 'GET',
|
512
|
url: 'delete-component?graphVersion=' + graphVersion + '&name=' + encodeURIComponent(vertex.name),
|
513
|
timeout: 180 * 1000, // in milliseconds
|
514
|
});
|
515
|
|
516
|
deletePromises.push(deletePromise);
|
517
|
});
|
518
|
|
519
|
return app.utils.promiseAll(deletePromises);
|
520
|
}
|
521
|
|
522
|
function copyComponents(vertexList) {
|
523
|
var involvedComponents = vertexList.filter(function(vertex) {
|
524
|
return vertex.name !== app.constants.notFoundVertexName;
|
525
|
}).map(function(vertex) {
|
526
|
return {
|
527
|
'id': vertex.id,
|
528
|
'name': vertex.name,
|
529
|
};
|
530
|
});
|
531
|
|
532
|
return $.ajax({
|
533
|
type: 'POST',
|
534
|
url: 'api/copy-components',
|
535
|
data: JSON.stringify({
|
536
|
'components': involvedComponents,
|
537
|
}),
|
538
|
contentType: 'application/json',
|
539
|
timeout: 180 * 1000, // in milliseconds
|
540
|
});
|
541
|
}
|
542
|
|
543
|
function loadGraphData(graphVersion) {
|
544
|
return $.getJSON(app.API.loadGraph + '?graphVersion=' + graphVersion);
|
545
|
}
|
546
|
|
547
|
function acceptChange() {
|
548
|
var self = this;
|
549
|
var graphVersion = parseInt(app.cookies.get('graphVersion'));
|
550
|
var replaceComponents = replaceComponentsCheckbox.checked;
|
551
|
|
552
|
app.loader.enable();
|
553
|
|
554
|
var promise;
|
555
|
if (this.isDetailsLoaded()) {
|
556
|
var deleteComponentsPromise;
|
557
|
if (replaceComponents) {
|
558
|
deleteComponentsPromise = deleteComponents(graphVersion + 1, oldVertexList);
|
559
|
} else {
|
560
|
deleteComponentsPromise = $.when();
|
561
|
}
|
562
|
|
563
|
promise = deleteComponentsPromise.then(function() {
|
564
|
return loadGraphData(graphVersion + 1);
|
565
|
});
|
566
|
|
567
|
} else {
|
568
|
// download and copy components on the server side and then load the graph
|
569
|
promise = downloadComponents(graphVersion + 1, newVertexList).then(function(responses) {
|
570
|
var involvedVertexList = app.vertexList;
|
571
|
|
572
|
if (replaceComponents) {
|
573
|
involvedVertexList = involvedVertexList.filter(function(vertex) {
|
574
|
return oldVertexList.some(function(oldVertex) {
|
575
|
return oldVertex.name !== vertex.name;
|
576
|
});
|
577
|
});
|
578
|
}
|
579
|
|
580
|
return copyComponents(involvedVertexList);
|
581
|
|
582
|
}).then(function() {
|
583
|
return loadGraphData(graphVersion + 1);
|
584
|
});
|
585
|
}
|
586
|
|
587
|
promise.then(function(data) {
|
588
|
// increment graph version number
|
589
|
app.cookies.set('graphVersion', graphVersion + 1);
|
590
|
|
591
|
var graphExportData = app.graphExporter.run();
|
592
|
|
593
|
app.reset();
|
594
|
app.graphLoader.run(data, graphExportData);
|
595
|
|
596
|
}).always(function() {
|
597
|
app.loader.disable();
|
598
|
});
|
599
|
}
|
600
|
|
601
|
function revokeChange() {
|
602
|
var self = this;
|
603
|
var graphVersion = parseInt(app.cookies.get('graphVersion'));
|
604
|
|
605
|
app.loader.enable();
|
606
|
|
607
|
var deleteComponentsPromise;
|
608
|
if (this.isDetailsLoaded()) {
|
609
|
// delete components on the server side
|
610
|
deleteComponentsPromise = deleteComponents(graphVersion + 1, newVertexList);
|
611
|
} else {
|
612
|
deleteComponentsPromise = $.when();
|
613
|
}
|
614
|
|
615
|
deleteComponentsPromise.then(function() {
|
616
|
newVertexList.forEach(function(vertex) {
|
617
|
// change details were loaded
|
618
|
if (self.isDetailsLoaded()) {
|
619
|
// remove edges connected with the vertex
|
620
|
vertex.getInEdgeList().forEach(function(edge) {
|
621
|
edge.remove();
|
622
|
});
|
623
|
vertex.getOutEdgeList().forEach(function(edge) {
|
624
|
edge.remove();
|
625
|
});
|
626
|
|
627
|
var existingVertex = app.findVertexByName(vertex.name);
|
628
|
if (app.utils.isDefined(existingVertex)) {
|
629
|
// remove vertex from app
|
630
|
app.nodeList.splice(app.nodeList.indexOf(existingVertex), 1);
|
631
|
app.vertexList.splice(app.vertexList.indexOf(existingVertex), 1);
|
632
|
}
|
633
|
}
|
634
|
|
635
|
// remove vertex from this change
|
636
|
newVertexListComponent.removeChild(vertex);
|
637
|
});
|
638
|
|
639
|
newVertexList = [];
|
640
|
|
641
|
self.setTriggered(false);
|
642
|
self.setDetailsLoaded(false);
|
643
|
|
644
|
}).always(function() {
|
645
|
app.loader.disable();
|
646
|
});
|
647
|
}
|
648
|
|
649
|
function moveToPostponed() {
|
650
|
if (oldVertexList.length === 0) return;
|
651
|
|
652
|
newVertexList.forEach(function(vertex) {
|
653
|
// remove vertex from app
|
654
|
var existingVertex = app.findVertexByName(vertex.name);
|
655
|
if (app.utils.isDefined(existingVertex)) {
|
656
|
app.nodeList.splice(app.nodeList.indexOf(existingVertex), 1);
|
657
|
app.vertexList.splice(app.vertexList.indexOf(existingVertex), 1);
|
658
|
}
|
659
|
});
|
660
|
|
661
|
this.setPostponed(true);
|
662
|
this.remove();
|
663
|
|
664
|
app.sidebarComponent.setChangePostponed(this);
|
665
|
}
|
666
|
|
667
|
function moveToActive() {
|
668
|
newVertexList.forEach(function(vertex) {
|
669
|
// add vertex to app
|
670
|
app.nodeList.push(vertex);
|
671
|
app.vertexList.push(vertex);
|
672
|
});
|
673
|
|
674
|
this.setPostponed(false);
|
675
|
this.remove();
|
676
|
|
677
|
app.sidebarComponent.setChangeActive(this);
|
678
|
}
|
679
|
|
680
|
function toggleButtonGroup() {
|
681
|
if (oldVertexList.length > 0) {
|
682
|
buttonGroup.classList.remove('hidden');
|
683
|
} else {
|
684
|
buttonGroup.classList.add('hidden');
|
685
|
}
|
686
|
}
|
687
|
|
688
|
function getInvolvedComponents() {
|
689
|
var involvedComponents = [];
|
690
|
|
691
|
oldVertexList.forEach(function(vertex) {
|
692
|
vertex.getInEdgeList().forEach(function(edge) {
|
693
|
involvedComponents.push(edge.getFrom());
|
694
|
});
|
695
|
|
696
|
vertex.getOutEdgeList().forEach(function(edge) {
|
697
|
involvedComponents.push(edge.getTo());
|
698
|
});
|
699
|
});
|
700
|
|
701
|
return involvedComponents;
|
702
|
}
|
703
|
}
|