Skip to content

Commit 1546424

Browse files
authored
Merge branch 'main' into fix-import-bpmn-preview
2 parents 9e48908 + 25fd372 commit 1546424

66 files changed

Lines changed: 3612 additions & 1929 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/engine/universal/core/src/engine/engine.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,16 @@ class Engine {
129129
* @param {string} the version of the process to deploy
130130
*/
131131
async deployProcessVersion(definitionId, versionId) {
132+
const otherVersions = this.versions.filter((version) => version !== versionId);
133+
otherVersions.forEach((version) => {
134+
const process = this._versionProcessMapping[version];
135+
136+
// deactivate other versions so they don't keep spawning new instances automatically
137+
if (process) {
138+
process.undeploy();
139+
}
140+
});
141+
132142
if (!this._versionProcessMapping[versionId]) {
133143
// Fetch the stored BPMN
134144
const bpmn = await distribution.db.getProcessVersion(definitionId, versionId);
@@ -213,6 +223,22 @@ class Engine {
213223
this._versionProcessMapping[versionId] = process;
214224
this._versionBpmnMapping[versionId] = bpmn;
215225
this.versions.push(versionId);
226+
} else if (!this._versionProcessMapping[versionId].isDeployed()) {
227+
// activate the process so auto-start events like timer events are allowed to trigger new
228+
// instances
229+
this._versionProcessMapping[versionId].deploy();
230+
}
231+
}
232+
233+
/**
234+
* Removes the deployed state from the process version in the NeoBPMN Engine preventing it from starting instances
235+
*
236+
* @param {string} the version of the process to undeploy
237+
*/
238+
undeployProcessVersion(versionId) {
239+
const process = this._versionProcessMapping[versionId];
240+
if (process && process.isDeployed()) {
241+
process.undeploy();
216242
}
217243
}
218244

@@ -1014,6 +1040,9 @@ class Engine {
10141040
* Clean up some data when the engine is supposed to be removed
10151041
*/
10161042
destroy() {
1043+
for (const version of this.versions) {
1044+
this._versionProcessMapping[version].undeploy();
1045+
}
10171046
for (const instanceId of this.instanceIDs) {
10181047
this.deleteInstance(instanceId);
10191048
}

src/engine/universal/core/src/management.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,7 @@ const Management = {
5555
const engine = this.ensureProcessEngine(definitionId);
5656

5757
// ensure that the version is deployed
58-
if (!engine.versions.includes(version)) {
59-
await engine.deployProcessVersion(definitionId, version);
60-
}
58+
await engine.deployProcessVersion(definitionId, version);
6159

6260
return engine;
6361
},

src/engine/universal/distribution/src/routes/ProcessInstanceRoutes.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,4 +393,71 @@ module.exports = (path, management) => {
393393
});
394394
},
395395
);
396+
397+
network.put(`${path}/:definitionId/active`, { cors: true }, async (req) => {
398+
const { definitionId } = req.params;
399+
400+
const {
401+
body: { active },
402+
} = req;
403+
404+
if (active === true) {
405+
return {
406+
statusCode: 400,
407+
mimeType: 'text/plain',
408+
response:
409+
'Cannot set active true on a process. Please select a specific version to activate.',
410+
};
411+
} else if (active === false) {
412+
const engine = await management.getEngineWithDefinitionId(definitionId);
413+
414+
if (engine) {
415+
engine.versions.forEach((version) => engine.undeployProcessVersion(version));
416+
}
417+
418+
return {
419+
statusCode: 200,
420+
mimeType: 'application/json',
421+
response: '{}',
422+
};
423+
} else {
424+
return {
425+
statusCode: 400,
426+
mimeType: 'text/plain',
427+
response:
428+
'This endpoint expects the request body to contain an entry called active with a boolean value of "false".',
429+
};
430+
}
431+
});
432+
433+
network.put(`${path}/:definitionId/versions/:version/active`, { cors: true }, async (req) => {
434+
const { definitionId, version } = req.params;
435+
436+
const {
437+
body: { active },
438+
} = req;
439+
440+
if (active === true) {
441+
await management.ensureProcessEngineWithVersion(definitionId, version);
442+
} else if (active === false) {
443+
const engine = await management.getEngineWithDefinitionId(definitionId);
444+
445+
if (engine) {
446+
engine.undeployProcessVersion(version);
447+
}
448+
} else {
449+
return {
450+
statusCode: 400,
451+
mimeType: 'text/plain',
452+
response:
453+
'This endpoint expects the request body to contain an entry called active with a boolean value',
454+
};
455+
}
456+
457+
return {
458+
statusCode: 200,
459+
mimeType: 'application/json',
460+
response: '{}',
461+
};
462+
});
396463
};

