Initial commit
This commit is contained in:
commit
b06ca2d99e
31
.gitignore
vendored
Normal file
31
.gitignore
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
|
||||||
|
.yarn/*
|
||||||
|
!.yarn/patches
|
||||||
|
!.yarn/plugins
|
||||||
|
!.yarn/releases
|
||||||
|
!.yarn/sdks
|
||||||
|
!.yarn/versions
|
||||||
3
.vscode/extensions.json
vendored
Normal file
3
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"recommendations": ["Vue.volar"]
|
||||||
|
}
|
||||||
942
.yarn/releases/yarn-4.10.2.cjs
vendored
Executable file
942
.yarn/releases/yarn-4.10.2.cjs
vendored
Executable file
File diff suppressed because one or more lines are too long
22
.yarnrc.yml
Normal file
22
.yarnrc.yml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
yarnPath: .yarn/releases/yarn-4.10.2.cjs
|
||||||
|
|
||||||
|
enableStrictSsl: false
|
||||||
|
|
||||||
|
nodeLinker: node-modules
|
||||||
|
|
||||||
|
npmRegistryServer: 'https://nexus.services.mts.ru/repository/npm-all/'
|
||||||
|
|
||||||
|
unsafeHttpWhitelist:
|
||||||
|
- '*.mts.ru'
|
||||||
|
|
||||||
|
npmScopes:
|
||||||
|
mts-ds:
|
||||||
|
npmRegistryServer: 'https://artifactory.mts.ru/artifactory/api/npm/web-designsystem-npm-local/'
|
||||||
|
servicedesk:
|
||||||
|
npmRegistryServer: 'https://artifactory.mts.ru/artifactory/api/npm/mts-servicedesk-npm-local/'
|
||||||
|
stash:
|
||||||
|
npmRegistryServer: 'https://artifactory.mts.ru/artifactory/api/npm/mts-abp-mts-ui-npm-local/'
|
||||||
|
mts-ui-next:
|
||||||
|
npmRegistryServer: 'https://artifactory.mts.ru/artifactory/api/npm/mts-abp-mts-ui-npm-local/'
|
||||||
|
docflow:
|
||||||
|
npmRegistryServer: 'https://artifactory.mts.ru/artifactory/api/npm/npm-plf-df-plf-df-demo-autotest-inside-0000s1-npm-local/'
|
||||||
5
README.md
Normal file
5
README.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Vue 3 + TypeScript + Vite
|
||||||
|
|
||||||
|
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
||||||
|
|
||||||
|
Learn more about the recommended Project Setup and IDE Support in the [Vue Docs TypeScript Guide](https://vuejs.org/guide/typescript/overview.html#project-setup).
|
||||||
23
eslint.config.js
Normal file
23
eslint.config.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import antfu from '@antfu/eslint-config'
|
||||||
|
|
||||||
|
export default antfu({
|
||||||
|
ignores: [
|
||||||
|
'src/__generated__',
|
||||||
|
'scripts',
|
||||||
|
],
|
||||||
|
vue: {
|
||||||
|
vueVersion: 3,
|
||||||
|
sfcBlocks: false,
|
||||||
|
},
|
||||||
|
typescript: true,
|
||||||
|
formatters: {
|
||||||
|
css: true,
|
||||||
|
},
|
||||||
|
overrides: {
|
||||||
|
vue: {
|
||||||
|
'vue/block-order': ['error', {
|
||||||
|
order: ['template', 'script', 'style'],
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
13
index.html
Normal file
13
index.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>BPMN</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.ts"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
41
package.json
Normal file
41
package.json
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"name": "bpmn-test",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vue-tsc -b && vite build",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"pack-lint-config": "bpmnlint-pack-config -c ./src/bpmn/.bpmnlintrc -o ./src/bpmn/packed-lint-config.js -t es"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@mts-ds/base": "^3.0.0",
|
||||||
|
"@mts-ds/icons": "^3.0.0",
|
||||||
|
"@servicedesk/ui-kit": "^2.0.4",
|
||||||
|
"@stash/hubify": "^0.45.6",
|
||||||
|
"@stash/icons": "^1.0.0",
|
||||||
|
"bpmn-js": "^18.6.4",
|
||||||
|
"bpmn-js-bpmnlint": "^0.23.0",
|
||||||
|
"bpmn-js-properties-panel": "^5.42.1",
|
||||||
|
"camunda-bpmn-js": "^5.13.0",
|
||||||
|
"vue": "^3.5.21"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@antfu/eslint-config": "^5.4.1",
|
||||||
|
"@types/node": "^24.5.2",
|
||||||
|
"@vitejs/plugin-vue": "^6.0.1",
|
||||||
|
"@vue/tsconfig": "^0.8.1",
|
||||||
|
"bpmnlint-pack-config": "^0.8.0",
|
||||||
|
"eslint": "^9.36.0",
|
||||||
|
"eslint-plugin-format": "^1.0.2",
|
||||||
|
"sass-embedded": "^1.93.0",
|
||||||
|
"typescript": "~5.8.3",
|
||||||
|
"vite": "^7.1.6",
|
||||||
|
"vue-tsc": "^3.0.7"
|
||||||
|
},
|
||||||
|
"packageManager": "yarn@4.10.2",
|
||||||
|
"resolutions": {
|
||||||
|
"bpmnlint-plugin-service-desk": "portal:/Users/nvkrug/Work/forms/bpmnlint-plugin-service-desk"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
public/vite.svg
Normal file
1
public/vite.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
8
src/App.vue
Normal file
8
src/App.vue
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<template>
|
||||||
|
<BpmnModeler :diagram-xml="DiagramExample" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import DiagramExample from './assets/diagrams/approvement_test_1.bpmn?raw'
|
||||||
|
import BpmnModeler from './components/BpmnModeler.vue'
|
||||||
|
</script>
|
||||||
114
src/assets/diagrams/approvement_test_1.bpmn
Normal file
114
src/assets/diagrams/approvement_test_1.bpmn
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:bioc="http://bpmn.io/schema/bpmn/biocolor/1.0" xmlns:color="http://www.omg.org/spec/BPMN/non-normative/color/1.0" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_16l7d92" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.25.0" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.21.0">
|
||||||
|
<bpmn:process id="approvement_test_1" name="approvement-test" isExecutable="true" camunda:historyTimeToLive="100">
|
||||||
|
<bpmn:startEvent id="StartEvent_1">
|
||||||
|
<bpmn:outgoing>Flow_1ai9etl</bpmn:outgoing>
|
||||||
|
</bpmn:startEvent>
|
||||||
|
<bpmn:userTask id="Activity_1bne0zs" name="Согласование руководителем" camunda:assignee="assavinc10">
|
||||||
|
<bpmn:extensionElements>
|
||||||
|
<camunda:properties>
|
||||||
|
<camunda:property name="tags" value="approvement" />
|
||||||
|
<camunda:property name="serviceKey" value="sd-adapter" />
|
||||||
|
</camunda:properties>
|
||||||
|
</bpmn:extensionElements>
|
||||||
|
<bpmn:incoming>Flow_15bt283</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_1e4gjlx</bpmn:outgoing>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:sequenceFlow id="Flow_1ai9etl" sourceRef="StartEvent_1" targetRef="Activity_05wz618" />
|
||||||
|
<bpmn:endEvent id="Event_0e1s3ol">
|
||||||
|
<bpmn:incoming>Flow_1kfmx5m</bpmn:incoming>
|
||||||
|
</bpmn:endEvent>
|
||||||
|
<bpmn:sequenceFlow id="Flow_1e4gjlx" sourceRef="Activity_1bne0zs" targetRef="Activity_10de6ie" />
|
||||||
|
<bpmn:userTask id="Activity_10de6ie" name="Согласование HR" camunda:assignee="sa0000jocasta">
|
||||||
|
<bpmn:extensionElements>
|
||||||
|
<camunda:properties>
|
||||||
|
<camunda:property name="tags" value="approvement" />
|
||||||
|
<camunda:property name="serviceKey" value="sd-adapter" />
|
||||||
|
</camunda:properties>
|
||||||
|
<camunda:inputOutput>
|
||||||
|
<camunda:outputParameter name="lastDecision">${comment}</camunda:outputParameter>
|
||||||
|
</camunda:inputOutput>
|
||||||
|
</bpmn:extensionElements>
|
||||||
|
<bpmn:incoming>Flow_1e4gjlx</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_1yxc8vk</bpmn:outgoing>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:sequenceFlow id="Flow_1yxc8vk" sourceRef="Activity_10de6ie" targetRef="Activity_0i59amn" />
|
||||||
|
<bpmn:serviceTask id="Activity_0i59amn" name="Смена статуса на "Завершено"" camunda:asyncAfter="true">
|
||||||
|
<bpmn:extensionElements>
|
||||||
|
<camunda:inputOutput>
|
||||||
|
<camunda:inputParameter name="type">save</camunda:inputParameter>
|
||||||
|
<camunda:inputParameter name="statusDescription">Заявка завершена</camunda:inputParameter>
|
||||||
|
<camunda:inputParameter name="statusID">solved</camunda:inputParameter>
|
||||||
|
<camunda:inputParameter name="statusComment">${lastDecision}</camunda:inputParameter>
|
||||||
|
</camunda:inputOutput>
|
||||||
|
<camunda:connector>
|
||||||
|
<camunda:inputOutput>
|
||||||
|
<camunda:inputParameter name="signalKey">update_status</camunda:inputParameter>
|
||||||
|
<camunda:inputParameter name="serviceKey">sd-adapter</camunda:inputParameter>
|
||||||
|
</camunda:inputOutput>
|
||||||
|
<camunda:connectorId>kafka-connector</camunda:connectorId>
|
||||||
|
</camunda:connector>
|
||||||
|
</bpmn:extensionElements>
|
||||||
|
<bpmn:incoming>Flow_1yxc8vk</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_1kfmx5m</bpmn:outgoing>
|
||||||
|
</bpmn:serviceTask>
|
||||||
|
<bpmn:sequenceFlow id="Flow_1kfmx5m" sourceRef="Activity_0i59amn" targetRef="Event_0e1s3ol" />
|
||||||
|
<bpmn:userTask id="Activity_05wz618" name="Согласование группой" camunda:candidateUsers="approvers" camunda:candidateGroups="6d78cf93-a9f6-4b51-95ed-c85ecbb1dc40">
|
||||||
|
<bpmn:extensionElements>
|
||||||
|
<camunda:properties>
|
||||||
|
<camunda:property name="tags" value="approvement" />
|
||||||
|
<camunda:property name="serviceKey" value="sd-adapter" />
|
||||||
|
</camunda:properties>
|
||||||
|
</bpmn:extensionElements>
|
||||||
|
<bpmn:incoming>Flow_1ai9etl</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_15bt283</bpmn:outgoing>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:sequenceFlow id="Flow_15bt283" sourceRef="Activity_05wz618" targetRef="Activity_1bne0zs" />
|
||||||
|
</bpmn:process>
|
||||||
|
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||||
|
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="approvement_test_1">
|
||||||
|
<bpmndi:BPMNShape id="Event_0e1s3ol_di" bpmnElement="Event_0e1s3ol">
|
||||||
|
<dc:Bounds x="882" y="99" width="36" height="36" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="BPMNShape_10in7yl" bpmnElement="Activity_0i59amn" bioc:stroke="#0d4372" bioc:fill="#bbdefb" color:background-color="#bbdefb" color:border-color="#0d4372">
|
||||||
|
<dc:Bounds x="720" y="77" width="100" height="80" />
|
||||||
|
<bpmndi:BPMNLabel />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_1bne0zs_di" bpmnElement="Activity_1bne0zs">
|
||||||
|
<dc:Bounds x="400" y="77" width="100" height="80" />
|
||||||
|
<bpmndi:BPMNLabel />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="BPMNShape_05m0nz6" bpmnElement="Activity_10de6ie">
|
||||||
|
<dc:Bounds x="560" y="77" width="100" height="80" />
|
||||||
|
<bpmndi:BPMNLabel />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||||
|
<dc:Bounds x="152" y="99" width="36" height="36" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="BPMNShape_10f3ez1" bpmnElement="Activity_05wz618">
|
||||||
|
<dc:Bounds x="240" y="77" width="100" height="80" />
|
||||||
|
<bpmndi:BPMNLabel />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_1ai9etl_di" bpmnElement="Flow_1ai9etl">
|
||||||
|
<di:waypoint x="188" y="117" />
|
||||||
|
<di:waypoint x="240" y="117" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_1e4gjlx_di" bpmnElement="Flow_1e4gjlx">
|
||||||
|
<di:waypoint x="500" y="117" />
|
||||||
|
<di:waypoint x="560" y="117" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_1yxc8vk_di" bpmnElement="Flow_1yxc8vk">
|
||||||
|
<di:waypoint x="660" y="117" />
|
||||||
|
<di:waypoint x="720" y="117" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_1kfmx5m_di" bpmnElement="Flow_1kfmx5m">
|
||||||
|
<di:waypoint x="820" y="117" />
|
||||||
|
<di:waypoint x="882" y="117" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_15bt283_di" bpmnElement="Flow_15bt283">
|
||||||
|
<di:waypoint x="340" y="117" />
|
||||||
|
<di:waypoint x="400" y="117" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
</bpmndi:BPMNPlane>
|
||||||
|
</bpmndi:BPMNDiagram>
|
||||||
|
</bpmn:definitions>
|
||||||
1
src/assets/vue.svg
Normal file
1
src/assets/vue.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 496 B |
9
src/bpmn/.bpmnlintrc
Normal file
9
src/bpmn/.bpmnlintrc
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"extends": [
|
||||||
|
"bpmnlint:recommended",
|
||||||
|
"plugin:service-desk/recommended"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"label-required": "warn"
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/bpmn/modules/i18n/Translate.js
Normal file
11
src/bpmn/modules/i18n/Translate.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import translations from './ru.json'
|
||||||
|
|
||||||
|
export default function Translate(template, replacements) {
|
||||||
|
replacements = replacements || {}
|
||||||
|
|
||||||
|
template = translations[template] || template
|
||||||
|
|
||||||
|
return template.replace(/\{([^}]+)\}/g, (_, key) => {
|
||||||
|
return replacements[key] || `{${key}}`
|
||||||
|
})
|
||||||
|
}
|
||||||
5
src/bpmn/modules/i18n/index.js
Normal file
5
src/bpmn/modules/i18n/index.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import Translate from './Translate.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
translate: ['value', Translate],
|
||||||
|
}
|
||||||
154
src/bpmn/modules/i18n/ru.json
Normal file
154
src/bpmn/modules/i18n/ru.json
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
{
|
||||||
|
"Activate create/remove space tool": "Включить инструмент «Управление пространством»",
|
||||||
|
"Activate global connect tool": "Включить инструмент «Глобальное соединение»",
|
||||||
|
"Activate hand tool": "Включить инструмент «Рука»",
|
||||||
|
"Activate lasso tool": "Включить инструмент «Лассо»",
|
||||||
|
"Ad-hoc": "Для этого случая",
|
||||||
|
"Ad-hoc sub-process (collapsed)": "Специальный подпроцесс (свернутый)",
|
||||||
|
"Ad-hoc sub-process (expanded)": "Специальный подпроцесс (развернутый)",
|
||||||
|
"Add lane above": "Добавить дорожку сверху",
|
||||||
|
"Add lane below": "Добавить дорожку снизу",
|
||||||
|
"Add text annotation": "Добавить текстовую аннотацию",
|
||||||
|
"Align elements": "Выровнять элементы",
|
||||||
|
"Align elements bottom": "Выровнять элементы по нижней границе",
|
||||||
|
"Align elements center": "Выровнять элементы по центру",
|
||||||
|
"Align elements left": "Выровнять элементы по левому краю",
|
||||||
|
"Align elements middle": "Выровнять элементы посередине",
|
||||||
|
"Align elements right": "Выровнять элементы по правому краю",
|
||||||
|
"Align elements top": "Выровнять элементы по верхней границе",
|
||||||
|
"Append compensation activity": "Добавить компенсирующее действие",
|
||||||
|
"Append conditional intermediate catch event": "Добавить обработчик промежуточного события-условия",
|
||||||
|
"Append end event": "Добавить конечное событие",
|
||||||
|
"Append gateway": "Добавить шлюз",
|
||||||
|
"Append intermediate/boundary event": "Добавить промежуточное/граничное событие",
|
||||||
|
"Append message intermediate catch event": "Добавить обработчик промежуточного события-сообщения",
|
||||||
|
"Append receive task": "Добавить задачу получения сообщения",
|
||||||
|
"Append signal intermediate catch event": "Добавить обработчик промежуточного события-сигнала",
|
||||||
|
"Append task": "Добавить задачу",
|
||||||
|
"Append text annotation": "Добавить комментарий",
|
||||||
|
"Append timer intermediate catch event": "Добавить обработчик промежуточного события-таймера",
|
||||||
|
"Business rule task": "Задача выполнения бизнес-правила",
|
||||||
|
"Call activity": "Действие «Вызов»",
|
||||||
|
"Cancel boundary event": "Граничное событие-отмена",
|
||||||
|
"Cancel end event": "Конечное событие-отмена",
|
||||||
|
"Change element": "Изменить элемент",
|
||||||
|
"Change type": "Изменить тип",
|
||||||
|
"Collection": "Коллекция",
|
||||||
|
"Compensation boundary event": "Граничное событие-компенсация",
|
||||||
|
"Compensation end event": "Конечное событие-компенсация",
|
||||||
|
"Compensation intermediate throw event": "Инициатор промежуточного события-компенсации",
|
||||||
|
"Compensation start event": "Начальное событие-компенсация",
|
||||||
|
"Complex gateway": "Комплексный шлюз",
|
||||||
|
"Conditional boundary event": "Граничное событие-условие",
|
||||||
|
"Conditional boundary event (non-interrupting)": "Граничное событие-условие (без прерываний)",
|
||||||
|
"Conditional flow": "Граничный поток",
|
||||||
|
"Conditional intermediate catch event": "Обработчик промежуточного события-условия",
|
||||||
|
"Conditional start event": "Начальное событие-условие",
|
||||||
|
"Conditional start event (non-interrupting)": "Начальное событие-условие (без прерываний)",
|
||||||
|
"Connect to other element": "Соединить с другим элементом",
|
||||||
|
"Connect using association": "Соединить с использованием ассоциации",
|
||||||
|
"Connect using data input association": "Соединить с использованием ассоциации ввода данных",
|
||||||
|
"Connect using sequence/message flow or association": "Соединить с использованием потока управления/сообщений или ассоциации",
|
||||||
|
"Create data object reference": "Создать объект данных",
|
||||||
|
"Create data store reference": "Создать хранилище данных",
|
||||||
|
"Create end event": "Создать конечное событие",
|
||||||
|
"Create expanded sub-process": "Создать развернутый подпроцесс",
|
||||||
|
"Create gateway": "Создать шлюз",
|
||||||
|
"Create group": "Создать группу",
|
||||||
|
"Create intermediate/boundary event": "Создать промежуточное/граничное событие",
|
||||||
|
"Create pool/participant": "Создать пул/участника",
|
||||||
|
"Create start event": "Создать начальное событие",
|
||||||
|
"Create task": "Создать задачу",
|
||||||
|
"Data object reference": "Объект данных",
|
||||||
|
"Data store reference": "Хранилище данных",
|
||||||
|
"Default flow": "Поток по умолчанию",
|
||||||
|
"Delete": "Удалить",
|
||||||
|
"Distribute elements horizontally": "Расположить элементы по горизонтали",
|
||||||
|
"Distribute elements vertically": "Расположить элементы по вертикали",
|
||||||
|
"Divide into three lanes": "Разделить на три дорожки",
|
||||||
|
"Divide into two lanes": "Разделить на две дорожки",
|
||||||
|
"Empty pool/participant": "Пустой пул",
|
||||||
|
"Empty pool/participant (removes content)": "Пустой пул (удаляет контент)",
|
||||||
|
"End event": "Конечное событие",
|
||||||
|
"Error boundary event": "Граничное событие-ошибка",
|
||||||
|
"Error end event": "Конечное событие-ошибка",
|
||||||
|
"Error start event": "Начальное событие-ошибка",
|
||||||
|
"Escalation boundary event": "Граничное событие-эскалация",
|
||||||
|
"Escalation boundary event (non-interrupting)": "Граничное событие-эскалация (без прерываний)",
|
||||||
|
"Escalation end event": "Конечное событие-эскалация",
|
||||||
|
"Escalation intermediate throw event": "Инициатор промежуточного события-эскалации",
|
||||||
|
"Escalation start event": "Начальное событие-эскалация",
|
||||||
|
"Escalation start event (non-interrupting)": "Начальное событие-эскалация (без прерываний)",
|
||||||
|
"Event sub-process": "Подпроцесс по событию",
|
||||||
|
"Event-based gateway": "Шлюз по событиям",
|
||||||
|
"Exclusive gateway": "Шлюз «исключающее или»",
|
||||||
|
"Inclusive gateway": "Шлюз «или»",
|
||||||
|
"Intermediate throw event": "Промежуточное событие-инициатор",
|
||||||
|
"Link intermediate catch event": "Обработчик промежуточного события-ссылки",
|
||||||
|
"Link intermediate throw event": "Инициатор промежуточного события-ссылки",
|
||||||
|
"Loop": "Цикл",
|
||||||
|
"Manual task": "Задача, выполняемая вручную",
|
||||||
|
"Message boundary event": "Граничное событие-сообщение",
|
||||||
|
"Message boundary event (non-interrupting)": "Граничное событие-сообщение (без прерываний)",
|
||||||
|
"Message end event": "Конечное событие-сообщение",
|
||||||
|
"Message intermediate catch event": "Обработчик промежуточного события-сообщения",
|
||||||
|
"Message intermediate throw event": "Инициатор промежуточного события-сообщения",
|
||||||
|
"Message start event": "Начальное событие-сообщение",
|
||||||
|
"Message start event (non-interrupting)": "Начальное событие-сообщение (без прерываний)",
|
||||||
|
"Open {element}": "Открыть {element}",
|
||||||
|
"Parallel gateway": "Шлюз «и»",
|
||||||
|
"Parallel multi-instance": "Параллельное выполнение",
|
||||||
|
"Participant multiplicity": "Множество участников",
|
||||||
|
"Receive task": "Задача получения сообщения",
|
||||||
|
"Remove": "Удалить",
|
||||||
|
"Script task": "Задача-сценарий",
|
||||||
|
"Search in diagram": "Поиск на диаграмме",
|
||||||
|
"Send task": "Задача отправки сообщения",
|
||||||
|
"Sequence flow": "Поток управления",
|
||||||
|
"Sequential multi-instance": "Последовательное выполнение",
|
||||||
|
"Service task": "Задача-сервис",
|
||||||
|
"Signal boundary event": "Граничное событие-сигнал",
|
||||||
|
"Signal boundary event (non-interrupting)": "Граничное событие-сигнал (без прерываний)",
|
||||||
|
"Signal end event": "Конечное событие-сигнал",
|
||||||
|
"Signal intermediate catch event": "Обработчик промежуточного события-сигнала",
|
||||||
|
"Signal intermediate throw event": "Инициатор промежуточного события-сигнала",
|
||||||
|
"Signal start event": "Начальное событие-сигнал",
|
||||||
|
"Signal start event (non-interrupting)": "Начальное событие-сигнал (без прерываний)",
|
||||||
|
"Start event": "Начальное событие",
|
||||||
|
"Sub-process": "Подпроцесс",
|
||||||
|
"Sub-process (collapsed)": "Свернутый подпроцесс",
|
||||||
|
"Sub-process (expanded)": "Развернутый подпроцесс",
|
||||||
|
"Task": "Задача",
|
||||||
|
"Terminate end event": "Конечное событие-остановка",
|
||||||
|
"Timer boundary event": "Граничное событие-таймер",
|
||||||
|
"Timer boundary event (non-interrupting)": "Граничное событие-таймер (без прерываний)",
|
||||||
|
"Timer intermediate catch event": "Обработчик промежуточного события-таймера",
|
||||||
|
"Timer start event": "Начальное событие-таймер",
|
||||||
|
"Timer start event (non-interrupting)": "Начальное событие-таймер (без прерываний)",
|
||||||
|
"Transaction": "Транзакция",
|
||||||
|
"User task": "Задача, выполняемая пользователем",
|
||||||
|
"User Task": "Задача, выполняемая пользователем",
|
||||||
|
"correcting missing bpmnElement on {plane} to {rootElement}": "Исправление отсутствующего bpmn-элемента на {plane} у {rootElement}",
|
||||||
|
"element {element} referenced by {referenced}#{property} not yet drawn": "Элемент {element}, на который ссылается {referenced}#{property}, еще не отрисован",
|
||||||
|
"failed to import {element}": "Не удалось импортировать {element}",
|
||||||
|
"flow elements must be children of pools/participants": "Элементы потока должны быть дочерними элементами пула/участников",
|
||||||
|
"missing {semantic}#attachedToRef": "Отсутствует {semantic}#attachedToRef",
|
||||||
|
"multiple DI elements defined for {element}": "Определено множество DI элементов для {element}",
|
||||||
|
"no bpmnElement referenced in {element}": "нет ни одного bpmn-элемента, ссылающегося на {element}",
|
||||||
|
"no diagram to display": "Нет диаграммы для отображения",
|
||||||
|
"no process or collaboration to display": "Нет процесса или взаимодействия для отображения",
|
||||||
|
|
||||||
|
"Approvement": "Согласование",
|
||||||
|
"Create element": "Создать элемент",
|
||||||
|
"Append element": "Добавить элемент",
|
||||||
|
"Open minimap": "Карта",
|
||||||
|
"Close minimap": "Закрыть",
|
||||||
|
"Tasks": "Задачи",
|
||||||
|
"Sub-processes": "Подпроцессы",
|
||||||
|
"Gateways": "Шлюзы",
|
||||||
|
"Events": "События",
|
||||||
|
"Data": "Данные",
|
||||||
|
"Process": "Процесс",
|
||||||
|
"Function name": "Название функции",
|
||||||
|
"Loading...": "Загрузка..."
|
||||||
|
}
|
||||||
76
src/bpmn/modules/service-desk/PaletteProvider.js
Normal file
76
src/bpmn/modules/service-desk/PaletteProvider.js
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
export default function PaletteProvider(bpmnFactory, create, elementFactory, palette, translate) {
|
||||||
|
this.bpmnFactory = bpmnFactory
|
||||||
|
this.create = create
|
||||||
|
this.elementFactory = elementFactory
|
||||||
|
this.translate = translate
|
||||||
|
|
||||||
|
palette.registerProvider(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
PaletteProvider.$inject = [
|
||||||
|
'bpmnFactory',
|
||||||
|
'create',
|
||||||
|
'elementFactory',
|
||||||
|
'palette',
|
||||||
|
'translate',
|
||||||
|
]
|
||||||
|
|
||||||
|
PaletteProvider.prototype.getPaletteEntries = function () {
|
||||||
|
const {
|
||||||
|
bpmnFactory,
|
||||||
|
create,
|
||||||
|
elementFactory,
|
||||||
|
translate,
|
||||||
|
} = this
|
||||||
|
|
||||||
|
function createApprovementUserTask(event) {
|
||||||
|
const extensionElements = bpmnFactory.create('bpmn:ExtensionElements', {
|
||||||
|
values: [
|
||||||
|
bpmnFactory.create('camunda:Properties', {
|
||||||
|
values: [
|
||||||
|
bpmnFactory.create('camunda:Property', {
|
||||||
|
name: 'tags',
|
||||||
|
value: 'approvement',
|
||||||
|
}),
|
||||||
|
bpmnFactory.create('camunda:Property', {
|
||||||
|
name: 'serviceKey',
|
||||||
|
value: 'sd-adapter',
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
|
const businessObject = bpmnFactory.create('bpmn:UserTask', {
|
||||||
|
name: translate('Approvement'),
|
||||||
|
extensionElements,
|
||||||
|
})
|
||||||
|
|
||||||
|
const shape = elementFactory.createShape({
|
||||||
|
type: 'bpmn:UserTask',
|
||||||
|
businessObject,
|
||||||
|
})
|
||||||
|
|
||||||
|
create.start(event, shape)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
'sd-separator-top': {
|
||||||
|
group: 'sd',
|
||||||
|
separator: true,
|
||||||
|
},
|
||||||
|
'create.approvement': {
|
||||||
|
group: 'sd',
|
||||||
|
className: 'bpmn-icon-user sd-badge',
|
||||||
|
title: translate('Approvement'),
|
||||||
|
action: {
|
||||||
|
dragstart: createApprovementUserTask,
|
||||||
|
click: createApprovementUserTask,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'sd-separator-bottom': {
|
||||||
|
group: 'sd',
|
||||||
|
separator: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
68
src/bpmn/modules/service-desk/PropertiesProvider.js
Normal file
68
src/bpmn/modules/service-desk/PropertiesProvider.js
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import { is } from 'bpmn-js/lib/util/ModelUtil.js'
|
||||||
|
import FunctionSelect from '@/bpmn/modules/service-desk/PropertiesProvider/FunctionSelect.js'
|
||||||
|
import { ensureExtensionProperty } from '@/bpmn/utils/extesion-properties.js'
|
||||||
|
|
||||||
|
export default function PropertiesProvider(propertiesPanel, translate, commandStack, bpmnFactory) {
|
||||||
|
this.translate = translate
|
||||||
|
this.commandStack = commandStack
|
||||||
|
this.bpmnFactory = bpmnFactory
|
||||||
|
|
||||||
|
propertiesPanel.registerProvider(500, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertiesProvider.$inject = [
|
||||||
|
'propertiesPanel',
|
||||||
|
'translate',
|
||||||
|
'commandStack',
|
||||||
|
'bpmnFactory',
|
||||||
|
]
|
||||||
|
|
||||||
|
PropertiesProvider.prototype.getGroups = function (element) {
|
||||||
|
const { translate, commandStack, bpmnFactory } = this
|
||||||
|
|
||||||
|
return (groups) => {
|
||||||
|
if (!is(element, 'bpmn:ScriptTask')) {
|
||||||
|
return groups
|
||||||
|
}
|
||||||
|
|
||||||
|
return groups.map((group) => {
|
||||||
|
if (group.id === 'CamundaPlatform__ExtensionProperties') {
|
||||||
|
const propertyName = 'functionName'
|
||||||
|
const id = `${element.id}-extensionProperty-${propertyName}`
|
||||||
|
|
||||||
|
const property = ensureExtensionProperty(bpmnFactory, commandStack, element, propertyName)
|
||||||
|
|
||||||
|
const groupItem = group.items.find((item) => {
|
||||||
|
return !!item.entries.find(entry => entry.property.name === propertyName)
|
||||||
|
})
|
||||||
|
const entry = {
|
||||||
|
id,
|
||||||
|
component: FunctionSelect,
|
||||||
|
property,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (groupItem) {
|
||||||
|
groupItem.id = id
|
||||||
|
groupItem.label = translate('Function name')
|
||||||
|
groupItem.entries = [entry]
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
group.items.unshift({
|
||||||
|
id,
|
||||||
|
label: translate('Function name'),
|
||||||
|
entries: [
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
component: FunctionSelect,
|
||||||
|
property,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
autoFocusEntry: `${id}-name`,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return group
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
import { SelectEntry } from '@bpmn-io/properties-panel'
|
||||||
|
import { useEffect, useState } from '@bpmn-io/properties-panel/preact/hooks'
|
||||||
|
import { useService } from 'bpmn-js-properties-panel'
|
||||||
|
import { html } from 'htm/preact'
|
||||||
|
|
||||||
|
export default function FunctionSelect(props) {
|
||||||
|
const { element, id, property } = props
|
||||||
|
|
||||||
|
const commandStack = useService('commandStack')
|
||||||
|
const translate = useService('translate')
|
||||||
|
|
||||||
|
const getValue = () => {
|
||||||
|
return property?.value
|
||||||
|
}
|
||||||
|
|
||||||
|
const setValue = (value) => {
|
||||||
|
return commandStack.execute('element.updateModdleProperties', {
|
||||||
|
element,
|
||||||
|
moddleElement: property,
|
||||||
|
properties: {
|
||||||
|
value,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const [functionList, setFunctionList] = useState([])
|
||||||
|
const [fetching, setFetching] = useState(false)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
function fetch() {
|
||||||
|
setFetching(true)
|
||||||
|
new Promise((resolve) => {
|
||||||
|
setTimeout(resolve, 5000)
|
||||||
|
}).then(() => {
|
||||||
|
setFunctionList(Array.from({ length: 10 }, (v, k) => `Function ${k}`))
|
||||||
|
}).finally(() => {
|
||||||
|
setFetching(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch()
|
||||||
|
}, [setFunctionList])
|
||||||
|
|
||||||
|
const getOptions = () => {
|
||||||
|
return functionList.map(functionName => ({
|
||||||
|
label: functionName,
|
||||||
|
value: functionName.toLowerCase().replace(/\s/, '_'),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
return html`<${SelectEntry}
|
||||||
|
id=${id}
|
||||||
|
element=${element}
|
||||||
|
label=${translate('Function name')}
|
||||||
|
description=${fetching ? translate('Loading...') : undefined}
|
||||||
|
disabled=${fetching}
|
||||||
|
getValue=${getValue}
|
||||||
|
setValue=${setValue}
|
||||||
|
getOptions=${getOptions}
|
||||||
|
/>`
|
||||||
|
}
|
||||||
8
src/bpmn/modules/service-desk/index.js
Normal file
8
src/bpmn/modules/service-desk/index.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import Palette from './PaletteProvider.js'
|
||||||
|
import PropertiesProvider from './PropertiesProvider.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
__init__: ['sdPaletteProvider', 'sdPropertiesProvider'],
|
||||||
|
sdPaletteProvider: ['type', Palette],
|
||||||
|
sdPropertiesProvider: ['type', PropertiesProvider],
|
||||||
|
}
|
||||||
2739
src/bpmn/packed-lint-config.js
Normal file
2739
src/bpmn/packed-lint-config.js
Normal file
File diff suppressed because it is too large
Load Diff
68
src/bpmn/utils/extesion-properties.js
Normal file
68
src/bpmn/utils/extesion-properties.js
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
export function ensureExtensionProperty(bpmnFactory, commandStack, element, propertyName) {
|
||||||
|
const commands = []
|
||||||
|
|
||||||
|
const businessObject = element.businessObject
|
||||||
|
|
||||||
|
let extensionElements = businessObject.get('extensionElements')
|
||||||
|
|
||||||
|
if (!extensionElements) {
|
||||||
|
extensionElements = bpmnFactory.create(
|
||||||
|
'bpmn:ExtensionElements',
|
||||||
|
{ values: [] },
|
||||||
|
)
|
||||||
|
extensionElements.parent = businessObject
|
||||||
|
|
||||||
|
commands.push({
|
||||||
|
cmd: 'element.updateModdleProperties',
|
||||||
|
context: {
|
||||||
|
element,
|
||||||
|
moddleElement: businessObject,
|
||||||
|
properties: { extensionElements },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let properties = (extensionElements?.values ?? [])[0]
|
||||||
|
|
||||||
|
if (!properties) {
|
||||||
|
const parent = extensionElements
|
||||||
|
|
||||||
|
properties = bpmnFactory.create('camunda:Properties', {
|
||||||
|
values: [],
|
||||||
|
})
|
||||||
|
properties.parent = parent
|
||||||
|
|
||||||
|
commands.push({
|
||||||
|
cmd: 'element.updateModdleProperties',
|
||||||
|
context: {
|
||||||
|
element,
|
||||||
|
moddleElement: extensionElements,
|
||||||
|
properties: {
|
||||||
|
values: [...extensionElements.get('values'), properties],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let property = properties?.values?.find(property => property.name === propertyName)
|
||||||
|
|
||||||
|
if (!property) {
|
||||||
|
property = bpmnFactory.create('camunda:Property', { name: propertyName })
|
||||||
|
property.parent = properties
|
||||||
|
|
||||||
|
commands.push({
|
||||||
|
cmd: 'element.updateModdleProperties',
|
||||||
|
context: {
|
||||||
|
element,
|
||||||
|
moddleElement: properties,
|
||||||
|
properties: {
|
||||||
|
values: [...properties.get('values'), property],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
commandStack.execute('properties-panel.multi-command-executor', commands)
|
||||||
|
|
||||||
|
return property
|
||||||
|
}
|
||||||
125
src/components/BpmnModeler.vue
Normal file
125
src/components/BpmnModeler.vue
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
<template>
|
||||||
|
<div class="bpmn-modeler">
|
||||||
|
<div ref="container" class="bpmn-modeler__viewer" />
|
||||||
|
<div ref="properties-panel" class="bpmn-modeler__properties-panel" />
|
||||||
|
|
||||||
|
<div class="bpmn-modeler__toolbar">
|
||||||
|
<button @click="openXmlDialog">
|
||||||
|
XML
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<dialog ref="xmlDialog" class="bpmn-modeler__xml-dialog">
|
||||||
|
<pre>{{ currentXml }}</pre>
|
||||||
|
</dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import LintModule from 'bpmn-js-bpmnlint'
|
||||||
|
import BpmnModeler from 'camunda-bpmn-js/lib/camunda-platform/Modeler'
|
||||||
|
import { ref, shallowRef, useTemplateRef, watchEffect } from 'vue'
|
||||||
|
import I18nModule from '@/bpmn/modules/i18n'
|
||||||
|
import SdElementsModule from '@/bpmn/modules/service-desk'
|
||||||
|
import bpmnlintConfig from '@/bpmn/packed-lint-config'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
diagramXml: string
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const containerRef = useTemplateRef('container')
|
||||||
|
const propertiesPanelRef = useTemplateRef('properties-panel')
|
||||||
|
const xmlDialogRef = useTemplateRef('xmlDialog')
|
||||||
|
|
||||||
|
const modeler = shallowRef<BpmnModeler>()
|
||||||
|
|
||||||
|
const currentXml = ref(props.diagramXml)
|
||||||
|
|
||||||
|
watchEffect(() => {
|
||||||
|
if (modeler.value) {
|
||||||
|
modeler.value.destroy()
|
||||||
|
modeler.value = undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!containerRef.value || !propertiesPanelRef.value)
|
||||||
|
return
|
||||||
|
|
||||||
|
modeler.value = new BpmnModeler({
|
||||||
|
container: containerRef.value,
|
||||||
|
propertiesPanel: {
|
||||||
|
parent: propertiesPanelRef.value,
|
||||||
|
},
|
||||||
|
additionalModules: [
|
||||||
|
SdElementsModule,
|
||||||
|
I18nModule,
|
||||||
|
LintModule,
|
||||||
|
],
|
||||||
|
linting: {
|
||||||
|
bpmnlint: bpmnlintConfig,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
modeler.value.importXML(props.diagramXml)
|
||||||
|
})
|
||||||
|
|
||||||
|
async function openXmlDialog() {
|
||||||
|
try {
|
||||||
|
const { xml } = await modeler.value?.saveXML({ format: true })
|
||||||
|
currentXml.value = xml
|
||||||
|
|
||||||
|
xmlDialogRef.value?.showModal()
|
||||||
|
}
|
||||||
|
catch {}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.bpmn-modeler {
|
||||||
|
height: 100%;
|
||||||
|
flex: 1;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 350px;
|
||||||
|
grid-template-rows: 1fr 30px;
|
||||||
|
grid-template-areas: 'viewer properties' 'toolbar toolbar';
|
||||||
|
|
||||||
|
&__viewer {
|
||||||
|
grid-area: viewer;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__properties-panel {
|
||||||
|
overflow-x: auto;
|
||||||
|
grid-area: properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__toolbar {
|
||||||
|
grid-area: toolbar;
|
||||||
|
background-color: lightgray;
|
||||||
|
|
||||||
|
> button {
|
||||||
|
height: 100%;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__xml-dialog {
|
||||||
|
width: 80%;
|
||||||
|
max-height: 80%;
|
||||||
|
outline: none;
|
||||||
|
|
||||||
|
&::backdrop {
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
11
src/main.ts
Normal file
11
src/main.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { createApp } from 'vue'
|
||||||
|
import App from './App.vue'
|
||||||
|
|
||||||
|
// import 'bpmn-js/dist/assets/diagram-js.css';
|
||||||
|
// import 'bpmn-js/dist/assets/bpmn-js.css';
|
||||||
|
// import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css';
|
||||||
|
import 'bpmn-js-bpmnlint/dist/assets/css/bpmn-js-bpmnlint.css'
|
||||||
|
import 'camunda-bpmn-js/dist/assets/camunda-platform-modeler.css'
|
||||||
|
import './style.css'
|
||||||
|
|
||||||
|
createApp(App).mount('#app')
|
||||||
65
src/style.css
Normal file
65
src/style.css
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
:root {
|
||||||
|
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||||
|
line-height: 1.5;
|
||||||
|
font-weight: 400;
|
||||||
|
|
||||||
|
font-synthesis: none;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-weight: 500;
|
||||||
|
color: #646cff;
|
||||||
|
text-decoration: inherit;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: #535bf2;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 3.2em;
|
||||||
|
line-height: 1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry.sd-badge {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: 'SD';
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 700;
|
||||||
|
border-radius: 9999px;
|
||||||
|
padding: 0 3px;
|
||||||
|
line-height: 14px;
|
||||||
|
background-color: #ff0032;
|
||||||
|
color: white;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bjs-powered-by {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
1
src/vite-env.d.ts
vendored
Normal file
1
src/vite-env.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/// <reference types="vite/client" />
|
||||||
15
tsconfig.app.json
Normal file
15
tsconfig.app.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"extends": "@vue/tsconfig/tsconfig.dom.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||||
|
|
||||||
|
/* Linting */
|
||||||
|
"strict": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"erasableSyntaxOnly": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"noUncheckedSideEffectImports": true
|
||||||
|
},
|
||||||
|
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
|
||||||
|
}
|
||||||
7
tsconfig.json
Normal file
7
tsconfig.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"files": [],
|
||||||
|
"references": [
|
||||||
|
{ "path": "./tsconfig.app.json" },
|
||||||
|
{ "path": "./tsconfig.node.json" }
|
||||||
|
]
|
||||||
|
}
|
||||||
25
tsconfig.node.json
Normal file
25
tsconfig.node.json
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
||||||
|
"target": "ES2023",
|
||||||
|
"lib": ["ES2023"],
|
||||||
|
"module": "ESNext",
|
||||||
|
"skipLibCheck": true,
|
||||||
|
|
||||||
|
/* Bundler mode */
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"verbatimModuleSyntax": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"noEmit": true,
|
||||||
|
|
||||||
|
/* Linting */
|
||||||
|
"strict": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"erasableSyntaxOnly": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"noUncheckedSideEffectImports": true
|
||||||
|
},
|
||||||
|
"include": ["vite.config.ts"]
|
||||||
|
}
|
||||||
21
vite.config.ts
Normal file
21
vite.config.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import * as fs from 'node:fs'
|
||||||
|
import { resolve } from 'node:path'
|
||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
import { defineConfig } from 'vite'
|
||||||
|
|
||||||
|
// https://vite.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [vue()],
|
||||||
|
server: {
|
||||||
|
https: {
|
||||||
|
cert: fs.readFileSync('/Users/nvkrug/Work/localhost.pem'),
|
||||||
|
key: fs.readFileSync('/Users/nvkrug/Work/localhost-key.pem'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
alias: [
|
||||||
|
{ find: '@', replacement: resolve(__dirname, './src') },
|
||||||
|
{ find: '@mts-icons', replacement: resolve(__dirname, './node_modules/@mts-ds/icons/web2') },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})
|
||||||
Loading…
x
Reference in New Issue
Block a user