Skip to content

Commit

Permalink
Merge branch 'upstream-master' into dev-main
Browse files Browse the repository at this point in the history
# Conflicts:
#	components/bpmn-q/modeler-component/editor/plugin/PluginHandler.js
#	components/bpmn-q/modeler-component/extensions/opentosca/configTabs/OpenTOSCATab.js
#	components/bpmn-q/modeler-component/extensions/quantme/QuantMEPlugin.js
#	components/bpmn-q/modeler-component/extensions/quantme/framework-config/config.js
#	components/bpmn-q/package-lock.json
#	components/bpmn-q/test/tests/editor/plugin.spec.js
#	components/bpmn-q/webpack.config.js
  • Loading branch information
wiomoc committed Aug 25, 2023
2 parents 396ff92 + 64100ce commit 551d381
Show file tree
Hide file tree
Showing 33 changed files with 1,402 additions and 669 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import './modeler.css';
import React from 'react';
import { createRoot } from 'react-dom/client';
import ButtonToolbar from "./editor/ui/ButtonToolbar";
import { createNewDiagram, loadDiagram } from "./editor/util/IoUtilities";
import { createNewDiagram, loadDiagram, setAutoSaveInterval } from "./editor/util/IoUtilities";
import NotificationHandler from "./editor/ui/notifications/NotificationHandler";
import { createModeler, getModeler } from "./editor/ModelerHandler";
import { getPluginButtons, getTransformationButtons } from "./editor/plugin/PluginHandler";
Expand Down Expand Up @@ -336,6 +336,7 @@ export class QuantumWorkflowModeler extends HTMLElement {
// restart modeler to apply plugin config when shadow dom is rendered
requestAnimationFrame(() => {
this.startModeler();
setAutoSaveInterval();
});
}
}
Expand Down
9 changes: 7 additions & 2 deletions components/bpmn-q/modeler-component/editor/EditorConstants.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,18 @@ export const workflowEventTypes = {
LOADED: 'quantum-workflow-loaded', // New Workflow loaded in modeler
SAVED: 'quantum-workflow-saved', // Workflow saved
TRANSFORMED: 'quantum-workflow-transformed', // Workflow transformed
DEPLOYED: 'quantum-workflow-deployed' // Workflow deployed to workflow engine
DEPLOYED: 'quantum-workflow-deployed', // Workflow deployed to workflow engine
};

export const autoSaveFile = {
INTERVAL: 'Interval',
ON_ACTION: 'On Action'
}

// supported save file options
export const saveFileFormats = {
ALL: 'all',
BPMN: '.bpmn',
PNG: '.png',
SVG: '.svg'
};
};
31 changes: 21 additions & 10 deletions components/bpmn-q/modeler-component/editor/ModelerHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,27 +85,38 @@ export function createTempModeler() {
}

