Skip to content

Commit

Permalink
fix replacement of collapsed subprocess
Browse files Browse the repository at this point in the history
  • Loading branch information
LaviniaStiliadou committed Aug 22, 2023
1 parent fd24add commit 744f05f
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 37 deletions.
22 changes: 22 additions & 0 deletions components/bpmn-q/modeler-component/editor/ModelerHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,28 @@ export async function createTempModelerFromXml(xml) {
return undefined;
}

/**
* Creates a modeler with all additional modules and extension moddles from all active plugins which is not
* saved in as the current modeler instance and load the given xml into it.
*
* @param xml the xml representing the BPMN diagram to load
*
* @returns the created modeler
*/
export async function createModelerFromXml(xml) {
// create new modeler with the custom QuantME extensions
const bpmnModeler = createModeler();

// import the xml containing the definitions
try {
await bpmnModeler.importXML(xml);
return bpmnModeler;
} catch (err) {
console.error(err);
}
return undefined;
}

/**
* Returns the current modeler instance rendered into the UI of the Quantum Workflow Modeler
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import * as Constants from '../Constants';
import { replaceHardwareSelectionSubprocess } from './hardware-selection/QuantMEHardwareSelectionHandler';
import { replaceCuttingSubprocess } from './circuit-cutting/QuantMECuttingHandler';
import { insertShape } from '../../../editor/util/TransformationUtilities';
import { createTempModelerFromXml } from '../../../editor/ModelerHandler';
import { createModelerFromXml } from '../../../editor/ModelerHandler';
import {
getCamundaInputOutput,
getDefinitionsFromXml,
Expand All @@ -35,13 +35,13 @@ const xmlParser = require('xml-js');
* @param endpointConfig endpoints of the services required for the dynamic hardware selection
*/
export async function startQuantmeReplacementProcess(xml, currentQRMs, endpointConfig) {
let modeler = await createTempModelerFromXml(xml);
let modeler = await createModelerFromXml(xml);
let modeling = modeler.get('modeling');
let elementRegistry = modeler.get('elementRegistry');

// get root element of the current diagram
const definitions = modeler.getDefinitions();
const rootElement = getRootProcess(definitions);
let definitions = modeler.getDefinitions();
let rootElement = getRootProcess(definitions);
console.log(rootElement);
if (typeof rootElement === 'undefined') {
console.log('Unable to retrieve root process element from definitions!');
Expand Down Expand Up @@ -113,7 +113,7 @@ export async function startQuantmeReplacementProcess(xml, currentQRMs, endpointC
}

// layout diagram after successful transformation
layout(modeling, elementRegistry, rootElement);
//layout(modeling, elementRegistry, rootElement);
let updated_xml = await getXml(modeler);

// Parse the XML string into a JavaScript object
Expand Down Expand Up @@ -191,9 +191,18 @@ export async function startQuantmeReplacementProcess(xml, currentQRMs, endpointC
// Serialize the modified JavaScript object back to XML string
modifiedXmlString = xmlParser.js2xml(xmlDoc, { compact: true });
}
modeler = await createModelerFromXml(modifiedXmlString);
modeling = modeler.get('modeling');
elementRegistry = modeler.get('elementRegistry');

// get root element of the current diagram
definitions = modeler.getDefinitions();
rootElement = getRootProcess(definitions);
layout(modeling, elementRegistry, rootElement);
let updated_xml2 = await getXml(modeler);


return { status: 'transformed', xml: modifiedXmlString };
return { status: 'transformed', xml: updated_xml2 };
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
* SPDX-License-Identifier: Apache-2.0
*/

import {getDi, is} from 'bpmn-js/lib/util/ModelUtil';
import {isFlowLikeElement} from '../../../../editor/util/ModellingUtilities';
import { getDi, is } from 'bpmn-js/lib/util/ModelUtil';
import { isFlowLikeElement } from '../../../../editor/util/ModellingUtilities';

// space between multiple boundary events of a task/subprocess
let BOUNDARY_EVENT_MARGIN = '10';
Expand Down Expand Up @@ -56,15 +56,6 @@ function layoutProcess(modeling, elementRegistry, process) {
// layout elements in subprocess
if (['bpmn:SubProcess', 'quantme:QuantumHardwareSelectionSubprocess', 'quantme:CircuitCuttingSubprocess'].includes(flowElements[i].$type)) {
console.log('Flow element is subprocess. Layouting contained elements...');
const flowElement = elementRegistry.get(flowElements[i].id);
let oldBounds = getDi(flowElement).bounds;
modeling.resizeShape(elementRegistry.get(flowElements[i].id), {
x: oldBounds.x,
y: oldBounds.y,
height: 10,
width: 10
});

layoutProcess(modeling, elementRegistry, elementRegistry.get(flowElements[i].id).businessObject);
}

Expand Down Expand Up @@ -97,7 +88,7 @@ function layoutProcess(modeling, elementRegistry, process) {
nodes.push(elementRegistry.get(artifact.id));

if (artifact.$type === 'bpmn:Association') {
edges.push({id: artifact.id, sourceId: artifact.sourceRef.id, targetId: artifact.targetRef.id});
edges.push({ id: artifact.id, sourceId: artifact.sourceRef.id, targetId: artifact.targetRef.id });
}
}
}
Expand Down Expand Up @@ -140,7 +131,7 @@ function layoutBoundaryEvents(modeling, elementRegistry) {
let offset = (attachedToElementBoundaries.length + 1) * (parseInt(boundaryEventBounds.width) + parseInt(BOUNDARY_EVENT_MARGIN));
let to_move_x = bottomOfAttached - offset;
let to_move_y = attachedToBounds.y - boundaryEventBounds.y + attachedToBounds.height - boundaryEventBounds.height / 2;
modeling.moveShape(boundaryEventShape, {x: to_move_x, y: to_move_y});
modeling.moveShape(boundaryEventShape, { x: to_move_x, y: to_move_y });

// update list for the next boundary event
attachedToElementBoundaries.push(boundaryEventShape.id);
Expand All @@ -155,7 +146,7 @@ function layoutBoundaryEvents(modeling, elementRegistry) {
let sourceX = boundaryEventBounds.x + boundaryEventBounds.width / 2;
let sourceY = boundaryEventBounds.y + boundaryEventBounds.height;
waypoints.shift();
waypoints.unshift({x: sourceX, y: sourceY});
waypoints.unshift({ x: sourceX, y: sourceY });

// update diagram
modeling.updateWaypoints(connectionShape, waypoints);
Expand Down Expand Up @@ -234,7 +225,7 @@ function adaptLabels(modeling, connection) {
// place the first label of the given connection
let firstLabel = connection.labels[0];
let middle = getMiddleOfLocation(connection, firstLabel);
modeling.moveElements([firstLabel], {x: middle.x - firstLabel.x, y: middle.y - firstLabel.y});
modeling.moveElements([firstLabel], { x: middle.x - firstLabel.x, y: middle.y - firstLabel.y });
}

// TODO: handle cases with multiple labels defined for the connection
Expand All @@ -255,11 +246,11 @@ function getMiddleOfLocation(connection, label) {
let middlePoint2 = waypoints[middleWaypointIndex];

if (middlePoint1.x === middlePoint2.x) {
return {x: middlePoint1.x - LABEL_MARGIN - parseInt(label.width), y: (middlePoint1.y + middlePoint2.y) / 2};
return { x: middlePoint1.x - LABEL_MARGIN - parseInt(label.width), y: (middlePoint1.y + middlePoint2.y) / 2 };
}

if (middlePoint1.y === middlePoint2.y) {
return {x: (middlePoint1.x + middlePoint2.x) / 2, y: middlePoint1.y - LABEL_MARGIN - parseInt(label.height)};
return { x: (middlePoint1.x + middlePoint2.x) / 2, y: middlePoint1.y - LABEL_MARGIN - parseInt(label.height) };
}

return {
Expand Down Expand Up @@ -356,7 +347,7 @@ function getEdgeFromFlowElement(elementRegistry, flowElement) {
sourceElement = sourceElement.attachedToRef;
}

return {id: flowElement.id, sourceId: sourceElement.id, targetId: flowElement.targetRef.id};
return { id: flowElement.id, sourceId: sourceElement.id, targetId: flowElement.targetRef.id };
}

/**
Expand All @@ -372,14 +363,14 @@ function layoutWithDagre(modeling, elementRegistry, dagre, tasks, flows, options
console.log('Adding %i tasks to the graph for layouting: ', tasks.length);
for (let i = 0; i < tasks.length; i++) {
let task = tasks[i];
g.setNode(task.id, {label: task.id, width: task.width, height: task.height});
g.setNode(task.id, { label: task.id, width: task.width, height: task.height });
}

// add flows as edges to the graph
console.log('Adding %i flows to the graph for layouting: ', flows.length);
for (let i = 0; i < flows.length; i++) {
let flow = flows[i];
g.setEdge(flow['sourceId'], flow['targetId'], {label: flow['id']});
g.setEdge(flow['sourceId'], flow['targetId'], { label: flow['id'] });
}

// layout the graph
Expand All @@ -393,7 +384,7 @@ function layoutWithDagre(modeling, elementRegistry, dagre, tasks, flows, options
// determine new position of task and move it there
let to_move_x = node.x - element.x - element.width / 2;
let to_move_y = node.y - element.y - element.height / 2;
let delta_string = {x: to_move_x, y: to_move_y};
let delta_string = { x: to_move_x, y: to_move_y };
modeling.moveElements([element], delta_string);
});

Expand All @@ -402,18 +393,21 @@ function layoutWithDagre(modeling, elementRegistry, dagre, tasks, flows, options
let edge = g.edge(e);
let points = edge.points;
let element = elementRegistry.get(edge.label);
let waypoints = element.waypoints;
if (element !== undefined) {
let waypoints = element.waypoints;

while (waypoints.length > 0) {
waypoints.pop();
}
while (waypoints.length > 0) {
waypoints.pop();
}

for (let pointsIndex = 0; pointsIndex < points.length; pointsIndex++) {
let point;
point = {x: points[pointsIndex].x, y: points[pointsIndex].y};
waypoints.push(point);
}
for (let pointsIndex = 0; pointsIndex < points.length; pointsIndex++) {
let point;
point = { x: points[pointsIndex].x, y: points[pointsIndex].y };
waypoints.push(point);
}

element.waypoints = waypoints;
element.waypoints = waypoints;
}
});

}

0 comments on commit 744f05f

Please sign in to comment.