BPMNFActory create properties panel

yes i am still getting error dont know what is issue from last 10 hours finding solution but not getting help

Why don’t you share the part of your code where you’re including camunda-bpmn-moddle? Then we might be able to help you.

IN BpmnReplace I AM trying to set color of element dynamicallyy so in that i am calling this function and getting issue

import {
    pick,
    assign,
    filter,
    forEach,
    isArray,
    isUndefined,
    has
} from 'min-dash';
import { is } from 'bpmn-js/lib/util/ModelUtil';
import { isAny } from 'bpmn-js/lib/features/modeling/util/ModelingUtil';
import {

    getBusinessObject
} from 'bpmn-js/lib/util/ModelUtil';
//util/ModelUtil

import {
    isExpanded,
    isEventSubProcess
} from 'bpmn-js/lib/util/DiUtil';

//../copy-paste/ModdleCopy
import { getPropertyNames } from 'bpmn-js/lib/features/copy-paste/ModdleCopy';
import * as _ModelCloneHelper from '../model/ModelCloneHelper';
import * as _ModelCloneUtils from '../model/ModelCloneUtils'
import * as _minDash from 'min-dash'
import * as _DiUtil from 'bpmn-js/lib/util/DiUtil'

function copyProperties(source, target, properties) {
    if (!isArray(properties)) {
        properties = [properties];
    }

    forEach(properties, function(property) {
        if (!isUndefined(source[property])) {
            target[property] = source[property];
        }
    });
}

var CUSTOM_PROPERTIES = [
    'cancelActivity',
    'instantiate',
    'eventGatewayType',
    'triggeredByEvent',
    'isInterrupting'
];


function toggeling(element, target) {

    var oldCollapsed = (
        element && has(element, 'collapsed') ? element.collapsed : !isExpanded(element)
    );

    var targetCollapsed;

    if (target && (has(target, 'collapsed') || has(target, 'isExpanded'))) {

        // property is explicitly set so use it
        targetCollapsed = (
            has(target, 'collapsed') ? target.collapsed : !target.isExpanded
        );
    } else {

        // keep old state
        targetCollapsed = oldCollapsed;
    }

    if (oldCollapsed !== targetCollapsed) {
        element.collapsed = oldCollapsed;
        return true;
    }

    return false;
}



/**
 * This module takes care of replacing BPMN elements
 */
