diff --git a/lib/import/BpmnImporter.js b/lib/import/BpmnImporter.js index db0d86ce..4b13cbe7 100644 --- a/lib/import/BpmnImporter.js +++ b/lib/import/BpmnImporter.js @@ -108,7 +108,11 @@ BpmnImporter.prototype.add = function(semantic, di, parentElement) { // add a virtual element (not being drawn) element = this._elementFactory.createRoot(elementData(semantic, di)); - this._canvas.setRootElement(element); + if (is(semantic, 'bpmn:SubProcess')) { + element.id = element.id + '_plane'; + } + + this._canvas.createPlane(semantic.id, element); } // SHAPE @@ -144,7 +148,7 @@ BpmnImporter.prototype.add = function(semantic, di, parentElement) { // check whether data store is inside our outside of its semantic parent if (!isPointInsideBBox(parentElement, getMid(bounds))) { - parentElement = this._canvas.getRootElement(); + parentElement = this._canvas.findPlane(parentElement).rootElement; } } @@ -172,7 +176,7 @@ BpmnImporter.prototype.add = function(semantic, di, parentElement) { // are rendered correctly across different "hacks" people // love to model such as cross participant / sub process // associations - parentElement = null; + parentElement = this._canvas.findPlane(parentElement).rootElement; } // insert sequence flows behind other flow nodes (cf. #727) diff --git a/lib/import/BpmnTreeWalker.js b/lib/import/BpmnTreeWalker.js index 214d5191..760f028a 100644 --- a/lib/import/BpmnTreeWalker.js +++ b/lib/import/BpmnTreeWalker.js @@ -216,7 +216,7 @@ export default function BpmnTreeWalker(handler, translate) { var ctx = visitRoot(rootElement, plane); - if (is(rootElement, 'bpmn:Process')) { + if (is(rootElement, 'bpmn:Process') || is(rootElement, 'bpmn:SubProcess')) { handleProcess(rootElement, ctx); } else if (is(rootElement, 'bpmn:Collaboration')) { handleCollaboration(rootElement, ctx); diff --git a/lib/import/Importer.js b/lib/import/Importer.js index 7434f220..fdde1f4f 100644 --- a/lib/import/Importer.js +++ b/lib/import/Importer.js @@ -33,7 +33,8 @@ export function importBpmnDiagram(diagram, definitions, bpmnDiagram) { var importer, eventBus, - translate; + translate, + canvas; var error, warnings = []; @@ -66,7 +67,16 @@ export function importBpmnDiagram(diagram, definitions, bpmnDiagram) { // traverse BPMN 2.0 document model, // starting at definitions - walker.handleDefinitions(definitions, bpmnDiagram); + if (!bpmnDiagram && definitions.diagrams) { + for (var i = 0; i < definitions.diagrams.length; i++) { + walker.handleDefinitions(definitions, definitions.diagrams[i]); + } + } else { + walker.handleDefinitions(definitions, bpmnDiagram); + } + + var mainDiagram = bpmnDiagram || definitions.diagrams[0]; + canvas.setActivePlane(mainDiagram.plane.bpmnElement.id); } return new Promise(function(resolve, reject) { @@ -74,6 +84,7 @@ export function importBpmnDiagram(diagram, definitions, bpmnDiagram) { importer = diagram.get('bpmnImporter'); eventBus = diagram.get('eventBus'); translate = diagram.get('translate'); + canvas = diagram.get('canvas'); eventBus.fire('import.render.start', { definitions: definitions }); diff --git a/lib/util/DiUtil.js b/lib/util/DiUtil.js index 0bde14d7..b35db883 100644 --- a/lib/util/DiUtil.js +++ b/lib/util/DiUtil.js @@ -18,6 +18,10 @@ export function isExpanded(element, di) { if (is(element, 'bpmn:SubProcess')) { di = di || getDi(element); + if (di && is(di, 'bpmndi:BPMNPlane')) { + return true; + } + return di && !!di.isExpanded; } diff --git a/test/fixtures/bpmn/import/collapsed-subprocess.bpmn b/test/fixtures/bpmn/import/collapsed-subprocess.bpmn new file mode 100644 index 00000000..e6ffbc95 --- /dev/null +++ b/test/fixtures/bpmn/import/collapsed-subprocess.bpmn @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/spec/import/ImporterSpec.js b/test/spec/import/ImporterSpec.js index aef20379..ed16d261 100644 --- a/test/spec/import/ImporterSpec.js +++ b/test/spec/import/ImporterSpec.js @@ -665,6 +665,71 @@ describe('import - Importer', function() { }); + + describe('Multiple Planes', function() { + + it('should import multiple diagrams', function() { + + // given + var xml = require('../../fixtures/bpmn/multiple-diagrams.bpmn'); + + // when + return runImport(diagram, xml).then(function(result) { + + var warnings = result.warnings; + + // then + expect(warnings).to.have.length(0); + + expect(diagram.get('elementRegistry').get('Task_A')).to.exist; + expect(diagram.get('elementRegistry').get('Task_B')).to.exist; + }); + }); + + + it('should allow subProcess to have attached plane', function() { + + // given + var xml = require('../../fixtures/bpmn/import/collapsed-subprocess.bpmn'); + + // when + return runImport(diagram, xml).then(function(result) { + + var warnings = result.warnings; + + // then + expect(warnings).to.have.length(0); + + expect(diagram.get('elementRegistry').get('Subprocess')).to.exist; + expect(diagram.get('elementRegistry').get('Subprocess_plane')).to.exist; + }); + }); + + + it('should render Tasks on different layers', function() { + + // given + var xml = require('../../fixtures/bpmn/multiple-diagrams.bpmn'); + + // when + return runImport(diagram, xml).then(function() { + + var elementRegistry = diagram.get('elementRegistry'), + canvas = diagram.get('canvas'), + taskA = elementRegistry.get('Task_A'), + taskB = elementRegistry.get('Task_B'); + + var activePlane = canvas.getActivePlane(), + planeA = canvas.findPlane(taskA), + planeB = canvas.findPlane(taskB); + + // then + expect(activePlane).to.eql(planeA); + expect(planeA).to.not.eql(planeB); + }); + }); + + }); });