fix(drilldown): patch legacy processes before import
This commit is contained in:
parent
732aae361e
commit
e154d88d15
|
@ -1,113 +1,149 @@
|
||||||
|
|
||||||
import { selfAndAllChildren } from 'diagram-js/lib/util/Elements';
|
import { asBounds, asTRBL } from 'diagram-js/lib/layout/LayoutUtil';
|
||||||
import { isExpanded } from '../../util/DiUtil';
|
import { is } from '../../util/ModelUtil';
|
||||||
import { getBusinessObject, getDi, is } from '../../util/ModelUtil';
|
|
||||||
|
|
||||||
export default function SubprocessCompatibility(eventBus, elementRegistry, canvas, moddle, elementFactory, bpmnjs) {
|
var DEFAULT_POSITION = {
|
||||||
|
x: 180,
|
||||||
|
y: 160
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hooks into `import.render.start` and creates new planes for collapsed
|
||||||
|
* subprocesses with elements on the parent diPlane.
|
||||||
|
*
|
||||||
|
* @param {eventBus} eventBus
|
||||||
|
* @param {moddle} moddle
|
||||||
|
*/
|
||||||
|
export default function SubprocessCompatibility(eventBus, moddle) {
|
||||||
this._eventBus = eventBus;
|
this._eventBus = eventBus;
|
||||||
this._elementRegistry = elementRegistry;
|
|
||||||
this._canvas = canvas;
|
|
||||||
this._bpmnjs = bpmnjs;
|
|
||||||
this._moddle = moddle;
|
this._moddle = moddle;
|
||||||
this._elementFactory = elementFactory;
|
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
eventBus.on('import.done', 1500, function() {
|
eventBus.on('import.render.start', 1500, function(e, context) {
|
||||||
self._handleImport();
|
self.handleImport(context.definitions);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
SubprocessCompatibility.prototype._handleImport = function() {
|
SubprocessCompatibility.prototype.handleImport = function(definitions) {
|
||||||
var elementRegistry = this._elementRegistry;
|
if (!definitions.diagrams) {
|
||||||
var canvas = this._canvas;
|
return;
|
||||||
var elementFactory = this._elementFactory;
|
}
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
var legacyProcesses = elementRegistry.filter(function(element) {
|
this._definitions = definitions;
|
||||||
return is(element, 'bpmn:SubProcess') && !isExpanded(element) && element.children && element.children.length;
|
this._processToDiagramMap = {};
|
||||||
|
|
||||||
|
definitions.diagrams.forEach(function(diagram) {
|
||||||
|
if (!diagram.plane || !diagram.plane.bpmnElement) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self._processToDiagramMap[diagram.plane.bpmnElement.id] = diagram;
|
||||||
});
|
});
|
||||||
|
|
||||||
legacyProcesses.forEach(function(oldParent) {
|
var newDiagrams = [];
|
||||||
var bo = getBusinessObject(oldParent);
|
definitions.diagrams.forEach(function(diagram) {
|
||||||
|
var createdDiagrams = self.createNewDiagrams(diagram.plane);
|
||||||
var newDiagram = self.createDiagram(bo);
|
Array.prototype.push.apply(newDiagrams, createdDiagrams);
|
||||||
|
|
||||||
var newParent = elementFactory.createRoot(
|
|
||||||
{
|
|
||||||
id: bo.id,
|
|
||||||
type: bo.$type,
|
|
||||||
businessObject: bo,
|
|
||||||
di: newDiagram.plane
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
newParent.id = newParent.id + '_plane';
|
|
||||||
|
|
||||||
canvas.createPlane(bo.id, newParent);
|
|
||||||
|
|
||||||
var elementsToChange = selfAndAllChildren(oldParent).filter(function(el) {
|
|
||||||
return el !== oldParent;
|
|
||||||
});
|
|
||||||
|
|
||||||
self.moveElementsToRoot(elementsToChange);
|
|
||||||
|
|
||||||
elementsToChange.forEach(function(el) {
|
|
||||||
if (el.parent === oldParent) {
|
|
||||||
el.parent = newParent;
|
|
||||||
}
|
|
||||||
el.hidden = el.parent && (el.parent.hidden || el.parent.collapsed);
|
|
||||||
|
|
||||||
self.moveToDiPlane(el, newDiagram.plane);
|
|
||||||
|
|
||||||
self._eventBus.fire('elements.changed', { elements: [el] });
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
newDiagrams.forEach(function(diagram) {
|
||||||
|
self.movePlaneElementsToOrigin(diagram.plane);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
SubprocessCompatibility.prototype.moveToDiPlane = function(element, newPlane) {
|
|
||||||
var di = getDi(element);
|
|
||||||
var containingDiagram = findRootDiagram(di);
|
|
||||||
|
|
||||||
// Remove DI from old Plane and add it to the new one
|
/**
|
||||||
var parentPlaneElement = containingDiagram.plane.get('planeElement');
|
* Moves all DI elements from collapsed subprocesses to a new plane.
|
||||||
parentPlaneElement.splice(parentPlaneElement.indexOf(di), 1);
|
*
|
||||||
newPlane.get('planeElement').push(di);
|
* @param {Object} plane
|
||||||
};
|
* @return {Array} new diagrams created for the collapsed subprocesses
|
||||||
|
*/
|
||||||
|
SubprocessCompatibility.prototype.createNewDiagrams = function(plane) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
SubprocessCompatibility.prototype.moveElementsToRoot = function(elements) {
|
var collapsedElements = [];
|
||||||
var defaultPosition = { x: 180, y: 160 },
|
var elementsToMove = [];
|
||||||
minX = Infinity,
|
|
||||||
minY = Infinity;
|
|
||||||
|
|
||||||
elements.forEach(function(el) {
|
plane.get('planeElement').forEach(function(diElement) {
|
||||||
minX = Math.min(minX, el.x || Infinity);
|
var bo = diElement.bpmnElement;
|
||||||
minY = Math.min(minY, el.y || Infinity);
|
var parent = bo.$parent;
|
||||||
|
|
||||||
|
if (is(bo, 'bpmn:SubProcess') && !diElement.isExpanded) {
|
||||||
|
collapsedElements.push(bo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is(parent, 'bpmn:SubProcess') && parent !== plane.bpmnElement) {
|
||||||
|
|
||||||
|
// don't change the array while we iterate over it
|
||||||
|
elementsToMove.push({ element: diElement, parent: parent });
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var xOffset = defaultPosition.x - minX;
|
var newDiagrams = [];
|
||||||
var yOffset = defaultPosition.y - minY;
|
|
||||||
|
|
||||||
elements.forEach(function(el) {
|
elementsToMove.forEach(function(element) {
|
||||||
if (el.waypoints) {
|
var diElement = element.element;
|
||||||
el.waypoints.forEach(function(waypoint) {
|
var parent = element.parent;
|
||||||
waypoint.x = waypoint.x + xOffset;
|
|
||||||
waypoint.y = waypoint.y + yOffset;
|
// parent is expanded, get nearest collapsed parent
|
||||||
|
while (parent && !collapsedElements.includes(parent)) {
|
||||||
|
parent = parent.$parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// false positive, all parents are expanded
|
||||||
|
if (!parent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var diagram = self._processToDiagramMap[parent.id];
|
||||||
|
if (!diagram) {
|
||||||
|
diagram = self.createDiagram(parent);
|
||||||
|
self._processToDiagramMap[parent.id] = diagram;
|
||||||
|
newDiagrams.push(diagram);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.moveToDiPlane(diElement, diagram.plane);
|
||||||
|
});
|
||||||
|
|
||||||
|
return newDiagrams;
|
||||||
|
};
|
||||||
|
|
||||||
|
SubprocessCompatibility.prototype.movePlaneElementsToOrigin = function(plane) {
|
||||||
|
var elements = plane.get('planeElement');
|
||||||
|
|
||||||
|
// get bounding box of all elements
|
||||||
|
var planeBounds = getPlaneBounds(plane);
|
||||||
|
|
||||||
|
var offset = {
|
||||||
|
x: planeBounds.x - DEFAULT_POSITION.x,
|
||||||
|
y: planeBounds.y - DEFAULT_POSITION.y
|
||||||
|
};
|
||||||
|
|
||||||
|
elements.forEach(function(diElement) {
|
||||||
|
if (diElement.waypoint) {
|
||||||
|
diElement.waypoint.forEach(function(waypoint) {
|
||||||
|
waypoint.x = waypoint.x - offset.x;
|
||||||
|
waypoint.y = waypoint.y - offset.y;
|
||||||
});
|
});
|
||||||
} else {
|
} else if (diElement.bounds) {
|
||||||
el.x = el.x + xOffset;
|
diElement.bounds.x = diElement.bounds.x - offset.x;
|
||||||
el.y = el.y + yOffset;
|
diElement.bounds.y = diElement.bounds.y - offset.y;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
SubprocessCompatibility.prototype.getDefinitions = function() {
|
|
||||||
return this._bpmnjs._definitions || [];
|
SubprocessCompatibility.prototype.moveToDiPlane = function(diElement, newPlane) {
|
||||||
|
var containingDiagram = findRootDiagram(diElement);
|
||||||
|
|
||||||
|
// remove DI from old Plane and add it to the new one
|
||||||
|
var parentPlaneElement = containingDiagram.plane.get('planeElement');
|
||||||
|
parentPlaneElement.splice(parentPlaneElement.indexOf(diElement), 1);
|
||||||
|
newPlane.get('planeElement').push(diElement);
|
||||||
};
|
};
|
||||||
|
|
||||||
SubprocessCompatibility.prototype.getDiagrams = function() {
|
|
||||||
return this.getDefinitions().diagrams || [];
|
|
||||||
};
|
|
||||||
|
|
||||||
SubprocessCompatibility.prototype.createDiagram = function(bo) {
|
SubprocessCompatibility.prototype.createDiagram = function(bo) {
|
||||||
var plane = this._moddle.create('bpmndi:BPMNPlane', { bpmnElement: bo });
|
var plane = this._moddle.create('bpmndi:BPMNPlane', { bpmnElement: bo });
|
||||||
|
@ -116,20 +152,42 @@ SubprocessCompatibility.prototype.createDiagram = function(bo) {
|
||||||
});
|
});
|
||||||
plane.$parent = diagram;
|
plane.$parent = diagram;
|
||||||
plane.bpmnElement = bo;
|
plane.bpmnElement = bo;
|
||||||
diagram.$parent = this.getDefinitions();
|
diagram.$parent = this._definitions;
|
||||||
this.getDiagrams().push(diagram);
|
this._definitions.diagrams.push(diagram);
|
||||||
return diagram;
|
return diagram;
|
||||||
};
|
};
|
||||||
|
|
||||||
SubprocessCompatibility.$inject = [ 'eventBus', 'elementRegistry', 'canvas', 'moddle', 'elementFactory', 'bpmnjs' ];
|
SubprocessCompatibility.$inject = [ 'eventBus', 'moddle' ];
|
||||||
|
|
||||||
|
|
||||||
// Util
|
// helpers
|
||||||
|
|
||||||
var findRootDiagram = function(element) {
|
function findRootDiagram(element) {
|
||||||
if (is(element, 'bpmndi:BPMNDiagram')) {
|
if (is(element, 'bpmndi:BPMNDiagram')) {
|
||||||
return element;
|
return element;
|
||||||
} else {
|
} else {
|
||||||
return findRootDiagram(element.$parent);
|
return findRootDiagram(element.$parent);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
function getPlaneBounds(plane) {
|
||||||
|
var planeTrbl = {
|
||||||
|
top: Infinity,
|
||||||
|
right: -Infinity,
|
||||||
|
bottom: -Infinity,
|
||||||
|
left: Infinity
|
||||||
|
};
|
||||||
|
|
||||||
|
plane.planeElement.forEach(function(element) {
|
||||||
|
if (!element.bounds) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var trbl = asTRBL(element.bounds);
|
||||||
|
|
||||||
|
planeTrbl.top = Math.min(trbl.top, planeTrbl.top);
|
||||||
|
planeTrbl.left = Math.min(trbl.left, planeTrbl.left);
|
||||||
|
});
|
||||||
|
|
||||||
|
return asBounds(planeTrbl);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue