首页 > 其他分享 >Replace bpmn-js and Let Frontend Developers Become More Familiar with Workflow Business

Replace bpmn-js and Let Frontend Developers Become More Familiar with Workflow Business

时间:2023-08-07 18:24:24浏览次数:44  
标签:code frontend Business bpmn workflow js Frontend LogicFlow

(背景:发在国外社区的文章,国内博客做份存档)

Preface

Seeing this title, some of you may wonder: Isn't bpmn-js the most common frontend solution for workflow systems? Why do we need to replace bpmn-js? Here, from a frontend perspective, let's first clarify the relationships among workflows, workflow management systems, workflow engines, BPMN specifications, and bpmn-js.

Workflow

The concept of a workflow is described in a somewhat abstract manner on Baidu Baike and Wikipedia. In general terms, we can understand a workflow as a series of steps used to perform a task, where these steps are organized in a logical sequence to achieve the desired outcome. For example, the activities we perform in the morning can be viewed as a workflow, which can be broken down into steps like going to the restroom, washing hands, having breakfast, and brushing teeth. Different individuals may organize these steps differently; some might follow the sequence "restroom -> washing hands -> having breakfast -> brushing teeth," while others may follow "brushing teeth -> restroom -> having breakfast -> washing hands." The variation in the organization of these steps leads to different outcomes.

By transferring the processes of task decomposition, organization, execution, and management to the realm of computers, we create what is known as a workflow in the digital context.

Workflow Management System:

This is the type of system we usually develop, which revolves around processes and uses a graphical representation of workflows. Since it involves graphics, drawing is required, and most systems have moved the drawing process to web-based platforms. This is why the frontend involvement becomes necessary.

Workflow Engine:

The workflow engine is generally used on the backend to execute the organized steps. It determines the sequence of events, like whether we should have breakfast or wash hands after going to the restroom. There are several workflow engines available, with the most common ones being Activiti, Camunda BPM, and Flowable.

BPMN Specification:

BPMN stands for "Business Process Model and Notation," which translates to "业务流程建模符号" in Chinese. It is an industry standard defined by an organization. As mentioned earlier, describing how to perform a task can be done graphically. However, different people may draw different diagrams, and different workflow engines may produce different data from the diagrams. To ensure better understanding of diagrams by both humans and machines, an organization introduced a standard that provides specific definitions for the meaning of nodes and connections on the diagram, as well as the data format to be submitted to the workflow engine.

Currently, most open-source workflow engines support the BPMN specification. Below is a snippet of information from Wikipedia:

在这里插入图片描述

bpmn-js

This is easy to understand; it is an open-source web-based modeler that implements the BPMN 2.0 specification. It is essential to note that although bpmn-js has "bpmn" in its name, it is not developed by the official organization responsible for the BPMN specification. Therefore, the support of the BPMN specification by a workflow engine does not necessarily mean that frontend developers must use bpmn-js. Instead, we can develop a custom process designer based on the BPMN specification that aligns with our specific business needs.

Why am I choosing to replace bpmn-js?

From the above description, we can see that bpmn-js naturally complies with the BPMN specification, and the vast majority of workflow engines also support the BPMN specification. As frontend developers, we can easily integrate bpmn-js into our project and use it out of the box. However, why would we consider replacing bpmn-js? The main reason is that bpmn-js has brought us the following pain points.

Business Logic Black Box

In workflow-related projects, as the maintenance period grows, frontend developers often take on resource-oriented roles and may not be concerned with the entire workflow's business logic. Since bpmn-js implements all the business logic internally, frontend developers cannot directly perceive the business logic at the code level. In such cases, any modifications made at the frontend level can become chaotic due to the lack of constraints.

For instance, if the backend needs to add a field to the data generated at a certain node, some may choose to directly replace it using aggressive regex during data export, while others might hardcode it into the bpmn-js source code or forcefully retrieve all nodes and update the corresponding properties. As more and more ad-hoc code is scattered throughout the project, changing frontend developers can eventually make the project difficult to maintain.

Currently, there are various tutorials and "hacks" available online for customizing bpmn-js. However, these are rooted in the fact that bpmn-js does not provide complete openness for customization. Although there are many examples of predefined scenarios, they might not cover all real-world project scenarios.

Furthermore, the bpmn-js documentation is relatively lacking and mostly consists of knowledge shared by users based on their practical experiences.

Readability of the Source Code

