<template lang="xml">
<el-container class="fm2-container"  
   >
  <el-header class="btn-bar" height="56px">
    <!-- <el-button icon="el-icon-arrow-left" @click="handleUndo">撤回</el-button>
    <el-button icon="el-icon-arrow-right" @click="handleRedo">重做</el-button> -->
    <div class="btn-bar_center">
      <ul>
        <li @click="onHandTool">
          <i class="bpmn-icon-hand-tool"></i>
          <span>抓手</span>
        </li>
        <li class="line"></li>
        <li @click="onLassoTool">
          <i class="bpmn-icon-lasso-tool"></i>
          <span>套索</span>
        </li>
        <li class="line"></li>
        <li @click="onSpaceTool">
          <i class="bpmn-icon-space-tool"></i>
          <span>调整间距</span>
        </li>
      </ul>
      <div class="btn-bar_center_scale">
        <i class="el-icon-zoom-out" @click="handleZoom(-0.2)"></i>
        <span>{{(scale*100).toFixed(0)}}%</span>
        <i class="el-icon-zoom-in" @click="handleZoom(0.2)"></i>
      </div>
      <div @click="handleClear" class="btn-bar_center_clear">
        <i class="el-icon-delete"></i>
        <span>清空</span>
      </div>
    </div>
    <div class="btn-bar_right">
      <el-button  @click="handlePublish" v-prevent-re-click type="primary"   v-loading.fullscreen.lock="loading"  element-loading-text="正在发布中...">发布</el-button>
      <el-button  @click="handlePreviewXml">预览</el-button>
      <el-button  @click="importXml">导入</el-button>
      <el-button @click="handleExportXmlAction">导出XML</el-button>
      <el-button @click="handleExportSvgAction">导出SVG</el-button>
       <el-upload action="" :before-upload="openBpmn" style="display: none" accept="xml">
        <el-button ref="importBtn" size="mini" icon="el-icon-folder-opened" />
      </el-upload>
    </div>
  </el-header>
  <el-container class="fm2-main-content">
    <el-main>
      <div class="containers">
        <div class="canvas" ref="canvas" />
        <el-dialog :visible.sync="xmlVisible" title="预览" fullscreen center append-to-body>
          <vue-ace-editor v-model="process.xml" @init="editorInit" lang="xml" theme="chrome" width="100%" height="calc(100vh - 214px)" :options="{wrap: true, readOnly: true}">
          </vue-ace-editor>
          <span slot="footer">
            <el-button icon="el-icon-document" type="primary" v-clipboard:copy="process.xml" v-clipboard:success="onCopy">复 制</el-button>
            <el-button icon="el-icon-close" @click="xmlVisible = false">关闭</el-button>
          </span>
        </el-dialog>
      </div>
    </el-main>
    <el-aside class="widget-config-container" width="300px">
      <flowBasicPropertyPanel v-if="importParseComplete" :modeler="bpmnModeler" :processStatus="processStatus" :modelData.sync="modelData"/>
    </el-aside>
  </el-container>
  <el-footer height="30px" style="font-weight: 600;">
    Powered by <a target="_blank" href="http://help.hotent.com/">hotent-bpmn-js</a>
  </el-footer>
  <el-dialog
    v-if="dialogVisible"
    title="发布提示"
    :visible.sync="dialogVisible"
    width="858px"
    append-to-body
    top="10vh"
    :before-close="handleClose"
    >
    <el-scrollbar class="dialog-scrollbar" >
    <el-form
      label-width="100px"
    >
      <el-form-item label="版本">
        <el-radio-group v-model="isDeploy" @change="currentRow.action=isDeploy?'发布新版本' : '保存'">
          <el-radio :label="false">覆盖更新</el-radio>
          <el-radio :label="true">新版本</el-radio>
        </el-radio-group>
      </el-form-item>

      <ht-form-item label="操作类型">
        <span class="form-value">{{ currentRow.action }}</span>
      </ht-form-item>
      <ht-form-item label="配置人名称">
        <span class="form-value">{{ currentRow.fullName }}</span>
      </ht-form-item>
      <ht-form-item label="配置时间">
        <span class="form-value">{{ currentRow.showTime }}</span>
      </ht-form-item>
      <ht-form-item label="配置事由">
        <ht-input
            ref="reasons"
            v-model="currentRow.reasons"
            type="textarea"
            display-style="block"
            style="width: 97%;"
            placeholder="请输入配置事由......"
            name="配置事由"
            validate="required"
            :maxlength="500"
            :max="500"
            :autosize="{ minRows: 4, maxRows: 8 }"
            :show-word-limit="true"
        />
      </ht-form-item>
      <el-form-item label="" v-if="isDeploy">
        <el-checkbox
          v-model="isDeployMain"
        >是否同步发布为主版本</el-checkbox>
      </el-form-item>
      <el-form-item label="说明" v-if="isDeploy">
        <span>若同步发布为主版本，则用户可即刻体验主版本设计内容。建议对设计内容测试通过后，再通过版本管理手动发布为主版本</span>
      </el-form-item>
    </el-form>
    </el-scrollbar>
  <span slot="footer" class="dialog-footer">
    <el-button @click="handleClose">取 消</el-button>
    <el-button type="primary" @click="handleSave"  element-loading-text="正在发布中..."   v-loading.fullscreen.lock="loading"  v-prevent-re-click>确 定</el-button>
  </span>
