Create task from my custom html, add bussinessObject async

when i use this code create task, it will cause the shape is still in drag state,when i use click event, it’s ok

const create = modeler.get("create"),
          elementFactory = modeler.get("elementFactory");

      const span = document.querySelector("#create-service-task");

      span.addEventListener("dragstart", (event) => {
        getName().then(name => {
          const shape = elementFactory.createShape({ type: "bpmn:ServiceTask", businessObject: {name}});

          create.start(event, shape);
        })

      });

      //request backend api
      getName() {
        return new Promise((resolve,reject) => {
          resolve('aa')
        })
      }

Hi @SmithXiong ,

From your post, it is not clear what your question is and what is currently not working. Could you explain your issue in a structured and detailed manner, so anyone has a fair chance to understand your use case?

If you are stuck with a particular problem, provide the necessary context. Phrase your post so that we can follow your line of thought, step by step.

Please revise your post; we may not be able to help you otherwise. We may also close topics of low quality to prevent spam.

Thanks :heart:

now i use click event in custom-task-node, it’s appears in the container with a delay of a few seconds, when i user dragstart event in custom-task-node, i drop the node in the container, it’s still in dragging state, Is there any way to assign businessObject async when creating shapes

<template>
  <div class="my-process-palette" :class="{'palette-collapsed': !collapsed }">
    <div class="collapsed-button" @click="collapsed = !collapsed"><i :class="collapsed ? 'el-icon-arrow-left' : 'el-icon-arrow-right'"></i></div>
    <el-input class="search" size="small" prefix-icon="el-icon-search" placeholder="输入关键字进行过滤" v-model="filterText"></el-input>
    <el-tree ref="tree" default-expand-all :filter-node-method="filterNode" :data="data" :props="defaultProps">
      <span slot-scope="{ node, data }" >
        <span class="custom-tool-node" title="点击选择工具" v-if="data.class === 'tool'" @click="handleDragStart($event,data)">
          <i :class="data.icon" />
          <span>{{node.label}}</span>
        </span>
        <span class="custom-task-node" title="拖拽创建元素" v-else @click="handleDragStart($event,data)">
          <i :class="data.icon" />
          <span>{{node.label}}</span>
        </span>
      </span>
    </el-tree>
  </div>
</template>

<script>