Due to the limited openness of bpmn-js' customization mechanism, when certain products require more in-depth extensions, its default customization often falls short. For example, I came across a requirement to add an expand and collapse feature to the process diagram, which is virtually impossible to achieve using bpmn-js. Some projects might introduce the bpmn-js source code into their project for extensive custom modifications. However, they may eventually find that due to issues with the source code's readability, frontend developers struggle to understand bpmn-js's underlying logic. In order to meet the requirements, they have to resort to making ad-hoc changes, and the final result is often frontend developers leaving the project.

In the past, our department worked on an approval project for the education sector. However, no matter which frontend developer took over, they would leave shortly after. The end result was “a rock-solid workflow backend, but a constantly changing frontend”, which was quite frustrating.

Career Development

For frontend developers, investing a significant amount of effort to study the bpmn-js source code is not very meaningful. As iron-clad bpmn-js frontend developers, it hinders our career choices and growth. In terms of bpmn-js itself, its form and specifications are fixed, which limits our frontend expertise in the UI layer. If faced with any requirements, answering "no, bpmn-js doesn't have that functionality" challenges our own professionalism and hampers our ability to advance in this field.

How to Replace bpmn-js

Technology Selection

Since we are going to replace bpmn-js, we need to find a flowchart editing tool that offers better support for customization and higher maintainability. After searching online, we chose LogicFlow for the following reasons:

  1. Completely open-source: Developers maintain it frequently, and issues are handled promptly

  2. Comprehensive customization mechanism: LogicFlow allows you to customize any SVG effects on the flowchart. This mechanism ensures that we can fully meet the requirements of any product, with the remaining challenge being the workload.

  3. Controllable workload: LogicFlow already provides an official plugin for bpmn customization, and the code for this plugin is relatively simple. We can directly copy it to our project and continue with further customization.

  4. Clearer source code and frontend-friendliness: Built on the MobX and Preact technology stack, LogicFlow's source code is easy for frontend developers to understand, especially those familiar with React, as it uses an inheritance-based customization mechanism.

Defining Basic Elements in a Flowchart

While BPMN 2.0 categorizes the semantics of process execution into three elements - Events, Gateways, and Activities, in practical projects, we don't necessarily need to adhere strictly to the BPMN specification for defining the content of flowcharts. Instead, we should define the flowchart's content based on our project's specific business requirements. Let's take the example of an educational approval process that I previously worked on: In the flowchart, there is an "Approval" node, which corresponds to an "Activities" element in the BPMN specification, specifically a "UserTask."

In our implementation, we simply define an "ApprovalNode" node, and when exporting data, we convert it to a "UserTask" as required by the backend engine. The advantage of this approach is that both the product's term "Approval" and the backend's term "UserTask" are reflected in our code, ensuring that we are no longer disconnected from the business logic.

Here is the main code for LogicFlow's fully customized node implementation:

import { h, RectNode, RectNodeModel } from '@logicflow/core';
class ApprovalModel extends RectNodeModel {
  initNodeData(data) {
    super.initNodeData(data);
    this.text = {
      value: data.text || "",
      x: data.x,
      y: data.y + 40,
    };
    this.width = 100;
    this.height = 80;
  }
}


class ApprovalView extends RectNode {
  /**
   * Methods for Fully Customizing Node Appearance
   */
  getShape() {
    const { model, graphModel } = this.props;
    const { x, y, width, height, radius } = model;
    const style = model.getNodeStyle();
    return h("g", {}, [
      h("rect", {
        ...style,
        x: x - width / 2,
        y: y - height / 2,
        rx: radius,
        ry: radius,
        width,
        height
      })
    ]);
  }
}


export default {
  type: 'approval',
  view: ApprovalView,
  model: ApprovalModel,
}

For information on customizing LogicFlow, you can refer to these resources:

Get to know the basic nodes of LogicFlow

For fully customizing nodes in bpmn-js, the main code is as follows:

import inherits from 'inherits'
import BaseRenderer from 'diagram-js/lib/draw/BaseRenderer'
import { append as svgAppend, create as svgCreate } from 'tiny-svg'
import { customElements, customConfig } from '../../utils/util'
export default function CustomRenderer(eventBus, styles) {
    BaseRenderer.call(this, eventBus, 2000)
    var computeStyle = styles.computeStyle
    this.drawCustomElements = function(parentNode, element) {
        const shape = this.bpmnRenderer.drawShape(parentNode, element)
        return shape
    }
}
inherits(CustomRenderer, BaseRenderer)
CustomRenderer.$inject = ['eventBus', 'styles']
CustomRenderer.prototype.canRender = function(element) {
    return !element.labelTarget;
}
/**
 * Methods for Fully Customizing Node Appearance
 */