export default function BpmnReplace(

    bpmnFactory, elementFactory, moddleCopy, replace, selection, modeling, eventBus
) {
    //start 123
    var helper = new _ModelCloneHelper.default(eventBus, bpmnFactory);

    //end 123
    /**
     * Prepares a new business object for the replacement element
     * and triggers the replace operation.
     *
     * @param  {djs.model.Base} element
     * @param  {Object} target
     * @param  {Object} [hints]
     *
     * @return {djs.model.Base} the newly created element
     */
    function replaceElement(element, target, hints) {

        hints = hints || {};

        var type = target.type,
            oldBusinessObject = element.businessObject;

        if (isSubProcess(oldBusinessObject)) {
            if (type === 'bpmn:SubProcess') {
                if (toggeling(element, target)) {

                    // expanding or collapsing process
                    modeling.toggleCollapse(element);

                    return element;
                }
            }
        }

        var newBusinessObject = bpmnFactory.create(type);

        var newElement = {
            type: type,
            businessObject: newBusinessObject
        };
        //akhil changes for unit testing of bots starts here
        if (newBusinessObject) {
            var elementProps = getPropertyNames(oldBusinessObject.$descriptor),
                newElementProps = getPropertyNames(newBusinessObject.$descriptor, true),
                copyProps = intersection(elementProps, newElementProps);
            assign(newBusinessObject, pick(target, CUSTOM_PROPERTIES));
            var properties = filter(copyProps, function(propertyName) {
                var propName = propertyName.replace(/bpmn:/, '');

                // copying event definitions, unless we replace
                if (propName === 'eventDefinitions') {
                    return hasEventDefinition(element, target.eventDefinitionType);
                }

                // retain loop characteristics if the target element
                // is not an event sub process
                if (propName === 'loopCharacteristics') {
                    return !isEventSubProcess(newBusinessObject);
                }

                // so the applied properties from 'target' don't get lost
                if (newBusinessObject.hasOwnProperty(propertyName)) {
                    return false;
                }

                if (propName === 'processRef' && target.isExpanded === false) {
                    return false;
                }

                if (propName === 'triggeredByEvent') {
                    return false;
                }
                return _ModelCloneUtils.IGNORED_PROPERTIES.indexOf(propName) === -1;

                // return true;
            });
            // newBusinessObject = helper.clone(oldBusinessObject, newBusinessObject, properties); // initialize custom BPMN extensions

            newBusinessObject = moddleCopy.copyElement(
                oldBusinessObject,
                newBusinessObject,
                properties
            );
            var custAttr = target.customAtttr;
            if (custAttr) {

                //ExtensionElementsHelper.addEntry(newBusinessObject,"camunda:Properties", {"name": "category", "value": "Java"});
                console.info("I am here");
                if (!newBusinessObject.extensionElements) {
                    console.info("Not extensions found");
                    newBusinessObject.extensionElements = bpmnFactory.create('bpmn:ExtensionElements');
                }
                var taskextvalues = newBusinessObject.extensionElements.values;
                if (!taskextvalues) {
                    taskextvalues = new Array();
                    newBusinessObject.extensionElements.values = taskextvalues
                }
                var taskproperties;
                for (var j = 0; j < taskextvalues.length; j++) {
                    if (taskextvalues[j].$type === "camunda:Properties") {
                        taskproperties = taskextvalues[j];
                        break;
                    }
                }
                if (!taskproperties) {
                    console.log(taskproperties, 'inside if')
                        taskproperties = bpmnFactory.create("camunda:Properties");
                        console.log(taskproperties, 'after calling create if')
                        // newBusinessObject.extensionElements.values.push(taskproperties);
                        // taskproperties.values = new Array();
                }

            }
        }
        //akhil changes for unit testing of bots end here

        // initialize special properties defined in target definition



        // initialize custom BPMN extensions
        if (target.eventDefinitionType) {

            // only initialize with new eventDefinition
            // if we did not set an event definition yet,
            // i.e. because we copied it
            if (!hasEventDefinition(newBusinessObject, target.eventDefinitionType)) {
                newElement.eventDefinitionType = target.eventDefinitionType;
                newElement.eventDefinitionAttrs = target.eventDefinitionAttrs;
            }
        }

        if (is(oldBusinessObject, 'bpmn:Activity')) {

            if (isSubProcess(oldBusinessObject)) {

                // no toggeling, so keep old state
                newElement.isExpanded = isExpanded(oldBusinessObject);
            }

            // else if property is explicitly set, use it
            else if (target && has(target, 'isExpanded')) {
                newElement.isExpanded = target.isExpanded;
            }

            // TODO: need also to respect min/max Size
            // copy size, from an expanded subprocess to an expanded alternative subprocess
            // except bpmn:Task, because Task is always expanded
            if ((isExpanded(oldBusinessObject) && !is(oldBusinessObject, 'bpmn:Task')) && newElement.isExpanded) {
                newElement.width = element.width;
                newElement.height = element.height;
            }
        }

        // remove children if not expanding sub process
        if (isSubProcess(oldBusinessObject) && !isSubProcess(newBusinessObject)) {
            hints.moveChildren = false;
        }

        // transform collapsed/expanded pools
        if (is(oldBusinessObject, 'bpmn:Participant')) {

            // create expanded pool
            if (target.isExpanded === true) {
                newBusinessObject.processRef = bpmnFactory.create('bpmn:Process');
            } else {

                // remove children when transforming to collapsed pool
                hints.moveChildren = false;
            }

            // apply same width and default height
            newElement.width = element.width;
            newElement.height = elementFactory._getDefaultSize(newBusinessObject).height;
        }

        newBusinessObject.name = oldBusinessObject.name;

        // retain default flow's reference between inclusive <-> exclusive gateways and activities
        if (
            isAny(oldBusinessObject, [
                'bpmn:ExclusiveGateway',
                'bpmn:InclusiveGateway',
                'bpmn:Activity'
            ]) &&
            isAny(newBusinessObject, [
                'bpmn:ExclusiveGateway',
                'bpmn:InclusiveGateway',
                'bpmn:Activity'
            ])
        ) {
            newBusinessObject.default = oldBusinessObject.default;
        }

        if (
            target.host &&
            !is(oldBusinessObject, 'bpmn:BoundaryEvent') &&
            is(newBusinessObject, 'bpmn:BoundaryEvent')
        ) {
            newElement.host = target.host;
        }

        newElement.di = {};

        // fill and stroke will be set to DI
        copyProperties(oldBusinessObject.di, newElement.di, [
            'fill',
            'stroke'
        ]);

        newElement = replace.replaceElement(element, newElement, hints);

        if (hints.select !== false) {
            selection.select(newElement);
        }

        return newElement;
    }

    this.replaceElement = replaceElement;
}

