Skip to content

Commit b9c33e5

Browse files
2 parents dbe0edf + 73b761c commit b9c33e5

File tree

9 files changed

+249
-75
lines changed

9 files changed

+249
-75
lines changed

components/bpmn-q/modeler-component/QuantumWorkflowModeler.js

Lines changed: 65 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@ import Toolbar from "./editor/ui/Toolbar";
1717
import {
1818
createNewDiagram,
1919
loadDiagram,
20+
openFile,
2021
setAutoSaveInterval,
2122
} from "./editor/util/IoUtilities";
2223
import NotificationHandler from "./editor/ui/notifications/NotificationHandler";
23-
import { createModeler, getModeler } from "./editor/ModelerHandler";
24+
import { createModeler } from "./editor/ModelerHandler";
2425
import {
2526
getConfigTabs,
2627
getPluginButtons,
@@ -42,6 +43,8 @@ import ace from "ace-builds";
4243
*/
4344
export class QuantumWorkflowModeler extends HTMLElement {
4445
workflowModel;
46+
bpmnjsModeler;
47+
4548
constructor() {
4649
super();
4750
}
@@ -66,7 +69,7 @@ export class QuantumWorkflowModeler extends HTMLElement {
6669

6770
// open sent workflow and save its file name
6871
editorConfig.setFileName(event.data.name);
69-
loadDiagram(xmlString, getModeler()).then();
72+
loadDiagram(xmlString, self.bpmnjsModeler).then();
7073
}
7174
});
7275