CustomRenderer.prototype.drawShape = function(p, element) {
  const type = element.type// Get the type
  // Define the customization for the required types
  if (customElements.includes(type)) {
    const { url, attr } = customConfig[type]
    const customIcon = svgCreate('image', {
      ...attr,
      href: url
    })
    element['width'] = attr.width
    element['height'] = attr.height
    svgAppend(parentNode, customIcon)
    return customIcon
  }
  const shape = this.bpmnRenderer.drawShape(parentNode, element)
  return this.drawCustomElements(p, element)
}
CustomRenderer.prototype.getShapePath = function(shape) {
    console.log(shape)
}

It appears that, similar to LogicFlow, we can fully customize the appearance of nodes using SVG within the "drawShape" function. However, there are still many differences in practice: First, in the "drawShape" function, all elements share common attributes, so we need to identify the element type before applying customization. Unlike LogicFlow, there is no straightforward way to define a separate class for each element, and the model-view architecture of LogicFlow is more aligned with frontend development practices. Additionally, bpmn-js does not support fine-grained definitions for text position, selection status, outline, and other details. In our actual development, we may need to modify the source code or use global CSS to forcefully override these aspects.

For defining bpmn-js elements, you can refer to the following resources: bpmn-js-examples

Customizing Business Properties

As mentioned earlier, if we need to add an attribute to a certain type of node, let's see how LogicFlow handles it. Firstly, LogicFlow reserves a "properties" attribute in the data, allowing us to set any custom properties inside it. LogicFlow separates business data and graph data at the data level, which is more intuitive.

Let's assume we have an attribute called "rollback" to indicate whether a node supports rollback. If a node supports rollback, its color is green; otherwise, it is blue. For the backend service, it doesn't need to care about the color; it only requires the presence of the "rollback" field in the node information.

{
  id: "userTask",
  type: "rect",
  x: 100,
  y: 100,
  text: { x: 100, y: 100, value: '节点文本' },
  properties: { // Any business properties can be placed here.
    rollback: true
  }
}

When customizing a node in LogicFlow, you can write it like this:

class ApprovalModel extends RectNodeModel {
  getNodeStyle() {
    const style = super.getNodeStyle()
    const { properties } = this
    if (properties.rollback) {
      style.fill = 'green'
    } else {
      style.fill = 'blue'
    }
    return style
  }
}

Converting to XML Recognizable by the Workflow Engine

From the code above, we can see that our code focuses more on defining business and UI elements, without delving too much into the BPMN specification. So, how can we convert the data generated by this business code into a format recognizable by the workflow engine?

The most convenient method is to let the backend handle the conversion. For example, if the backend is using Java, they can write a filter to perform the conversion. However, in some cases, the backend might not be willing to take on this task, and in such situations, the frontend can handle the conversion. The process of writing the conversion logic also helps frontend developers gain a better understanding of the BPMN specification.

LogicFlow provides a plugin called "bpmnAdapter" to achieve mutual conversion between LogicFlow data and BPMN data (both in JSON and XML formats). In practical projects, I recommend copying the source code of this LogicFlow plugin into our local codebase to avoid making this part of the logic a black box. Our product might have more specific logic, and as the business evolves, the data format produced might not fully comply with the BPMN specification.

Summary

In workflow projects, starting with bpmn-js for quick results is not a problem. Moreover, many projects may be aimed at providing backend management tools for R&D colleagues, with no specific UI requirements. In some cases, the backend team might handle everything on their own without involving the frontend.

However, as the project evolves, especially when product roles come into play and there are plans to commercialize the application, sticking with bpmn-js as the process designer can create tremendous pressure for frontend development. In such cases, it is advisable for frontend developers to be more proactive and opt for a more maintainable process designer for development.

LogicFlow is indeed a good choice in this regard, with comprehensive documentation and understandable source code. Using LogicFlow will liberate you from the pain of working with bpmn-js. When your code becomes more maintainable and closely aligned with the business requirements, it also becomes easier for other team members to quickly take over the project, avoiding the predicament of being stuck when someone leaves.

Appendix

GitHub repository link for LogicFlow: https://github.com/didi/LogicFlow

discord: https://discord.gg/3Px753mg