/**
* Create a Modeler with only Camunda native extensions and no additional modules
* 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 bpmn-js modeler
* @returns the created modeler
*/
export function createLightweightModeler() {
return new BpmnModeler({
moddleExtensions: getExtensions(),
});
export async function createTempModelerFromXml(xml) {
// create new modeler with the custom QuantME extensions
const bpmnModeler = createTempModeler();

// import the xml containing the definitions
try {
await bpmnModeler.importXML(xml);
return bpmnModeler;
} catch (err) {
console.error(err);
}
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.
* Creates a modeler with all additional modules and extension moddles from all active plugins which is
* saved 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 createTempModelerFromXml(xml) {
export async function createModelerFromXml(xml) {
// create new modeler with the custom QuantME extensions
const bpmnModeler = createTempModeler();
const bpmnModeler = createModeler();

// import the xml containing the definitions
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { getPluginConfig } from '../plugin/PluginConfigHandler';
import { saveFileFormats, transformedWorkflowHandlers } from '../EditorConstants';
import { saveFileFormats, transformedWorkflowHandlers, autoSaveFile } from '../EditorConstants';

// default configurations of the editor
const defaultConfig = {
camundaEndpoint: process.env.CAMUNDA_ENDPOINT,
fileName: process.env.DOWNLOAD_FILE_NAME,
transformedWorkflowHandler: transformedWorkflowHandlers.NEW_TAB,
fileFormat: saveFileFormats.BPMN
autoSaveFileOption: autoSaveFile.INTERVAL,
fileFormat: saveFileFormats.BPMN,
autoSaveIntervalSize: process.env.AUTOSAVE_INTERVAL
};

let config = {};
Expand Down Expand Up @@ -90,6 +92,33 @@ export function setTransformedWorkflowHandler(transformedWorkflowHandler) {
}

/**
* Get the id of the handler to handle auto save of files.
*
* @return {string} the currently specified handler id
*/
export function getAutoSaveFileOption() {
if (config.autoSaveFileOption === undefined) {
const autoSaveFileOption = autoSaveFile[getPluginConfig('editor').autoSaveFileOption];
setAutoSaveFileOption(autoSaveFileOption || defaultConfig.autoSaveFileOption);
}
return config.autoSaveFileOption;
}

/**
* Set the id of the handler to handle auto save of files
*
* @param autoSaveFileOption the id of the transformed workflow handler
*/
export function setAutoSaveFileOption(autoSaveFileOption) {
if (autoSaveFileOption !== null && autoSaveFileOption !== undefined
// check that the new value is a valid handler id
&& Object.values(autoSaveFile).includes(autoSaveFileOption)) {

config.autoSaveFileOption = autoSaveFileOption;
}
}

/**
* Get the file format
*
* @return {string} the currently specified handler id
Expand All @@ -116,6 +145,29 @@ export function setFileFormat(fileFormat) {
}
}

/**
* Get the autosave interval size
*
* @return {string} the current interval size
*/
export function getAutoSaveIntervalSize() {
if (config.autoSaveIntervalSize === undefined) {
setAutoSaveIntervalSize(getPluginConfig('editor').autoSaveIntervalSize || defaultConfig.autoSaveIntervalSize);
}
return config.autoSaveIntervalSize;
}

/**
* Set the interval size of the autosave function
*
* @param intervalSize the interval size
*/
export function setAutoSaveIntervalSize(intervalSize) {
if (intervalSize !== null && intervalSize !== undefined) {
config.autoSaveIntervalSize = intervalSize;
}
}

/**
* Resets the current editor configs
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useState } from 'react';
import { getModeler } from "../ModelerHandler";
import * as editorConfig from "./EditorConfigManager";
import { transformedWorkflowHandlers, saveFileFormats } from '../EditorConstants';
import { autoSaveFile, saveFileFormats, transformedWorkflowHandlers } from '../EditorConstants';

/**
* Tab for the ConfigModal. Used to allow the configurations of the editor configs, namely the camunda endpoint and the
Expand All @@ -14,8 +14,11 @@ export default function EditorTab() {

const [camundaEndpoint, setCamundaEndpoint] = useState(editorConfig.getCamundaEndpoint());
const [workflowHandler, setWorkflowHandler] = useState(editorConfig.getTransformedWorkflowHandler());
const [autoSaveFileOption, setAutoSaveFileOption] = useState(editorConfig.getAutoSaveFileOption());
const [fileName, setFileName] = useState(editorConfig.getFileName());
const [fileFormat, setFileFormat] = useState(editorConfig.getFileFormat());
const [autoSaveIntervalSize, setAutoSaveIntervalSize] = useState(editorConfig.getAutoSaveIntervalSize());


const modeler = getModeler();

Expand Down Expand Up @@ -45,8 +48,11 @@ export default function EditorTab() {
modeler.config.fileName = fileName;
editorConfig.setCamundaEndpoint(camundaEndpoint);
editorConfig.setTransformedWorkflowHandler(workflowHandler);
editorConfig.setAutoSaveFileOption(autoSaveFileOption);
modeler.get('eventBus').fire('autoSaveOptionChanged', { autoSaveFileOption });
editorConfig.setFileName(fileName);
editorConfig.setFileFormat(fileFormat);
editorConfig.setAutoSaveIntervalSize(autoSaveIntervalSize);
};

// return tab which contains entries to change the camunda endpoint and the workflow handler
Expand Down Expand Up @@ -118,6 +124,38 @@ export default function EditorTab() {
</tr>
</tbody>
</table>
<h3>Auto save file:</h3>
<table>
<tbody>
<tr className="spaceUnder">
<td align="right">Auto save file option:</td>
<td align="left">
<select
name="autoSaveFileOption"
value={autoSaveFileOption}
onChange={event => setAutoSaveFileOption(event.target.value)}>
{Object.entries(autoSaveFile).map(([key, value]) => (
<option key={value} value={value}>
{value}
</option>
))}
</select>
</td>
</tr>
{autoSaveFileOption === autoSaveFile.INTERVAL && (
<tr className="spaceUnder">
<td align="right">Auto save interval size:</td>
<td align="left">
<input
type="number"
name="autoSaveIntervalSize"
value={autoSaveIntervalSize}
onChange={event => setAutoSaveIntervalSize(event.target.value)} />
</td>
</tr>
)}
</tbody>
</table>
</>);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,11 @@ export default class ConfigurationsEndpoint {
* Fetch the configured endpoint and store the result in this._configurations
*/
fetchConfigurations() {

fetch(this._endpointUrl)
.then(response => response.json())
.then(response => response.headers.get('content-type') === 'text/plain; charset=utf-8' ? response.text() : response.json())
.then(data => {
this._configurations = data;
console.log('Received ' + data.length + ' configurations: ');
console.log(data);
this._configurations = typeof data === "string" ? JSON.parse(data) : data;
console.log(this._configurations);
})
.catch(error => {
console.error('Error fetching configurations from ' + this._endpointUrl + ': \n' + error);
Expand Down
85 changes: 54 additions & 31 deletions components/bpmn-q/modeler-component/editor/plugin/PluginHandler.js
Original file line number Diff line number Diff line change
@@ -1,62 +1,81 @@
import PlanQKPlugin from "../../extensions/planqk/PlanQKPlugin";
import QuantMEPlugin from "../../extensions/quantme/QuantMEPlugin";
import PlanQKPlugin from '../../extensions/planqk/PlanQKPlugin';
import QuantMEPlugin from '../../extensions/quantme/QuantMEPlugin';
import OpenToscaPlugin from "../../extensions/opentosca/OpenTOSCAPlugin";
import DataFlowPlugin from '../../extensions/data-extension/DataFlowPlugin';
import QHAnaPlugin from '../../extensions/qhana/QHAnaPlugin';
import {getAllConfigs} from "./PluginConfigHandler";
import EditorTab from "../config/EditorTab";
import { getAllConfigs } from './PluginConfigHandler';
import GeneralTab from '../config/GeneralTab';
import GitHubTab from '../../extensions/quantme/configTabs/GitHubTab';

/**
* Handler for plugins of the modeler. Controls active plugins and the properties they define. Central access point to
* get the extensions the plugins define.
*/

// list of plugins integrated in the modeler, register new plugins here
// dependencies can be specified by the name of the corresponding plugins
const PLUGINS = [
DataFlowPlugin,
QHAnaPlugin,
PlanQKPlugin,
QuantMEPlugin,
OpenToscaPlugin
{
plugin: QuantMEPlugin,
dependencies: ['DataFlowPlugin']
},
{
plugin: DataFlowPlugin,
dependencies: []
},
{
plugin: QHAnaPlugin,
dependencies: []
},
{
plugin: PlanQKPlugin,
dependencies: []
},
{
plugin: OpenToscaPlugin,
dependencies: []
}
];

// list of currently active plugins in the current running instance of the modeler, defined based on the plugin configuration
let activePlugins = [];

/**
* Returns these plugins of PLUGINS which have an entry in the current plugin configuration of the modeler.
*
* @returns {*[]} Array of active plugins.
*/
export function getActivePlugins() {

// return saved active plugins array
if (activePlugins.length > 0) {
return activePlugins;

// determine active plugins
} else {

activePlugins = [];


let plugin;

// add all plugins of PLUGINS to active plugins which have a config entry for them
for (let pluginConfig of getAllConfigs()) {

plugin = PLUGINS.find(plugin => plugin.name === pluginConfig.name && checkEnabledStatus(plugin.name));
const loadPlugin = (plugin) => {
if (!activePlugins.includes(plugin.plugin)) {
for (const dependency of plugin.dependencies) {
const dependencyPlugin = PLUGINS.find((p) => p.plugin.name === dependency);
if (dependencyPlugin && !activePlugins.includes(dependencyPlugin.plugin)) {
activePlugins.push(dependencyPlugin.plugin);
loadPlugin(dependencyPlugin);
}
}
activePlugins.push(plugin.plugin);
}
};

for (const pluginConfig of getAllConfigs()) {
const plugin = PLUGINS.find(
(p) => p.plugin.name === pluginConfig.name && checkEnabledStatus(p.plugin.name)
);
if (plugin) {
activePlugins.push(plugin);
loadPlugin(plugin);
}
}

return activePlugins;
}
}



export function checkEnabledStatus(pluginName) {
switch(pluginName) {
switch (pluginName) {
case 'dataflow':
return process.env.ENABLE_DATA_FLOW_PLUGIN !== "false";
case 'planqk':
Expand Down Expand Up @@ -183,13 +202,17 @@ export function getConfigTabs() {
// add default editor tab to configure editor configs
let configTabs = [{
tabId: 'EditorTab',
tabTitle: 'Editor',
configTab: EditorTab,
tabTitle: 'General',
configTab: GeneralTab,
}, {
tabId: 'GitHubTab',
tabTitle: 'GitHub',
configTab: GitHubTab,
}];

// load the config tabs of the active plugins into one array
for (let plugin of getActivePlugins()) {
if (plugin.configTabs) {
if (plugin.configTabs && checkEnabledStatus(plugin.name)) {
configTabs = configTabs.concat(plugin.configTabs);
}
}
Expand Down
Loading

0 comments on commit 551d381

Please sign in to comment.