workflow-bpmn-modeler-andtv-vue3 10.1.1 → 10.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/fonts/bpmn.5d33bee4.eot +0 -0
  2. package/dist/fonts/bpmn.67058807.woff2 +0 -0
  3. package/dist/fonts/bpmn.b5c9250d.ttf +0 -0
  4. package/dist/fonts/bpmn.e9e7d076.woff +0 -0
  5. package/dist/img/bpmn.74eea12b.svg +224 -0
  6. package/dist/workflow-bpmn-modeler-andtv-vue3.common.js +199 -5
  7. package/dist/workflow-bpmn-modeler-andtv-vue3.umd.js +199 -5
  8. package/dist/workflow-bpmn-modeler-andtv-vue3.umd.min.js +199 -5
  9. package/package/CHANGELOG.md +6 -0
  10. package/package/LICENSE +21 -0
  11. package/package/README.md +208 -0
  12. package/package/components/nodePanel/process.vue +9 -2
  13. package/package/components/nodePanel/startEnd.vue +6 -2
  14. package/package/dist/demo.html +9 -0
  15. package/package/dist/fonts/bpmn.5d33bee4.eot +0 -0
  16. package/package/dist/fonts/bpmn.67058807.woff2 +0 -0
  17. package/package/dist/fonts/bpmn.b5c9250d.ttf +0 -0
  18. package/package/dist/fonts/bpmn.e9e7d076.woff +0 -0
  19. package/package/dist/img/bpmn.74eea12b.svg +224 -0
  20. package/package/dist/workflow-bpmn-modeler-andtv-vue3.common.js +5617 -0
  21. package/package/dist/workflow-bpmn-modeler-andtv-vue3.umd.js +5617 -0
  22. package/package/dist/workflow-bpmn-modeler-andtv-vue3.umd.min.js +5617 -0
  23. package/package/index.vue +91 -427
  24. package/package/package/BpmData.js +68 -0
  25. package/package/package/PropertyPanel.vue +342 -0
  26. package/package/package/common/customTranslate.js +20 -0
  27. package/package/package/common/mixinExecutionListener.js +24 -0
  28. package/package/package/common/mixinPanel.js +70 -0
  29. package/package/package/common/mixinXcrud.js +22 -0
  30. package/package/package/common/parseElement.js +53 -0
  31. package/package/package/components/custom/customContextPad.vue +24 -0
  32. package/package/package/components/nodePanel/gateway.vue +165 -0
  33. package/package/package/components/nodePanel/process.vue +201 -0
  34. package/package/package/components/nodePanel/property/executionListener.vue +240 -0
  35. package/package/package/components/nodePanel/property/listenerParam.vue +137 -0
  36. package/package/package/components/nodePanel/property/multiInstance.vue +177 -0
  37. package/package/package/components/nodePanel/property/signal.vue +178 -0
  38. package/package/package/components/nodePanel/property/taskListener.vue +242 -0
  39. package/package/package/components/nodePanel/sequenceFlow.vue +180 -0
  40. package/package/package/components/nodePanel/startEnd.vue +174 -0
  41. package/package/package/components/nodePanel/task.vue +452 -0
  42. package/package/package/flowable/flowable.json +1218 -0
  43. package/package/package/flowable/init.js +24 -0
  44. package/package/package/flowable/showConfig.js +51 -0
  45. package/package/package/index.js +9 -0
  46. package/package/package/index.ts +10 -0
  47. package/package/package/index.vue +730 -0
  48. package/package/package/lang/zh.js +227 -0
  49. package/package/package/types/components.d.ts +35 -0
  50. package/package/package.json +89 -0
  51. package/package.json +12 -13
  52. package/package/bpmn-styles.css +0 -40
