Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: use the "Update Style" API in the "Elements Identification" demo #2630

Merged
merged 8 commits into from
Apr 24, 2023
3 changes: 3 additions & 0 deletions dev/public/elements-identification.html
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@
</div>
<div id="display-options" style="margin-top: 1em;">
<label for="checkbox-display-overlays">Display overlays</label><input id="checkbox-display-overlays" type="checkbox" />

<label for="checkbox-css-style" title="To style the BPMN elements, check if you want to use CSS; otherwise not, if you want to use the API" class="tooltip">Use CSS style</label>
<input id="checkbox-css-style" type="checkbox" />
</div>
<div id="download-controls" style="margin-top: 1em;">
<button id="btn-dl-svg">Download SVG</button>
Expand Down
143 changes: 137 additions & 6 deletions dev/public/static/js/elements-identification.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,123 @@ import {
ShapeUtil,
startBpmnVisualization,
updateLoadOptions,
updateStyle,
windowAlertStatusKoNotifier,
} from '../../../ts/dev-bundle-index';

let lastIdentifiedBpmnIds = [];
const cssClassName = 'detection';
let isOverlaysDisplayed = true;
let useCSS = true;

function updateStyleByAPI(bpmnIds, bpmnKind) {
const style = { font: { spacing: {} }, fill: {}, stroke: {}, gradient: {}, label: {} };
switch (bpmnKind) {
case 'task':
csouchet marked this conversation as resolved.
Show resolved Hide resolved
case 'userTask':
case 'scriptTask':
case 'serviceTask':
case 'receiveTask':
case 'sendTask':
case 'manualTask':
case 'businessRuleTask':
style.font.color = 'Indigo';
style.fill.color = 'gold';
style.font.size = 14;
style.fill.opacity = 20;
break;
case 'startEvent':
case 'endEvent':
case 'intermediateCatchEvent':
case 'intermediateThrowEvent':
case 'boundaryEvent':
style.font.color = 'MediumTurquoise';
style.stroke.color = 'MediumTurquoise';
break;
case 'exclusiveGateway':
case 'inclusiveGateway':
case 'parallelGateway':
case 'eventBasedGateway':
case 'complexGateway':
style.font.color = 'CadetBlue';
style.font.opacity = 85;
style.stroke.color = 'OrangeRed';
style.stroke.width = 4;
break;
case 'lane':
case 'pool':
style.font.color = 'white !important';
style.fill.color = 'deeppink';
style.stroke.opacity = 80;
break;
case 'callActivity':
style.font.color = 'white';
style.font.family = 'Times New Roman';
style.font.isItalic = true;
style.font.isStrikeThrough = true;

style.fill.color = 'LimeGreen';
break;
case 'subProcess':
style.font.color = 'white';
style.font.size = 14;
style.font.family = 'Dialog';
style.font.isBold = true;
style.font.isItalic = true;
style.font.isUnderline = true;
style.font.isStrikeThrough = true;

style.fill.color = 'MidnightBlue';
style.opacity = 60;
break;
case 'group':
case 'textAnnotation':
style.font.color = 'Crimson';
style.font.size = 18;
style.font.family = 'Verdana';
style.font.isBold = true;
style.font.isUnderline = true;

style.stroke.color = 'Chartreuse';
style.stroke.width = 6;
break;
case 'messageFlow':
case 'sequenceFlow':
case 'association':
style.font.color = 'Chocolate';
style.stroke.color = 'Chocolate';
style.stroke.width = 4;
break;
}

updateStyle(bpmnIds, style);
}

function resetStyleByAPI() {
csouchet marked this conversation as resolved.
Show resolved Hide resolved
const style = {
font: {
color: 'default',
size: 10,
family: 'Arial',
isBold: false,
isItalic: false,
isUnderline: false,
isStrikeThrough: false,
opacity: 'default',
},
fill: {
color: 'default',
opacity: 'default',
},
stroke: {
color: 'default',
opacity: 'default',
width: 'default',
},
opacity: 'default',
};
updateStyle(lastIdentifiedBpmnIds, style);
}

