generated from process-analytics/bpmn-visualization-demo-template
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add resource allocation interaction (1st step) (#10)
When clicking on the "Allocate more resource" button, the sub-process diagram is displayed. - It's running task is highlighted and the path leading to it is modified as well. This task proposed a popover which opens on hover. - In the future, the style of some elements of the diagram will be modified when hovering on the row of the popover. When clicking on the "Contact-Client" button, a window alert is displayed. In the future, it will display the 2nd process of the diagram and it will let interact with it. ### Implementation notes This PR introduces refactoring to better encapsulate the logic. In particular, it provides classes that may be reused outside this demo and served as starting point for experimental features - BpmnElementsSearcher - PathResolver The case monitoring data are fully managed by dedicated classes both for the main process and the sub-process. Other parts of the code are still leaking the use cases at several places. This will be refactored later to limit the size of this PR. --------- Co-authored-by: Thomas Bouffard <[email protected]>
- Loading branch information
Showing
8 changed files
with
476 additions
and
185 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
import {type BpmnVisualization} from 'bpmn-visualization'; | ||
import {BpmnElementsSearcher} from './utils/bpmn-elements.js'; | ||
import {PathResolver} from './utils/paths.js'; | ||
|
||
export type CaseMonitoringData = { | ||
executedShapes: string[]; | ||
runningActivities: string[]; | ||
enabledShapes: string[]; | ||
pendingShapes: string[]; | ||
visitedEdges: string[]; | ||
}; | ||
|
||
/** | ||
* Simulate fetching data from an execution system. | ||
*/ | ||
abstract class AbstractCaseMonitoringDataProvider { | ||
protected readonly bpmnElementsSearcher: BpmnElementsSearcher; | ||
private readonly pathResolver: PathResolver; | ||
|
||
protected constructor(protected readonly bpmnVisualization: BpmnVisualization) { | ||
this.bpmnElementsSearcher = new BpmnElementsSearcher(bpmnVisualization); | ||
this.pathResolver = new PathResolver(bpmnVisualization); | ||
} | ||
|
||
/** | ||
* In real life, parameters would be passed to this method, at least the `case id`. | ||
*/ | ||
fetch(): CaseMonitoringData { | ||
const executedShapes = this.getExecutedShapes(); | ||
const runningActivities = this.getRunningActivities(); | ||
const enabledShapes = this.getEnabledShapes(); | ||
const pendingShapes = this.getPendingShapes(); | ||
|
||
const visitedEdges = this.pathResolver.getVisitedEdges([...executedShapes, ...runningActivities, ...enabledShapes, ...pendingShapes]); | ||
return { | ||
executedShapes, | ||
runningActivities, | ||
enabledShapes, | ||
pendingShapes, | ||
visitedEdges, | ||
}; | ||
} | ||
|
||
abstract getExecutedShapes(): string[]; | ||
|
||
abstract getRunningActivities(): string[]; | ||
|
||
abstract getEnabledShapes(): string[]; | ||
|
||
abstract getPendingShapes(): string[]; | ||
} | ||
|
||
class MainProcessCaseMonitoringDataProvider extends AbstractCaseMonitoringDataProvider { | ||
constructor(protected readonly bpmnVisualization: BpmnVisualization) { | ||
super(bpmnVisualization); | ||
} | ||
|
||
getEnabledShapes(): string[] { | ||
return []; | ||
} | ||
|
||
getExecutedShapes(): string[] { | ||
const shapes: string[] = []; | ||
addNonNullElement(shapes, this.bpmnElementsSearcher.getElementIdByName('New POI needed')); // Start event | ||
addNonNullElement(shapes, 'Gateway_0xh0plz'); // Parallel gateway after start event | ||
addNonNullElement(shapes, this.bpmnElementsSearcher.getElementIdByName('Vendor creates invoice')); | ||
addNonNullElement(shapes, this.bpmnElementsSearcher.getElementIdByName('Create Purchase Order Item')); | ||
return shapes; | ||
} | ||
|
||
getPendingShapes(): string[] { | ||
const pendingShapes: string[] = []; | ||
pendingShapes.push('Gateway_0domayw'); | ||
return pendingShapes; | ||
} | ||
|
||
getRunningActivities(): string[] { | ||
const activities: string[] = []; | ||
addNonNullElement(activities, this.bpmnElementsSearcher.getElementIdByName('SRM subprocess')); | ||
return activities; | ||
} | ||
} | ||
|
||
class SecondaryProcessCaseMonitoringDataProvider extends AbstractCaseMonitoringDataProvider { | ||
constructor(protected readonly bpmnVisualization: BpmnVisualization) { | ||
super(bpmnVisualization); | ||
} | ||
|
||
getEnabledShapes(): string[] { | ||
const shapes: string[] = []; | ||
addNonNullElement(shapes, this.bpmnElementsSearcher.getElementIdByName('SRM: Awaiting Approval')); | ||
return shapes; | ||
} | ||
|
||
getExecutedShapes(): string[] { | ||
const shapes: string[] = []; | ||
addNonNullElement(shapes, 'Event_1dnxra5'); // Start event | ||
addNonNullElement(shapes, this.bpmnElementsSearcher.getElementIdByName('SRM: Created')); | ||
addNonNullElement(shapes, this.bpmnElementsSearcher.getElementIdByName('SRM: Complete')); | ||
return shapes; | ||
} | ||
|
||
getPendingShapes(): string[] { | ||
return []; | ||
} | ||
|
||
getRunningActivities(): string[] { | ||
return []; | ||
} | ||
} | ||
|
||
export function getCaseMonitoringData(processId: string, bpmnVisualization: BpmnVisualization): CaseMonitoringData { | ||
const caseMonitoringDataProvider = processId === 'main' ? new MainProcessCaseMonitoringDataProvider(bpmnVisualization) : new SecondaryProcessCaseMonitoringDataProvider(bpmnVisualization); | ||
|
||
const executedShapes = caseMonitoringDataProvider.getExecutedShapes(); | ||
const runningActivities = caseMonitoringDataProvider.getRunningActivities(); | ||
const enabledShapes = caseMonitoringDataProvider.getEnabledShapes(); | ||
const pendingShapes = caseMonitoringDataProvider.getPendingShapes(); | ||
|
||
const visitedEdges = new PathResolver(bpmnVisualization).getVisitedEdges([...executedShapes, ...runningActivities, ...enabledShapes, ...pendingShapes]); | ||
return { | ||
executedShapes, | ||
runningActivities, | ||
enabledShapes, | ||
pendingShapes, | ||
visitedEdges, | ||
}; | ||
} | ||
|
||
function addNonNullElement(elements: string[], elt: string | undefined) { | ||
if (elt) { | ||
elements.push(elt); | ||
} | ||
} |
Oops, something went wrong.