</el-dialog>
</el-container>
</template>

<script>
// 汉化
import customTranslate from './translate/Translate.js'
// bpmn-js 设计器
// import BpmnModeler from './Modeler' // 上面说的index.js文件
import BpmnModeler from 'bpmn-js/lib/Modeler'

import {isAny} from 'bpmn-js/lib/features/modeling/util/ModelingUtil'
import {is} from 'bpmn-js/lib/util/ModelUtil'
// 这里引入的是右侧属性栏这个框
// import propertiesPanelModule from './bpmn-js-properties-panel/lib' // 自定义的属性面板
// 引入activiti的节点文件
import activiti from './bpmn-js-properties-panel/static/flowModel/activiti.json'
// 而这个引入的是右侧属性栏里的内容
//import propertiesProviderModule from './bpmn-js-properties-panel/lib/provider/flowable'
//import "./bpmn-js-properties-panel/styles/index.css"; // 右边工具栏样式
import VueAceEditor from 'vue2-ace-editor'
import newXml from './resources/newDiagram.js'
import flowBasicPropertyPanel from './vue-properties-panel/FlowBasicPropertyPanel' // 属性面板

import lintModule from 'bpmn-js-bpmnlint'
import bpmnlintConfig from './.bpmnlintrc'
//import fileDrop from "file-drops";

import customModule from './custom'
import BpmData from './resources/BpmData'
import {mixins} from '@/mixins/index'
import './custom/BpmnExtends.js'
import flow from '@/api/flow.js'

const SHOW_TYPE = 'bpmDef'

