Has anyone had any luck getting the “camunda” bpmn-js-properties-panel to work properly in an Angular 5/6 application? I’ve seen various projects out there where they make use of a custom panel (which kind of skirts the issue) however I am more interested in replicating exactly what is in the Javascript bpmn-js-properties-panel example. In the Javascript bpmn-js-properties-panel example when you select a service task you see a panel that contains various property groups which relate to the type of service:
Using the same imports and the same calls (except in TypeScript) the Angular version of the panel looks like:
Notice that property groups that correspond to the selected task type such as “Details” where the implementation is set and “Asynchronous Continuation” are missing. Also, the CSS looks different.
Further, when inspecting the DOM of the Javascript bpmn-js-properties-panel example you see the elements corresponding to the type of task:
<div class="bpp-properties-group" data-group="details">
<span class="group-toggle"></span><span class="group-label">Details</span>
<div class="bpp-properties-entry bpp-dropdown" data-entry="implementation">
<label for="camunda-implementation">Implementation</label>
<select id="camunda-implementation-select" name="implType" data-value="">
<option value="class">Java Class</option>
<option value="expression">Expression</option>
<option value="delegateExpression">Delegate Expression</option>
<option value="external">External</option>
<option value="connector">Connector</option>
<option value=""></option>
</select>
</div>
<div class="bpp-properties-entry bpp-textfield" data-entry="delegate">
<label for="camunda-delegate" data-show="isHidden" data-value="delegationLabel" class="bpp-hidden"></label>
<div class="bpp-field-wrapper bpp-hidden" data-show="isHidden"><input id="camunda-delegate" type="text" name="delegate" data-show="isHidden" class="bpp-hidden"><button class="clear bpp-hidden" data-action="clear" data-show="canClear"><span>X</span></button></div>
</div>
<div class="bpp-properties-entry bpp-textfield" data-entry="resultVariable">
<label for="camunda-resultVariable" data-show="isHidden" class="bpp-hidden">Result Variable</label>
<div class="bpp-field-wrapper bpp-hidden" data-show="isHidden"><input id="camunda-resultVariable" type="text" name="resultVariable" data-show="isHidden" class="bpp-hidden"><button class="clear bpp-hidden" data-action="clear" data-show="canClear"><span>X</span></button></div>
</div>
<div class="bpp-properties-entry bpp-textfield" data-entry="externalTopic">
<label for="camunda-externalTopic" data-show="isHidden" class="bpp-hidden">Topic</label>
<div class="bpp-field-wrapper bpp-hidden" data-show="isHidden"><input id="camunda-externalTopic" type="text" name="externalTopic" data-show="isHidden" class="bpp-hidden"><button class="clear bpp-hidden" data-action="clear" data-show="canClear"><span>X</span></button></div>
</div>
<div class="bpp-properties-entry" data-entry="configureConnectorLink"><a data-action="linkSelected" data-show="hideLink" class="bpp-entry-link bpp-hidden"></a></div>
</div>
When looking at the Angular version you can pinpoint where the property element should be, but aren’t – as well as visibility settings set to hidden:
<div class="bpp-properties-group bpp-hidden" data-group="details">
<span class="group-toggle"></span>
<span class="group-label">Details</span>
</div>
Without knowing too much about the library my assumption is that the CSS or the moddle isn’t being loaded properly into my Angular 6 application. I’ve tried various differing things to see if I could make it work but haven’t had much luck. My thought is that I could show what I already have in place and hopefully something who’s gone through this already can pinpoint where I went wrong.
app.component.ts
import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {Observable} from 'rxjs';
import Modeler from 'bpmn-js/lib/Modeler.js';
import propertiesPanelModule from 'bpmn-js-properties-panel';
import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda';
import * as camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda.json';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'Workflow Modeler';
modeler: Modeler;
@ViewChild('canvas')
private canvesRef: ElementRef;
constructor(private http: HttpClient) {
}
ngOnInit(): void {
this.modeler = new Modeler({
container: '#canvas',
width: '100%',
height: '600px',
propertiesPanel: {
parent: '#properties'
},
additionalModules: [
propertiesPanelModule,
propertiesProviderModule
],
moddleExtensions: {
camunda: camundaModdleDescriptor
}
});
this.load();
}
load(): void {
this.getExample().subscribe(data => {
this.modeler.importXML(data, value => this.handleError(value));
});
}
handleError(err: any) {
if (err) {
console.warn('Ups, error: ', err);
}
}
public getExample(): Observable<string> {
const url = '/assets/bpmn/initial.bpmn'; // local
return this.http.get(url, {responseType: 'text'});
}
}
app.component.html
<h1>
{{title}}
</h1>
<button (click)="load()">Load <i class="fa fa-folder-open"></i></button>
<div class="modeler">
<div id="canvas" #canvas></div>
<div class="properties-panel" id="properties"></div>
</div>
app.component.css
.properties-panel {
position: absolute;
top: 0;
bottom: 0;
right: 0;
width: 260px;
z-index: 10;
border-left: 1px solid #ccc;
overflow: auto;
}
.properties-panel:empty {
display: none;
}
.properties-panel > .djs-properties-panel {
padding-bottom: 70px;
min-height: 100%;
}
Some of the smaller changes I’ve made is adding “(window as any).global = window;
” to my polyfills.ts document as well as adding support for JSON files in my typings.d.ts:
declare module '*.json' {
const value: any;
export default value;
}
As for importing the stylesheets from the various underlying projects I’ve tried multiple things in the angular.json document:
"styles": [
"src/styles.css",
"node_modules/bpmn-js/dist/assets/diagram-js.css",
"node_modules/bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css",
"node_modules/bpmn-js-properties-panel/styles/properties.less"
],
as well as pulling the styles from the installed node modules:
"styles": [
"src/styles.css",
"node_modules/diagram-js/assets/diagram-js.css",
"node_modules/bpmn-font/dist/css/bpmn-embedded.css",
"node_modules/bpmn-js-properties-panel/styles/properties.less"
],
And, just for full disclosure, here is the package.json
{
"name": "workflow-modeler",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"prod": "ng build --base-href /workflow-modeler/"
},
"private": true,
"dependencies": {
"@angular/animations": "^6.1.0",
"@angular/common": "^6.1.0",
"@angular/compiler": "^6.1.0",
"@angular/core": "^6.1.0",
"@angular/forms": "^6.1.0",
"@angular/http": "^6.1.0",
"@angular/platform-browser": "^6.1.0",
"@angular/platform-browser-dynamic": "^6.1.0",
"@angular/router": "^6.1.0",
"bpmn-js": "^2.5.2",
"bpmn-js-properties-panel": "^0.26.2",
"camunda-bpmn-moddle": "^3.0.0",
"core-js": "^2.5.4",
"diagram-js": "^2.6.1",
"rxjs": "~6.2.0",
"zone.js": "~0.8.26"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.8.0",
"@angular/cli": "~6.2.1",
"@angular/compiler-cli": "^6.1.0",
"@angular/language-service": "^6.1.0",
"@types/jasmine": "~2.8.8",
"@types/jasminewd2": "~2.0.3",
"@types/node": "~8.9.4",
"codelyzer": "~4.3.0",
"jasmine-core": "~2.99.1",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~3.0.0",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.1",
"karma-jasmine": "~1.1.2",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~5.4.0",
"ts-node": "~7.0.0",
"tslint": "~5.11.0",
"typescript": "~2.9.2"
}
}
Being new to front end development I’m at a loss of what may be going on under the hood which is causing the issues seen above but I plan to keep hacking away at it and hopefully figure it out – although if anyone has any suggestions that would be greatly appreciated!
Thanks,
Paul