@@ -89,27 +92,26 @@ export class QuantumWorkflowModeler extends HTMLElement {
8992
setInnerHtml() {
9093
this.innerHTML = `
9194
<div style="display: flex; flex-direction: column; height: 100%;" class="qwm">
92-
<div id="toolbar-container" style="flex-shrink: 0;"></div>
93-
<div id="button-container" style="flex-shrink: 0;"></div>
95+
<div class="toolbar-container" id="toolbar-container" style="flex-shrink: 0;"></div>
96+
<div class="button-container" id="button-container" style="flex-shrink: 0;"></div>
9497
<hr class="qwm-toolbar-splitter" />
95-
<div id="main-div" style="display: flex; flex: 1; height: 100%">
96-
<div id="canvas" style="width: 100%"></div>
97-
<div id="properties" style="overflow: auto; width:350px; max-height: 93.5vh; background: #f8f8f8;"></div>
98-
<div id="modal-container"></div>
98+
<div class="main-div" id="main-div" style="display: flex; flex: 1; height: 100%">
99+
<div class="canvas" id="canvas" style="width: 100%"></div>
100+
<div class="properties" id="properties" style="overflow: auto; width:350px; max-height: 93.5vh; background: #f8f8f8;"></div>
101+
<div class="modal-container" id="modal-container"></div>
99102
</div>
100-
<div id="qwm-notification-container"></div>
103+
<div class="qwm-notification-container" id="qwm-notification-container"></div>
101104
</div>`;
102105

103-
let panel = document.getElementById("properties");
104-
let maindiv = document.getElementById("main-div");
106+
let propertiesPanel = this.querySelector(".properties");
107+
let maindiv = this.querySelector(".main-div");
105108

106109
let isResizing = false;
107110
let startX;
108111
let startWidth;
109-
let width = panel.style.width;
110-
let propertiesElement = document.getElementById("properties");
112+
let width = propertiesPanel.style.width;
111113

112-
propertiesElement.addEventListener("mousemove", function (e) {
114+
propertiesPanel.addEventListener("mousemove", function (e) {
113115
let rect = this.getBoundingClientRect();
114116
let x = e.clientX - rect.left;
115117
let y = e.clientY - rect.top;
@@ -129,9 +131,9 @@ export class QuantumWorkflowModeler extends HTMLElement {
129131
});
130132

131133
// Mouse down event listener
132-
panel.addEventListener("mousedown", handleMouseDown);
134+
propertiesPanel.addEventListener("mousedown", handleMouseDown);
133135

134-
panel.addEventListener("mouseup", function () {
136+
propertiesPanel.addEventListener("mouseup", function () {
135137
this.style.cursor = "default";
136138
});
137139

@@ -143,7 +145,7 @@ export class QuantumWorkflowModeler extends HTMLElement {
143145

144146
// Mouse down handler
145147
function handleMouseDown(event) {
146-
let rect = panel.getBoundingClientRect();
148+
let rect = propertiesPanel.getBoundingClientRect();
147149
let x = event.clientX - rect.left;
148150

149151
let borderSize = 5;
@@ -152,7 +154,7 @@ export class QuantumWorkflowModeler extends HTMLElement {
152154
isResizing = true;
153155
}
154156
startX = event.clientX;
155-
startWidth = parseFloat(panel.style.width);
157+
startWidth = parseFloat(propertiesPanel.style.width);
156158
}
157159
let isCollapsed = false;
158160
const resizeButton = document.createElement("button");
@@ -166,7 +168,7 @@ export class QuantumWorkflowModeler extends HTMLElement {
166168
return;
167169
}
168170
maindiv.style.cursor = "w-resize";
169-
panel.style.cursor = "w-resize";
171+
propertiesPanel.style.cursor = "w-resize";
170172
const deltaX = event.clientX - startX;
171173
let newWidth = startWidth - deltaX;
172174

@@ -176,26 +178,26 @@ export class QuantumWorkflowModeler extends HTMLElement {
176178
isCollapsed = true;
177179
resizeButton.className = "fa fa-angle-left resize";
178180
}
179-
panel.style.width = `${newWidth}px`;
181+
propertiesPanel.style.width = `${newWidth}px`;
180182
}
181183

182184
// Mouse up handler
183185
function handleMouseUp() {
184-
panel.style.cursor = "default";
186+
propertiesPanel.style.cursor = "default";
185187
isResizing = false;
186188
}
187189

188190
resizeButton.addEventListener("click", function () {
189-
let offsetWidth = panel.offsetWidth;
191+
let offsetWidth = propertiesPanel.offsetWidth;
190192
if (isCollapsed) {
191-
panel.style.display = "block";
192-
panel.style.width = offsetWidth;
193-
if (panel.offsetWidth < parseInt(width, 10)) {
194-
panel.style.width = width;
193+
propertiesPanel.style.display = "block";
194+
propertiesPanel.style.width = offsetWidth;
195+
if (propertiesPanel.offsetWidth < parseInt(width, 10)) {
196+
propertiesPanel.style.width = width;
195197
}
196198
resizeButton.className = "fa fa-angle-right resize";
197199
} else {
198-
panel.style.display = "none";
200+
propertiesPanel.style.display = "none";
199201
resizeButton.className = "fa fa-angle-left resize";
200202
}
201203

@@ -223,7 +225,7 @@ export class QuantumWorkflowModeler extends HTMLElement {
223225
let startTop = parseInt(editorElement.css("top"));
224226
let startHeight = editor_wrap.height();
225227

226-
$(document).mousemove(function (e) {
228+
$(document).on("mousemove", function (e) {
227229
if (!dragging) return;
228230

229231
let actualY = e.pageY;
@@ -251,10 +253,10 @@ export class QuantumWorkflowModeler extends HTMLElement {
251253
});
252254
});
253255

254-
$(document).mouseup(function () {
256+
$(document).on("mouseup", function () {
255257
if (dragging) {
256258
dragging = false;
257-
$(document).unbind("mousemove");
259+
$(document).off("mousemove");
258260
}
259261
});
260262
}
@@ -270,18 +272,18 @@ export class QuantumWorkflowModeler extends HTMLElement {
270272
initEditorEventHandler(this);
271273

272274
// get and reset the container in which the bpmn-js modeler and its properties panel should be rendered
273-
const bpmnContainer = document.getElementById("canvas");
274-
const propertiesPanelContainer = document.getElementById("properties");
275+
const bpmnContainer = this.querySelector(".canvas");
276+
const propertiesPanelContainer = this.querySelector(".properties");
275277
bpmnContainer.innerHTML = "";
276278
propertiesPanelContainer.innerHTML = "";
277279

278280
// create a new bpmn-js modeler instance with all additional modules and extensions defined by the plugins
279-
const modeler = createModeler(bpmnContainer, propertiesPanelContainer);
281+
this.bpmnjsModeler = createModeler(bpmnContainer, propertiesPanelContainer);
280282
console.log("Created Modeler");
281283

282284
// set up the notification handler and render it into the DOM
283-
const notificationsContainer = document.getElementById(
284-
"qwm-notification-container"
285+
const notificationsContainer = this.querySelector(
286+
".qwm-notification-container"
285287
);
286288
const handler = NotificationHandler.getInstance();
287289
const notificationComponent = handler.createNotificationsComponent(
@@ -297,46 +299,44 @@ export class QuantumWorkflowModeler extends HTMLElement {
297299
const transformationButtons = getTransformationButtons();
298300

299301
// integrate the React ButtonToolbar into its DOM container
300-
const toolbarRoot = createRoot(
301-
document.getElementById("toolbar-container")
302-
);
302+
const toolbarRoot = createRoot(this.querySelector(".toolbar-container"));
303303
toolbarRoot.render(
304304
<Toolbar
305-
modeler={modeler}
305+
modeler={this.bpmnjsModeler}
306306
pluginButtons={getPluginButtons()}
307307
transformButtons={transformationButtons}
308308
/>
309309
);
310-
const root = createRoot(document.getElementById("button-container"));
310+
const root = createRoot(this.querySelector(".button-container"));
311311
root.render(
312312
<ButtonToolbar
313-
modeler={modeler}
313+
modeler={this.bpmnjsModeler}
314314
pluginButtons={getPluginButtons()}
315315
transformButtons={transformationButtons}
316316
/>
317317
);
318318

319+
const self = this;
320+
319321
// load initial workflow
320322
this.workflowModel =
321323
this.workflowModel || getPluginConfig("editor").defaultWorkflow;
322-
getModeler().on("commandStack.changed", function () {
323-
getModeler()
324-
.saveXML({ format: true })
325-
.then(function (result) {
326-
modeler.xml = result;
327-
});
324+
this.bpmnjsModeler.on("commandStack.changed", function () {
325+
self.bpmnjsModeler.saveXML({ format: true }).then(function (result) {
326+
self.bpmnjsModeler.xml = result;
327+
});
328328
});
329-
if (!modeler.config) {
330-
modeler.config = {};
329+
if (!this.bpmnjsModeler.config) {
330+
this.bpmnjsModeler.config = {};
331331
let configTabs = getConfigTabs();
332332
for (let tab of configTabs) {
333333
tab.configTab.prototype.config();
334334
}
335335
}
336336
if (this.workflowModel) {
337-
loadDiagram(this.workflowModel, getModeler()).then();
337+
loadDiagram(this.workflowModel, this.bpmnjsModeler).then();
338338
} else {
339-
createNewDiagram(modeler);
339+
createNewDiagram(this.bpmnjsModeler);
340340
}
341341
}
342342

@@ -347,10 +347,22 @@ export class QuantumWorkflowModeler extends HTMLElement {
347347
* @return {Promise<*|undefined>}
348348
*/
349349
async loadWorkflowDiagram(xmlDiagram) {
350-
const modeler = getModeler();
350+
const modeler = this.bpmnjsModeler;
351+
352+
if (modeler) {
353+
return await loadDiagram(xmlDiagram, this.bpmnjsModeler);
354+
} else {
355+
console.log(
356+
"Loading of Workflow via external interface not possible until modeler is loaded."
357+
);
358+
}
359+
}
360+
361+
async loadWorkflowFile(file) {
362+
const modeler = this.bpmnjsModeler;
351363

352364
if (modeler) {
353-
return await loadDiagram(xmlDiagram, getModeler());
365+
await openFile(file);
354366
} else {
355367
console.log(
356368
"Loading of Workflow via external interface not possible until modeler is loaded."

components/bpmn-q/modeler-component/editor/EditorConstants.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,12 @@ export const transformedWorkflowHandlers = {
2424

2525
// workflow event types dispatched by the EditorEventHandler
2626
export const workflowEventTypes = {
27+
REQUEST_OPEN: "quantum-workflow-request-open", // Fired when the user wants to open a Workflow
2728
LOADED: "quantum-workflow-loaded", // New Workflow loaded in modeler
29+
BEFORE_SAVE: "quantum-workflow-before-save", // Fired before a Workflow is saved
2830
SAVED: "quantum-workflow-saved", // Workflow saved
2931
TRANSFORMED: "quantum-workflow-transformed", // Workflow transformed
32+
BEFORE_DEPLOY: "quantum-workflow-before-deploy", // Fired before Workflow is deployed
3033
DEPLOYED: "quantum-workflow-deployed", // Workflow deployed to workflow engine
3134
};
3235

components/bpmn-q/modeler-component/editor/events/EditorEventHandler.js

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,31 @@ export function initEditorEventHandler(newModelerComponent) {
2020
* @param type The type of the event, one of the workflowEventTypes
2121
* @param workflowXml The workflow diagram as xml string the current event is triggered for.
2222
* @param workflowName The name of the workflow diagram the current event is triggered for.
23+
* @param extra Additional data to be included in the event details
2324
* @returns {*} Boolean, true if either event's cancelable attribute value is false or its preventDefault() method was
2425
* not invoked, and false otherwise.
2526
*/
26-
export function dispatchWorkflowEvent(type, workflowXml, workflowName) {
27+
export function dispatchWorkflowEvent(type, workflowXml, workflowName, extra) {
28+
const detail = {};
29+
if (workflowName != null) {
30+
detail.workflowName = workflowName;
31+
}
32+
if (workflowXml != null) {
33+
detail.workflow = workflowXml;
34+
}
35+
if (extra) {
36+
Object.keys(extra).forEach((key) => {
37+
if (
38+
extra.hasOwnProperty(key) &&
39+
key !== "workflowName" &&
40+
key !== "workflow"
41+
) {
42+
detail[key] = extra[key];
43+
}
44+
});
45+
}
2746
const newEvent = new CustomEvent(type, {
28-
detail: {
29-
workflowName: workflowName,
30-
workflow: workflowXml,
31-
},
47+
detail: detail,
3248
cancelable: true,
3349
});
3450
return modelerComponent?.dispatchEvent?.(newEvent) ?? true;

components/bpmn-q/modeler-component/editor/ui/DeploymentButton.js

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import DeploymentSelectionModal from "./DeploymentSelectionModal";
77
import { startDataFlowReplacementProcess } from "../../extensions/dataflow/replacement/DataFlowTransformator";
88
import { startPlanqkReplacementProcess } from "../../extensions/planqk/replacement/PlanQKTransformator";
99
import { checkEnabledStatus } from "../plugin/PluginHandler";
10-
import { pluginNames } from "../EditorConstants";
10+
import { pluginNames, workflowEventTypes } from "../EditorConstants";
11+
import { dispatchWorkflowEvent } from "../events/EditorEventHandler";
12+
import * as editorConfig from "../config/EditorConfigManager";
1113

1214
/**
1315
* React button for starting the deployment of the workflow.
@@ -159,10 +161,26 @@ export default function DeploymentButton(props) {
159161

160162
async function onClick() {
161163
const planqkEnabled = checkEnabledStatus(pluginNames.PLANQK);
162-
setWindowOpenDemandSelection(planqkEnabled);
163-
console.log("PlanQK enabled: " + planqkEnabled);
164-
if (!planqkEnabled) {
165-
deploy((await modeler.saveXML({ format: true })).xml);
164+
const workflowXml = (await modeler.saveXML({ format: true })).xml;
165+
const filename = editorConfig.getFileName();
166+
const extra = {
167+
deployToCamunda: (xml) => deploy(xml),
168+
};
169+
if (planqkEnabled) {
170+
extra.deployToPlanqk = (xml) => deployAsPlanQKService(xml);
171+
}
172+
const defaultBehaviour = dispatchWorkflowEvent(
173+
workflowEventTypes.BEFORE_DEPLOY,
174+
workflowXml,
175+
filename,
176+
extra
177+
);
178+
if (defaultBehaviour) {
179+
setWindowOpenDemandSelection(planqkEnabled);
180+
console.log("PlanQK enabled: " + planqkEnabled);
181+
if (!planqkEnabled) {
182+
deploy(workflowXml);
183+
}
166184
}
167185
}
168186

components/bpmn-q/modeler-component/editor/ui/OpenButton.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import React, { useRef } from "react";
22
import { openFile } from "../util/IoUtilities";
3+
import { workflowEventTypes } from "../EditorConstants";
4+
import { dispatchWorkflowEvent } from "../events/EditorEventHandler";
35

46
/**
57
* React button which starts loading a saved workflow from the users local file system
@@ -11,7 +13,12 @@ export default function OpenButton() {
1113
const inputRef = useRef(null);
1214

1315
function handleClick() {
14-
inputRef.current.click();
16+
const defaultBehaviour = dispatchWorkflowEvent(
17+
workflowEventTypes.REQUEST_OPEN
18+
);
19+
if (defaultBehaviour) {
20+
inputRef.current.click();
21+
}
1522
}
1623

1724
function handleChange(event) {

0 commit comments

Comments
 (0)