export default {
  mixins: [mixins],
  props: {
    defKey: {
      type: String,
      default: ''
    },
    modelData: {
      type: Object,
      default: {
        id: undefined,
        key: 'processId_1',
        name: 'processName_1',
        category: 'category_1',
        description: 'description_1'
      }
    },
    operateType: String,
    processStatus: String
  },
  components: {
    VueAceEditor,
    flowBasicPropertyPanel
  },
  data() {
    return {
      scale: 1, //流程图比例（用于放大缩小）
      bpmnModeler: null,
      process: {
        xml: '',
        svg: ''
      },
      nodeProcessSelect: null,
      xmlVisible: false,
      loading: false,
      bpmData: new BpmData(),
      activeName: 'propertiesPanel',
      bpmnlintActive: false,
      importParseComplete: false,
      dialogVisible: false,
      isDeploy: false,
      isDeployMain: false,
      currentRow: {
        taskId: '',
        account: '',
        fullName: '',
        showTime: '',
        reasons: '',
        action: '',
        showType: SHOW_TYPE
      }
    }
  },
  methods: {
    // 抓手工具
    onHandTool() {
      this.bpmnModeler.get('handTool').toggle()
    },
    // 拉索工具
    onLassoTool() {
      this.bpmnModeler.get('lassoTool').toggle()
    },
    // 平移工具
    onSpaceTool() {
      this.bpmnModeler.get('spaceTool').toggle()
    },
    // 连线工具
    onConnectionMulti() {
      this.bpmnModeler.get('globalConnect').toggle()
    },
    handleClose() {
      this.loading = false
      this.dialogVisible = false
    },
    // 调整左侧工具栏排版
    adjustPalette() {
      try {
        // 获取 bpmn 设计器实例
        const canvas = this.$refs.canvas
        const djsPalette = canvas.children[0].children[1].children[5]
        // const djsPalStyle = {
        //   width: "95px",
        //   left: "0px",
        //   background: "white",
        //   borderRadius: 0,
        // };
        // for (var key in djsPalStyle) {
        //   djsPalette.style[key] = djsPalStyle[key];
        // }
        const palette = djsPalette.children[0]
        const allGroups = palette.children
        // 修改控件样式
        for (var gKey in allGroups) {
          const group = allGroups[gKey]
          for (var cKey in group.children) {
            const control = group.children[cKey]
            // const controlStyle = {
            //   display: 'flex',
            //   justifyContent: 'flex-start',
            //   alignItems: 'center',
            //   width: '100%',
            // }
            if (
              control.className &&
              control.dataset &&
              control.className.indexOf('entry') !== -1
            ) {
              const controlProps = this.bpmData.getControl(
                control.dataset.action
              )
              if (controlProps['title']) {
                control.innerHTML = `<div style='font-size: 12px;font-weight:500;' title='${controlProps['title']}'>${controlProps['title']}</div>`
                // for (var csKey in controlStyle) {
                //   control.style[csKey] = controlStyle[csKey]
                // }
              } else {
                // 隐藏
                control.style.display = 'none'
              }
            }
          }
        }
      } catch (e) {}
    },
    // bind SVG element height.
    // getContainerHeight() {
    //   return document.body.offsetHeight + "px";
    // },
    // init ace editor
    editorInit: function() {
      require('brace/ext/language_tools')
      require('brace/mode/xml')
      require('brace/theme/chrome')
    },
    getProcessElement() {
      return this.bpmnModeler.getDefinitions().rootElements.find(item => {
        return item.$type == 'bpmn:Process'
      })
    },
    getProcess() {
      const element = this.getProcessElement()
      return element
    },
    // 初始化流程图
    createNewDiagram(xml, type = '') {
      let originalXML = this.process.xml
      if (!xml) {
        // 初始化XML文本
        this.process.xml = newXml(
          this.modelData.key,
          this.modelData.name,
          this.modelData.category,
          this.modelData.description,
          this.modelData.designPattern
        )
      } else {
        //this.process.xml = this.encodeCDATA(xml)
        this.process.xml = xml
      }
      // 将字符串转换成图显示出来
      this.bpmnModeler
        .importXML(this.process.xml)
        .then((err, msg) => {
          if (originalXML) {
            //不是初始化，是导入的情况
            this.$message.success(type === 'clear' ? '清空成功' : '导入成功!')
          }

          if (err.warnings.length > 0) {
            //  console.error(err);
          }
          this.adjustPalette()
        })
        .catch(() => {
          this.$message.error('文件错误!')
        })
    },
    // 当图发生改变的时候会调用这个函数，这个data就是图的xml
    setEncoded(type, data) {
      // 把xml转换为URI，下载要用到的
      const encodedData = encodeURIComponent(data)
      if (data) {
        if (type === 'xml') {
          // 获取到图的xml，保存就是把这个xml提交给后台
          this.process.xml = data
          return {
            filename: this.process.name + '.bpmn20.xml',
            href: 'data:application/bpmn20-xml;charset=UTF-8,' + encodedData,
            data: data
          }
        }
        if (type === 'svg') {
          this.process.svg = data
          return {
            filename: this.process.name + '.bpmn20.svg',
            href: 'data:application/text/xml;charset=UTF-8,' + encodedData,
            data: data
          }
        }
      }
    },
    // 导入
    importXml() {
      this.$refs.importBtn.$el.click()
    },
    // 导入文件选择完成
    openBpmn(file) {
      let ext = file.name.substring(file.name.lastIndexOf('.') + 1)
      if (ext != 'xml') {
        this.$message.warning('请选xml文件进行导入!')
        return false
      }
      const reader = new FileReader()
      reader.readAsText(file, 'utf-8')
      reader.onload = () => {
        // this.$
        this.createNewDiagram(reader.result)
      }
      return false
    },
    /**
     * 下载xml/svg
     *  @param  type  类型  svg / xml
     *  @param  data  数据
     *  @param  name  文件名称
     */
    download(type, data, name) {
      let dataTrack = ''
      const a = document.createElement('a')
      switch (type) {
        case 'xml':
          dataTrack = 'bpmn'
          break
        case 'svg':
          dataTrack = 'svg'
          break
        default:
          break
      }
      name = name || `diagram.${dataTrack}`
      a.setAttribute(
        'href',
        `data:application/bpmn20-xml;charset=UTF-8,${encodeURIComponent(data)}`
      )
      a.setAttribute('target', '_blank')
      a.setAttribute('dataTrack', `diagram:download-${dataTrack}`)
      a.setAttribute('download', name)
      document.body.appendChild(a)
      a.click()
      URL.revokeObjectURL(a.href) // 释放URL 对象
      document.body.removeChild(a)
    },
    // 导出XML文件
    handleExportXmlAction() {
      const _this = this
      this.bpmnModeler
        .saveXML({
          format: true
        })
        .then(({xml}) => {
          _this.download('xml', xml, _this.getProcess().name + '.bpmn20.xml')
        })
    },
    // 导出SVG文件
    handleExportSvgAction() {
      const _this = this
      this.bpmnModeler
        .saveSVG({
          format: true
        })
        .then(({svg}) => {
          _this.download('svg', svg, _this.getProcess().name + '.bpmn20.svg')
        })
    },
    // 预览
    handlePreviewXml() {
      this.bpmnModeler
        .saveXML({
          format: true,
          preamble: false
        })
        .then(({xml}) => {
          this.process.xml = xml
          this.xmlVisible = true
        })
    },
    // 清空
    handleClear() {
      this.createNewDiagram('', 'clear')
    },
    getErrorMsg(issues) {
      let errors = []
      Object.keys(issues).forEach(item => {
        issues[item].forEach(error => {
          if (error.category == 'error') {
            let msg = error.id + ' ' + error.message + '<br/>'
            errors.push(msg)
          }
        })
      })
      return errors
    },
    //发布
    handlePublish() {
      this.initModifyLog()
      if (this.operateType === 'add' && !this.modelData.id) {
        this.currentRow.reasons = '初始发布'
        this.currentRow.action = '发布新版本'
        this.handleSave4Add()
      } else {
        this.dialogVisible = true
      }
    },
    handleSave() {
      if (!this.currentRow.reasons) {
        return this.$message.warning('请输入配置事由！')
      }
      this.handleSave4Add()
    },
    // 保存
    handleSave4Add() {
      this.loading = true

      this.bpmnlintActive = true
      var linting = this.bpmnModeler.get('linting')
      if (Object.keys(linting._issues).length > 0) {
        let errorMsg = this.getErrorMsg(linting._issues)
        if (errorMsg.length > 0) {
          this.$message.error({
            dangerouslyUseHTMLString: true,
            message: errorMsg
          })
          this.loading = false
          return
        }
      }
      // 校验外部子流程 是否绑定了 流程key
      let flowElement = this.bpmnModeler.getDefinitions()
      if (flowElement && flowElement.rootElements) {
        let flag = false
        let msg = ''
        flowElement.rootElements.forEach(item => {
          if (item.flowElements && item.flowElements.length) {
            item.flowElements.forEach(subItem => {
              if (
                subItem.$type == 'bpmn:CallActivity' &&
                !subItem.calledElement
              ) {
                flag = true
                msg = `外部子流程【${subItem.name}】未绑定流程！`
              }
            })
          }
        })
        if (flag) {
          this.$message.info(msg)
          this.loading = false
          return
        }
      }
      const _this = this

      this.bpmnModeler
        .saveXML({
          format: true
        })
        .then(({xml}) => {
          this.loading = false
          const process = _this.getProcess()
          if (!_this.modelData.typeName) {
            this.$message.error({
              message: '请选择分类'
            })
            this.activeName = 'gloablePropertyPanel'
            return
          }
          if (!process.id) {
            this.$message.error({
              message: '请输入流程key'
            })
            this.activeName = 'gloablePropertyPanel'
            return
          } else if (!/^[^0-9][\w]{1,30}$/.test(process.id)) {
            this.$message.error({
              message:
                '流程key只能由字母开头的不超过30位的字母、数字、下划线组成'
            })
            this.activeName = 'gloablePropertyPanel'
            return
          }
          if (!process.name) {
            this.$message.error({
              message: '请输入流程名称'
            })
            this.activeName = 'gloablePropertyPanel'
            return
          }

          //外部子流程任务key判断 begin
          for (let i = 0; i < process.flowElements.length; i++) {
            let item = process.flowElements[i]
            if (item.$type === 'bpmn:CallActivity' && !item.calledElement) {
              this.$message.error({
                message: '请选择子流程任务key'
              })
              this.activeName = 'gloablePropertyPanel'
              return
            }
          }
          //end

          _this.process.xml = xml
          _this.modelData.bpmnXml = xml
          _this.modelData.key = process.id
          _this.modelData.defKey = process.id
          _this.modelData.name = process.name
          _this.modelData.category = process.category
          let params = {
            defaultBpmDefinition: _this.modelData,
            isdeploy: this.dialogVisible ? this.isDeploy : true,
            isDeployMain: this.dialogVisible ? this.isDeployMain : false
          }
          //保存流程成功后，继续保存日志
          this.currentRow.taskId = process.id
          flow.saveBpmShowRecord(this.currentRow).then(response => {
            if (!response.data.state) {
              this.$message.fail(data.message)
            }
          })
          _this.$emit('save', params, () => {
            this.dialogVisible = false
          })
        })
    },
    /**
     * 加载查阅日志默认值
     */
    initModifyLog() {
      //编号，为实例时就是实例id，为任务时就是任务id
      this.currentRow['taskId'] = this.defKey
      //主题
      const {account, username} = this.$store.state.login.currentUser
      //当前查阅人
      this.currentRow['account'] = account
      this.currentRow['action'] = '保存'
      this.currentRow['fullName'] = username
      this.currentRow['showTime'] = new Date().format('yyyy-MM-dd HH:mm:ss')
      //流程实例中查看
      this.currentRow['showType'] = SHOW_TYPE
      this.currentRow['reasons'] = ''
    },
    // 复制成功
    onCopy() {
      this.$message.success('内容复制成功')
    },
    // 前进
    handleRedo() {
      this.bpmnModeler.get('commandStack').redo()
    },
    // 后退
    handleUndo() {
      this.bpmnModeler.get('commandStack').undo()
    },
    // 流程图放大缩小
    handleZoom(radio) {
      const newScale = !radio
        ? 1.0 // 不输入radio则还原
        : this.scale + radio <= 0.2 // 最小缩小倍数
        ? 0.2
        : this.scale + radio
      this.bpmnModeler.get('canvas').zoom(newScale)
      this.scale = newScale
    },
    _ensureId(element) {
      // generate semantic ids for elements
      // bpmn:SequenceFlow -> SequenceFlow_ID
      var prefix
      if (is(element, 'bpmn:UserTask')) {
        prefix = 'UserTask'
        if (element.loopCharacteristics) {
          prefix = 'SignTask'
        }
      } else if (is(element, 'bpmn:Activity')) {
        prefix = 'Activity'
      } else if (is(element, 'bpmn:StartEvent')) {
        prefix = 'StartEvent'
      } else if (is(element, 'bpmn:EndEvent')) {
        prefix = 'EndEvent'
      } else if (is(element, 'bpmn:Event')) {
        prefix = 'Event'
      } else if (is(element, 'bpmn:Gateway')) {
        prefix = 'Gateway'
      } else if (isAny(element, ['bpmn:SequenceFlow', 'bpmn:MessageFlow'])) {
        prefix = 'Flow'
      } else {
        prefix = (element.$type || '').replace(/^[^:]*:/g, '')
      }

      prefix += '_'
      if (!element.id && this._needsId(element)) {
        element.id = this.bpmnModeler._moddle.ids.nextPrefixed(prefix, element)
      }
    },
    _needsId(element) {
      return isAny(element, [
        'bpmn:RootElement',
        'bpmn:FlowElement',
        'bpmn:MessageFlow',
        'bpmn:DataAssociation',
        'bpmn:Artifact',
        'bpmn:Participant',
        'bpmn:Lane',
        'bpmn:LaneSet',
        'bpmn:Process',
        'bpmn:Collaboration',
        'bpmndi:BPMNShape',
        'bpmndi:BPMNEdge',
        'bpmndi:BPMNDiagram',
        'bpmndi:BPMNPlane',
        'bpmn:Property',
        'bpmn:CategoryValue'
      ])
    }
  },
  mounted() {
    const canvas = this.$refs.canvas
    // 生成实例
    this.bpmnModeler = new BpmnModeler({
      container: canvas,
      linting: {
        bpmnlint: bpmnlintConfig,
        active: this.bpmnlintActive
      },
      additionalModules: [
        customModule[this.modelData.designPattern],
        lintModule,
        //  propertiesPanelModule,
        //propertiesProviderModule,
        {
          translate: ['value', customTranslate]
        }
      ],
      moddleExtensions: {
        activiti: activiti
      },
      // propertiesPanel: {
      //     parent: '#properties'
      // },
      height: '100%',
      width: '100%',
      keyboard: {
        bindTo: document
      }
    })
    let bpmnFactory = this.bpmnModeler.get('bpmnFactory')
    bpmnFactory._ensureId = this._ensureId

    var linting = this.bpmnModeler.get('linting')
    linting.setLinterConfig(bpmnlintConfig)

    this.bpmnModeler.on('import.parse.complete', event => {
      this.importParseComplete = true
    })

    this.bpmnModeler.on('linting.toggle', event => {
      this.bpmnlintActive = event.active
    })
    // 监听流程图改变事件
    const _this = this
    this.bpmnModeler.on('element.changed', (e, l) => {
      const {element} = e
      if (
        element &&
        element.businessObject &&
        element.businessObject.name &&
        element.businessObject.name.length > 20
      ) {
        _this.$message.warning('节点名称不能超过20个字符！')
        _this.handleUndo()
        return
      }
    })
    this.bpmnModeler.on('commandStack.changed', () => {
      _this.bpmnModeler
        .saveSVG({
          format: true
        })
        .then((err, svg) => {
          _this.setEncoded('svg', err ? null : svg)
        })
      _this.bpmnModeler
        .saveXML({
          format: true
        })
        .then(({xml}) => {
          _this.setEncoded('xml', xml)
        })
    })
    // 新增流程定义
    this.createNewDiagram(this.modelData && this.modelData.bpmnXml)
  }
}
</script>

