@reskin/bpmn 0.0.6 → 0.1.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.
@@ -1,18 +1,140 @@
1
1
  import * as i0 from '@angular/core';
2
- import { EventEmitter, Component, Input, Output, ViewChild, NgModule } from '@angular/core';
2
+ import { Directive, ViewChild, EventEmitter, Component, Input, Output, NgModule } from '@angular/core';
3
3
  import * as i2 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import Viewer from 'bpmn-js/lib/Viewer';
6
- import minimapModule from 'diagram-js-minimap';
7
- import { from } from 'rxjs';
8
- import ZoomScrollModule from 'diagram-js/lib/navigation/zoomscroll';
9
6
  import MoveCanvasModule from 'diagram-js/lib/navigation/movecanvas';
7
+ import ZoomScrollModule from 'diagram-js/lib/navigation/zoomscroll';
8
+ import minimapModule from 'diagram-js-minimap';
10
9
  import ModelingModule from 'bpmn-js/lib/features/modeling';
11
- import BpmnJS from 'bpmn-js/lib/Modeler';
10
+ import { Subject, from } from 'rxjs';
11
+ import { takeUntil } from 'rxjs/operators';
12
+ import { __awaiter } from 'tslib';
13
+ import BpmnModeler from 'bpmn-js/lib/Modeler';
12
14
  import gridModule from 'diagram-js-grid';
13
15
  import * as i1 from '@reskin/core/directives';
14
16
  import { RkDirectivesModule } from '@reskin/core/directives';
15
17
 
18
+ /**
19
+ * BPMN 组件抽象基类
20
+ * 提供通用的缩放、重置等功能
21
+ */
22
+ class RkBpmnBaseComponent {
23
+ constructor() {
24
+ /** 当前缩放比例 */
25
+ this.currentScale = 1;
26
+ /** 缩放配置 */
27
+ this.zoomConfig = {
28
+ scale: 0.1,
29
+ minScale: 0.2,
30
+ maxScale: 4,
31
+ };
32
+ /** 组件销毁信号 */
33
+ this.destroy$ = new Subject();
34
+ /** 是否已初始化 */
35
+ this.initialized = false;
36
+ }
37
+ ngOnDestroy() {
38
+ var _a;
39
+ this.destroy$.next();
40
+ this.destroy$.complete();
41
+ (_a = this.viewer) === null || _a === void 0 ? void 0 : _a.destroy();
42
+ }
43
+ /**
44
+ * 获取 Canvas 实例
45
+ */
46
+ getCanvas() {
47
+ var _a;
48
+ return (_a = this.viewer) === null || _a === void 0 ? void 0 : _a.get('canvas');
49
+ }
50
+ /**
51
+ * 放大画布
52
+ */
53
+ zoomIn() {
54
+ var _a;
55
+ if (!this.viewer) {
56
+ return;
57
+ }
58
+ const newScale = this.currentScale + this.zoomConfig.scale;
59
+ if (newScale <= this.zoomConfig.maxScale) {
60
+ this.currentScale = newScale;
61
+ (_a = this.getCanvas()) === null || _a === void 0 ? void 0 : _a.zoom(this.currentScale);
62
+ }
63
+ }
64
+ /**
65
+ * 缩小画布
66
+ */
67
+ zoomOut() {
68
+ var _a;
69
+ if (!this.viewer) {
70
+ return;
71
+ }
72
+ const newScale = this.currentScale - this.zoomConfig.scale;
73
+ if (newScale >= this.zoomConfig.minScale) {
74
+ this.currentScale = newScale;
75
+ (_a = this.getCanvas()) === null || _a === void 0 ? void 0 : _a.zoom(this.currentScale);
76
+ }
77
+ }
78
+ /**
79
+ * 重置画布位置和缩放
80
+ */
81
+ zoomReset() {
82
+ var _a;
83
+ if (!this.viewer) {
84
+ return;
85
+ }
86
+ this.currentScale = 1;
87
+ (_a = this.getCanvas()) === null || _a === void 0 ? void 0 : _a.zoom('fit-viewport', { x: 0, y: 0 });
88
+ }
89
+ /**
90
+ * 设置缩放比例
91
+ * @param scale 缩放比例
92
+ */
93
+ setZoom(scale) {
94
+ var _a;
95
+ if (!this.viewer) {
96
+ return;
97
+ }
98
+ const clampedScale = Math.max(this.zoomConfig.minScale, Math.min(this.zoomConfig.maxScale, scale));
99
+ this.currentScale = clampedScale;
100
+ (_a = this.getCanvas()) === null || _a === void 0 ? void 0 : _a.zoom(clampedScale);
101
+ }
102
+ /**
103
+ * 获取当前缩放比例
104
+ */
105
+ getZoom() {
106
+ return this.currentScale;
107
+ }
108
+ /**
109
+ * 注册导入完成事件
110
+ * 导入完成后自动居中显示
111
+ */
112
+ registerImportDoneEvent() {
113
+ var _a;
114
+ (_a = this.viewer) === null || _a === void 0 ? void 0 : _a.on('import.done', ({ error }) => {
115
+ if (!error) {
116
+ this.zoomReset();
117
+ }
118
+ });
119
+ }
120
+ /**
121
+ * 检查容器是否已准备好
122
+ */
123
+ isContainerReady() {
124
+ var _a;
125
+ const rect = (_a = this.containerRef) === null || _a === void 0 ? void 0 : _a.nativeElement.getBoundingClientRect();
126
+ return !!(rect && rect.width > 0 && rect.height > 0);
127
+ }
128
+ }
129
+ RkBpmnBaseComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: RkBpmnBaseComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
130
+ RkBpmnBaseComponent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.2.17", type: RkBpmnBaseComponent, viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["container"], descendants: true }], ngImport: i0 });
131
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: RkBpmnBaseComponent, decorators: [{
132
+ type: Directive
133
+ }], propDecorators: { containerRef: [{
134
+ type: ViewChild,
135
+ args: ['container', { static: false }]
136
+ }] } });
137
+
16
138
  /**
17
139
  * 写英文对应的中文内容
18
140
  */
@@ -276,411 +398,421 @@ function customTranslate(template, replacements) {
276
398
  }
277
399
 
278
400
  /**
279
- * 默认值
401
+ * 生成唯一 ID
402
+ * @returns 随机字符串
403
+ */
404
+ function generateUid() {
405
+ return Math.random().toString(36).substring(2, 11);
406
+ }
407
+ /**
408
+ * 下载文件
409
+ * @param content 文件内容或 Blob URL
410
+ * @param filename 文件名
280
411
  */