src/engine/universal/system/src/script-execution.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ class ScriptExecutor extends System {
172172
path += '/organization';
173173
dataPath = dataPath.split('.').slice(1).join('.');
174174
} else {
175-
if (dataPath.startsWith('@user')) {
175+
if (dataPath.startsWith('@user') || dataPath.startsWith('@process-initiator')) {
176176
dataPath = dataPath.split('.').slice(1).join('.');
177177
} else if (dataPath.startsWith('@')) {
178178
throw new Error(

src/engine/universal/ui/src/display-items/tasklist/TaskList-DisplayItem.js

Lines changed: 56 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/helper-modules/bpmn-helper/src/getters.d.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,15 +424,16 @@ export function getAllUserTaskFileNamesAndUserTaskIdsMapping(bpmn: string | obje
424424
[userTaskFileName: string]: string[];
425425
}>;
426426
/**
427-
* Get all fileName for all scriptTasks,
427+
* Get all fileName and taskName for all scriptTasks,
428428
* (The attribute 'filename' is defined in the PROCEED XML Schema and not a standard BPMN attribute.)
429429
*
430430
* @param {(string|object)} bpmn - the process definition as XML string or BPMN-Moddle Object
431-
* @returns { Promise.<{ [scriptTaskId: string]: { fileName?: string }}> } an object (a map) with all scriptTaskIds as keys
431+
* @returns { Promise.<{ [scriptTaskId: string]: { fileName?: string, taskName?: string }}> } an object (a map) with all scriptTaskIds as keys
432432
*/
433433
export function getScriptTaskFileNameMapping(bpmn: string | object): Promise<{
434434
[scriptTaskId: string]: {
435435
fileName?: string;
436+
taskName?: string;
436437
};
437438
}>;
438439
/**

src/helper-modules/bpmn-helper/src/getters.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ async function getUserTaskFileNameMapping(bpmn) {
235235
* (The attribute 'filename' is defined in the PROCEED XML Schema and not a standard BPMN attribute.)
236236
*
237237
* @param {(string|object)} bpmn - the process definition as XML string or BPMN-Moddle Object
238-
* @returns { Promise.<{ [scriptTaskId: string]: { fileName?: string }}> } an object (a map) with all scriptTaskIds as keys
238+
* @returns { Promise.<{ [scriptTaskId: string]: { fileName?: string, taskName?: string }}> } an object (a map) with all scriptTaskIds as keys
239239
*/
240240
async function getScriptTaskFileNameMapping(bpmn) {
241241
const bpmnObj = typeof bpmn === 'string' ? await toBpmnObject(bpmn) : bpmn;

src/helper-modules/user-task-helper/index.d.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,31 @@ export function getCorrectMilestoneState(
223223
value: number;
224224
}[]
225225
>;
226+
/**
227+
* Function that returns all occurences of variables of the form "@global..." in placeholders
228+
*
229+
* @param {string | Buffer} html the html that contains placeholders that might reference global
230+
* variables
231+
* @returns {string[]} an array with all unique occurences of variable placholders
232+
*/
233+
export function getGlobalVariableReferences(html: string | Buffer): string[];
234+
/**
235+
* Function that will create an object containing the values for global variables referenced in the
236+
* given html
237+
*
238+
* @param {string | Buffer} html the html that contains placeholders that might reference global
239+
* variables
240+
* @param {(varPath: string) => Promise<any>} variableGetterFn a function that given a path to a
241+
* specific global variable returns the value of that variable
242+
* @returns {Promise<{ [key: string]: any }>} an object that maps the global variable paths in the html to
243+
* values returned by the provided varaibleGetterFn
244+
*/
245+
export function getGlobalVariables(
246+
html: string | Buffer,
247+
variableGetterFn: (varPath: string) => Promise<any>,
248+
): Promise<{
249+
[key: string]: any;
250+
}>;
226251
/**
227252
* Function that replaces the {{script}} placeholder in the html with the default script
228253
*

src/helper-modules/user-task-helper/index.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const { render } = require('./src/render.js');
2+
const { tokenize } = require('./src/tokenize.js');
23

34
const { getMilestonesFromElementById } = require('@proceed/bpmn-helper/src/getters');
45
/**
@@ -446,9 +447,76 @@ function inlineUserTaskData(html, variables, milestones) {
446447
return finalHtml;
447448
}
448449

450+
/**
451+
* Function that returns all occurences of variables of the form "@global..." in placeholders
452+
*
453+
* @param {string | Buffer} html the html that contains placeholders that might reference global
454+
* variables
455+
* @returns {string[]} an array with all unique occurences of variable placholders
456+
*/
457+
function getGlobalVariableReferences(html) {
458+
if (Buffer.isBuffer(html)) html = html.toString();
459+
460+
const globalDataVariables = tokenize(html);
461+
462+
const uniqueGlobalDataVariables = globalDataVariables
463+
.filter(
464+
(token, index) =>
465+
token.type === 'variable' &&
466+
token.variableName.startsWith('@global') &&
467+
!globalDataVariables
468+
.slice(0, index)
469+
.some((entry) => entry.variableName === token.variableName),
470+
)
471+
.map(({ variableName }) => variableName.split('.').slice(1).join('.'));
472+
473+
return uniqueGlobalDataVariables;
474+
}
475+
476+
/**
477+
* Function that will create an object containing the values for global variables referenced in the
478+
* given html
479+
*
480+
* @param {string | Buffer} html the html that contains placeholders that might reference global
481+
* variables
482+
* @param {(varPath: string) => Promise<any>} variableGetterFn a function that given a path to a
483+
* specific global variable returns the value of that variable
484+
* @returns {Promise<{ [key: string]: any }>} an object that maps the global variable paths in the html to
485+
* values returned by the provided varaibleGetterFn
486+
*/
487+
async function getGlobalVariables(html, variableGetterFn) {
488+
const variableReferences = getGlobalVariableReferences(html);
489+
490+
const globalVarPromises = variableReferences.map(async (varPath) => [
491+
`@global.${varPath}`,
492+
await variableGetterFn(varPath),
493+
]);
494+
495+
const globalVariables = await Promise.all(globalVarPromises);
496+
497+
const variables = {};
498+
499+
globalVariables.forEach(([varPath, value]) => {
500+
const path = varPath.split('.');
501+
const [varName] = path.splice(path.length - 1);
502+
let current = variables;
503+
for (const entry of path) {
504+
if (!(entry in current)) {
505+
current[entry] = {};
506+
}
507+
current = current[entry];
508+
}
509+
current[varName] = value;
510+
});
511+
512+
return variables;
513+
}
514+
449515
module.exports = {
450516
getCorrectVariableState,
451517
getCorrectMilestoneState,
518+
getGlobalVariableReferences,
519+
getGlobalVariables,
452520
inlineScript,
453521
inlineUserTaskData,
454522
};

0 commit comments

Comments
 (0)