<style lang="scss">
/*左边工具栏以及编辑节点的样式*/
@import '~bpmn-js/dist/assets/diagram-js.css';
@import '~bpmn-js/dist/assets/bpmn-font/css/bpmn.css';
@import '~bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css';
@import '~bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css';
@import '~bpmn-js-bpmnlint/dist/assets/css/bpmn-js-bpmnlint.css';

$primary-color: #409eff;
$primary-background-color: #ecf5ff;

.fm2-container {
  background: #fff;
  height: calc(100vh - 50px);
  border: 1px solid #e0e0e0;

  .btn-bar {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    border-bottom: 1px solid #e0e0e0;
    .btn-bar_center {
      flex: 1;
      display: flex;
      align-items: center;
      justify-content: center;
      height: 28px;
      > ul {
        display: flex;
        align-items: center;
        background: #f6f6f6;
        padding: 5px 16px;
        margin-right: 10px;
        li {
          margin-right: 16px;
          color: #333333;
          cursor: pointer;
          > i {
            font-size: 16px;
            margin-right: 4px;
          }
          &.line {
            width: 1px;
            height: 14px;
            background: #cecece;
          }
          &:last-child {
            margin-right: 0;
          }
        }
      }
      > div {
        margin-right: 16px;
      }
      .btn-bar_center_scale {
        display: flex;
        align-items: center;
        span {
          background: #f6f6f6;
          display: inline-block;
          width: 72px;
          margin: 0 1px;
          height: 28px;
          line-height: 28px;
          text-align: center;
          color: #333;
        }
        i {
          background: #f6f6f6;
          color: #333333;
          font-weight: bold;
          display: inline-block;
          width: 32px;
          height: 28px;
          text-align: center;
          display: flex;
          align-items: center;
          justify-content: center;
          cursor: pointer;
          font-size: 16px;
          &:hover {
            color: $primary-color;
          }
        }
      }
      .btn-bar_center_clear {
        width: 76px;
        background: #f6f6f6;
        display: flex;
        align-items: center;
        justify-content: center;
        height: 28px;
        color: #333;
        cursor: pointer;
        &:hover {
          color: $primary-color;
        }
        i {
          font-weight: bold;
          margin-right: 5px;
          font-size: 16px;
        }
      }
    }
  }

  .fm2-main-content {
    overflow: hidden;
    > .el-main {
      padding: 0;
    }
  }

  footer {
    height: 30px;
    line-height: 30px;
    border-top: 1px solid #e0e0e0;
    font-size: 12px;
    text-align: right;
    color: $primary-color;
    background: #fafafa;

    a {
      color: $primary-color;
    }
  }
}