function updateSelectedBPMNElements(textArea, bpmnKind) {
log(`Searching for Bpmn elements of '${bpmnKind}' kind`);
Expand All @@ -50,9 +161,14 @@ function updateSelectedBPMNElements(textArea, bpmnKind) {
// newly identified elements and values
const newlyIdentifiedBpmnIds = elementsByKinds.map(elt => elt.bpmnSemantic.id);

// CSS classes update
removeCssClasses(lastIdentifiedBpmnIds, cssClassName);
addCssClasses(newlyIdentifiedBpmnIds, cssClassName);
// style update
if (useCSS) {
removeCssClasses(lastIdentifiedBpmnIds, cssClassName);
addCssClasses(newlyIdentifiedBpmnIds, cssClassName);
} else {
resetStyleByAPI(lastIdentifiedBpmnIds);
updateStyleByAPI(newlyIdentifiedBpmnIds, bpmnKind);
}

// Overlays update
lastIdentifiedBpmnIds.forEach(id => removeAllOverlays(id));
Expand All @@ -75,22 +191,37 @@ function configureControls() {

document.getElementById('clear-btn').onclick = function () {
textArea.value = '';
removeCssClasses(lastIdentifiedBpmnIds, cssClassName);
useCSS ? removeCssClasses(lastIdentifiedBpmnIds, cssClassName) : resetStyleByAPI(lastIdentifiedBpmnIds);
lastIdentifiedBpmnIds.forEach(id => removeAllOverlays(id));

// reset identified elements and values
lastIdentifiedBpmnIds = [];
};

// display options
// display overlay option
const checkboxDisplayOverlaysElt = document.getElementById('checkbox-display-overlays');
checkboxDisplayOverlaysElt.addEventListener('change', function () {
isOverlaysDisplayed = this.checked;
log('Request overlays display:', isOverlaysDisplayed);
updateSelectedBPMNElements(textArea, selectedKindElt.value);
});
checkboxDisplayOverlaysElt.checked = isOverlaysDisplayed;

checkboxDisplayOverlaysElt.checked = true;
// use CSS or API to style the BPMN elements
const checkboxUseCSSElt = document.getElementById('checkbox-css-style');
checkboxUseCSSElt.addEventListener('change', function () {
useCSS = this.checked;
log('Request CSS style feature:', useCSS);

if (useCSS) {
resetStyleByAPI(lastIdentifiedBpmnIds);
addCssClasses(lastIdentifiedBpmnIds, cssClassName);
} else {
removeCssClasses(lastIdentifiedBpmnIds, cssClassName);
updateStyleByAPI(lastIdentifiedBpmnIds, selectedKindElt.value);
}
});
checkboxUseCSSElt.checked = useCSS;
}

function getOverlay(bpmnKind) {
Expand Down
10 changes: 7 additions & 3 deletions dev/ts/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,14 +310,18 @@ export function getVersion(): Version {
return version;
}

export function updateStyle(bpmnElementIds: string | string[], style: StyleUpdate): void {
log('Applying style using the style API: %O', style);
bpmnVisualization.bpmnElementsRegistry.updateStyle(bpmnElementIds, style);
log('New style applied');
}

function updateStyleOfElementsIfRequested(): void {
if (style) {
log("Applying style using the style API: '%s'", style);
const bpmnElementIds = retrieveAllBpmnElementIds();
log('Number of elements whose style is to be updated', bpmnElementIds.length);

bpmnVisualization.bpmnElementsRegistry.updateStyle(bpmnElementIds, style);
log('New style applied');
updateStyle(bpmnElementIds, style);
}
}

Expand Down
5 changes: 4 additions & 1 deletion src/component/registry/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,10 @@ export type Fill = StyleWithOpacity & {
color?: 'default' | 'none' | string;
};

type StyleWithOpacity = {
/**
* @category Element Style
*/
export type StyleWithOpacity = {
/**
* The value must be between 0 and 100:
* - If the set value is less than 0, the used value is 0.
Expand Down