281
- const defaultBpmnData = `
282
- <?xml version="1.0" encoding="UTF-8"?>
283
- <bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
284
- <bpmn:process id="Process_${uid()}" isExecutable="false" />
285
- <bpmndi:BPMNDiagram id="BPMNDiagram_${uid()}">
286
- <bpmndi:BPMNPlane id="BPMNPlane_${uid()}" bpmnElement="Process_${uid()}" />
412
+ function downloadFile(content, filename) {
413
+ let url;
414
+ if (content instanceof Blob) {
415
+ url = URL.createObjectURL(content);
416
+ }
417
+ else if (content.startsWith('blob:')) {
418
+ url = content;
419
+ }
420
+ else {
421
+ // 处理 XML 字符串
422
+ const encodedData = encodeURIComponent(content);
423
+ url = `data:application/bpmn20-xml;charset=UTF-8,${encodedData}`;
424
+ }
425
+ const link = document.createElement('a');
426
+ link.style.display = 'none';
427
+ link.href = url;
428
+ link.download = filename;
429
+ document.body.appendChild(link);
430
+ link.click();
431
+ document.body.removeChild(link);
432
+ // 清理 Blob URL
433
+ if (content instanceof Blob) {
434
+ setTimeout(() => URL.revokeObjectURL(url), 100);
435
+ }
436
+ }
437
+ /**
438
+ * 读取文件内容
439
+ * @param file 文件对象
440
+ * @returns Promise<string>
441
+ */
442
+ function readFileAsText(file) {
443
+ return new Promise((resolve, reject) => {
444
+ const reader = new FileReader();
445
+ reader.onload = () => resolve(reader.result);
446
+ reader.onerror = () => reject(reader.error);
447
+ reader.readAsText(file, 'utf-8');
448
+ });
449
+ }
450
+
451
+ /**
452
+ * 生成默认 BPMN XML 数据
453
+ * @returns 默认的 BPMN XML 字符串
454
+ */
455
+ function getDefaultBpmnXML() {
456
+ const processId = `Process_${generateUid()}`;
457
+ const diagramId = `BPMNDiagram_${generateUid()}`;
458
+ const planeId = `BPMNPlane_${generateUid()}`;
459
+ return `<?xml version="1.0" encoding="UTF-8"?>
460
+ <bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
461
+ xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"
462
+ xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
463
+ xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
464
+ id="Definitions_${generateUid()}"
465
+ targetNamespace="http://bpmn.io/schema/bpmn">
466
+ <bpmn:process id="${processId}" isExecutable="false" />
467
+ <bpmndi:BPMNDiagram id="${diagramId}">
468
+ <bpmndi:BPMNPlane id="${planeId}" bpmnElement="${processId}" />
287
469
  </bpmndi:BPMNDiagram>