.widget-config-container {
  overflow: hidden;
  position: relative;

  .el-header {
    border-bottom: solid 2px #e4e7ed;
    padding: 0 5px;
  }

  .config-tab {
    height: 45px;
    line-height: 45px;
    display: inline-block;
    width: 145px;
    text-align: center;
    font-size: 14px;
    font-weight: 500;
    position: relative;
    cursor: pointer;

    &.active {
      border-bottom: solid 2px $primary-color;
    }
  }

  .config-content {
    padding: 10px;

    .el-form-item__label {
      padding: 0;
      font-weight: 500;
    }

    .el-form-item {
      border-bottom: solid 1px #e1e1e1;
      padding-bottom: 10px;
    }
  }

  .ghost {
    background: #fff;
    border: 1px dashed $primary-color;

    &::after {
      background: #fff;
      display: block;
      content: '';
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
    }
  }

  ul {
    margin: 0;
    padding: 0;
  }

  li.ghost {
    list-style: none;
    font-size: 0;
    display: block;
    position: relative;
  }
}

.containers {
  background-color: #ffffff;
  width: 100%;
  height: 100%;

  .canvas {
    width: 100%;
    height: 100%;
  }

  .panel {
    position: absolute;
    right: 0;
    top: 50px;
    width: 300px;
  }

  .bjs-powered-by {
    display: none;
  }

  .toolbar {
    position: absolute;
    top: 0;
    right: 320px;
    height: 40px;
    width: 600px;
    border: 1px solid red;

    a {
      text-decoration: none;
      margin: 5px;
      color: #409eff;
    }
  }
}

