fix(import): patch legacy processes before import

This commit is contained in:
Martin Stamm 2021-11-02 08:28:35 +01:00
parent c9b4310f07
commit 10546945bb
No known key found for this signature in database
GPG Key ID: B3A641060A8CBCF4
2 changed files with 78 additions and 100 deletions

View File

@ -1,113 +1,103 @@
import { selfAndAllChildren } from 'diagram-js/lib/util/Elements';
import { isExpanded } from '../../util/DiUtil';
import { getBusinessObject, getDi, is } from '../../util/ModelUtil';
import { is } from '../../util/ModelUtil';
export default function SubprocessCompatibility(eventBus, elementRegistry, canvas, moddle, elementFactory, bpmnjs) {
/**
* 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._elementRegistry = elementRegistry;
this._canvas = canvas;
this._bpmnjs = bpmnjs;
this._moddle = moddle;
this._elementFactory = elementFactory;
var self = this;
eventBus.on('import.done', 1500, function() {
self._handleImport();
eventBus.on('import.render.start', 1500, function(e, context) {
self.handleImport(context.definitions);
});
}
SubprocessCompatibility.prototype._handleImport = function() {
var elementRegistry = this._elementRegistry;
var canvas = this._canvas;
var elementFactory = this._elementFactory;
SubprocessCompatibility.prototype.handleImport = function(definitions) {
if (!definitions.diagrams) {
return;
}
var self = this;
var legacyProcesses = elementRegistry.filter(function(element) {
return is(element, 'bpmn:SubProcess') && !isExpanded(element) && element.children && element.children.length;
this._definitions = definitions;
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 bo = getBusinessObject(oldParent);
var newDiagram = self.createDiagram(bo);
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] });
});
definitions.diagrams.forEach(function(diagram) {
self.fixPlaneDi(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');
parentPlaneElement.splice(parentPlaneElement.indexOf(di), 1);
newPlane.get('planeElement').push(di);
};
SubprocessCompatibility.prototype.fixPlaneDi = function(plane) {
var self = this;
SubprocessCompatibility.prototype.moveElementsToRoot = function(elements) {
var defaultPosition = { x: 180, y: 160 },
minX = Infinity,
minY = Infinity;
var collapsedElements = [];
var elementsToMove = [];
elements.forEach(function(el) {
minX = Math.min(minX, el.x || Infinity);
minY = Math.min(minY, el.y || Infinity);
});
plane.get('planeElement').forEach(function(diElement) {
var bo = diElement.bpmnElement;
var parent = bo.$parent;
var xOffset = defaultPosition.x - minX;
var yOffset = defaultPosition.y - minY;
if (is(bo, 'bpmn:SubProcess') && !diElement.isExpanded) {
collapsedElements.push(bo);
}
elements.forEach(function(el) {
if (el.waypoints) {
el.waypoints.forEach(function(waypoint) {
waypoint.x = waypoint.x + xOffset;
waypoint.y = waypoint.y + yOffset;
});
} else {
el.x = el.x + xOffset;
el.y = el.y + yOffset;
if (is(parent, 'bpmn:SubProcess') && parent !== plane.bpmnElement) {
// don't change the array while we iterate over it
elementsToMove.push({ element: diElement, parent: parent });
}
});
elementsToMove.forEach(function(element) {
var diElement = element.element;
var parent = element.parent;
// 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;
}
self.moveToDiPlane(diElement, diagram.plane);
});
};
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) {
var plane = this._moddle.create('bpmndi:BPMNPlane', { bpmnElement: bo });
@ -116,20 +106,20 @@ SubprocessCompatibility.prototype.createDiagram = function(bo) {
});
plane.$parent = diagram;
plane.bpmnElement = bo;
diagram.$parent = this.getDefinitions();
this.getDiagrams().push(diagram);
diagram.$parent = this._definitions;
this._definitions.diagrams.push(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')) {
return element;
} else {
return findRootDiagram(element.$parent);
}
};
}

View File

@ -187,18 +187,6 @@ describe('features - subprocess-navigation', function() {
expect(inlineProcess2).to.exist;
}));
it('should move inlined elements to sensible position', inject(function(elementRegistry) {
// when
var startEvent = elementRegistry.get('subprocess_startEvent');
// then
expect(startEvent).to.exist;
expect(startEvent.x).to.equal(180);
expect(startEvent.y).to.equal(160);
}));
});