标签:code,frontend,Business,bpmn,workflow,js,Frontend,LogicFlow
From: https://www.cnblogs.com/zhangmingzhao/p/17612148.html

相关文章

  • vue2集成bpmn流程图,可导入导出预览等
    1.使用到的组件组件源码版本licensebpmn-js地址7.3.1bpmn.iobpmn-js-properties-panel地址0.37.2MITcamunda-bpmn-moddle地址4.5.0MIT版本一定要对,否则可能会报错2.组件代码<template><divid="app"><divclass="container">......
  • 在Lync/Skype for Business中部署SEFAUtil工具
    需求背景SEFAUtil是Skype服务器的一款很便利的工具,它使Skype管理员能够在SkypeforBusiness服务器端直接帮助用户配置代理响铃、呼叫转接和组呼叫应答等设置。这一功能在针对于一些VIP用户的需求时尤为有帮助,管理员只需要在服务器端帮助VIP用户进行代理相关配置,而无需在VIP的Sk......
  • zabbixn 源码中 ui / frontends 文件夹下的代码文件负责的是哪方面的职责
    ui/frontends代码的职责通过下载源码查看,可以看到在zabbix-4.X中前端代码在frontends目录下,zabbix-6.X在ui目录下,虽然换了个马甲,但里面都是一些php文件。在Zabbix源码中,ui/frontends文件夹下的代码文件负责处理与用户界面(UI)相关的职责。这些文件包含了Zabbix前端......
  • unable to access 'https://git.oak.net.cn/pigsales/frontend/ai-sales.git/': F
    Git远程仓库无法访问的问题及解决方法在使用Git进行协作开发时,我们经常会遇到无法访问远程仓库的问题。本文将介绍一种常见的错误信息:“unabletoaccess'F”,并提供解决方法。错误信息分析错误信息中的“unabletoaccess”表示无法访问,后面的URL是远程仓库的地址。而最后的“......
  • 【网络流,dp】Gym102220A Apple Business
    ProblemLink有一棵\(n\)个点的完全二叉树(点\(i\)的父亲是\(\lfloori/2\rfloor\)),第\(i\)个点有\(a_i\)个苹果。现在有\(m\)个订单,每个订单只接受\(u_i\)到\(v_i\)路径上的苹果,保证\(u_i\)是\(v_i\)的父亲,并且最多只接受\(c_i\)个苹果,单价为\(w_i\)。你可......
  • bpmn.js修改默认节点颜色
    从node_modules依赖中找到定义图形颜色的js文件bpmn-js/lib/draw/BpmnRenderer.js找到BpmnRenderer.js文件的以下代码: 这里是代码:找到BpmnRenderer.js文件的以下代码:vardefaultFillColor=config&&config.defaultFillColor,  defaultStrokeColor=config&&config......
  • Ubuntu资源暂时不可用 E: 无法获得锁 /var/lib/dpkg/lock-frontend - open (11: 资源
    ubuntu使用apt时出现Ubuntu资源暂时不可用E:无法获得锁/var/lib/dpkg/lock-frontend-open(11:资源暂时不可用)一般是已经存在apt进程占用了,通过ps-grep查看ps-grep|apt查到相关进程后通过kill删掉kill-93298kill-93302再依次执行下面命令sudorm/var/cache......
  • ERP 软件领域的 frontend office 和 backend office
    在企业资源规划(ERP)软件领域中,前端(frontendoffice)和后端(backendoffice)通常指的是企业内部操作和管理的不同方面。它们之间的区别在于,前端主要关注与客户交互和销售相关的任务,而后端则涉及企业内部的运营和管理。在本文中,我们将详细介绍前端和后端办公的概念、功能和优势,以及它们......
  • aws 开源的微前端发现实现 frontend-discovery
    实际上此协议已经开放一段时间了(一年左右),里边一些实践还是很不错的,对于微前端实现的同学可以参考学习同时官方也提供了一个基于aws服务的参考实践,作者的一些演讲也是值得学习的参考格式如下图,可以看到包含了一些不错的设计,以及对于实际的部署维护,包含了元数据,多版本,fallback,......
  • SAP FI -Company Basics&Define Business/Functional Area/Credit Control
    CompanyBasics-公司基础信息SAP中公司被定义为可以根据商业法律法规创建财务报表的最小单位。在SAPFI中,一家公司可以由多个代码组成,但它提供财务报表的单单位。所有公司代码必须使用相同的会计科目表和会计年度,但每个代码可以具有不同的本地货币。科目表列表由所有可用的科目表......