288
470
  </bpmn:definitions>`;
471
+ }
289
472
  /**
290
- * 生成随机字符串
473
+ * 默认 BPMN XML 数据(向后兼容)
474
+ * @deprecated 请使用 getDefaultBpmnXML() 函数
291
475
  */
292
- function uid() {
293
- return Math.random().toString(36).substring(2);
294
- }
476
+ const defaultBpmnData = getDefaultBpmnXML();
295
477
 
296
- class RkBpmnViewerComponent {
478
+ /// <reference path="../types/diagram-js.d.ts" />
479
+ /**
480
+ * BPMN 流程图查看器组件
481
+ * 提供只读的 BPMN 2.0 流程图查看功能
482
+ */
483
+ class RkBpmnViewerComponent extends RkBpmnBaseComponent {
297
484
  constructor() {
485
+ super(...arguments);
298
486
  /**
299
- * 监听渲染完成
487
+ * 渲染完成事件
300
488
  */
301
489
  this.afterRenderChange = new EventEmitter();
302
- this.scale = 1;
303
490
  }
304
- ngOnInit() { }
305
491
  ngOnChanges(changes) {
306
- if (changes.data && changes.data.currentValue) {
307
- if (this.Viewer) {
308
- this.setDefaultData(this.data).subscribe();
309
- }
492
+ if (changes.data && changes.data.currentValue && this.initialized) {
493
+ this.importXML(changes.data.currentValue).pipe(takeUntil(this.destroy$)).subscribe();
310
494
  }
311
495
  }
312
- ngAfterContentChecked() {
313
- var _a;
314
- const rect = (_a = this.el) === null || _a === void 0 ? void 0 : _a.nativeElement.getBoundingClientRect();
315
- if ((rect === null || rect === void 0 ? void 0 : rect.width) && !this.Viewer) {
316
- this.onInitBpmn();
317
- this.registerEvents();
318
- this.setDefaultData(this.data).subscribe();
319
- }
320
- }
321
- ngOnDestroy() {
322
- var _a;
323
- (_a = this.Viewer) === null || _a === void 0 ? void 0 : _a.destroy();
496
+ ngAfterViewInit() {
497
+ // 延迟初始化,确保容器已渲染
498
+ setTimeout(() => {
499
+ if (this.isContainerReady() && !this.initialized) {
500
+ this.initViewer();
501
+ this.registerEvents();
502
+ const xmlData = this.data || getDefaultBpmnXML();
503
+ this.importXML(xmlData).pipe(takeUntil(this.destroy$)).subscribe();
504
+ this.initialized = true;
505
+ }
506
+ });
324
507
  }
325
508
  /**
326
- * 初始化bpmnJS app
509
+ * 初始化 BPMN 查看器
327
510
  */
328
- onInitBpmn() {
511
+ initViewer() {
329
512
  var _a;
330
- this.Viewer = new Viewer({
331
- container: (_a = this.el) === null || _a === void 0 ? void 0 : _a.nativeElement,
513
+ this.viewer = new Viewer({
514
+ container: (_a = this.containerRef) === null || _a === void 0 ? void 0 : _a.nativeElement,
332
515
  additionalModules: [
333
516
  minimapModule,
334
517
  ZoomScrollModule,
335
518
  MoveCanvasModule,
336
- // 汉化
519
+ ModelingModule,
337
520
  {
338
521
  translate: ['value', customTranslate],
339
522
  },
340
- ModelingModule,
341
523
  ],
342
- poweredBy: false, // 禁用powered-by
524
+ poweredBy: false,
343
525
  });
344
526
  }
345
527
  /**
346
- * 注册事件
528
+ * 注册事件监听
347
529
  */
348
530
  registerEvents() {
349
- // 注册导入完成事件
350
- this.Viewer.on('import.done', ({ error }) => {
351
- if (!error) {
352
- // 加载完成后居中
353
- this.Viewer.get('canvas').zoom('fit-viewport', { x: 0, y: 0 });
354
- // 获得顶层节点
355
- // bpmnModeler.get('canvas').getRootElement()
356
- // 选中节点
357
- // bpmnModeler.get('selection').select(element)
358
- // 遍历所有节点
359
- // bpmnModeler.get('canvas').getRootElement()[0]
360
- // 设置某个节点颜色
361
- const elementRegistry = this.Viewer.get('elementRegistry');
531
+ var _a;
532
+ this.registerImportDoneEvent();
533
+ // 监听导入完成事件,触发渲染完成回调
534
+ (_a = this.viewer) === null || _a === void 0 ? void 0 : _a.on('import.done', ({ error }) => {
535
+ if (!error && this.viewer) {
536
+ const elementRegistry = this.viewer.get('elementRegistry');
362
537
  const nodes = elementRegistry.getAll();
363
538
  if (nodes && nodes.length > 0) {
364
- const modeling = this.Viewer.get('modeling');
539
+ const modeling = this.viewer.get('modeling');
365
540
  this.afterRenderChange.emit({
366
- nodes,
541
+ nodes: nodes,
367
542
  modeling,
368
- viewer: this.Viewer,
543
+ viewer: this.viewer,
369
544
  });
370
- // const start = nodes.find((n) => n.businessObject.$attrs.description === 'start');
371
- // const manager = nodes.find((n) => n.businessObject.$attrs.description === 'leader');
372
- // if (start && manager && modeling) {
373
- // modeling.setColor([start, manager] as BpmnModelTypes.Element[], {
374
- // // fill: null,
375
- // stroke: '#1890ff',
376
- // });
377
- //
378
- // // 设置线的颜色
379
- // // 进线
380
- // const edgesIn = manager.incoming.filter((v: any) => !!start.outgoing.find((n: any) => n.id === v.id));
381
- //
382
- // // 出线
383
- // const edgesOut = manager.outgoing;
384
- // modeling.setColor([...edgesIn, ...edgesOut] as [BpmnModelTypes.Element], {
385
- // stroke: '#1890ff',
386
- // });
387
- // }
388
545
  }
389
546
  }
390
547
  });
391
548
  }
392
549
  /**
393
- * 设置默认值
550
+ * 导入 BPMN XML
551
+ * @param xml BPMN XML 字符串
394
552
  */
395
- setDefaultData(data) {
396
- return from(this.Viewer.importXML(data));
553
+ importXML(xml) {
554
+ if (!this.viewer) {
555
+ throw new Error('BPMN Viewer 未初始化');
556
+ }
557
+ return from(this.viewer.importXML(xml));
397
558
  }
398
559
  /**
399
560
  * 重置画板
400
561
  */
401
- resetDrawingBoard() {
402
- return this.setDefaultData(defaultBpmnData);
403
- }
404
- /**
405
- * 放大
406
- */
407
- zoomIn() {
408
- this.Viewer.get('canvas').zoom(++this.scale);
562
+ reset() {
563
+ return this.importXML(getDefaultBpmnXML());
409
564
  }
410
565
  /**
411
- * 缩小
566
+ * 获取元素注册表
412
567
  */
413
- zoomOut() {
414
- if (this.scale > 1) {
415
- this.Viewer.get('canvas').zoom(--this.scale);
416
- }
568
+ getElementRegistry() {
569
+ var _a;
570
+ return (_a = this.viewer) === null || _a === void 0 ? void 0 : _a.get('elementRegistry');
417
571
  }
418
572
  /**
419
- * 重置位置
573
+ * 获取建模对象
420
574
  */
421
- zoomReset() {
422
- this.Viewer.get('canvas').zoom('fit-viewport', { x: 0, y: 0 });
575
+ getModeling() {
576
+ var _a;
577
+ return (_a = this.viewer) === null || _a === void 0 ? void 0 : _a.get('modeling');
423
578
  }
424
579
  }
425
- RkBpmnViewerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: RkBpmnViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
426
- RkBpmnViewerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.17", type: RkBpmnViewerComponent, selector: "rk-bpmn-viewer", inputs: { data: "data" }, outputs: { afterRenderChange: "afterRenderChange" }, viewQueries: [{ propertyName: "el", first: true, predicate: ["ref"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"layout:col\">\r\n <div class=\"layout:header px-4\">\r\n <div class=\"btn-group\">\r\n <button class=\"btn icon\" title=\"\u653E\u5927\" (click)=\"zoomIn()\">\r\n <i icon type=\"plus-circle\"></i>\r\n </button>\r\n <button class=\"btn icon\" title=\"\u7F29\u5C0F\" (click)=\"zoomOut()\">\r\n <i icon type=\"minus-circle\"></i>\r\n </button>\r\n <button class=\"btn icon\" title=\"\u91CD\u7F6E\u4F4D\u7F6E\" (click)=\"zoomReset()\">\r\n <i icon type=\"map-pin\"></i>\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"layout:content\">\r\n <div #ref class=\"w-full h-full\"></div>\r\n </div>\r\n</div>\r\n", styles: [".layout\\:col{display:flex;flex-direction:column;height:100%;overflow:hidden}.layout\\:aside{width:20rem;background-color:#fff;border-right:1px solid #e5e7eb}.layout\\:row{display:flex;flex-direction:row;height:100%;overflow:hidden}.layout\\:header{height:3.5rem;display:flex;align-items:center;border-bottom:1px solid #e5e7eb;background-color:#fff}.layout\\:footer{height:3.5rem;display:flex;align-items:center;border-top:1px solid #e5e7eb;background-color:#fff}.layout\\:content{flex:1;overflow:hidden;background-color:#fff}.layout\\:content+.layout\\:aside{border:0;border-left:1px solid #e5e7eb}.px-4{padding-left:1rem;padding-right:1rem}.ml-4{margin-left:1rem}.w-full{width:100%}.h-full{height:100%}.btn{box-shadow:0 2px #00000004;cursor:pointer;transition:all .3s cubic-bezier(.645,.045,.355,1);-webkit-user-select:none;user-select:none;height:32px;padding:4px 15px;font-size:14px;border-radius:2px;color:#000000d9;border:1px solid #d9d9d9;background:#fff}.btn.icon{width:32px;height:32px;display:flex;justify-content:center;align-items:center}.btn:hover{color:#40a9ff;border-color:#40a9ff;z-index:1}.btn-group{display:flex}.btn-group .btn{margin-left:-1px;margin-right:-1px;border-radius:0}.btn-group .btn:first-child{border-top-left-radius:2px;border-bottom-left-radius:2px}.btn-group .btn:last-child{border-top-right-radius:2px;border-bottom-right-radius:2px}i[icon]{display:block;width:18px;height:18px}i[type=folder-open]:before{content:url('data:image/svg+xml; utf8, <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon icon-tabler icons-tabler-outline icon-tabler-folder-open\"><path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M5 19l2.757 -7.351a1 1 0 0 1 .936 -.649h12.307a1 1 0 0 1 .986 1.164l-.996 5.211a2 2 0 0 1 -1.964 1.625h-14.026a2 2 0 0 1 -2 -2v-11a2 2 0 0 1 2 -2h4l3 3h7a2 2 0 0 1 2 2v2\" /></svg>')}i[type=reset]:before{content:url('data:image/svg+xml; utf8, <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon icon-tabler icons-tabler-outline icon-tabler-zoom-reset\"><path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M21 21l-6 -6\" /><path d=\"M3.268 12.043a7.017 7.017 0 0 0 6.634 4.957a7.012 7.012 0 0 0 7.043 -6.131a7 7 0 0 0 -5.314 -7.672a7.021 7.021 0 0 0 -8.241 4.403\" /><path d=\"M3 4v4h4\" /></svg>')}i[type=plus-circle]:before{content:url('data:image/svg+xml; utf8, <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon icon-tabler icons-tabler-outline icon-tabler-circle-plus\"><path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0\" /><path d=\"M9 12h6\" /><path d=\"M12 9v6\" /></svg>')}i[type=minus-circle]:before{content:url('data:image/svg+xml; utf8, <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon icon-tabler icons-tabler-outline icon-tabler-circle-minus\"><path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0\" /><path d=\"M9 12l6 0\" /></svg>')}i[type=map-pin]:before{content:url('data:image/svg+xml; utf8, <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon icon-tabler icons-tabler-outline icon-tabler-map-pin\"><path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M9 11a3 3 0 1 0 6 0a3 3 0 0 0 -6 0\" /><path d=\"M17.657 16.657l-4.243 4.243a2 2 0 0 1 -2.827 0l-4.244 -4.243a8 8 0 1 1 11.314 0z\" /></svg>')}i[type=down-svg]:before{content:url('data:image/svg+xml; utf8, <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon icon-tabler icons-tabler-outline icon-tabler-file-type-svg\"><path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M14 3v4a1 1 0 0 0 1 1h4\" /><path d=\"M5 12v-7a2 2 0 0 1 2 -2h7l5 5v4\" /><path d=\"M4 20.25c0 .414 .336 .75 .75 .75h1.25a1 1 0 0 0 1 -1v-1a1 1 0 0 0 -1 -1h-1a1 1 0 0 1 -1 -1v-1a1 1 0 0 1 1 -1h1.25a.75 .75 0 0 1 .75 .75\" /><path d=\"M10 15l2 6l2 -6\" /><path d=\"M20 15h-1a2 2 0 0 0 -2 2v2a2 2 0 0 0 2 2h1v-3\" /></svg>')}i[type=down-file]:before{content:url('data:image/svg+xml; utf8, <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon icon-tabler icons-tabler-outline icon-tabler-file-download\"><path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M14 3v4a1 1 0 0 0 1 1h4\" /><path d=\"M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z\" /><path d=\"M12 17v-6\" /><path d=\"M9.5 14.5l2.5 2.5l2.5 -2.5\" /></svg>')}\n", ":host ::ng-deep a.bjs-powered-by{display:none!important}\n"] });
580
+ RkBpmnViewerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: RkBpmnViewerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
581
+ RkBpmnViewerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.17", type: RkBpmnViewerComponent, selector: "rk-bpmn-viewer", inputs: { data: "data" }, outputs: { afterRenderChange: "afterRenderChange" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"flex flex-col h-full overflow-hidden\">\r\n <!-- \u5DE5\u5177\u680F -->\r\n <div class=\"flex items-center h-14 px-4 bg-white border-b border-gray-200\">\r\n <!-- \u7F29\u653E\u64CD\u4F5C -->\r\n <div class=\"flex -space-x-px\">\r\n <button\r\n class=\"inline-flex items-center justify-center w-8 h-8 text-gray-700 bg-white border border-gray-300 rounded-l hover:text-blue-500 hover:border-blue-500 hover:z-10 transition-colors\"\r\n title=\"\u653E\u5927\"\r\n (click)=\"zoomIn()\">\r\n <svg class=\"w-[18px] h-[18px]\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3 12a9 9 0 1 0 18 0a9 9 0 0 0-18 0\" />\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 12h6\" />\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 9v6\" />\r\n </svg>\r\n </button>\r\n <button\r\n class=\"inline-flex items-center justify-center w-8 h-8 text-gray-700 bg-white border border-gray-300 hover:text-blue-500 hover:border-blue-500 hover:z-10 transition-colors\"\r\n title=\"\u7F29\u5C0F\"\r\n (click)=\"zoomOut()\">\r\n <svg class=\"w-[18px] h-[18px]\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0-18 0\" />\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 12l6 0\" />\r\n </svg>\r\n </button>\r\n <button\r\n class=\"inline-flex items-center justify-center w-8 h-8 text-gray-700 bg-white border border-gray-300 rounded-r hover:text-blue-500 hover:border-blue-500 hover:z-10 transition-colors\"\r\n title=\"\u91CD\u7F6E\u4F4D\u7F6E\"\r\n (click)=\"zoomReset()\">\r\n <svg class=\"w-[18px] h-[18px]\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 11a3 3 0 1 0 6 0a3 3 0 0 0-6 0\" />\r\n <path\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n d=\"M17.657 16.657l-4.243 4.243a2 2 0 0 1-2.827 0l-4.244-4.243a8 8 0 1 1 11.314 0z\" />\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- \u753B\u5E03\u533A\u57DF -->\r\n <div class=\"flex-1 overflow-hidden bg-white\">\r\n <div #container class=\"w-full h-full\"></div>\r\n </div>\r\n</div>\r\n", styles: [":host ::ng-deep a.bjs-powered-by{display:none!important}\n"] });
427
582
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: RkBpmnViewerComponent, decorators: [{
428
583
  type: Component,
429
584
  args: [{
430
585
  selector: 'rk-bpmn-viewer',
431
586
  templateUrl: './bpmn-viewer.component.html',
432
- styleUrls: ['../common.scss', './bpmn-viewer.component.scss'],
587
+ styleUrls: ['./bpmn-viewer.component.scss'],
433
588
  }]
434
- }], ctorParameters: function () { return []; }, propDecorators: { data: [{
589
+ }], propDecorators: { data: [{
435
590
  type: Input
436
591
  }], afterRenderChange: [{
437
592
  type: Output
438
- }], el: [{
439
- type: ViewChild,
440
- args: ['ref']
441
593
  }] } });
442
594
 
443
- /*
444
- * @Description: 代码简介
445
- * @Author: Cyclone77
446
- * @E-Mail: cyclone77@126.com
447
- * @Date: 2024-04-24 09:48:29
448
- * @LastEditTime: 2024-04-24 09:48:29
595
+ /**
596
+ * BPMN 流程图编辑器组件
597
+ * 提供完整的 BPMN 2.0 流程图编辑功能
449
598
  */
450
- class RkBpmnEditorComponent {
599
+ class RkBpmnEditorComponent extends RkBpmnBaseComponent {
451
600
  constructor() {
601
+ super(...arguments);
452
602
  /**
453
- * 选中元素变化时触发
603
+ * 选中元素变化事件
454
604
  */
455
605
  this.selectionChange = new EventEmitter();
606
+ /**
607
+ * 需要加载的样式文件
608
+ */
456
609
  this.loadStyles = [
457
610
  'assets/bpmn-js/diagram-js.css',
458
611
  'assets/bpmn-js/bpmn-font/css/bpmn.css',
459
612
  'assets/diagram-js-minimap/diagram-js-minimap.css',
460
613
  ];
461
- this.scale = 1;
462
614
  }
463
- ngOnInit() { }
464
- ngOnChanges(changes) {
465
- if (changes.data && changes.data.currentValue) {
466
- if (this.bpmnJS) {
467
- this.setDefaultData(changes.data.currentValue).subscribe();
468
- }
469
- }
615
+ /**
616
+ * BPMN 建模器实例
617
+ */
618
+ get modeler() {
619
+ return this.viewer;
470
620
  }
471
- ngAfterContentChecked() {
472
- var _a, _b;
473
- const rect = (_a = this.el) === null || _a === void 0 ? void 0 : _a.nativeElement.getBoundingClientRect();
474
- if ((rect === null || rect === void 0 ? void 0 : rect.width) && !this.bpmnJS) {
475
- this.onInitBpmn();
476
- this.registerEvents();
477
- this.setDefaultData((_b = this.data) !== null && _b !== void 0 ? _b : defaultBpmnData).subscribe();
621
+ ngOnChanges(changes) {
622
+ if (changes.data && changes.data.currentValue && this.initialized) {
623
+ this.importXML(changes.data.currentValue).pipe(takeUntil(this.destroy$)).subscribe();
478
624
  }
479
625
  }
480
- ngOnDestroy() {
481
- var _a;
482
- (_a = this.bpmnJS) === null || _a === void 0 ? void 0 : _a.destroy();
626
+ ngAfterViewInit() {
627
+ // 延迟初始化,确保容器已渲染
628
+ setTimeout(() => {
629
+ if (this.isContainerReady() && !this.initialized) {
630
+ this.initModeler();
631
+ this.registerEvents();
632
+ const xmlData = this.data || getDefaultBpmnXML();
633
+ this.importXML(xmlData).pipe(takeUntil(this.destroy$)).subscribe();
634
+ this.initialized = true;
635
+ }
636
+ });
483
637
  }
484
638
  /**
485
- * 初始化bpmnJS app
639
+ * 初始化 BPMN 建模器
486
640
  */
487
- onInitBpmn() {
488
- var _a, _b;
489
- this.bpmnJS = new BpmnJS({
490
- container: (_a = this.el) === null || _a === void 0 ? void 0 : _a.nativeElement,
641
+ initModeler() {
642
+ var _a;
643
+ this.viewer = new BpmnModeler({
644
+ container: (_a = this.containerRef) === null || _a === void 0 ? void 0 : _a.nativeElement,
491
645
  additionalModules: [
492
646
  gridModule,
493
647
  minimapModule,
494
- // 汉化
495
648
  {
496
649
  translate: ['value', customTranslate],
497
650
  },
498
651
  ],
499
- //添加属性面板
500
- propertiesPanel: {
501
- parent: (_b = this.properties) === null || _b === void 0 ? void 0 : _b.nativeElement,
502
- },
503
- poweredBy: false, // 禁用powered-by
652
+ poweredBy: false,
504
653
  });
505
654
  }
506
655
  /**
507
- * 注册事件
656
+ * 注册事件监听
508
657
  */
509
658
  registerEvents() {
510
- // 注册导入完成事件
511
- this.bpmnJS.on('import.done', ({ error }) => {
512
- if (!error) {
513
- // 加载完成后居中
514
- this.bpmnJS.get('canvas').zoom('fit-viewport', { x: 0, y: 0 });
659
+ var _a;
660
+ this.registerImportDoneEvent();
661
+ // 监听选中元素变化
662
+ (_a = this.modeler) === null || _a === void 0 ? void 0 : _a.on('selection.changed', (event) => {
663
+ const [element] = event.newSelection;
664
+ this.selectedElement = element;
665
+ if (element && this.modeler) {
666
+ const modeling = this.modeler.get('modeling');
667
+ this.selectionChange.emit({
668
+ modeler: this.modeler,
669
+ modeling,
670
+ element,
671
+ });
515
672
  }
516
673
  });
517
- this.bpmnJS.on('selection.changed', (e) => {
518
- const [element] = e.newSelection;
519
- this.targetElement = element;
520
- this.bpmnJS.get('elementRegistry');
521
- const modeling = this.bpmnJS.get('modeling');
522
- this.selectionChange.emit({ modeler: this.bpmnJS, modeling, element });
523
- });
524
- }
525
- /**
526
- * 更新选中元素节点标签值
527
- * @param modeling
528
- * @param element
529
- * @param data
530
- */
531
- updateProperties(modeling, element, data) {
532
- modeling.updateProperties(element, data);
533
- }
534
- /**
535
- * 更新选中元素节点标签值
536
- * @param modeling
537
- * @param element
538
- * @param key
539
- * @param value
540
- */
541
- updatePropertiesByKey(modeling, element, key, value) {
542
- modeling.updateProperties(element, { [key]: value });
543
674
  }
544
675
  /**
545
- * 设置默认值
676
+ * 导入 BPMN XML
677
+ * @param xml BPMN XML 字符串
546
678
  */
547
- setDefaultData(data) {
548
- return from(this.bpmnJS.importXML(data));
679
+ importXML(xml) {
680
+ if (!this.modeler) {
681
+ throw new Error('BPMN Modeler 未初始化');
682
+ }
683
+ return from(this.modeler.importXML(xml));
549
684
  }
550
685
  /**
551
- * 导入模型
552
- * @param event
686
+ * 导入 BPMN 文件
687
+ * @param event 文件输入事件
553
688
  */
554
- importModelXML(event) {
689
+ importFile(event) {
555
690
  var _a;
556
- const input = event.target;
557
- if (!((_a = input.files) === null || _a === void 0 ? void 0 : _a.length)) {
558
- return;
559
- }
560
- const file = input.files.item(0);
561
- const reader = new FileReader();
562
- // 读取File对象中的文本信息,编码格式为UTF-8
563
- reader.readAsText(file, 'utf-8');
564
- reader.onload = () => {
565
- input.value = '';
566
- //读取完毕后将文本信息导入到Bpmn建模器
567
- this.setDefaultData(reader.result).subscribe(() => { }, ({ error }) => {
568
- console.error('打开模型出错,请确认该模型符合Bpmn2.0规范');
569
- });
570
- };
691
+ return __awaiter(this, void 0, void 0, function* () {
692
+ const input = event.target;
693
+ const file = (_a = input.files) === null || _a === void 0 ? void 0 : _a[0];
694
+ if (!file) {
695
+ return;
696
+ }
697
+ try {
698
+ const xml = yield readFileAsText(file);
699
+ yield this.importXML(xml).toPromise();
700
+ input.value = '';
701
+ }
702
+ catch (error) {
703
+ console.error('导入 BPMN 文件失败,请确认文件符合 BPMN 2.0 规范', error);
704
+ input.value = '';
705
+ }
706
+ });
571
707
  }
572
708
  /**
573
709
  * 重置画板
574
710
  */
575
- resetDrawingBoard() {
576
- return this.setDefaultData(defaultBpmnData);
711
+ reset() {
712
+ return this.importXML(getDefaultBpmnXML());
577
713
  }
578
714
  /**
579
- * 放大
715
+ * 保存为 XML
716
+ * @param format 是否格式化输出
580
717
  */
581
- zoomIn() {
582
- this.bpmnJS.get('canvas').zoom(++this.scale);
718
+ saveXML(format = true) {
719
+ return __awaiter(this, void 0, void 0, function* () {
720
+ if (!this.modeler) {
721
+ throw new Error('BPMN Modeler 未初始化');
722
+ }
723
+ return this.modeler.saveXML({ format });
724
+ });
583
725
  }
584
726
  /**
585
- * 缩小
727
+ * 保存为 SVG
586
728
  */
587
- zoomOut() {
588
- if (this.scale > 1) {
589
- this.bpmnJS.get('canvas').zoom(--this.scale);
590
- }
729
+ saveSVG() {
730
+ return __awaiter(this, void 0, void 0, function* () {
731
+ if (!this.modeler) {
732
+ throw new Error('BPMN Modeler 未初始化');
733
+ }
734
+ return this.modeler.saveSVG();
735
+ });
591
736
  }
592
737
  /**
593
- * 重置位置
738
+ * 下载为 BPMN 文件
739
+ * @param config 导出配置
594
740
  */
595
- zoomReset() {
596
- this.bpmnJS.get('canvas').zoom('fit-viewport', { x: 0, y: 0 });
741
+ downloadBPMN(config = {}) {
742
+ return __awaiter(this, void 0, void 0, function* () {
743
+ const { format = true, filename } = config;
744
+ const { xml } = yield this.saveXML(format);
745
+ if (xml) {
746
+ const name = filename ? `${filename}.bpmn` : `diagram-${generateUid()}.bpmn`;
747
+ downloadFile(xml, name);
748
+ }
749
+ });
597
750
  }
598
751
  /**
599
- * 保存当前 BPMN 图的 XML 表示
600
- *
601
- * 此方法用于将当前 BPMN 图的 XML 表示保存下来它可以接受一个可选参数 format,
602
- * 该参数指示是否应格式化 XML 输出当 format 设置为 true 时,XML 将以一种更易于阅读的格式输出;
603
- * 否则,它将以紧凑的形式输出
604
- *
605
- * @param format {boolean} - 可选参数,默认为 true如果设置为 true,保存的 XML 将被格式化以提高可读性
606
- * @returns {Promise<string>} - 返回一个 Promise,解析为 BPMN 图的 XML 字符串表示
752
+ * 下载为 SVG 文件
753
+ * @param filename 文件名(不含扩展名)
607
754
  */
608
- saveXML(format = true) {
609
- return this.bpmnJS.saveXML({ format });
755
+ downloadSVG(filename) {
756
+ return __awaiter(this, void 0, void 0, function* () {
757
+ const { svg } = yield this.saveSVG();
758
+ if (svg) {
759
+ const blob = new Blob([svg], { type: 'image/svg+xml' });
760
+ const name = filename ? `${filename}.svg` : `diagram-${generateUid()}.svg`;
761
+ downloadFile(blob, name);
762
+ }
763
+ });
610
764
  }
611
765
  /**
612
- * 下载 .bpmn 格式
766
+ * 更新元素属性
767
+ * @param element 要更新的元素
768
+ * @param properties 属性对象
613
769
  */
614
- downloadBPMN(name) {
615
- this.saveXML().then(({ xml }) => {
616
- if (xml) {
617
- // 把数据转换为URI,下载要用到的
618
- const encodedData = encodeURIComponent(xml);
619
- const href = `data:application/bpmn20-xml;charset=UTF-8,${encodedData}`;
620
- this.downloadFile(href, name !== null && name !== void 0 ? name : `diagram-${uid()}.bpmn`);
621
- }
622
- });
770
+ updateProperties(element, properties) {
771
+ if (!this.modeler) {
772
+ return;
773
+ }
774
+ const modeling = this.modeler.get('modeling');
775
+ modeling.updateProperties(element, properties);
623
776
  }
624
777
  /**
625
- * 保存SVG图形
626
- *
627
- * 此方法用于将当前图表以SVG格式保存它不接受任何参数
628
- * 返回一个Promise对象,该Promise解析为SaveSVGResult类型的结果
629
- * 主要用于需要以SVG格式导出或保存当前图表的场景
778
+ * 更新元素单个属性
779
+ * @param element 要更新的元素
780
+ * @param key 属性键
781
+ * @param value 属性值
630
782
  */
631
- saveSVG() {
632
- return this.bpmnJS.saveSVG();
783
+ updateProperty(element, key, value) {
784
+ this.updateProperties(element, { [key]: value });
633
785
  }
634
786
  /**
635
- * 下载 .svg 格式
787
+ * 获取元素注册表
636
788
  */
637
- downloadSVG() {
638
- this.saveSVG().then(({ svg }) => {
639
- if (svg) {
640
- const svgBlob = new Blob([svg], {
641
- type: 'image/svg+xml',
642
- });
643
- this.downloadFile(URL.createObjectURL(svgBlob), `diagram-${uid()}.svg`);
644
- }
645
- });
789
+ getElementRegistry() {
790
+ var _a;
791
+ return (_a = this.modeler) === null || _a === void 0 ? void 0 : _a.get('elementRegistry');
646
792
  }
647
793
  /**
648
- * 通过href下载文件
794
+ * 获取建模对象
649
795
  */
650
- downloadFile(href, filename) {
651
- const tempLink = document.createElement('a');
652
- tempLink.style.display = 'none';
653
- tempLink.href = href;
654
- tempLink.setAttribute('download', filename);
655
- if (typeof tempLink.download === 'undefined') {
656
- tempLink.setAttribute('target', '_blank');
657
- }
658
- document.body.appendChild(tempLink);
659
- tempLink.click();
660
- document.body.removeChild(tempLink);
796
+ getModeling() {
797
+ var _a;
798
+ return (_a = this.modeler) === null || _a === void 0 ? void 0 : _a.get('modeling');
661
799
  }
662
800
  }
663
- RkBpmnEditorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: RkBpmnEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
664
- RkBpmnEditorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.17", type: RkBpmnEditorComponent, selector: "rk-bpmn-editor", inputs: { data: "data", propertiesTemplate: "propertiesTemplate" }, outputs: { selectionChange: "selectionChange" }, viewQueries: [{ propertyName: "el", first: true, predicate: ["ref"], descendants: true }, { propertyName: "properties", first: true, predicate: ["properties"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"layout:col\">\r\n <div class=\"layout:header px-4\">\r\n <div class=\"btn-group\">\r\n <button class=\"btn icon\" title=\"\u5BFC\u5165\u6A21\u578B .bpmn\" (click)=\"fileRef.click()\">\r\n <input #fileRef type=\"file\" style=\"display: none\" accept=\".bpmn\" (change)=\"importModelXML($event)\" />\r\n <i icon type=\"folder-open\"></i>\r\n </button>\r\n <button class=\"btn icon\" title=\"\u91CD\u7F6E\u753B\u677F\" (click)=\"resetDrawingBoard().subscribe()\">\r\n <i icon type=\"reset\"></i>\r\n </button>\r\n </div>\r\n\r\n <div class=\"ml-4\">\r\n <div class=\"btn-group\">\r\n <button class=\"btn icon\" title=\"\u653E\u5927\" (click)=\"zoomIn()\">\r\n <i icon type=\"plus-circle\"></i>\r\n </button>\r\n <button class=\"btn icon\" title=\"\u7F29\u5C0F\" (click)=\"zoomOut()\">\r\n <i icon type=\"minus-circle\"></i>\r\n </button>\r\n <button class=\"btn icon\" title=\"\u91CD\u7F6E\u4F4D\u7F6E\" (click)=\"zoomReset()\">\r\n <i icon type=\"map-pin\"></i>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"ml-4\">\r\n <div class=\"btn-group\">\r\n <button class=\"btn icon\" title=\"\u4E0B\u8F7D\u4E3A.bpmn\u683C\u5F0F\" (click)=\"downloadBPMN()\">\r\n <i icon type=\"down-file\"></i>\r\n </button>\r\n <button class=\"btn icon\" title=\"\u4E0B\u8F7D\u4E3A.svg\u683C\u5F0F\" (click)=\"downloadSVG()\">\r\n <i icon type=\"down-svg\"></i>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"layout:content layout:row\">\r\n <div class=\"layout:content\">\r\n <ng-container [rkLoadStyles]=\"loadStyles\">\r\n <div #ref class=\"w-full h-full\"></div>\r\n </ng-container>\r\n </div>\r\n <div class=\"layout:aside\" *ngIf=\"propertiesTemplate\">\r\n <ng-template [ngTemplateOutlet]=\"propertiesTemplate\"></ng-template>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".layout\\:col{display:flex;flex-direction:column;height:100%;overflow:hidden}.layout\\:aside{width:20rem;background-color:#fff;border-right:1px solid #e5e7eb}.layout\\:row{display:flex;flex-direction:row;height:100%;overflow:hidden}.layout\\:header{height:3.5rem;display:flex;align-items:center;border-bottom:1px solid #e5e7eb;background-color:#fff}.layout\\:footer{height:3.5rem;display:flex;align-items:center;border-top:1px solid #e5e7eb;background-color:#fff}.layout\\:content{flex:1;overflow:hidden;background-color:#fff}.layout\\:content+.layout\\:aside{border:0;border-left:1px solid #e5e7eb}.px-4{padding-left:1rem;padding-right:1rem}.ml-4{margin-left:1rem}.w-full{width:100%}.h-full{height:100%}.btn{box-shadow:0 2px #00000004;cursor:pointer;transition:all .3s cubic-bezier(.645,.045,.355,1);-webkit-user-select:none;user-select:none;height:32px;padding:4px 15px;font-size:14px;border-radius:2px;color:#000000d9;border:1px solid #d9d9d9;background:#fff}.btn.icon{width:32px;height:32px;display:flex;justify-content:center;align-items:center}.btn:hover{color:#40a9ff;border-color:#40a9ff;z-index:1}.btn-group{display:flex}.btn-group .btn{margin-left:-1px;margin-right:-1px;border-radius:0}.btn-group .btn:first-child{border-top-left-radius:2px;border-bottom-left-radius:2px}.btn-group .btn:last-child{border-top-right-radius:2px;border-bottom-right-radius:2px}i[icon]{display:block;width:18px;height:18px}i[type=folder-open]:before{content:url('data:image/svg+xml; utf8, <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon icon-tabler icons-tabler-outline icon-tabler-folder-open\"><path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M5 19l2.757 -7.351a1 1 0 0 1 .936 -.649h12.307a1 1 0 0 1 .986 1.164l-.996 5.211a2 2 0 0 1 -1.964 1.625h-14.026a2 2 0 0 1 -2 -2v-11a2 2 0 0 1 2 -2h4l3 3h7a2 2 0 0 1 2 2v2\" /></svg>')}i[type=reset]:before{content:url('data:image/svg+xml; utf8, <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon icon-tabler icons-tabler-outline icon-tabler-zoom-reset\"><path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M21 21l-6 -6\" /><path d=\"M3.268 12.043a7.017 7.017 0 0 0 6.634 4.957a7.012 7.012 0 0 0 7.043 -6.131a7 7 0 0 0 -5.314 -7.672a7.021 7.021 0 0 0 -8.241 4.403\" /><path d=\"M3 4v4h4\" /></svg>')}i[type=plus-circle]:before{content:url('data:image/svg+xml; utf8, <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon icon-tabler icons-tabler-outline icon-tabler-circle-plus\"><path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0\" /><path d=\"M9 12h6\" /><path d=\"M12 9v6\" /></svg>')}i[type=minus-circle]:before{content:url('data:image/svg+xml; utf8, <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon icon-tabler icons-tabler-outline icon-tabler-circle-minus\"><path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0\" /><path d=\"M9 12l6 0\" /></svg>')}i[type=map-pin]:before{content:url('data:image/svg+xml; utf8, <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon icon-tabler icons-tabler-outline icon-tabler-map-pin\"><path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M9 11a3 3 0 1 0 6 0a3 3 0 0 0 -6 0\" /><path d=\"M17.657 16.657l-4.243 4.243a2 2 0 0 1 -2.827 0l-4.244 -4.243a8 8 0 1 1 11.314 0z\" /></svg>')}i[type=down-svg]:before{content:url('data:image/svg+xml; utf8, <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon icon-tabler icons-tabler-outline icon-tabler-file-type-svg\"><path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M14 3v4a1 1 0 0 0 1 1h4\" /><path d=\"M5 12v-7a2 2 0 0 1 2 -2h7l5 5v4\" /><path d=\"M4 20.25c0 .414 .336 .75 .75 .75h1.25a1 1 0 0 0 1 -1v-1a1 1 0 0 0 -1 -1h-1a1 1 0 0 1 -1 -1v-1a1 1 0 0 1 1 -1h1.25a.75 .75 0 0 1 .75 .75\" /><path d=\"M10 15l2 6l2 -6\" /><path d=\"M20 15h-1a2 2 0 0 0 -2 2v2a2 2 0 0 0 2 2h1v-3\" /></svg>')}i[type=down-file]:before{content:url('data:image/svg+xml; utf8, <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon icon-tabler icons-tabler-outline icon-tabler-file-download\"><path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M14 3v4a1 1 0 0 0 1 1h4\" /><path d=\"M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z\" /><path d=\"M12 17v-6\" /><path d=\"M9.5 14.5l2.5 2.5l2.5 -2.5\" /></svg>')}\n", ":host ::ng-deep a.bjs-powered-by{display:none!important}\n"], directives: [{ type: i1.RkLoadStylesDirective, selector: "[rkLoadStyles]", inputs: ["rkLoadStyles"], outputs: ["stylesLoaded"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }] });
801
+ RkBpmnEditorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: RkBpmnEditorComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
802
+ RkBpmnEditorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.17", type: RkBpmnEditorComponent, selector: "rk-bpmn-editor", inputs: { data: "data", propertiesTemplate: "propertiesTemplate" }, outputs: { selectionChange: "selectionChange" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"flex flex-col h-full overflow-hidden\">\r\n <!-- \u5DE5\u5177\u680F -->\r\n <div class=\"flex items-center h-14 px-4 bg-white border-b border-gray-200\">\r\n <!-- \u6587\u4EF6\u64CD\u4F5C -->\r\n <div class=\"flex -space-x-px\">\r\n <button\r\n class=\"inline-flex items-center justify-center w-8 h-8 text-gray-700 bg-white border border-gray-300 rounded-l hover:text-blue-500 hover:border-blue-500 hover:z-10 transition-colors\"\r\n title=\"\u5BFC\u5165\u6A21\u578B .bpmn\"\r\n (click)=\"fileInput.click()\">\r\n <input #fileInput type=\"file\" class=\"hidden\" accept=\".bpmn\" (change)=\"importFile($event)\" />\r\n <svg class=\"w-[18px] h-[18px]\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" viewBox=\"0 0 24 24\">\r\n <path\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n d=\"M5 19l2.757-7.351a1 1 0 0 1 .936-.649h12.307a1 1 0 0 1 .986 1.164l-.996 5.211a2 2 0 0 1-1.964 1.625h-14.026a2 2 0 0 1-2-2v-11a2 2 0 0 1 2-2h4l3 3h7a2 2 0 0 1 2 2v2\" />\r\n </svg>\r\n </button>\r\n <button\r\n class=\"inline-flex items-center justify-center w-8 h-8 text-gray-700 bg-white border border-gray-300 rounded-r hover:text-blue-500 hover:border-blue-500 hover:z-10 transition-colors\"\r\n title=\"\u91CD\u7F6E\u753B\u677F\"\r\n (click)=\"reset().subscribe()\">\r\n <svg class=\"w-[18px] h-[18px]\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M21 21l-6-6\" />\r\n <path\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n d=\"M3.268 12.043a7.017 7.017 0 0 0 6.634 4.957a7.012 7.012 0 0 0 7.043-6.131a7 7 0 0 0-5.314-7.672a7.021 7.021 0 0 0-8.241 4.403\" />\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3 4v4h4\" />\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <!-- \u7F29\u653E\u64CD\u4F5C -->\r\n <div class=\"flex -space-x-px ml-4\">\r\n <button\r\n class=\"inline-flex items-center justify-center w-8 h-8 text-gray-700 bg-white border border-gray-300 rounded-l hover:text-blue-500 hover:border-blue-500 hover:z-10 transition-colors\"\r\n title=\"\u653E\u5927\"\r\n (click)=\"zoomIn()\">\r\n <svg class=\"w-[18px] h-[18px]\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3 12a9 9 0 1 0 18 0a9 9 0 0 0-18 0\" />\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 12h6\" />\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 9v6\" />\r\n </svg>\r\n </button>\r\n <button\r\n class=\"inline-flex items-center justify-center w-8 h-8 text-gray-700 bg-white border border-gray-300 hover:text-blue-500 hover:border-blue-500 hover:z-10 transition-colors\"\r\n title=\"\u7F29\u5C0F\"\r\n (click)=\"zoomOut()\">\r\n <svg class=\"w-[18px] h-[18px]\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0-18 0\" />\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 12l6 0\" />\r\n </svg>\r\n </button>\r\n <button\r\n class=\"inline-flex items-center justify-center w-8 h-8 text-gray-700 bg-white border border-gray-300 rounded-r hover:text-blue-500 hover:border-blue-500 hover:z-10 transition-colors\"\r\n title=\"\u91CD\u7F6E\u4F4D\u7F6E\"\r\n (click)=\"zoomReset()\">\r\n <svg class=\"w-[18px] h-[18px]\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 11a3 3 0 1 0 6 0a3 3 0 0 0-6 0\" />\r\n <path\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n d=\"M17.657 16.657l-4.243 4.243a2 2 0 0 1-2.827 0l-4.244-4.243a8 8 0 1 1 11.314 0z\" />\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <!-- \u5BFC\u51FA\u64CD\u4F5C -->\r\n <div class=\"flex -space-x-px ml-4\">\r\n <button\r\n class=\"inline-flex items-center justify-center w-8 h-8 text-gray-700 bg-white border border-gray-300 rounded-l hover:text-blue-500 hover:border-blue-500 hover:z-10 transition-colors\"\r\n title=\"\u4E0B\u8F7D\u4E3A .bpmn \u683C\u5F0F\"\r\n (click)=\"downloadBPMN()\">\r\n <svg class=\"w-[18px] h-[18px]\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M14 3v4a1 1 0 0 0 1 1h4\" />\r\n <path\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n d=\"M17 21h-10a2 2 0 0 1-2-2v-14a2 2 0 0 1 2-2h7l5 5v11a2 2 0 0 1-2 2z\" />\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 17v-6\" />\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9.5 14.5l2.5 2.5l2.5-2.5\" />\r\n </svg>\r\n </button>\r\n <button\r\n class=\"inline-flex items-center justify-center w-8 h-8 text-gray-700 bg-white border border-gray-300 rounded-r hover:text-blue-500 hover:border-blue-500 hover:z-10 transition-colors\"\r\n title=\"\u4E0B\u8F7D\u4E3A .svg \u683C\u5F0F\"\r\n (click)=\"downloadSVG()\">\r\n <svg class=\"w-[18px] h-[18px]\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M14 3v4a1 1 0 0 0 1 1h4\" />\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M5 12v-7a2 2 0 0 1 2-2h7l5 5v4\" />\r\n <path\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n d=\"M4 20.25c0 .414.336.75.75.75h1.25a1 1 0 0 0 1-1v-1a1 1 0 0 0-1-1h-1a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h1.25a.75.75 0 0 1 .75.75\" />\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M10 15l2 6l2-6\" />\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M20 15h-1a2 2 0 0 0-2 2v2a2 2 0 0 0 2 2h1v-3\" />\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- \u5185\u5BB9\u533A\u57DF -->\r\n <div class=\"flex flex-1 overflow-hidden\">\r\n <!-- \u753B\u5E03\u533A\u57DF -->\r\n <div class=\"flex-1 overflow-hidden bg-white\">\r\n <ng-container [rkLoadStyles]=\"loadStyles\">\r\n <div #container class=\"w-full h-full\"></div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- \u5C5E\u6027\u9762\u677F -->\r\n <div *ngIf=\"propertiesTemplate\" class=\"w-80 bg-white border-l border-gray-200 overflow-auto\">\r\n <ng-template [ngTemplateOutlet]=\"propertiesTemplate\"></ng-template>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host ::ng-deep a.bjs-powered-by{display:none!important}\n"], directives: [{ type: i1.RkLoadStylesDirective, selector: "[rkLoadStyles]", inputs: ["rkLoadStyles"], outputs: ["stylesLoaded"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }] });
665
803
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: RkBpmnEditorComponent, decorators: [{
666
804
  type: Component,
667
805
  args: [{
668
806
  selector: 'rk-bpmn-editor',
669
807
  templateUrl: './bpmn-editor.component.html',
670
- styleUrls: ['../common.scss', './bpmn-editor.component.scss'],
808
+ styleUrls: ['./bpmn-editor.component.scss'],
671
809
  }]
672
- }], ctorParameters: function () { return []; }, propDecorators: { data: [{
810
+ }], propDecorators: { data: [{
673
811
  type: Input
674
812
  }], propertiesTemplate: [{
675
813
  type: Input
676
814
  }], selectionChange: [{
677
815
  type: Output
678
- }], el: [{
679
- type: ViewChild,
680
- args: ['ref']
681
- }], properties: [{
682
- type: ViewChild,
683
- args: ['properties']
684
816
  }] } });
685
817
 
686
818
  class RkBpmnModule {
@@ -701,5 +833,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImpo
701
833
  * Generated bundle index. Do not edit.
702
834
  */
703
835
 
704
- export { RkBpmnEditorComponent, RkBpmnModule, RkBpmnViewerComponent };
836
+ export { RkBpmnEditorComponent, RkBpmnModule, RkBpmnViewerComponent, defaultBpmnData, downloadFile, generateUid, getDefaultBpmnXML, readFileAsText };
705
837
  //# sourceMappingURL=reskin-bpmn.js.map