BpmnReplace.$inject = ['bpmnFactory', 'elementFactory', 'moddleCopy', 'replace', 'selection', 'modeling', 'eventBus'];


function isSubProcess(bo) {
    return is(bo, 'bpmn:SubProcess');
}

function hasEventDefinition(element, type) {

    var bo = getBusinessObject(element);

    return type && bo.get('eventDefinitions').some(function(definition) {
        return is(definition, type);
    });
}

/**
 * Compute intersection between two arrays.
 */
function intersection(a1, a2) {
    return a1.filter(function(el) {
        return a2.indexOf(el) !== -1;
    });
}```

And where in this code are you including camunda-bpmn-moddle?

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”;

import propertiesPanelModule from “bpmn-js-properties-panel”;

import propertiesProviderModule from “bpmn-js-properties-panel/lib/provider/camunda”;

import camundaModdleExtension from “camunda-bpmn-moddle/lib”;

import “bpmn-js/dist/assets/diagram-js.css”;

import “bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css”;

import “bpmn-js-properties-panel/dist/assets/bpmn-js-properties-panel.css”;

import * as camundaModdleDescriptor from ‘camunda-bpmn-moddle/resources/camunda.json’;

import * as FileSaver from ‘file-saver’;

import $ from ‘jquery’;

import ReplaceMenuProvider from ‘./popup-menu’;

@Component({

selector: ‘app-root’,

templateUrl: ‘./app.component.html’,

styleUrls: [’./app.component.css’]

})

export class AppComponent implements OnInit {

title = ‘Workflow Modeler’;

modeler: Modeler;

collapse1 = true;

@ViewChild(‘canvas’)

private canvesRef: ElementRef;

constructor(private http: HttpClient) {

 $('#collapsedPanel').css('right', '-40px');

}

ngOnInit(): void {

this.modeler = new Modeler({

  container: '#canvas',

  width: '100%',

  height: '600px',

  propertiesPanel: {

    parent: '#properties'

  },

  additionalModules: [

    propertiesPanelModule,

    propertiesProviderModule,

    ReplaceMenuProvider,

    camundaModdleExtension

  ],

  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 {

const url = '/assets/bpmn/initial.bpmn'; // local

return this.http.get(url, {responseType: 'text'});

}

save(): void {

this.modeler.saveSVG((err,result)=>{

  if(err){

    console.log(err,'got gerro')

  }

  else{

    const blob = new Blob([result], {type: 'text/plain;charset=utf-8'});

    FileSaver.saveAs(blob, 'bpmnSample.svg');

  }

})

}

saveBPMN():void{

this.modeler.saveSVG((err,result)=>{

  if(err){

    console.log(err,'got gerro')

  }

  else{

    const blob = new Blob([result], {type: 'text/plain;charset=utf-8'});

    FileSaver.saveAs(blob, 'bpmnSample.bpmn');

  }

})

}

collapsePanel() {

if (this.collapse1) {

$("#properties").css({"display": "none",});

$("#collapsedPanel").css({ "right": "-43px"});



  this.collapse1 = false;

} else {

$("#properties").css('display','block');

$("#collapsedPanel").css('right','216px')

  this.collapse1 = true;

}

}

}

I’m happy to have a look if you format the code.

app.comonent.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";
import propertiesPanelModule from "bpmn-js-properties-panel";
import propertiesProviderModule from "bpmn-js-properties-panel/lib/provider/camunda";
import "bpmn-js/dist/assets/diagram-js.css";
import "bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css";
import "bpmn-js-properties-panel/dist/assets/bpmn-js-properties-panel.css";
import * as camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda.json';
import ReplaceMenuProvider from './popup-menu';
import  * as FileSaver  from 'file-saver';
// import * as externalTaskConfiguration from "bpmn-js/lib"
import $ from 'jquery';
import * as botdetails from './botdetails.js'
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'Workflow Modeler';
  modeler: Modeler;
  collapse1 = true;
  @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,
        ReplaceMenuProvider
      ],
      elementTemplates:botdetails.botdetails,

      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'});
  }
  
  save(): void {
    this.modeler.saveSVG((err,result)=>{
      if(err){
        console.log(err,'got gerro')
      }
      else{
        const blob = new Blob([result], {type: 'text/plain;charset=utf-8'});
        FileSaver.saveAs(blob, 'bpmnSample.svg');
      }
    })
   
  }
  saveBPMN():void{
    this.modeler.saveSVG((err,result)=>{
      if(err){
        console.log(err,'got gerro')
      }
      else{
        const blob = new Blob([result], {type: 'text/plain;charset=utf-8'});
        FileSaver.saveAs(blob, 'bpmnSample.bpmn');
      }
    })
  }
  collapsePanel() {

    if (this.collapse1) {
      $("#properties").css({"display": "none",});
      $("#collapsedPanel").css({ "right": "-43px"});
  
      
        this.collapse1 = false;
    } else {
  
      $("#properties").css('display','block');
      $("#collapsedPanel").css('right','216px')
        this.collapse1 = true;
    }
  }
}
app.componet.html
<div class="modeler">
    <div id="canvas" #canvas>
        <button type="button" id="collapsedPanel" (click)="collapsePanel()">Properties Panel</button>
    </div>
    <div class="properties-panel" id="properties"></div>
</div>
<button id="download-svg" (click)="save()">svg image</button>
<button id="download-svg" (click)="saveBPMN()">  BPMN diagram</button>

From all the code that you posted it’s hard to tell which part of it leads to the error. Anyway, here’s an example of creating a camunda:Properties element and as you can see it works: https://codesandbox.io/s/camunda-properties-example-q8c89?file=/src/index.js

sorry but i need this one in angular 8 because in angular i am facing issue and this one is javascript can you please send codesandbox in angular

Do you realize that your issue has nothing to do with Angular or whatever framework out there?

ok i will convert this one in angular again if facing any issue will pic you on this post same
thanks

No sure what you mean by converting to Angular. The example simply shows what setup is necessary for Camunda properties to work. Make sure to set up the bpmn-js including the Camunda extension and you should be fine.

hi see i am trying to convert in angular but some libarraies having issue while importing
image

Displayed error is caused by your configuration. Please read this topic carefully: Error while using bpmn-js-properties-panel and camunda-bpmn-moddle in angular10 application

Change it to

import { default as camundaModdleDescriptor } from 'camunda-bpmn-moddle/resources/camunda.json';

and add following two options in the tsconfig.json compiler options
“resolveJsonModule”: true,
“esModuleInterop”: true

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2015",
    "lib": [
      "es2018",
      "dom"
    ]
  },
  "angularCompilerOptions": {
    "fullTemplateTypeCheck": true,
    "strictInjectionParameters": true
  }
}

This should resolve the issue. Project setup is the Problem here not camunda or bpmn code bug.

1 Like

@mallesh
can you please tell me how can i access this library in angular its related to bpmn i need this library some customization related
getTemplate = require(’…/Helper’).getTemplate,
getTemplateId = require(’…/Helper’).getTemplateId;

ERROR Error: unknown type bpmn:customTask
at Registry.push…/node_modules/moddle/dist/index.esm.js.Registry.mapTypes (index.esm.js:518)
at Registry.push…/node_modules/moddle/dist/index.esm.js.Registry.getEffectiveDescriptor (index.esm.js:543)
at BpmnModdle.push…/node_modules/moddle/dist/index.esm.js.Moddle.getType (index.esm.js:768)
at BpmnFactory.push…/node_modules/bpmn-js/lib/features/modeling/BpmnFactory.js.BpmnFactory.create (BpmnFactory.js:71)
at replaceElement (BpmnReplace.js:168)
at replaceAction (ReplaceMenuProvider.js:379)
at PopupMenu.push…/node_modules/diagram-js/lib/features/popup-menu/PopupMenu.js.PopupMenu.trigger (PopupMenu.js:236)
at HTMLDivElement. (PopupMenu.js:384)
at HTMLDivElement. (index.esm.js:359)

bpmn:upgradeBot
bpmn:configureBot’
bpmn:customTask
same thing i need this custom bot but getting error so could you please let me know how can i access this libraries

These are two new questions. For a new question please open a new topic.