// .el-tabs__content {
//   height: 100%;
// }

// 隐藏暂时用不到的功能

.djs-context-pad {
  box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
  border-radius: 6px;
  width: 308px;
  background: #fff;
  padding: 12px;
  .entry {
    margin-right: 16px;
    margin-bottom: 0;
    &:nth-child(3n) {
      margin-right: 0;
    }
  }
  .group {
    padding: 10px;
    background: #f8f8f8;
    margin-bottom: 10px;
    position: relative;
    margin-top: 34px;
    display: flex;
    flex-wrap: wrap;
    padding-bottom: 0;
    &[data-group='model']::before {
      display: block;
      content: '新增';
      font-weight: bold;
      font-size: 14px;
      position: absolute;
      top: -24px;
    }
    &[data-group='edit']::before {
      display: block;
      content: '修改类型';
      font-weight: bold;
      font-size: 14px;
      position: absolute;
      top: -24px;
    }
    &[data-group='connect']::before {
      display: block;
      content: '设置';
      font-weight: bold;
      font-size: 14px;
      position: absolute;
      top: -24px;
    }
    &:last-child {
      margin-bottom: 0;
    }
    .entry {
      width: 33%;
      margin: 0;
      text-align: left;
      display: flex;
      align-items: center;
      margin-bottom: 10px;
      background: none;
      box-shadow: none;
      border: none;
      &::before {
        margin-right: 4px;
      }
      &[data-action='append.end-event2']::after {
        display: inline-block;
        content: '结束';
        font-size: 12px;
        flex: 1;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
      }
      &[data-action='append.gateway2']::after {
        display: inline-block;
        content: '条件网关';
        font-size: 12px;
        flex: 1;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
      }
      &[data-action='append-task']::after {
        display: inline-block;
        content: '追加任务';
        font-size: 12px;
        flex: 1;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
      }
      &[data-action='append.intermediate-event']::after {
        display: inline-block;
        content: '追加中间/边界事件';
        font-size: 12px;
        flex: 1;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
      }
      &[data-action='append.user-task']::after {
        display: inline-block;
        content: '用户任务';
        font-size: 12px;
        flex: 1;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
      }
      &[data-action='append.sign-task']::after {
        display: inline-block;
        content: '会签并行';
        font-size: 12px;
        flex: 1;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
      }
      &[data-action='append.sign-task-sequential']::after {
        display: inline-block;
        content: '会签串行';
        font-size: 12px;
        flex: 1;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
      }
      &[data-action='create.subprocess-collapsed']::after {
        display: inline-block;
        content: '外部子流程';
        font-size: 12px;
        flex: 1;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
      }
      &[data-action='replace']::after {
        display: inline-block;
        content: '修改类型';
        font-size: 12px;
        flex: 1;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
      }

      &[data-action='delete']::after {
        display: inline-block;
        content: '移除';
        font-size: 12px;
        flex: 1;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
      }
      &[data-action='connect']::after {
        display: inline-block;
        content: '使用顺序/消息流或者关联连接';
        font-size: 12px;
        flex: 1;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
      }
      &[data-action='append.inclusiveGateway']::after {
        display: inline-block;
        content: '条件同步网关';
        font-size: 12px;
        flex: 1;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
      }
      &[data-action='append.parallelGateway']::after {
        display: inline-block;
        content: '同步网关';
        font-size: 12px;
        flex: 1;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
      }
      &[data-action='create.subprocess-expanded']::after {
        display: inline-block;
        content: '内部子流程';
        font-size: 12px;
        flex: 1;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
      }
      &[data-action='append.gateway'],
      &[data-action='append.end-event'] {
        display: none;
      }
    }
    .entry.bpmn-icon-task,  // 追加任务
    .entry.bpmn-icon-text-annotation,  // 文本注释
    .entry.bpmn-icon-intermediate-event-none // 中间/边界事件
 {
      display: none;
    }
  }
}