@@ -0,0 +1,342 @@
1
+ <template>
2
+ <div ref="propertyPanel" class="property-panel">
3
+ <div v-if="nodeName" class="node-name">{{ nodeName }}</div>
4
+ <div class="property-content">
5
+ <component
6
+ :is="getComponent"
7
+ v-if="element && getComponent"
8
+ :element="element"
9
+ :modeler="modeler"
10
+ :users="users"
11
+ :groups="groups"
12
+ :categorys="categorys"
13
+ />
14
+ </div>
15
+ </div>
16
+ </template>
17
+
18
+ <script setup lang="ts">
19
+ import { ref, computed, onMounted, nextTick } from 'vue'
20
+
21
+ defineOptions({
22
+ name: 'PropertyPanel'
23
+ })
24
+ import taskPanel from './components/nodePanel/task.vue'
25
+ import startEndPanel from './components/nodePanel/startEnd.vue'
26
+ import processPanel from './components/nodePanel/process.vue'
27
+ import sequenceFlowPanel from './components/nodePanel/sequenceFlow.vue'
28
+ import gatewayPanel from './components/nodePanel/gateway.vue'
29
+ import { NodeName } from './lang/zh'
30
+ import Modeler from 'bpmn-js/lib/Modeler'
31
+
32
+ interface User {
33
+ name: string
34
+ id: string
35
+ }
36
+
37
+ interface Group {
38
+ name: string
39
+ id: string
40
+ }
41
+
42
+ interface Category {
43
+ name: string
44
+ id: string
45
+ }
46
+
47
+ interface Props {
48
+ users: User[]
49
+ groups: Group[]
50
+ categorys: Category[]
51
+ modeler: Modeler
52
+ }
53
+
54
+ const props = defineProps<Props>()
55
+ const propertyPanel = ref<HTMLElement | null>(null)
56
+ const element = ref<any>(null)
57
+ const form = ref({
58
+ id: '',
59
+ name: '',
60
+ color: null as string | null
61
+ })
62
+ const roles = ref([
63
+ { value: 'manager', label: '经理' },
64
+ { value: 'personnel', label: '人事' },
65
+ { value: 'charge', label: '主管' }
66
+ ])
67
+ const getComponent = computed(() => {
68
+ if (!element.value) return null
69
+
70
+ const bizObj = element.value.businessObject
71
+ const type = bizObj.eventDefinitions
72
+ ? bizObj.eventDefinitions[0].$type
73
+ : bizObj.$type
74
+
75
+
76
+ // 根据元素类型返回对应的组件
77
+ switch (type) {
78
+ case 'bpmn:UserTask':
79
+ case 'bpmn:ServiceTask':
80
+ case 'bpmn:ScriptTask':
81
+ case 'bpmn:BusinessRuleTask':
82
+ case 'bpmn:ManualTask':
83
+ case 'bpmn:ReceiveTask':
84
+ case 'bpmn:SendTask':
85
+ return taskPanel
86
+ case 'bpmn:StartEvent':
87
+ case 'bpmn:EndEvent':
88
+ case 'bpmn:IntermediateThrowEvent':
89
+ case 'bpmn:IntermediateCatchEvent':
90
+ case 'bpmn:BoundaryEvent':
91
+ return startEndPanel
92
+ case 'bpmn:Process':
93
+ return processPanel
94
+ case 'bpmn:SequenceFlow':
95
+ return sequenceFlowPanel
96
+ case 'bpmn:ExclusiveGateway':
97
+ case 'bpmn:InclusiveGateway':
98
+ case 'bpmn:ParallelGateway':
99
+ case 'bpmn:EventBasedGateway':
100
+ return gatewayPanel
101
+ default:
102
+ return null
103
+ }
104
+ })
105
+
106
+ const nodeName = computed(() => {
107
+ if (element.value) {
108
+ const bizObj = element.value.businessObject
109
+ const type = bizObj?.eventDefinitions
110
+ ? bizObj.eventDefinitions[0].$type
111
+ : bizObj.$type
112
+ return (NodeName as any)[type] || type
113
+ }
114
+ return ''
115
+ })
116
+
117
+ const handleModeler = (): void => {
118
+ props.modeler.on('root.added', (e: any) => {
119
+ if (e.element.type === 'bpmn:Process') {
120
+ element.value = null
121
+ nextTick().then(() => {
122
+ element.value = e.element
123
+ })
124
+ }
125
+ })
126
+ props.modeler.on('element.click', (e: any) => {
127
+ const { element: clickedElement } = e
128
+ // 允许所有类型的元素显示在属性面板中
129
+ element.value = clickedElement
130
+ })
131
+ props.modeler.on('selection.changed', (e: any) => {
132
+ // hack 同类型面板不刷新
133
+ element.value = null
134
+ const selectedElement = e.newSelection[0]
135
+ if (selectedElement) {
136
+ nextTick().then(() => {
137
+ element.value = selectedElement
138
+ })
139
+ }
140
+ })
141
+ }
142
+
143
+ onMounted(() => {
144
+ handleModeler()
145
+ })
146
+
147
+ </script>
148
+
149
+ <style lang="scss">
150
+ .property-panel {
151
+ height: 100%;
152
+ display: flex;
153
+ flex-direction: column;
154
+ background: white;
155
+
156
+ .node-name {
157
+ background: #f8f9fa;
158
+ color: #495057;
159
+ padding: 16px 20px;
160
+ margin-top: -16px;
161
+ font-size: 16px;
162
+ font-weight: 600;
163
+ text-align: center;
164
+ border-bottom: 1px solid #e9ecef;
165
+ flex-shrink: 0;
166
+ }
167
+
168
+ .property-content {
169
+ flex: 1;
170
+ overflow-y: auto;
171
+ overflow-x: hidden;
172
+ padding: 20px;
173
+
174
+ // 自定义滚动条
175
+ &::-webkit-scrollbar {
176
+ width: 6px;
177
+ }
178
+
179
+ &::-webkit-scrollbar-track {
180
+ background: #f1f1f1;
181
+ border-radius: 3px;
182
+ }
183
+
184
+ &::-webkit-scrollbar-thumb {
185
+ background: #c1c1c1;
186
+ border-radius: 3px;
187
+
188
+ &:hover {
189
+ background: #a8a8a8;
190
+ }
191
+ }
192
+ }
193
+
194
+ // 重置 Ant Design 样式
195
+ :deep(.ant-form-vertical .ant-form-item-label) {
196
+ padding: 0;
197
+ font-weight: 500;
198
+ color: #262626;
199
+ width: 100px;
200
+ flex-shrink: 0;
201
+ }
202
+
203
+ :deep(.ant-form-item) {
204
+ margin-bottom: 16px;
205
+ display: flex;
206
+ align-items: center;
207
+ }
208
+
209
+ :deep(.ant-form-item-label > label) {
210
+ font-size: 14px;
211
+ color: #595959;
212
+ margin-right: 12px;
213
+ white-space: nowrap;
214
+ }
215
+
216
+ :deep(.ant-form-item-control) {
217
+ flex: 1;
218
+ }
219
+
220
+ :deep(.ant-input),
221
+ :deep(.ant-select),
222
+ :deep(.ant-textarea) {
223
+ border-radius: 6px;
224
+ border-color: #d9d9d9;
225
+ transition: all 0.3s;
226
+
227
+ &:hover {
228
+ border-color: #40a9ff;
229
+ }
230
+
231
+ &:focus,
232
+ &.ant-input-focused,
233
+ &.ant-select-focused {
234
+ border-color: #1890ff;
235
+ box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
236
+ }
237
+ }
238
+
239
+ :deep(.ant-button) {
240
+ border-radius: 6px;
241
+ font-weight: 500;
242
+ transition: all 0.3s;
243
+
244
+ &.ant-btn-primary {
245
+ background: #1890ff;
246
+ border-color: #1890ff;
247
+
248
+ &:hover {
249
+ background: #40a9ff;
250
+ border-color: #40a9ff;
251
+ transform: translateY(-1px);
252
+ box-shadow: 0 2px 8px rgba(24, 144, 255, 0.3);
253
+ }
254
+ }
255
+
256
+ &.ant-btn-default {
257
+ background: #ffffff;
258
+ border-color: #d9d9d9;
259
+ color: #595959;
260
+
261
+ &:hover {
262
+ border-color: #40a9ff;
263
+ color: #40a9ff;
264
+ transform: translateY(-1px);
265
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
266
+ }
267
+ }
268
+ }
269
+
270
+ :deep(.ant-badge) {
271
+ font-size: 12px;
272
+
273
+ .ant-badge-count {
274
+ background: #ff4d4f;
275
+ border-radius: 10px;
276
+ font-weight: 500;
277
+ }
278
+ }
279
+
280
+ :deep(.ant-switch) {
281
+ background-color: #d9d9d9;
282
+ transition: all 0.3s;
283
+
284
+ &.ant-switch-checked {
285
+ background: linear-gradient(135deg, #52c41a 0%, #73d13d 100%);
286
+ }
287
+ }
288
+
289
+ :deep(.ant-select-multiple .ant-select-selection-item) {
290
+ background: linear-gradient(135deg, #e6f7ff 0%, #bae7ff 100%);
291
+ border: 1px solid #91d5ff;
292
+ border-radius: 4px;
293
+ }
294
+
295
+ :deep(.ant-tabs) {
296
+ .ant-tabs-tab {
297
+ font-weight: 500;
298
+
299
+ &.ant-tabs-tab-active {
300
+ color: #1890ff;
301
+ }
302
+ }
303
+
304
+ .ant-tabs-ink-bar {
305
+ background: linear-gradient(135deg, #1890ff 0%, #40a9ff 100%);
306
+ }
307
+ }
308
+
309
+ :deep(.ant-table) {
310
+ .ant-table-thead > tr > th {
311
+ background: #fafafa;
312
+ font-weight: 600;
313
+ color: #262626;
314
+ }
315
+
316
+ .ant-table-tbody > tr:hover > td {
317
+ background: #f0f9ff;
318
+ }
319
+ }
320
+
321
+ :deep(.ant-modal) {
322
+ .ant-modal-header {
323
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
324
+ border-bottom: none;
325
+
326
+ .ant-modal-title {
327
+ color: white;
328
+ font-weight: 600;
329
+ }
330
+ }
331
+
332
+ .ant-modal-close {
333
+ color: white;
334
+
335
+ &:hover {
336
+ color: rgba(255, 255, 255, 0.8);
337
+ }
338
+ }
339
+ }
340
+ }
341
+ </style>
342
+
@@ -0,0 +1,20 @@
1
+ import translations from '../lang/zh'
2
+
3
+ export default function customTranslate(template, replacements) {
4
+ replacements = replacements || {}
5
+
6
+ // Translate
7
+ template = translations[template] || template
8
+
9
+ // Replace
10
+ return template.replace(/{([^}]+)}/g, function(_, key) {
11
+ var str = replacements[key]
12
+ if (
13
+ translations[replacements[key]] !== null &&
14
+ translations[replacements[key]] !== 'undefined'
15
+ ) {
16
+ str = translations[replacements[key]]
17
+ }
18
+ return str || '{' + key + '}'
19
+ })
20
+ }
@@ -0,0 +1,24 @@
1
+
2
+ import executionListenerDialog from '../components/nodePanel/property/executionListener'
3
+ export default {
4
+ components: {
5
+ executionListenerDialog
6
+ },
7
+ data() {
8
+ return {
9
+ executionListenerLength: 0,
10
+ dialogName: null
11
+ }
12
+ },
13
+ methods: {
14
+ computedExecutionListenerLength() {
15
+ this.executionListenerLength = this.element.businessObject.extensionElements?.values?.length ?? 0
16
+ },
17
+ finishExecutionListener() {
18
+ if (this.dialogName === 'executionListenerDialog') {
19
+ this.computedExecutionListenerLength()
20
+ }
21
+ this.dialogName = ''
22
+ }
23
+ }
24
+ }
@@ -0,0 +1,70 @@
1
+ import xcrud from 'xcrud'
2
+ import golbalConfig from 'xcrud/package/common/config'
3
+ import showConfig from '../flowable/showConfig'
4
+ golbalConfig.set({
5
+ input: {
6
+ // size: 'mini'
7
+ },
8
+ select: {
9
+ // size: 'mini'
10
+ },
11
+ colorPicker: {
12
+ showAlpha: true
13
+ },
14
+ xform: {
15
+ form: {
16
+ labelWidth: 'auto'
17
+ // size: 'mini'
18
+ }
19
+ }
20
+ })
21
+ export default {
22
+ components: { xForm: xcrud.xForm },
23
+ props: {
24
+ modeler: {
25
+ type: Object,
26
+ required: true
27
+ },
28
+ element: {
29
+ type: Object,
30
+ required: true
31
+ },
32
+ categorys: {
33
+ type: Array,
34
+ default: () => []
35
+ }
36
+ },
37
+ watch: {
38
+ 'formData.id': function(val) {
39
+ this.updateProperties({ id: val })
40
+ },
41
+ 'formData.name': function(val) {
42
+ this.updateProperties({ name: val })
43
+ },
44
+ 'formData.documentation': function(val) {
45
+ if (!val) {
46
+ this.updateProperties({ documentation: [] })
47
+ return
48
+ }
49
+ const documentationElement = this.modeler.get('moddle').create('bpmn:Documentation', { text: val })
50
+ this.updateProperties({ documentation: [documentationElement] })
51
+ }
52
+ },
53
+ methods: {
54
+ updateProperties(properties) {
55
+ const modeling = this.modeler.get('modeling')
56
+ modeling.updateProperties(this.element, properties)
57
+ }
58
+ },
59
+ computed: {
60
+ elementType() {
61
+ const bizObj = this.element.businessObject
62
+ return bizObj.eventDefinitions
63
+ ? bizObj.eventDefinitions[0].$type
64
+ : bizObj.$type
65
+ },
66
+ showConfig() {
67
+ return showConfig[this.elementType] || {}
68
+ }
69
+ }
70
+ }
@@ -0,0 +1,22 @@
1
+ import xcrud from 'xcrud'
2
+ import golbalConfig from 'xcrud/package/common/config'
3
+ golbalConfig.set({
4
+ input: {
5
+ // size: 'mini'
6
+ },
7
+ select: {
8
+ // size: 'mini'
9
+ },
10
+ colorPicker: {
11
+ showAlpha: true
12
+ },
13
+ xform: {
14
+ form: {
15
+ labelWidth: 'auto'
16
+ // size: 'mini'
17
+ }
18
+ }
19
+ })
20
+ export default {
21
+ components: { xForm: xcrud.xForm }
22
+ }
@@ -0,0 +1,53 @@
1
+ export function commonParse(element) {
2
+ const result = {
3
+ ...element.businessObject,
4
+ ...element.businessObject.$attrs
5
+ }
6
+ return formatJsonKeyValue(result)
7
+ }
8
+
9
+ export function formatJsonKeyValue(result) {
10
+ // 移除flowable前缀,格式化数组
11
+ for (const key in result) {
12
+ if (key.indexOf('flowable:') === 0) {
13
+ const newKey = key.replace('flowable:', '')
14
+ result[newKey] = result[key]
15
+ delete result[key]
16
+ }
17
+ }
18
+ result = documentationParse(result)
19
+ return result
20
+ }
21
+
22
+ export function documentationParse(obj) {
23
+ if ('documentation' in obj) {
24
+ let str = ''
25
+ obj.documentation.forEach(item => {
26
+ str += item.text
27
+ })
28
+ obj.documentation = str
29
+ }
30
+ return obj
31
+ }
32
+
33
+ export function conditionExpressionParse(obj) {
34
+ if ('conditionExpression' in obj) {
35
+ obj.conditionExpression = obj.conditionExpression.body
36
+ }
37
+ return obj
38
+ }
39
+
40
+ export function userTaskParse(obj) {
41
+ for (const key in obj) {
42
+ if (key === 'candidateUsers') {
43
+ obj.userType = 'candidateUsers'
44
+ obj[key] = obj[key]?.split(',') || []
45
+ } else if (key === 'candidateGroups') {
46
+ obj.userType = 'candidateGroups'
47
+ obj[key] = obj[key]?.split(',') || []
48
+ } else if (key === 'assignee') {
49
+ obj.userType = 'assignee'
50
+ }
51
+ }
52
+ return obj
53
+ }
@@ -0,0 +1,24 @@
1
+ export default class CustomContextPad {
2
+ constructor(config, contextPad, create, elementFactory, injector, translate) {
3
+ this.create = create;
4
+ this.elementFactory = elementFactory;
5
+ this.translate = translate;
6
+
7
+ if (config.autoPlace !== false) {
8
+ this.autoPlace = injector.get('autoPlace', false);
9
+ }
10
+
11
+ contextPad.registerProvider(this); // 定义这是一个contextPad
12
+ }
13
+
14
+ getContextPadEntries(element) {}
15
+ }
16
+
17
+ CustomContextPad.$inject = [
18
+ 'config',
19
+ 'contextPad',
20
+ 'create',
21
+ 'elementFactory',
22
+ 'injector',
23
+ 'translate'
24
+ ];