Skip to content

Commit

Permalink
feat: let hide 2nd process and disable subprocess navigation (#9)
Browse files Browse the repository at this point in the history
The second process is only displayed in the 'none' use case. It will
later be displayed in the "case
monitoring" on demand. The same applies to the sub-process navigation.
The diagram fits the container in the "process monitoring" to enlarge it
at maximum.
  • Loading branch information
tbouffard authored Mar 13, 2023
1 parent 7222848 commit de2b7b6
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 77 deletions.
10 changes: 5 additions & 5 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,20 @@

<div id="control" class="col-12 col-mx-auto form-horizontal mt-2 pt-2 pb-2">
<div class="form-group">
<div class="col-auto col-sm-10 mr-2" style="margin-left: auto">
<div class="col-auto col-ml-auto col-sm-10 mr-2">
<label class="form-label label-lg text-bold">Use case</label>
</div>
<div class="col-auto col-sm-10 ml-2" style="margin-right: auto">
<div class="col-auto col-mr-auto col-sm-10 ml-2">
<label class="form-radio form-inline input-lg">
<input id="radio-reset-all" type="radio" name="use_case" value="radio-reset-all" checked>
<input id="radio-reset-all" type="radio" name="use-case" value="radio-reset-all" checked>
<i class="form-icon"></i> None
</label>
<label class="form-radio form-inline input-lg">
<input id="radio-process-monitoring" type="radio" name="use_case" value="radio-process-monitoring">
<input id="radio-process-monitoring" type="radio" name="use-case" value="radio-process-monitoring">
<i class="form-icon"></i> Process Monitoring
</label>
<label class="form-radio form-inline input-lg">
<input id="radio-case-monitoring" type="radio" value="radio-case-monitoring" name="use_case">
<input id="radio-case-monitoring" type="radio" value="radio-case-monitoring" name="use-case">
<i class="form-icon"></i> Case Monitoring
</label>
</div>
Expand Down
8 changes: 8 additions & 0 deletions src/breadcrumb.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
import {displayBpmnDiagram} from './diagram.js';

export const configureBreadcrumb = (): void => {
document.querySelector('#breadcrumb-main-diagram')!.addEventListener('click', () => {
displayBpmnDiagram('main');
});
};

// Remove section of secondary diagram in Breadcrumb
export function removeSectionInBreadcrumb(): void {
const secondaryDiagramElt = document.querySelectorAll('.breadcrumb > #secondary-diagram').item(0);
Expand Down
67 changes: 66 additions & 1 deletion src/diagram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import {BpmnVisualization, FitType, type LoadOptions} from 'bpmn-visualization';
import subDiagram from './diagrams/SRM-subprocess.bpmn?raw';
import {removeSectionInBreadcrumb, addSectionInBreadcrumb} from './breadcrumb.js';

export const sharedLoadOptions: LoadOptions = {fit: {type: FitType.Center, margin: 20}};
const sharedFitOptions = {type: FitType.Center, margin: 20};

export const sharedLoadOptions: LoadOptions = {fit: sharedFitOptions};

let secondaryBpmnDiagramIsAlreadyLoad = false;
let currentView = 'main';
Expand Down Expand Up @@ -44,3 +46,66 @@ export function displayBpmnDiagram(tabIndex: string): void {

currentView = tabIndex;
}

const poolIdOfSubProcess = 'Participant_03ba50e';

export class ProcessVisualizer {
constructor(private readonly bpmnVisualization: BpmnVisualization) {}

showManuallyTriggeredProcess = (): void => {
this.changePoolVisibility(false, true);
};

hideManuallyTriggeredProcess = (fitDiagram = false): void => {
this.changePoolVisibility(true, fitDiagram);
};

private changePoolVisibility(hide = false, fitDiagram = false) {
const model = this.bpmnVisualization.graph.getModel();

// To ensure that the rendering is not affected by previous "hide then fit"
// Fit the whole diagram again: make it visible, then fit, then hide
if (hide && !fitDiagram) {
this.bpmnVisualization.graph.batchUpdate(() => {
for (const cell of [poolIdOfSubProcess].map(id => model.getCell(id))) {
model.setVisible(cell, true);
}
});
this.bpmnVisualization.navigation.fit(sharedFitOptions);
}

this.bpmnVisualization.graph.batchUpdate(() => {
for (const cell of [poolIdOfSubProcess].map(id => model.getCell(id))) {
model.setVisible(cell, !hide);
}
});

if (fitDiagram) {
this.bpmnVisualization.navigation.fit(sharedFitOptions);
}
}
}

const subProcessId = 'Activity_0ec8azh';

const doSubProcessNavigation = () => {
displayBpmnDiagram('secondary');
};

export class SubProcessNavigator {
private readonly subProcessHtmlElement: HTMLElement;

constructor(private readonly bpmnVisualization: BpmnVisualization) {
this.subProcessHtmlElement = this.bpmnVisualization.bpmnElementsRegistry.getElementsByIds(subProcessId)[0].htmlElement;
}

enable() {
this.subProcessHtmlElement.addEventListener('click', doSubProcessNavigation);
this.bpmnVisualization.bpmnElementsRegistry.addCssClasses(subProcessId, 'c-hand');
}

disable() {
this.subProcessHtmlElement.removeEventListener('click', doSubProcessNavigation);
this.bpmnVisualization.bpmnElementsRegistry.removeCssClasses(subProcessId, 'c-hand');
}
}
27 changes: 7 additions & 20 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,14 @@ limitations under the License.
import {BpmnVisualization} from 'bpmn-visualization';
// eslint-disable-next-line n/file-extension-in-import -- Vite syntax
import collapsedDiagram from './diagrams/EC-purchase-orders-collapsed.bpmn?raw';
import {displayBpmnDiagram, sharedLoadOptions} from './diagram.js';
import {configureRadioButtons} from './radio-buttons.js';
import {configureBreadcrumb} from './breadcrumb.js';
import {sharedLoadOptions} from './diagram.js';
import {configureUseCaseSelectors} from './use-case-management.js';

// 'bpmn-visualization' API documentation: https://process-analytics.github.io/bpmn-visualization-js/api/index.html
const mainBpmnVisualization = new BpmnVisualization({
const bpmnVisualization = new BpmnVisualization({
container: 'main-bpmn-container',
});
bpmnVisualization.load(collapsedDiagram, sharedLoadOptions);

// Load BPMN diagram
mainBpmnVisualization.load(collapsedDiagram, sharedLoadOptions);

// Interaction: open the sub-process
const subProcessId = 'Activity_0ec8azh';
mainBpmnVisualization.bpmnElementsRegistry.getElementsByIds(subProcessId)[0].htmlElement.addEventListener('click', () => {
displayBpmnDiagram('secondary');
});
mainBpmnVisualization.bpmnElementsRegistry.addCssClasses(subProcessId, 'c-hand');

// Return to main diagram
document.querySelector('#breadcrumb-main-diagram')!.addEventListener('click', () => {
displayBpmnDiagram('main');
});

configureRadioButtons(mainBpmnVisualization);
configureBreadcrumb();
configureUseCaseSelectors(bpmnVisualization);
51 changes: 0 additions & 51 deletions src/radio-buttons.ts

This file was deleted.

60 changes: 60 additions & 0 deletions src/use-case-management.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import {type BpmnVisualization} from 'bpmn-visualization';
import {hideCaseMonitoringData, showCaseMonitoringData} from './case-monitoring.js';
import {hideHappyPath, showHappyPath} from './process-monitoring.js';
import {ProcessVisualizer, SubProcessNavigator} from './diagram.js';

export function configureUseCaseSelectors(bpmnVisualization: BpmnVisualization) {
const processVisualizer = new ProcessVisualizer(bpmnVisualization);
const subProcessNavigator = new SubProcessNavigator(bpmnVisualization);

// eslint-disable-next-line no-warning-comments -- cannot be managed now
// TODO try to having calling constructor for side effects
// eslint-disable-next-line no-new
new UseCaseSelector('radio-process-monitoring', () => {
processVisualizer.hideManuallyTriggeredProcess(true);
showHappyPath(bpmnVisualization);
}, () => {
hideHappyPath(bpmnVisualization);
});
// eslint-disable-next-line no-new
new UseCaseSelector('radio-case-monitoring', () => {
processVisualizer.hideManuallyTriggeredProcess();
showCaseMonitoringData(bpmnVisualization);
}, () => {
hideCaseMonitoringData(bpmnVisualization);
});

const initialUseCase = new UseCaseSelector('radio-reset-all', () => {
processVisualizer.showManuallyTriggeredProcess();
subProcessNavigator.enable();
}, () => {
subProcessNavigator.disable();
});
initialUseCase.select();
}

let currentUseCase: UseCaseSelector | undefined;
class UseCaseSelector {
constructor(private readonly id: string, selectCallback: () => void, private readonly unselectCallback: () => void) {
document.querySelector(`#${id}`)?.addEventListener('click', () => {
if (currentUseCase !== this) {
currentUseCase?.unselect();
selectCallback();
// eslint-disable-next-line @typescript-eslint/no-this-alias,unicorn/no-this-assignment -- need to store this in a variable
currentUseCase = this;
}
});
}

select() {
const elt = document.querySelector(`#${(this.id)}`) ?? undefined;
(elt as HTMLInputElement)?.click();
}

private unselect() {
if (currentUseCase === this) {
this.unselectCallback();
currentUseCase = undefined;
}
}
}

0 comments on commit de2b7b6

Please sign in to comment.