.djs-popup {
  .djs-popup-body {
    .bpmn-icon-transaction,  // 运转
                        .bpmn-icon-event-subprocess-expanded, // 事件子流程
                        .bpmn-icon-gateway-complex, // 复杂网关
                        .bpmn-icon-gateway-eventbased, // 事件网关
                        .bpmn-icon-intermediate-event-none, // 中间事件
                        .bpmn-icon-start-event-message, // 消息开始事件
                        .bpmn-icon-start-event-timer, // 定时开始事件
                        .bpmn-icon-start-event-condition, // 条件开始事件
                        .bpmn-icon-start-event-signal, // 信号开始事件
                        .bpmn-icon-send, // 发送任务
                        .bpmn-icon-receive, // 接收任务
                        .bpmn-icon-manual, // 手工任务
                        .bpmn-icon-business-rule, // 业务规则任务
                        .bpmn-icon-script, // 脚本任务
                        .bpmn-icon-task, // 追加任务
                        .bpmn-icon-intermediate-event-none, // 中间事件
                        .bpmn-icon-end-event-message, // 消息结束事件
                        .bpmn-icon-end-event-escalation, // 定时结束事件
                        .bpmn-icon-end-event-error, // 错误结束事件
                        .bpmn-icon-end-event-compensation, // 补偿结束事件
                        .bpmn-icon-end-event-signal, // 信号结束事件
                        .bpmn-icon-end-event-terminate, // 终止结束事件
                        .bpmn-icon-subprocess-collapsed, //内部子流程（折叠的）
                        .bpmn-icon-default-flow, // 默认分支
                        .bpmn-icon-conditional-flow {
      display: none;
    }
  }
  .djs-popup-header {
    .entry.bpmn-icon-ad-hoc-marker, // adHocSubprocess 子流程 5.22版本不支持  activiti6.0以上的版本才支持
    .entry.bpmn-icon-loop-marker // 循环 暂时屏蔽
 {
      display: none;
    }
  }
}

.djs-palette {
  border: none;
  border-right: 1px solid #e6e6e6;
  // box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
  background: #fff;
  border-radius: 0;
  left: 0;
  top: 0;
  bottom: 0;
  width: 72px !important;
  overflow-y: auto;

  .entry,
  .djs-palette-toggle {
    // padding-left: 10px;
    box-sizing: border-box;
    height: 58px;
    line-height: 16px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 100%;
    color: #333;
    &:hover {
      color: $primary-color;
    }
  }

  .entry:before {
    font-size: 20px;
    margin-bottom: 2px;
  }
}
.djs-palette.two-column.open {
  width: 50px;
}
// .djs-palette-entries {
//   background: #F9F9F9;
// }

.entry.bpmn-icon-hand-tool,
.entry.bpmn-icon-lasso-tool,
.entry.bpmn-icon-space-tool {
  display: none;
}
.djs-palette-entries {
  .entry {
    &[data-action='create.parallel-gateway']::before {
      content: '\E804';
    }
    &[data-action='create.exclusive-gateway']::before {
      content: '\E80F';
    }
  }
}
.dialog-scrollbar {
  height: 50vh;
  .el-scrollbar__wrap {
    overflow-x: hidden;
  }
}
</style>