export default {
  name: 'MyProcessPalette',
  props: {
    prefix: String
  },
  data() {
    return {
      filterText: '',
      collapsed: true,
      defaultProps: {
        children: 'children',
        label: 'label'
      },
      data: [
        {
          label: '工具',
          children: [
            {
              class: 'tool',
              icon: 'bpmn-icon-hand-tool',
              label: '手型工具',
              type: 'handTool'
            },
            {
              class: 'tool',
              icon: 'bpmn-icon-lasso-tool',
              label: '框选工具',
              type: 'lassoTool'
            },
            {
              class: 'tool',
              icon: 'bpmn-icon-connection-multi',
              label: '连线工具',
              type: 'connectTool'
            }
          ]
        },
        {
          label: '基础元素',
          children: [
            {
              class: 'base',
              icon: 'bpmn-icon-start-event-none',
              label: '启动事件',
              type: 'StartEvent'
            },
            {
              class: 'base',
              icon: 'bpmn-icon-end-event-none',
              label: '结束事件',
              type: 'EndEvent'
            },
            {
              class: 'base',
              icon: 'bpmn-icon-gateway-xor',
              label: '互斥网关',
              type: 'ExclusiveGateway'
            },
            {
              class: 'base',
              icon: 'bpmn-icon-gateway-parallel',
              label: '并行网关',
              type: 'ParallelGateway'
            }
          ]
        },
        {
          label: '服务目录',
          children: []
        }
      ]
    }
  },
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val);
    }
  },
  mounted() {
    this.$axios.get('/soa/businessCenter/services?systemId=sys-oVgboNUV').then(res => {
      if (Array.isArray(res.obj) && res.obj.length > 0) {
        let list = res.obj
        list = list.map(o => ({
          class: 'service',
          icon: 'bpmn-icon-task',
          label: o.svName,
          svId: o.svId,
          type: 'Task'
        }))
        this.$set(this.data, 2, { label: '服务目录', children: list})
      }
    })
  },
  methods: {
    createElement(event, type, options = { }) {
      const ElementFactory = window.bpmnInstances.elementFactory
      const BpmnFactory = window.bpmnInstances.bpmnFactory
      const create = window.bpmnInstances.modeler.get('create')
      const svId = options.svId ? {svId: options.svId } : {}
      if (options.svId) {
        this.getServiceFields(options.svId).then(fields => {
          const extension = fields ? {extensionElements: fields } : {}
          const taskBusinessObject = BpmnFactory.create(`bpmn:${type}`, {
            name: options.name || '',
            ...svId,
            ...extension
          })
          const shape = ElementFactory.createShape({ type: `bpmn:${type}`, businessObject: taskBusinessObject })
          create.start(event, shape)
        })
      } else {
        const taskBusinessObject = BpmnFactory.create(`bpmn:${type}`, {
          name: options.name || '',
          ...svId
        })
        const shape = ElementFactory.createShape({ type: `bpmn:${type}`, businessObject: taskBusinessObject, replace: false })
        create.start(event, shape)
      }
    },
    startTool(event, type) {
      if (type === 'handTool') {
        window.bpmnInstances.modeler.get('handTool').activateHand(event)
      }
      if (type === 'lassoTool') {
        window.bpmnInstances.modeler.get('lassoTool').activateSelection(event)
      }
      if (type === 'connectTool') {
        window.bpmnInstances.modeler.get('globalConnect').toggle(event)
      }
    },
    filterNode(value, data) {
      if (!value) return true;
      return data.label.indexOf(value) !== -1;
    },
    handleDragStart(ev, data) {
      if (data.class === 'tool') {
        this.startTool(ev, data.type)
      } else {
        this.createElement(ev, data.type, data.class !== 'base' ? { name: data.label, svId: data.svId } : {})
      }
    },
    getServiceFields(svId) {
      return new Promise((resolve, reject) => {
        this.$axios.get(`/soa/businessCenter/serviceDetail?svId=${svId}`).then(res => {
          if (res.obj) {
            const { sceneFieldsIn = [] , sceneFieldsOut = [] } = res.obj
            let inList = sceneFieldsIn.map(o => ({id: o.sfId, name: o.sfEnName, value: o.sfCnName })).map(o => window.bpmnInstances.moddle.create(`${this.prefix}:FieldIn`, { ...o }))
            let outList = sceneFieldsOut.map(o => ({id: o.sfId, name: o.sfEnName, value: o.sfCnName })).map(o => window.bpmnInstances.moddle.create(`${this.prefix}:FieldOut`, { ...o }))
            const propertiesIn = inList.length > 0 ? window.bpmnInstances.moddle.create(`${this.prefix}:FieldsIn`, {
              values: inList
            }) : null;
            const propertiesOut = outList.length > 0 ? window.bpmnInstances.moddle.create(`${this.prefix}:FieldsOut`, {
              values: outList
            }) : null;
            const fields = propertiesIn ? [propertiesIn].concat(propertiesOut ? [propertiesOut] : []) : (propertiesOut ? [propertiesOut] : [])
            const extensions = fields.length > 0 ? window.bpmnInstances.moddle.create("bpmn:ExtensionElements", {
              values: fields
            }) : null;
            resolve(extensions)
          } else {
            resolve(null)
          }
        }).catch(e => {
          console.error(e)
          resolve(null)
        })
      })
    }
  }
}
</script>

<style scoped lang="scss">
.my-process-palette {
  box-sizing: border-box;
  padding: 8px;
  width: 260px;
  max-height: 100%;
  border-right: 1px solid #eeeeee;
  box-shadow: 0 0 8px #cccccc;
  position: relative;
  overflow-y: auto;
  .collapsed-button {
    position: absolute;
    right: 0;
    top: 48%;
    width: 12px;
    height: 36px;
    background: #cedae2;
    border-radius: 4px 0 0 4px;
    i {
      line-height: 36px;
      font-weight: 700;
    }
  }
}

.palette-collapsed {
  width: 12px;
  padding: 0;
  overflow-y: hidden;
  .search {
    display: none;
  }
  .collapsed-button {
    border-radius: 0 4px 4px 0;
  }
  ::v-deep .el-tree {
    display: none;
  }
}

.custom-tool-node, .custom-task-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  font-size: 14px;
  padding-right: 8px;
  line-height: 21px;
  i {
    margin-right: 4px;
    font-size: 18px;
  }
}
</style>

thanks, I solved it for add eventlistener on shape added

this.bpmnModeler.on("shape.added", async ({ element }) => {
        try {
          if ((element.type === 'bpmn:Task') && element.businessObject.svId) {
            let fields = await this.getServiceFields(element.businessObject.svId);
            fields && element.businessObject.set('bpmn:extensionElements', fields)
            this.initFormOnChanged(element);
          }
        } catch (e) {
          Log.prettyError(`[Event shape added]: ${e.message || e}`);
        }
      });
1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.