@brggroup/share-lib 0.1.74 → 0.1.76

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.
@@ -11377,8 +11377,8 @@ let WorkflowEditorOption$1 = class WorkflowEditorOption {
11377
11377
  AllowbackInUse;
11378
11378
  constructor(obj) {
11379
11379
  obj = obj || {};
11380
- this.panX = obj.panX || 0;
11381
- this.panY = obj.panY || 0;
11380
+ this.panX = Math.round(obj.panX) || 0;
11381
+ this.panY = Math.round(obj.panY) || 0;
11382
11382
  this.AllowbackInUse = obj.AllowbackInUse || false;
11383
11383
  }
11384
11384
  };
@@ -11607,6 +11607,7 @@ class WorkflowEditorComponent extends BaseComponent {
11607
11607
  previewY = 0;
11608
11608
  /** điểm đang chọn để di chuyển */
11609
11609
  draggingPoint;
11610
+ pointClickTimer = 0;
11610
11611
  /** đang kéo chọn nhiều node */
11611
11612
  isSelecting = false;
11612
11613
  /** điểm bắt đầu kéo */
@@ -11766,12 +11767,17 @@ class WorkflowEditorComponent extends BaseComponent {
11766
11767
  });
11767
11768
  this.lstAction = [...lstAction];
11768
11769
  }
11770
+ if (this.selectedStage && this.selectedStage.IsTempId) {
11771
+ this.selectedStage = undefined;
11772
+ }
11769
11773
  this.ready = true;
11770
11774
  console.log('WorkflowEditorComponent afterInput');
11771
11775
  console.log('template', this.template);
11772
11776
  console.log('lstStage', this.lstStage);
11773
11777
  console.log('lstAction', this.lstAction);
11774
11778
  console.log('lstActionRef', this.lstActionRef);
11779
+ console.log('selectedStage', this.selectedStage);
11780
+ console.log('lstActionOfCurrentStage', this.lstActionOfCurrentStage);
11775
11781
  this.updateMiniMap();
11776
11782
  }
11777
11783
  onclickaction(action) {
@@ -11791,8 +11797,8 @@ class WorkflowEditorComponent extends BaseComponent {
11791
11797
  canvasHeight: this.getCanvasHeight(),
11792
11798
  nodes: this.lstStage, // Truyền trực tiếp mảng dữ liệu Node
11793
11799
  onPanChange: (x, y) => {
11794
- this.template.editorOption.panX = x;
11795
- this.template.editorOption.panY = y;
11800
+ this.template.editorOption.panX = Math.round(x);
11801
+ this.template.editorOption.panY = Math.round(y);
11796
11802
  },
11797
11803
  });
11798
11804
  }
@@ -12496,15 +12502,28 @@ class WorkflowEditorComponent extends BaseComponent {
12496
12502
  //#endregion
12497
12503
  //#region Point action
12498
12504
  onmousedownPoint(event, p) {
12499
- console.log('onmousedownPoint', p);
12500
12505
  event.stopPropagation();
12501
12506
  event.preventDefault();
12502
- if (!this.draggingPoint) {
12503
- this.draggingPoint = p;
12504
- }
12505
- else {
12507
+ const currentTime = new Date().getTime();
12508
+ // Nếu khoảng cách giữa 2 lần click < 300ms => Nhận diện là Double Click
12509
+ if (currentTime - this.pointClickTimer < 300) {
12510
+ // 1. Tìm đường nối (edge) đang chứa điểm này
12511
+ const activeEdge = this.hoverAction || this.hoverAction;
12512
+ // 2. Xóa điểm khỏi mảng points
12513
+ if (activeEdge && activeEdge.editorOption.points) {
12514
+ const index = activeEdge.editorOption.points.indexOf(p);
12515
+ if (index > -1) {
12516
+ activeEdge.editorOption.points.splice(index, 1);
12517
+ }
12518
+ }
12519
+ // 3. Reset trạng thái
12506
12520
  this.draggingPoint = undefined;
12521
+ this.pointClickTimer = 0;
12522
+ return;
12507
12523
  }
12524
+ // Nếu click 1 lần (Single Click) => Nhận diện là bắt đầu kéo (Drag)
12525
+ this.pointClickTimer = currentTime;
12526
+ this.draggingPoint = p;
12508
12527
  }
12509
12528
  onRightClickPoint(event, edge, index) {
12510
12529
  console.log('onRightClickPoint', edge, index);
@@ -12747,8 +12766,8 @@ class WorkflowEditorComponent extends BaseComponent {
12747
12766
  const canvasY = (y - this.template.editorOption.panY) / this.zoom;
12748
12767
  this.zoom = parseFloat(newZoom.toFixed(2));
12749
12768
  // Tính toán lại vị trí Pan để điểm đang trỏ vẫn nằm dưới chuột
12750
- this.template.editorOption.panX = x - canvasX * this.zoom;
12751
- this.template.editorOption.panY = y - canvasY * this.zoom;
12769
+ this.template.editorOption.panX = Math.round(x - canvasX * this.zoom);
12770
+ this.template.editorOption.panY = Math.round(y - canvasY * this.zoom);
12752
12771
  this.syncMiniMapViewport();
12753
12772
  }
12754
12773
  //#endregion
@@ -12880,13 +12899,10 @@ class WorkflowEditorComponent extends BaseComponent {
12880
12899
  const pt = svg.createSVGPoint();
12881
12900
  pt.x = event.clientX;
12882
12901
  pt.y = event.clientY;
12902
+ // Áp dụng ma trận của SVG để quy đổi tọa độ màn hình -> tọa độ Canvas thực tế
12883
12903
  const result = pt.matrixTransform(svg.getScreenCTM().inverse());
12884
- if (preview) {
12885
- return { x: result.x, y: result.y };
12886
- }
12887
- else {
12888
- return { x: event.clientX, y: event.clientY };
12889
- }
12904
+ // Bỏ điều kiện preview, LUÔN LUÔN trả về tọa độ result (đã quy đổi theo zoom scale)
12905
+ return { x: result.x, y: result.y };
12890
12906
  }
12891
12907
  updateSelection() {
12892
12908
  if (!this.selectStart || !this.selectEnd)
@@ -18145,6 +18161,7 @@ class WF_TemplateDetail extends BaseComponent {
18145
18161
  lstAction = [];
18146
18162
  lstActionRef = [];
18147
18163
  wfeditor;
18164
+ onSave = new EventEmitter();
18148
18165
  ngOnInit() {
18149
18166
  this.getMasterData();
18150
18167
  }
@@ -18214,6 +18231,7 @@ class WF_TemplateDetail extends BaseComponent {
18214
18231
  .then((res) => {
18215
18232
  this.notiService.success();
18216
18233
  this.getData(res.Data);
18234
+ this.onSave.emit();
18217
18235
  }, (err) => {
18218
18236
  this.handleError(err);
18219
18237
  this.wfeditor.ready = true;
@@ -18279,7 +18297,7 @@ class WF_TemplateDetail extends BaseComponent {
18279
18297
  this.wfeditor.actionRuleModalVisible = false;
18280
18298
  }
18281
18299
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: WF_TemplateDetail, deps: null, target: i0.ɵɵFactoryTarget.Component });
18282
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.7", type: WF_TemplateDetail, isStandalone: true, selector: "wf-template-detail", viewQueries: [{ propertyName: "wfeditor", first: true, predicate: ["wfeditor"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"workflow-wrapper\" style=\"height: calc(100vh - 160px)\">\n <app-workflow-editor\n #wfeditor\n [lstOrg]=\"lstOrg\"\n [lstRole]=\"lstRole\"\n [lstUser]=\"lstUser\"\n [lstEmailTemplate]=\"lstEmailTemplate\"\n (onSave)=\"save($event)\"\n (onDeleteStage)=\"deleteStage($event)\"\n (onDeleteAction)=\"deleteAction($event)\"\n (onDeleteRule)=\"deleteRule($event)\"\n (onDeleteRuleLine)=\"deleteRuleLine($event)\"\n (onCheckRule)=\"onCheckRule($event)\"\n (onCheckAllRule)=\"onCheckAllRule($event)\"\n ></app-workflow-editor>\n</div>\n", styles: [".workflow-wrapper{position:relative}\n"], dependencies: [{ kind: "component", type: WorkflowEditorComponent, selector: "app-workflow-editor", inputs: ["lstOrg", "lstRole", "lstUser", "lstEmailTemplate"], outputs: ["onSave", "onDeleteStage", "onDeleteAction", "onDeleteRule", "onDeleteRuleLine", "onCheckRule", "onCheckAllRule"] }] });
18300
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.7", type: WF_TemplateDetail, isStandalone: true, selector: "wf-template-detail", outputs: { onSave: "onSave" }, viewQueries: [{ propertyName: "wfeditor", first: true, predicate: ["wfeditor"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"workflow-wrapper\" style=\"height: calc(100vh - 160px)\">\n <app-workflow-editor\n #wfeditor\n [lstOrg]=\"lstOrg\"\n [lstRole]=\"lstRole\"\n [lstUser]=\"lstUser\"\n [lstEmailTemplate]=\"lstEmailTemplate\"\n (onSave)=\"save($event)\"\n (onDeleteStage)=\"deleteStage($event)\"\n (onDeleteAction)=\"deleteAction($event)\"\n (onDeleteRule)=\"deleteRule($event)\"\n (onDeleteRuleLine)=\"deleteRuleLine($event)\"\n (onCheckRule)=\"onCheckRule($event)\"\n (onCheckAllRule)=\"onCheckAllRule($event)\"\n ></app-workflow-editor>\n</div>\n", styles: [".workflow-wrapper{position:relative}\n"], dependencies: [{ kind: "component", type: WorkflowEditorComponent, selector: "app-workflow-editor", inputs: ["lstOrg", "lstRole", "lstUser", "lstEmailTemplate"], outputs: ["onSave", "onDeleteStage", "onDeleteAction", "onDeleteRule", "onDeleteRuleLine", "onCheckRule", "onCheckAllRule"] }] });
18283
18301
  }
18284
18302
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: WF_TemplateDetail, decorators: [{
18285
18303
  type: Component,
@@ -18287,6 +18305,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImpor
18287
18305
  }], propDecorators: { wfeditor: [{
18288
18306
  type: ViewChild,
18289
18307
  args: ['wfeditor']
18308
+ }], onSave: [{
18309
+ type: Output
18290
18310
  }] } });
18291
18311
 
18292
18312
  //#region MODELS
@@ -18372,8 +18392,8 @@ class WorkflowEditorOption {
18372
18392
  AllowbackInUse;
18373
18393
  constructor(obj) {
18374
18394
  obj = obj || {};
18375
- this.panX = obj.panX || 0;
18376
- this.panY = obj.panY || 0;
18395
+ this.panX = Math.round(obj.panX) || 0;
18396
+ this.panY = Math.round(obj.panY) || 0;
18377
18397
  this.AllowbackInUse = obj.AllowbackInUse || false;
18378
18398
  }
18379
18399
  }
@@ -18470,6 +18490,7 @@ class WorkflowTemplateEdge {
18470
18490
  //#endregion MODELS
18471
18491
  class WF_Template_CombineEditorComponent extends BaseComponent {
18472
18492
  lstTemplateForSelect = [];
18493
+ getdata = new EventEmitter();
18473
18494
  onSave = new EventEmitter();
18474
18495
  onDeleteTempldateNode = new EventEmitter();
18475
18496
  lstTemplateSelected = [];
@@ -18525,19 +18546,23 @@ class WF_Template_CombineEditorComponent extends BaseComponent {
18525
18546
  previewX = 0;
18526
18547
  previewY = 0;
18527
18548
  draggingPoint;
18549
+ pointClickTimer = 0;
18528
18550
  edgeClickTimer = null;
18529
18551
  CLICK_DELAY = 250;
18530
18552
  canvasRef;
18531
18553
  svgRef;
18532
18554
  wftemplatedetail;
18533
18555
  get normalEdges() {
18534
- return this.lstTemplateEdge.filter((e) => e !== this.hoverTemplateEdge);
18556
+ const hoveredSet = new Set(this.hoverEdges);
18557
+ return this.lstTemplateEdge.filter((e) => !hoveredSet.has(e));
18535
18558
  }
18536
18559
  get hoverEdges() {
18537
- if (this.hoverTemplateEdge)
18538
- return [this.hoverTemplateEdge];
18539
- if (this.selectedTemplateEdge)
18540
- return [this.selectedTemplateEdge];
18560
+ if (this.hoverTemplateEdge) {
18561
+ return this.getDownstreamEdges(this.hoverTemplateEdge);
18562
+ }
18563
+ if (this.selectedTemplateEdge) {
18564
+ return [this.selectedTemplateEdge]; // Nếu chỉ click chọn thì đỏ 1 đường, hoặc bạn có thể dùng getDownstreamEdges ở đây nếu muốn
18565
+ }
18541
18566
  return [];
18542
18567
  }
18543
18568
  //#endregion
@@ -18645,8 +18670,8 @@ class WF_Template_CombineEditorComponent extends BaseComponent {
18645
18670
  canvasHeight: this.getCanvasHeight(),
18646
18671
  nodes: this.lstTemplateNode,
18647
18672
  onPanChange: (x, y) => {
18648
- this.templateCombine.editorOption.panX = x;
18649
- this.templateCombine.editorOption.panY = y;
18673
+ this.templateCombine.editorOption.panX = Math.round(x);
18674
+ this.templateCombine.editorOption.panY = Math.round(y);
18650
18675
  },
18651
18676
  });
18652
18677
  }
@@ -18995,7 +19020,26 @@ class WF_Template_CombineEditorComponent extends BaseComponent {
18995
19020
  onmousedownPoint(event, p) {
18996
19021
  event.stopPropagation();
18997
19022
  event.preventDefault();
18998
- this.draggingPoint = this.draggingPoint ? undefined : p;
19023
+ const currentTime = new Date().getTime();
19024
+ // Nếu khoảng cách giữa 2 lần click < 300ms => Nhận diện là Double Click
19025
+ if (currentTime - this.pointClickTimer < 300) {
19026
+ // 1. Tìm đường nối (edge) đang chứa điểm này
19027
+ const activeEdge = this.hoverTemplateEdge || this.selectedTemplateEdge;
19028
+ // 2. Xóa điểm khỏi mảng points
19029
+ if (activeEdge && activeEdge.editorOption.points) {
19030
+ const index = activeEdge.editorOption.points.indexOf(p);
19031
+ if (index > -1) {
19032
+ activeEdge.editorOption.points.splice(index, 1);
19033
+ }
19034
+ }
19035
+ // 3. Reset trạng thái
19036
+ this.draggingPoint = undefined;
19037
+ this.pointClickTimer = 0;
19038
+ return;
19039
+ }
19040
+ // Nếu click 1 lần (Single Click) => Nhận diện là bắt đầu kéo (Drag)
19041
+ this.pointClickTimer = currentTime;
19042
+ this.draggingPoint = p;
18999
19043
  }
19000
19044
  onRightClickPoint(event, edge, index) {
19001
19045
  event.preventDefault();
@@ -19109,8 +19153,10 @@ class WF_Template_CombineEditorComponent extends BaseComponent {
19109
19153
  const pt = svg.createSVGPoint();
19110
19154
  pt.x = event.clientX;
19111
19155
  pt.y = event.clientY;
19156
+ // Áp dụng ma trận của SVG để quy đổi tọa độ màn hình -> tọa độ Canvas thực tế
19112
19157
  const result = pt.matrixTransform(svg.getScreenCTM().inverse());
19113
- return preview ? { x: result.x, y: result.y } : { x: event.clientX, y: event.clientY };
19158
+ // Bỏ điều kiện preview, LUÔN LUÔN trả về tọa độ result (đã quy đổi theo zoom scale)
19159
+ return { x: result.x, y: result.y };
19114
19160
  }
19115
19161
  snapPoint(p, event) {
19116
19162
  if (!this.snapToGrid || event?.altKey)
@@ -19178,8 +19224,8 @@ class WF_Template_CombineEditorComponent extends BaseComponent {
19178
19224
  const canvasX = (x - this.templateCombine.editorOption.panX) / this.zoom;
19179
19225
  const canvasY = (y - this.templateCombine.editorOption.panY) / this.zoom;
19180
19226
  this.zoom = parseFloat(newZoom.toFixed(2));
19181
- this.templateCombine.editorOption.panX = x - canvasX * this.zoom;
19182
- this.templateCombine.editorOption.panY = y - canvasY * this.zoom;
19227
+ this.templateCombine.editorOption.panX = Math.round(x - canvasX * this.zoom);
19228
+ this.templateCombine.editorOption.panY = Math.round(y - canvasY * this.zoom);
19183
19229
  this.syncminimapViewport();
19184
19230
  }
19185
19231
  // UNDO/REDO
@@ -19456,8 +19502,23 @@ class WF_Template_CombineEditorComponent extends BaseComponent {
19456
19502
  this.selectedTemplateNode = undefined;
19457
19503
  }
19458
19504
  }
19505
+ getDownstreamEdges(startEdge) {
19506
+ const resultSet = new Set();
19507
+ const queue = [startEdge];
19508
+ while (queue.length > 0) {
19509
+ const currentEdge = queue.shift();
19510
+ // Nếu chưa có trong set thì mới xử lý (để chống lỗi vòng lặp vô hạn A->B->A)
19511
+ if (!resultSet.has(currentEdge)) {
19512
+ resultSet.add(currentEdge);
19513
+ // Tìm các cạnh tiếp theo: có From_ID bằng với To_ID của cạnh hiện tại
19514
+ const nextEdges = this.lstTemplateEdge.filter((e) => e.From_WF_Template_Id === currentEdge.To_WF_Template_Id);
19515
+ queue.push(...nextEdges);
19516
+ }
19517
+ }
19518
+ return Array.from(resultSet);
19519
+ }
19459
19520
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: WF_Template_CombineEditorComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
19460
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.7", type: WF_Template_CombineEditorComponent, isStandalone: true, selector: "app-workflow-combine-editor", inputs: { lstTemplateForSelect: "lstTemplateForSelect" }, outputs: { onSave: "onSave", onDeleteTempldateNode: "onDeleteTempldateNode" }, host: { listeners: { "window:keydown": "onKeyDown($event)" } }, viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["canvas"], descendants: true, static: true }, { propertyName: "svgRef", first: true, predicate: ["svg"], descendants: true, static: true }, { propertyName: "wftemplatedetail", first: true, predicate: ["wftemplatedetail"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div\n #canvas\n class=\"workflow-canvas\"\n [class.connecting]=\"!!connectingFrom\"\n [class.dragging-point]=\"!!draggingPoint\"\n style=\"width: 100%; height: 100%\"\n (mousedown)=\"onMouseDownCanvas($event)\"\n (mousemove)=\"onMouseMoveCanvas($event)\"\n (mouseup)=\"onMouseUpCanvas($event)\"\n (click)=\"onClickCanvas($event)\"\n (wheel)=\"onWheelCanvas($event)\"\n>\n <!-- TOOLBAR -->\n <div class=\"toolbar\" (mousedown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\">\n <button nz-button nzSize=\"small\" nz-tooltip=\"Editor setting\" (click)=\"settingVisible = true\">\n <nz-icon nzType=\"setting\"></nz-icon>\n </button>\n\n <button nz-button nzSize=\"small\" nz-tooltip=\"Infomation\" (click)=\"infoVisible = true\">\n <nz-icon nzType=\"info-circle\"></nz-icon>\n </button>\n\n <box [width]=\"1\"></box>\n <span class=\"divider\"></span>\n <box [width]=\"1\"></box>\n\n <button nz-button nzSize=\"small\" nz-tooltip=\"Global Setting\" (click)=\"drawTemplateVisibel = true\">\n <nz-icon nzType=\"setting\"></nz-icon> G\n </button>\n\n <box [width]=\"1\"></box>\n <span class=\"divider\"></span>\n <box [width]=\"1\"></box>\n\n <button nz-button nzSize=\"small\" nzDanger [nzLoading]=\"!ready\" nz-tooltip=\"Save (Ctrl + S)\" (click)=\"save()\">\n <nz-icon nzType=\"save\"></nz-icon>\n </button>\n <button nz-button nzSize=\"small\" nz-tooltip=\"Th\u00EAm Template m\u1EDBi\" (click)=\"isModalVisible = true\">\n <nz-icon nzType=\"plus\" class=\"color-primary\"></nz-icon>\n </button>\n\n <box [width]=\"1\"></box>\n <span class=\"divider\"></span>\n <box [width]=\"1\"></box>\n\n <button\n nz-button\n nzSize=\"small\"\n [nzType]=\"isMoveMode ? 'primary' : 'default'\"\n nz-tooltip=\"Move mode\"\n (click)=\"isMoveMode = true\"\n >\n <nz-icon><img src=\"/assets/icon/hand-palm.png\" width=\"19\" height=\"19\" /></nz-icon>\n </button>\n <button\n nz-button\n nzSize=\"small\"\n [nzType]=\"!isMoveMode ? 'primary' : 'default'\"\n nz-tooltip=\"Select mode\"\n (click)=\"isMoveMode = false\"\n >\n <nz-icon><img src=\"/assets/icon/cursor.png\" width=\"19\" height=\"19\" /></nz-icon>\n </button>\n\n <box [width]=\"1\"></box>\n <span class=\"divider\"></span>\n <box [width]=\"1\"></box>\n\n <!-- UNDO / REDO -->\n <button\n nz-button\n nzSize=\"small\"\n nzType=\"default\"\n [disabled]=\"undoStack.length === 0\"\n nz-tooltip=\"Undo\"\n (click)=\"undo()\"\n >\n <nz-icon nzType=\"undo\"></nz-icon>\n </button>\n <button\n nz-button\n nzSize=\"small\"\n nzType=\"default\"\n [disabled]=\"redoStack.length === 0\"\n nz-tooltip=\"Redo\"\n (click)=\"redo()\"\n >\n <nz-icon nzType=\"redo\"></nz-icon>\n </button>\n\n <box [width]=\"1\"></box>\n <span class=\"divider\"></span>\n <box [width]=\"1\"></box>\n\n <!-- ALIGN -->\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 2\" (click)=\"alignLeft()\">\u27F8</button>\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 2\" (click)=\"alignCenter()\">\u2261</button>\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 2\" (click)=\"alignRight()\">\u27F9</button>\n <span class=\"divider\"></span>\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 2\" (click)=\"alignTop()\">\u21D1</button>\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 2\" (click)=\"alignMiddle()\">\u2550</button>\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 2\" (click)=\"alignBottom()\">\u21D3</button>\n <span class=\"divider\"></span>\n <!-- DISTRIBUTE -->\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 3\" (click)=\"distributeHorizontal()\">\n \u21C4\n </button>\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 3\" (click)=\"distributeVertical()\">\n \u21C5\n </button>\n\n <box [width]=\"1\"></box>\n <span class=\"divider\"></span>\n <box [width]=\"1\"></box>\n\n <!-- ZOOM -->\n <button nz-button nzSize=\"small\" nzType=\"default\" (click)=\"zoomOut()\" nz-tooltip=\"Zoom Out\">\n <nz-icon nzType=\"minus\"></nz-icon>\n </button>\n <span>{{ Math.round(zoom * 100) }}%</span>\n <button nz-button nzSize=\"small\" nzType=\"default\" (click)=\"zoomIn()\" nz-tooltip=\"Zoom In\">\n <nz-icon nzType=\"plus\"></nz-icon>\n </button>\n <span class=\"divider\"></span>\n <button nz-button nzSize=\"small\" nzType=\"default\" (click)=\"resetZoom()\" nz-tooltip=\"Reset Zoom (Ctrl+0)\">\n <nz-icon nzType=\"expand\"></nz-icon>\n </button>\n </div>\n\n <div\n class=\"canvas-content\"\n [class.panning]=\"isMoveMode\"\n [style.width.px]=\"getCanvasWidth()\"\n [style.height.px]=\"getCanvasHeight()\"\n [style.transform]=\"\n 'translate(' +\n templateCombine.editorOption.panX +\n 'px,' +\n templateCombine.editorOption.panY +\n 'px) scale(' +\n zoom +\n ')'\n \"\n >\n <!-- GRID -->\n <div *ngIf=\"wfcSetting.ShowGrid\" class=\"grid-layer\"></div>\n\n <!-- SVG EDGES -->\n <svg #svg class=\"edges-layer\" width=\"100%\" height=\"100%\" preserveAspectRatio=\"none\">\n <g>\n <!-- DEFS -->\n <defs>\n <filter id=\"edge-glow\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\n <feGaussianBlur stdDeviation=\"2\" result=\"blur\" />\n <feMerge>\n <feMergeNode in=\"blur\" />\n <feMergeNode in=\"SourceGraphic\" />\n </feMerge>\n </filter>\n\n <marker\n id=\"arrow-blue\"\n markerWidth=\"10\"\n markerHeight=\"10\"\n refX=\"10\"\n refY=\"5\"\n orient=\"auto\"\n markerUnits=\"strokeWidth\"\n >\n <path class=\"blue\" d=\"M0,0 L10,5 L0,10\"></path>\n </marker>\n <marker\n id=\"arrow-red\"\n markerWidth=\"10\"\n markerHeight=\"10\"\n refX=\"10\"\n refY=\"5\"\n orient=\"auto\"\n markerUnits=\"strokeWidth\"\n >\n <path class=\"red\" d=\"M0,0 L10,5 L0,10\"></path>\n </marker>\n </defs>\n\n <!-- EDGES B\u00CCNH TH\u01AF\u1EDCNG -->\n <ng-container *ngFor=\"let e of normalEdges; let i = index\">\n <path class=\"edge\" [attr.id]=\"'edge-path-' + i\" [attr.d]=\"buildPath(e)\" marker-end=\"url(#arrow-blue)\"></path>\n\n <path\n class=\"edge-hit\"\n [attr.d]=\"buildPath(e)\"\n (mouseenter)=\"onMouseEnterEdge(e)\"\n (mouseleave)=\"onMouseLeaveEdge(e)\"\n (click)=\"onClickEdge(e, $event)\"\n ></path>\n\n <!-- \u0110\u00E3 x\u00F3a *ngIf=\"e.RuleLineDetails?.length\" \u1EDF \u0111\u00E2y \u0111\u1EC3 text lu\u00F4n hi\u1EC7n -->\n <text\n class=\"edge-label\"\n style=\"fill: #1890ff; font-weight: 500\"\n [attr.x]=\"getEdgeLabelPosition(e).x\"\n [attr.y]=\"getEdgeLabelPosition(e).y - 8\"\n [attr.text-anchor]=\"'middle'\"\n >\n {{ e.FromStage }} / {{ e.FromAction }} > {{ e.ToStage }} / {{ e.ToAction }}\n </text>\n </ng-container>\n\n <!-- EDGE \u0110ANG HOVER/SELECTED (HI\u1EC2N TH\u1ECA M\u00C0U \u0110\u1ECE) -->\n <ng-container *ngFor=\"let e of hoverEdges; let i = index\">\n <path\n class=\"edge red\"\n [attr.id]=\"'edge-path-hover-' + i\"\n [attr.d]=\"buildPath(e)\"\n marker-end=\"url(#arrow-red)\"\n ></path>\n\n <path\n class=\"edge-hit\"\n [attr.d]=\"buildPath(e)\"\n (mouseleave)=\"onMouseLeaveEdge(e)\"\n (click)=\"onClickEdge(e, $event)\"\n ></path>\n\n <text\n class=\"edge-label\"\n style=\"font-weight: bold; fill: red\"\n [attr.x]=\"getEdgeLabelPosition(e).x\"\n [attr.y]=\"getEdgeLabelPosition(e).y - 8\"\n [attr.text-anchor]=\"'middle'\"\n >\n {{ e.FromStage }} / {{ e.FromAction }} > {{ e.ToStage }} / {{ e.ToAction }}\n </text>\n </ng-container>\n\n <!-- PREVIEW LINE (\u0110\u01AF\u1EDCNG N\u1ED0I \u0110ANG K\u00C9O) -->\n <path\n *ngIf=\"connectingFrom\"\n class=\"edge\"\n [attr.d]=\"buildPreviewPath()\"\n stroke-dasharray=\"5,5\"\n marker-end=\"url(#arrow-blue)\"\n ></path>\n </g>\n </svg>\n\n <!-- BOX V\u00D9NG CH\u1ECCN MULTI -->\n <div\n *ngIf=\"isSelecting && selectStart && selectEnd\"\n class=\"selection-box\"\n [style.left.px]=\"Math.min(selectStart.x, selectEnd.x)\"\n [style.top.px]=\"Math.min(selectStart.y, selectEnd.y)\"\n [style.width.px]=\"Math.abs(selectEnd.x - selectStart.x)\"\n [style.height.px]=\"Math.abs(selectEnd.y - selectStart.y)\"\n ></div>\n\n <!-- NODE (TEMPLATE) L\u1EDAP HI\u1EC2N TH\u1ECA TR\u00CAN C\u00D9NG -->\n @for (n of lstTemplateNode; track n.WF_Template_Id) {\n <nz-card\n class=\"workflow-node\"\n [attr.data-id]=\"n.Code\"\n [class.selected]=\"\n n == selectedTemplateNode || n == hoverTemplateNode || lstSelectedTemplateId.has(n.WF_Template_Id)\n \"\n [style.left.px]=\"n.editorOption.x\"\n [style.top.px]=\"n.editorOption.y\"\n [class.connecting-source]=\"isConnectingFrom(n) || isDraggingFrom(n) || isSelectedNode(n)\"\n nzSize=\"small\"\n (mousedown)=\"onMouseDownNode($event, n)\"\n (click)=\"$event.stopPropagation(); onClickNode(n)\"\n >\n <div class=\"title\" style=\"color: #1890ff; display: flex; justify-content: space-between; align-items: center\">\n <span>{{ n.Code }}</span>\n <nz-icon nzType=\"layout\" nzTheme=\"outline\"></nz-icon>\n </div>\n <div\n style=\"\n font-size: 12px;\n line-height: 1.2;\n font-weight: 500;\n height: 28px;\n overflow: hidden;\n text-overflow: ellipsis;\n \"\n >\n {{ n.Name || \"Ch\u01B0a c\u00F3 t\u00EAn\" }}\n </div>\n <div style=\"font-size: 10px; color: gray; margin-top: 4px\">\n {{ n.DocType }}\n </div>\n\n <!-- CONNECTOR \u0110\u1EC2 K\u00C9O D\u00C2Y -->\n <div class=\"connector connector-right\" (click)=\"onClickConnector($event, n, 'right')\"></div>\n <div class=\"connector connector-left\" (click)=\"onClickConnector($event, n, 'left')\"></div>\n </nz-card>\n }\n\n <!-- C\u00C1C \u0110I\u1EC2M WAYPOINT \u0110\u1EC2 B\u1EBA CONG D\u00C2Y CHU\u1ED8T -->\n @for (p of connectingPoints; track $index) {\n @if (p != draggingPoint) {\n <div\n class=\"waypoint\"\n [style.left.px]=\"p.x\"\n [style.top.px]=\"p.y\"\n (mousedown)=\"onmousedownPoint($event, p)\"\n (contextmenu)=\"onRightClickPoint($event, hoverTemplateEdge!, $index)\"\n ></div>\n } @else {\n <div\n class=\"waypoint dragging\"\n [style.left.px]=\"p.x\"\n [style.top.px]=\"p.y\"\n (mousedown)=\"onmousedownPoint($event, p)\"\n ></div>\n }\n }\n </div>\n</div>\n\n<!-- ==============================================\n 1. DRAWER: GLOBAL TEMPLATE SETTINGS \n=============================================== -->\n<nz-drawer\n [nzTitle]=\"drawTemplateTitle\"\n nzPlacement=\"right\"\n [nzWidth]=\"500\"\n [nzClosable]=\"false\"\n [nzVisible]=\"drawTemplateVisibel\"\n [nzFooter]=\"footerTplTemplate\"\n (nzOnClose)=\"drawTemplateVisibel = false\"\n>\n <ng-template #drawTemplateTitle> <nz-icon nzType=\"global\"></nz-icon> &nbsp; Quy tr\u00ECnh ph\u1ED1i h\u1EE3p </ng-template>\n <ng-container *nzDrawerContent>\n <!-- Gi\u1EEF nguy\u00EAn c\u00E1c th\u00F4ng tin chung to\u00E0n c\u1EE5c c\u1EE7a b\u1EA1n \u1EDF \u0111\u00E2y -->\n\n <extend-input [label]=\"'Code'\" [(_ngModel)]=\"templateCombine.Code\"></extend-input>\n <extend-input [label]=\"'Name'\" [(_ngModel)]=\"templateCombine.Name\"></extend-input>\n <extend-textarea [label]=\"'Description'\" [(_ngModel)]=\"templateCombine.Description\"></extend-textarea>\n <extend-checkbox [label]=\"'Active'\" [(_ngModel)]=\"templateCombine.IsActive\"></extend-checkbox>\n </ng-container>\n\n <ng-template #footerTplTemplate>\n <div nz-flex [nzGap]=\"6\" [nzJustify]=\"'end'\">\n <button nz-button nzDanger [nzLoading]=\"!ready\" (click)=\"save()\">Save</button>\n <button nz-button (click)=\"drawTemplateVisibel = false\">Close</button>\n </div>\n </ng-template>\n</nz-drawer>\n\n<!-- ==============================================\n 2. DRAWER: NODE SETTINGS (CHI TI\u1EBET M\u1ED8T TEMPLATE)\n=============================================== -->\n<nz-drawer\n [nzTitle]=\"drawerTitleNode\"\n [nzPlacement]=\"selectedTemplateNode?.editorOption?.drawerPosition == 'left' ? 'left' : 'right'\"\n [nzVisible]=\"!!selectedTemplateNode\"\n [nzWidth]=\"'90vw'\"\n [nzClosable]=\"false\"\n [nzFooter]=\"footerTplNode\"\n (nzOnClose)=\"selectedTemplateNode = undefined\"\n>\n <ng-template #drawerTitleNode>\n <div nz-row nzJustify=\"space-between\">\n <span style=\"font-weight: bold; color: #1890ff\"\n ><nz-icon nzType=\"layout\"></nz-icon> TEMPLATE NODE: [{{ selectedTemplateNode?.Code }}]\n {{ selectedTemplateNode?.Name }}</span\n >\n <button\n nz-button\n nzSize=\"small\"\n nz-tooltip=\"Chuy\u1EC3n v\u1ECB tr\u00ED Drawer\"\n (click)=\"\n selectedTemplateNode!.editorOption.drawerPosition =\n selectedTemplateNode!.editorOption.drawerPosition === 'left' ? 'right' : 'left'\n \"\n >\n <nz-icon nzType=\"swap\"></nz-icon>\n </button>\n </div>\n </ng-template>\n\n <ng-container *nzDrawerContent>\n <ng-container *ngIf=\"selectedTemplateNode\">\n <wf-template-detail #wftemplatedetail></wf-template-detail>\n </ng-container>\n </ng-container>\n\n <ng-template #footerTplNode>\n <div\n nz-flex\n [nzGap]=\"6\"\n [nzJustify]=\"selectedTemplateNode?.editorOption?.drawerPosition == 'left' ? 'start' : 'end'\"\n >\n <button nz-button nzDanger [nzLoading]=\"!ready\" (click)=\"wftemplatedetail.wfeditor.save()\">Save</button>\n <button nz-button (click)=\"selectedTemplateNode = undefined\">Close</button>\n <button nz-button nzDanger (click)=\"deleteTemplateNode()\">Delete Template node</button>\n </div>\n </ng-template>\n</nz-drawer>\n\n<!-- ==============================================\n 3. DRAWER: EDGE SETTINGS (QU\u1EA2N L\u00DD QUY T\u1EAEC CHUY\u1EC2N TEMPLATE)\n=============================================== -->\n<nz-drawer\n [nzTitle]=\"drawerTitleEdge\"\n [nzPlacement]=\"selectedTemplateEdge?.editorOption?.drawerPosition == 'left' ? 'left' : 'right'\"\n [nzClosable]=\"false\"\n [nzWidth]=\"'450px'\"\n [nzVisible]=\"!!selectedTemplateEdge\"\n [nzFooter]=\"footerTplEdge\"\n (nzOnClose)=\"selectedTemplateEdge = undefined\"\n>\n <ng-template #drawerTitleEdge>\n <div nz-row nzJustify=\"space-between\">\n <span style=\"font-weight: bold; color: #ff4d4f\"><nz-icon nzType=\"swap-right\"></nz-icon> TRANSITION RULES </span>\n <button\n nz-button\n nzSize=\"small\"\n nz-tooltip=\"Chuy\u1EC3n v\u1ECB tr\u00ED Drawer\"\n (click)=\"\n selectedTemplateEdge!.editorOption.drawerPosition =\n selectedTemplateEdge!.editorOption.drawerPosition === 'left' ? 'right' : 'left'\n \"\n >\n <nz-icon nzType=\"swap\"></nz-icon>\n </button>\n </div>\n </ng-template>\n\n <ng-container *nzDrawerContent>\n <ng-container *ngIf=\"selectedTemplateEdge\">\n <!-- Th\u00F4ng tin 2 \u0111\u1EA7u n\u1ED1i -->\n <div\n style=\"background: #fdf5f6; padding: 12px; border: 1px solid #ffa39e; border-radius: 6px; margin-bottom: 16px\"\n >\n <div style=\"font-size: 14px\">\n <strong style=\"display: inline-block; width: 70px; color: #555\">From:</strong>\n <span style=\"color: #1890ff; font-weight: 500\">\n [{{ getNode(selectedTemplateEdge.From_WF_Template_Id)?.Code }}]\n {{ getNode(selectedTemplateEdge.From_WF_Template_Id)?.Name }} > {{ selectedTemplateEdge.FromStage }} >\n {{ selectedTemplateEdge.FromAction }}\n </span>\n </div>\n <div style=\"font-size: 14px; margin-top: 8px\">\n <strong style=\"display: inline-block; width: 70px; color: #555\">Taget:</strong>\n <span style=\"color: #1890ff; font-weight: 500\">\n [{{ getNode(selectedTemplateEdge.To_WF_Template_Id)?.Code }}]\n {{ getNode(selectedTemplateEdge.To_WF_Template_Id)?.Name }} > {{ selectedTemplateEdge.ToStage }} >\n {{ selectedTemplateEdge.ToAction }}\n </span>\n </div>\n </div>\n </ng-container>\n </ng-container>\n\n <ng-template #footerTplEdge>\n <div\n nz-flex\n [nzGap]=\"6\"\n [nzJustify]=\"selectedTemplateEdge?.editorOption?.drawerPosition == 'left' ? 'start' : 'end'\"\n >\n <button nz-button nzDanger [nzLoading]=\"!ready\" (click)=\"save()\">Save Rules</button>\n <button\n nz-button\n nzDanger\n (click)=\"\n lstTemplateEdge.splice(lstTemplateEdge.indexOf(selectedTemplateEdge!), 1); selectedTemplateEdge = undefined\n \"\n >\n Delete Transition\n </button>\n <button nz-button (click)=\"selectedTemplateEdge = undefined\">Close</button>\n </div>\n </ng-template>\n</nz-drawer>\n\n<!-- ==============================================\n 4. EDITOR SETTING & INFO\n=============================================== -->\n<nz-drawer\n [nzTitle]=\"drawSettingTitle\"\n nzPlacement=\"right\"\n [nzClosable]=\"false\"\n [nzVisible]=\"settingVisible\"\n (nzOnClose)=\"settingVisible = false\"\n>\n <ng-template #drawSettingTitle> <nz-icon nzType=\"setting\"></nz-icon> &nbsp; C\u00E0i \u0111\u1EB7t Editor </ng-template>\n <ng-container *nzDrawerContent>\n <div class=\"form-item-no-bottom\">\n <extend-checkbox\n [label]=\"'Hi\u1EC3n th\u1ECB L\u01B0\u1EDBi (Grid)'\"\n [labelSpan]=\"0\"\n [(_ngModel)]=\"wfcSetting.ShowGrid\"\n ></extend-checkbox>\n </div>\n </ng-container>\n</nz-drawer>\n\n<nz-drawer\n [nzTitle]=\"drawInfoTitle\"\n nzPlacement=\"right\"\n [nzClosable]=\"false\"\n [nzVisible]=\"infoVisible\"\n (nzOnClose)=\"infoVisible = false\"\n>\n <ng-template #drawInfoTitle> <nz-icon nzType=\"info-circle\"></nz-icon> &nbsp; H\u01B0\u1EDBng d\u1EABn (Infomation) </ng-template>\n <ng-container *nzDrawerContent>\n <p>\n <strong>1. C\u00E1c th\u00E0nh ph\u1EA7n:</strong> C\u00E1c \u00F4 ch\u1EEF nh\u1EADt l\u00E0 Template (Quy tr\u00ECnh nh\u1ECF), c\u00E1c \u0111\u01B0\u1EDDng n\u1ED1i l\u00E0 Transition Rule\n (Quy t\u1EAFc chuy\u1EC3n quy tr\u00ECnh).\n </p>\n <p><strong>2. C\u00E1ch n\u1ED1i 2 Template:</strong></p>\n <ul>\n <li>Click ch\u1EA5m cam b\u00EAn ph\u1EA3i Template A, sau \u0111\u00F3 k\u00E9o v\u00E0 click v\u00E0o Template B \u0111\u1EC3 t\u1EA1o Rule n\u1ED1i.</li>\n <li>C\u00F3 th\u1EC3 click nhi\u1EC1u \u0111i\u1EC3m trong l\u00FAc k\u00E9o \u0111\u1EC3 b\u1EBB \u0111\u01B0\u1EDDng cong tu\u1EF3 \u00FD (Waypoint).</li>\n <li>Click \u0111\u00FAp v\u00E0o c\u1EA1nh (\u0111\u01B0\u1EDDng n\u1ED1i) \u0111ang c\u00F3 \u0111\u1EC3 t\u1EA1o th\u00EAm m\u1ED9t \u0111i\u1EC3m b\u1EBB cong m\u1EDBi.</li>\n <li>Gi\u1EEF v\u00E0 k\u00E9o \u0111i\u1EC3m b\u1EBB cong \u0111\u1EC3 tu\u1EF3 ch\u1EC9nh \u0111\u01B0\u1EDDng \u0111i. Chu\u1ED9t ph\u1EA3i v\u00E0o \u0111i\u1EC3m \u0111\u00F3 \u0111\u1EC3 x\u00F3a n\u00F3.</li>\n </ul>\n <p>\n <strong>3. Qu\u1EA3n l\u00FD Rule:</strong> Click v\u00E0o \u0111\u01B0\u1EDDng n\u1ED1i gi\u1EEFa 2 Node \u0111\u1EC3 c\u1EA5u h\u00ECnh c\u00E1c lu\u1ED3ng th\u1EF1c thi (Stored, Ph\u00E2n\n quy\u1EC1n, G\u1EEDi mail).\n </p>\n </ng-container>\n</nz-drawer>\n\n<nz-modal\n [(nzVisible)]=\"isModalVisible\"\n nzTitle=\"Add template node\"\n [nzWidth]=\"600\"\n (nzOnCancel)=\"isModalVisible = false\"\n (nzOnOk)=\"addTemplateNodes()\"\n nzOkText=\"Add\"\n nzOkDanger\n nzCancelText=\"Cancel\"\n nzMaskClosable=\"false\"\n>\n <ng-container *nzModalContent>\n <extend-select\n label=\"Template\"\n [lstItem]=\"lstTemplateForSelect\"\n [displayField]=\"'Name'\"\n [multiple]=\"true\"\n [(_ngModel)]=\"lstTemplateSelected\"\n ></extend-select>\n </ng-container>\n</nz-modal>\n", styles: ["@charset \"UTF-8\";::ng-deep .workflow-wrapper{border:solid 1px lightgray;overflow:hidden;width:100%}.workflow-canvas{position:relative;background:#f0f2f5;cursor:default;overflow:hidden;outline:1px dashed rgba(0,0,0,.1)}.workflow-canvas .edges-layer{position:absolute;inset:0;width:100%;height:100%;z-index:1}.workflow-canvas .edges-layer path{stroke-width:2;fill:none}.canvas-content{transform-origin:0 0;width:100%;height:100%;transition:transform .05s linear}.canvas-content{outline:1px dashed red}.canvas-content.panning{cursor:grab}.canvas-content.panning:active{cursor:grabbing}.workflow-canvas.panning{cursor:grab}.workflow-canvas.panning:active{cursor:grabbing}.workflow-canvas.connecting,.workflow-canvas.connecting .workflow-node{cursor:crosshair}.workflow-node{position:absolute;width:160px;cursor:grab;-webkit-user-select:none;user-select:none;z-index:2}.workflow-node:active{cursor:grabbing}.workflow-node.connecting-source,.workflow-node.selected,.workflow-node:hover:not(.workflow-node-start,.workflow-node-end){outline:2px dashed #1890ff}.workflow-node .title{font-weight:600;margin-bottom:6px}.workflow-node-start{width:0px}.workflow-node-start.connecting-source,.workflow-node-start.selected,.workflow-node-start:hover{outline:unset}.workflow-node-start.connecting-source nz-tag,.workflow-node-start.selected nz-tag,.workflow-node-start:hover nz-tag{outline:2px dashed}.workflow-node-start nz-tag{position:relative;top:45px;right:35px}.workflow-node-end{width:0px}.workflow-node-end.connecting-source,.workflow-node-end.selected,.workflow-node-end:hover{outline:unset}.workflow-node-end.connecting-source nz-tag,.workflow-node-end.selected nz-tag,.workflow-node-end:hover nz-tag{outline:2px dashed}.workflow-node-end nz-tag{position:relative;top:45px;right:32px}.connector{position:absolute;top:39px;width:12px;height:12px;background:#1890ff;border-radius:50%;transform:translateY(-50%);cursor:crosshair;transition:box-shadow .15s ease-out,transform .15s ease-out}.connector:hover{box-shadow:0 0 0 3px #1890ff4d;transform:translateY(-50%) scale(1.15)}.connector-right{right:-8px;background:orange}.connector-right.reverse,.connector-left{left:-8px}.connector-left.reverse{left:unset;right:-8px}.connector-start{width:16px;height:16px;right:-8px;background:green;box-shadow:0 0 0 3px #1890ff4d}.connector-end{width:16px;height:16px;left:-8px;background:#000;box-shadow:0 0 0 3px #1890ff4d}.edge{cursor:pointer;stroke:#1890ff;stroke-linecap:round;stroke-linejoin:round;stroke-width:2;fill:none;transition:stroke .15s ease}.edge-hit{stroke:transparent;stroke-width:18px!important;fill:none;cursor:pointer}.edge-hit:hover+.edge{stroke:#ff4d4f;stroke-width:2}.workflow-canvas.dragging-point .edge-hit{pointer-events:none}.edge:hover+.edge-label{fill:#1890ff;font-weight:500}.edge-label{font-size:12px;fill:#555;pointer-events:none;-webkit-user-select:none;user-select:none}.blue{stroke:#1890ff!important}.red{stroke:#ff4d4f!important;box-shadow:0 0 0 3px #1890ff4d!important}.workflow-svg{background:transparent;overflow:visible}.waypoint{position:absolute;width:10px;height:10px;background:#ff4d4f;border-radius:50%;transform:translate(-50%,-50%) scale(1);cursor:move;z-index:1;transition:transform .12s ease-out,background-color .12s ease-out,box-shadow .12s ease-out}.waypoint:hover{background:#ff7875;transform:translate(-50%,-50%) scale(1.25);box-shadow:0 0 0 4px #ff787559}.waypoint.dragging{transition:none;transform:translate(-50%,-50%) scale(1.15);pointer-events:none}.workflow-canvas.dragging-point svg{cursor:grabbing}.selection-box{position:absolute;border:1px dashed #1890ff;background:#1890ff1a;pointer-events:none}.toolbar{position:absolute;top:8px;left:8px;display:flex;gap:4px;padding:6px;background:#fff;border-radius:6px;box-shadow:0 2px 8px #00000026;z-index:100}.toolbar .divider{width:1px;background:#e5e5e5;margin:0 2px}nz-tag.selected{outline:2px dashed #1890ff}.grid-layer{position:absolute;inset:0;pointer-events:none;z-index:0;background-image:radial-gradient(rgba(0,0,0,.08) 1px,transparent 1px);background-size:20px 20px}.grid-layer{background-image:linear-gradient(to right,rgba(0,0,0,.06) 1px,transparent 1px),linear-gradient(to bottom,rgba(0,0,0,.06) 1px,transparent 1px);background-size:20px 20px}.editable-tag{background:#fff;border-style:dashed}::ng-deep .minimap,.minimap-combine{position:absolute;width:180px;height:125px;top:0;right:0;background-color:#eee;border:1px solid #aaa;opacity:.9;z-index:1}::ng-deep .minimap{position:absolute;width:200px;height:140px;top:8px;right:8px;background-color:#f8f9fa;border:1px solid #d9d9d9;border-radius:8px;box-shadow:0 4px 12px #0000001a;overflow:hidden;z-index:100;-webkit-user-select:none;user-select:none}::ng-deep .minimap-node{position:absolute;background-color:#bfbfbf;border-radius:2px}::ng-deep .minimap-node-round{position:absolute;background-color:#bfbfbf;border-radius:50%}::ng-deep .minimap-node-round-start{background-color:#52c41a}::ng-deep .minimap-node-round-end{background-color:#ff4d4f}::ng-deep .minimap-viewport{position:absolute;box-sizing:border-box;background-color:#1890ff26;border:1.5px solid #1890ff;border-radius:4px;z-index:2;cursor:grab;transition:none}::ng-deep .minimap-viewport.grabbing,::ng-deep .minimap-viewport:active{cursor:grabbing;background-color:#1890ff40}::ng-deep .has-floating-label.floating-label{position:relative;padding-top:14px}::ng-deep .has-floating-label nz-form-item nz-form-label{position:absolute;top:12px;left:13px;transform:translateY(-50%);background:linear-gradient(to bottom,var(--form-bg-color, #ffffff) 80%,#ffffff 80%);z-index:1;height:auto;line-height:normal;padding:0 4px}::ng-deep .has-floating-label nz-form-item nz-form-label label{font-size:12px;color:var(--darkgray, #565656);font-weight:700;height:auto;line-height:normal;padding:0;display:flex;align-items:center}::ng-deep .has-floating-label .full-width{width:100%}.has-floating-label.floating-label nz-form-item:has(.ant-select-disabled) nz-form-label,.has-floating-label.floating-label nz-form-item:has(input[disabled]) nz-form-label,.has-floating-label.floating-label nz-form-item:has(.ant-input-disabled) nz-form-label{background:linear-gradient(to bottom,var(--form-bg-color, #ffffff) 60%,#f5f5f5 50%)}.has-floating-label.floating-label nz-form-item:has(.ant-select-disabled) nz-form-label label,.has-floating-label.floating-label nz-form-item:has(input[disabled]) nz-form-label label,.has-floating-label.floating-label nz-form-item:has(.ant-input-disabled) nz-form-label label{color:#bfbfbf}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: NzCardModule }, { kind: "component", type: i3$5.NzCardComponent, selector: "nz-card", inputs: ["nzBordered", "nzLoading", "nzHoverable", "nzBodyStyle", "nzCover", "nzActions", "nzType", "nzSize", "nzTitle", "nzExtra"], exportAs: ["nzCard"] }, { kind: "ngmodule", type: NzDrawerModule }, { kind: "component", type: i3$6.NzDrawerComponent, selector: "nz-drawer", inputs: ["nzContent", "nzCloseIcon", "nzClosable", "nzMaskClosable", "nzMask", "nzCloseOnNavigation", "nzNoAnimation", "nzKeyboard", "nzTitle", "nzExtra", "nzFooter", "nzPlacement", "nzSize", "nzMaskStyle", "nzBodyStyle", "nzWrapClassName", "nzWidth", "nzHeight", "nzZIndex", "nzOffsetX", "nzOffsetY", "nzVisible"], outputs: ["nzOnViewInit", "nzOnClose", "nzVisibleChange"], exportAs: ["nzDrawer"] }, { kind: "directive", type: i3$6.NzDrawerContentDirective, selector: "[nzDrawerContent]", exportAs: ["nzDrawerContent"] }, { kind: "ngmodule", type: NzTagModule }, { kind: "ngmodule", type: NzRadioModule }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$2.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "component", type: Box, selector: "box", inputs: ["display", "width", "height"] }, { kind: "ngmodule", type: NzButtonModule }, { kind: "component", type: i2$2.NzButtonComponent, selector: "button[nz-button], a[nz-button]", inputs: ["nzBlock", "nzGhost", "nzSearch", "nzLoading", "nzDanger", "disabled", "tabIndex", "nzType", "nzShape", "nzSize"], exportAs: ["nzButton"] }, { kind: "directive", type: i3$2.ɵNzTransitionPatchDirective, selector: "[nz-button], nz-button-group, [nz-icon], nz-icon, [nz-menu-item], [nz-submenu], nz-select-top-control, nz-select-placeholder, nz-input-group", inputs: ["hidden"] }, { kind: "directive", type: i4$1.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "ngmodule", type: NzToolTipModule }, { kind: "directive", type: i8.NzTooltipDirective, selector: "[nz-tooltip]", inputs: ["nzTooltipTitle", "nzTooltipTitleContext", "nz-tooltip", "nzTooltipTrigger", "nzTooltipPlacement", "nzTooltipOrigin", "nzTooltipVisible", "nzTooltipMouseEnterDelay", "nzTooltipMouseLeaveDelay", "nzTooltipOverlayClassName", "nzTooltipOverlayStyle", "nzTooltipArrowPointAtCenter", "cdkConnectedOverlayPush", "nzTooltipColor"], outputs: ["nzTooltipVisibleChange"], exportAs: ["nzTooltip"] }, { kind: "component", type: ExtendInput, selector: "extend-input", inputs: ["label", "floatingLabel", "placeHolder", "labelAlign", "inputClass", "labelSpan", "labelFlex", "inputFlex", "showClear", "disabled", "readOnly", "required", "noBottom", "selectModeType", "autocomplete", "autofocus", "inputWidth", "inputHeight", "borderBottomOnly", "displayInline", "size", "displayField", "valueField", "formData", "controlName", "_ngModel", "isSubmited"], outputs: ["_ngModelChange", "onclickClearIcon", "onenter"] }, { kind: "component", type: ExtendSelectComponent, selector: "extend-select", inputs: ["label", "floatingLabel", "placeHolder", "labelAlign", "dropdownMatchSelectWidth", "labelSpan", "labelFlex", "disabled", "required", "noBottom", "multiple", "showSelectAll", "maxTagCount", "inputWidth", "inputHeight", "borderBottomOnly", "displayInline", "size", "lstItem", "displayField", "displayFields", "info", "valueField", "formData", "controlName", "_ngModel", "isSubmited"], outputs: ["_ngModelChange", "itemChange", "onFocus"] }, { kind: "component", type: ExtendCheckbox, selector: "extend-checkbox", inputs: ["label", "labelSpan", "labelFlex", "paddingTop", "disabled", "formData", "controlName", "valueType", "_ngModel"], outputs: ["_ngModelChange"] }, { kind: "component", type: ExtendTextArea, selector: "extend-textarea", inputs: ["label", "placeHolder", "labelAlign", "floatingLabel", "displayInline", "formItemNoButtom", "labelSpan", "labelFlex", "inputFlex", "disabled", "required", "noBottom", "selectModeType", "inputClass", "size", "isSubmited", "minRows", "maxRows", "lstItem", "displayField", "valueField", "formData", "controlName", "_ngModel", "isTouched", "inputErrorMessage", "errorMessages"], outputs: ["_ngModelChange"] }, { kind: "ngmodule", type: NzInputModule }, { kind: "ngmodule", type: NzGridModule }, { kind: "directive", type: i2$1.NzRowDirective, selector: "[nz-row],nz-row,nz-form-item", inputs: ["nzAlign", "nzJustify", "nzGutter"], exportAs: ["nzRow"] }, { kind: "ngmodule", type: NzFlexModule }, { kind: "directive", type: i3$3.NzFlexDirective, selector: "[nz-flex],nz-flex", inputs: ["nzVertical", "nzJustify", "nzAlign", "nzGap", "nzWrap", "nzFlex"], exportAs: ["nzFlex"] }, { kind: "ngmodule", type: NzTableModule }, { kind: "ngmodule", type: NzDividerModule }, { kind: "ngmodule", type: NzAutocompleteModule }, { kind: "component", type: NzModalComponent, selector: "nz-modal", inputs: ["nzMask", "nzMaskClosable", "nzCloseOnNavigation", "nzVisible", "nzClosable", "nzOkLoading", "nzOkDisabled", "nzCancelDisabled", "nzCancelLoading", "nzKeyboard", "nzNoAnimation", "nzCentered", "nzDraggable", "nzContent", "nzFooter", "nzZIndex", "nzWidth", "nzWrapClassName", "nzClassName", "nzStyle", "nzTitle", "nzCloseIcon", "nzMaskStyle", "nzBodyStyle", "nzOkText", "nzCancelText", "nzOkType", "nzOkDanger", "nzIconType", "nzModalType", "nzAutofocus", "nzOnOk", "nzOnCancel"], outputs: ["nzOnOk", "nzOnCancel", "nzAfterOpen", "nzAfterClose", "nzVisibleChange"], exportAs: ["nzModal"] }, { kind: "directive", type: NzModalContentDirective, selector: "[nzModalContent]", exportAs: ["nzModalContent"] }, { kind: "component", type: WF_TemplateDetail, selector: "wf-template-detail" }] });
19521
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.7", type: WF_Template_CombineEditorComponent, isStandalone: true, selector: "app-workflow-combine-editor", inputs: { lstTemplateForSelect: "lstTemplateForSelect" }, outputs: { getdata: "getdata", onSave: "onSave", onDeleteTempldateNode: "onDeleteTempldateNode" }, host: { listeners: { "window:keydown": "onKeyDown($event)" } }, viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["canvas"], descendants: true, static: true }, { propertyName: "svgRef", first: true, predicate: ["svg"], descendants: true, static: true }, { propertyName: "wftemplatedetail", first: true, predicate: ["wftemplatedetail"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div\n #canvas\n class=\"workflow-canvas\"\n [class.connecting]=\"!!connectingFrom\"\n [class.dragging-point]=\"!!draggingPoint\"\n style=\"width: 100%; height: 100%\"\n (mousedown)=\"onMouseDownCanvas($event)\"\n (mousemove)=\"onMouseMoveCanvas($event)\"\n (mouseup)=\"onMouseUpCanvas($event)\"\n (click)=\"onClickCanvas($event)\"\n (wheel)=\"onWheelCanvas($event)\"\n>\n <!-- TOOLBAR -->\n <div class=\"toolbar\" (mousedown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\">\n <button nz-button nzSize=\"small\" nz-tooltip=\"Editor setting\" (click)=\"settingVisible = true\">\n <nz-icon nzType=\"setting\"></nz-icon>\n </button>\n\n <button nz-button nzSize=\"small\" nz-tooltip=\"Infomation\" (click)=\"infoVisible = true\">\n <nz-icon nzType=\"info-circle\"></nz-icon>\n </button>\n\n <box [width]=\"1\"></box>\n <span class=\"divider\"></span>\n <box [width]=\"1\"></box>\n\n <button nz-button nzSize=\"small\" nz-tooltip=\"Global Setting\" (click)=\"drawTemplateVisibel = true\">\n <nz-icon nzType=\"setting\"></nz-icon> G\n </button>\n\n <box [width]=\"1\"></box>\n <span class=\"divider\"></span>\n <box [width]=\"1\"></box>\n\n <button nz-button nzSize=\"small\" nzDanger [nzLoading]=\"!ready\" nz-tooltip=\"Save (Ctrl + S)\" (click)=\"save()\">\n <nz-icon nzType=\"save\"></nz-icon>\n </button>\n <button nz-button nzSize=\"small\" nz-tooltip=\"Th\u00EAm Template m\u1EDBi\" (click)=\"isModalVisible = true\">\n <nz-icon nzType=\"plus\" class=\"color-primary\"></nz-icon>\n </button>\n\n <box [width]=\"1\"></box>\n <span class=\"divider\"></span>\n <box [width]=\"1\"></box>\n\n <button\n nz-button\n nzSize=\"small\"\n [nzType]=\"isMoveMode ? 'primary' : 'default'\"\n nz-tooltip=\"Move mode\"\n (click)=\"isMoveMode = true\"\n >\n <nz-icon><img src=\"/assets/icon/hand-palm.png\" width=\"19\" height=\"19\" /></nz-icon>\n </button>\n <button\n nz-button\n nzSize=\"small\"\n [nzType]=\"!isMoveMode ? 'primary' : 'default'\"\n nz-tooltip=\"Select mode\"\n (click)=\"isMoveMode = false\"\n >\n <nz-icon><img src=\"/assets/icon/cursor.png\" width=\"19\" height=\"19\" /></nz-icon>\n </button>\n\n <box [width]=\"1\"></box>\n <span class=\"divider\"></span>\n <box [width]=\"1\"></box>\n\n <!-- UNDO / REDO -->\n <button\n nz-button\n nzSize=\"small\"\n nzType=\"default\"\n [disabled]=\"undoStack.length === 0\"\n nz-tooltip=\"Undo\"\n (click)=\"undo()\"\n >\n <nz-icon nzType=\"undo\"></nz-icon>\n </button>\n <button\n nz-button\n nzSize=\"small\"\n nzType=\"default\"\n [disabled]=\"redoStack.length === 0\"\n nz-tooltip=\"Redo\"\n (click)=\"redo()\"\n >\n <nz-icon nzType=\"redo\"></nz-icon>\n </button>\n\n <box [width]=\"1\"></box>\n <span class=\"divider\"></span>\n <box [width]=\"1\"></box>\n\n <!-- ALIGN -->\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 2\" (click)=\"alignLeft()\">\u27F8</button>\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 2\" (click)=\"alignCenter()\">\u2261</button>\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 2\" (click)=\"alignRight()\">\u27F9</button>\n <span class=\"divider\"></span>\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 2\" (click)=\"alignTop()\">\u21D1</button>\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 2\" (click)=\"alignMiddle()\">\u2550</button>\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 2\" (click)=\"alignBottom()\">\u21D3</button>\n <span class=\"divider\"></span>\n <!-- DISTRIBUTE -->\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 3\" (click)=\"distributeHorizontal()\">\n \u21C4\n </button>\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 3\" (click)=\"distributeVertical()\">\n \u21C5\n </button>\n\n <box [width]=\"1\"></box>\n <span class=\"divider\"></span>\n <box [width]=\"1\"></box>\n\n <!-- ZOOM -->\n <button nz-button nzSize=\"small\" nzType=\"default\" (click)=\"zoomOut()\" nz-tooltip=\"Zoom Out\">\n <nz-icon nzType=\"minus\"></nz-icon>\n </button>\n <span>{{ Math.round(zoom * 100) }}%</span>\n <button nz-button nzSize=\"small\" nzType=\"default\" (click)=\"zoomIn()\" nz-tooltip=\"Zoom In\">\n <nz-icon nzType=\"plus\"></nz-icon>\n </button>\n <span class=\"divider\"></span>\n <button nz-button nzSize=\"small\" nzType=\"default\" (click)=\"resetZoom()\" nz-tooltip=\"Reset Zoom (Ctrl+0)\">\n <nz-icon nzType=\"expand\"></nz-icon>\n </button>\n </div>\n\n <div\n class=\"canvas-content\"\n [class.panning]=\"isMoveMode\"\n [style.width.px]=\"getCanvasWidth()\"\n [style.height.px]=\"getCanvasHeight()\"\n [style.transform]=\"\n 'translate(' +\n templateCombine.editorOption.panX +\n 'px,' +\n templateCombine.editorOption.panY +\n 'px) scale(' +\n zoom +\n ')'\n \"\n >\n <!-- GRID -->\n <div *ngIf=\"wfcSetting.ShowGrid\" class=\"grid-layer\"></div>\n\n <!-- SVG EDGES -->\n <svg #svg class=\"edges-layer\" width=\"100%\" height=\"100%\" preserveAspectRatio=\"none\">\n <g>\n <!-- DEFS -->\n <defs>\n <filter id=\"edge-glow\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\n <feGaussianBlur stdDeviation=\"2\" result=\"blur\" />\n <feMerge>\n <feMergeNode in=\"blur\" />\n <feMergeNode in=\"SourceGraphic\" />\n </feMerge>\n </filter>\n\n <marker\n id=\"arrow-blue\"\n markerWidth=\"10\"\n markerHeight=\"10\"\n refX=\"10\"\n refY=\"5\"\n orient=\"auto\"\n markerUnits=\"strokeWidth\"\n >\n <path class=\"blue\" d=\"M0,0 L10,5 L0,10\"></path>\n </marker>\n <marker\n id=\"arrow-red\"\n markerWidth=\"10\"\n markerHeight=\"10\"\n refX=\"10\"\n refY=\"5\"\n orient=\"auto\"\n markerUnits=\"strokeWidth\"\n >\n <path class=\"red\" d=\"M0,0 L10,5 L0,10\"></path>\n </marker>\n </defs>\n\n <!-- EDGES B\u00CCNH TH\u01AF\u1EDCNG -->\n <ng-container *ngFor=\"let e of normalEdges; let i = index\">\n <path class=\"edge\" [attr.id]=\"'edge-path-' + i\" [attr.d]=\"buildPath(e)\" marker-end=\"url(#arrow-blue)\"></path>\n\n <path\n class=\"edge-hit\"\n [attr.d]=\"buildPath(e)\"\n (mouseenter)=\"onMouseEnterEdge(e)\"\n (mouseleave)=\"onMouseLeaveEdge(e)\"\n (click)=\"onClickEdge(e, $event)\"\n ></path>\n\n <!-- \u0110\u00E3 x\u00F3a *ngIf=\"e.RuleLineDetails?.length\" \u1EDF \u0111\u00E2y \u0111\u1EC3 text lu\u00F4n hi\u1EC7n -->\n <text\n class=\"edge-label\"\n style=\"fill: #1890ff; font-weight: 500\"\n [attr.x]=\"getEdgeLabelPosition(e).x\"\n [attr.y]=\"getEdgeLabelPosition(e).y - 8\"\n [attr.text-anchor]=\"'middle'\"\n >\n {{ e.FromStage }} / {{ e.FromAction }} > {{ e.ToStage }} / {{ e.ToAction }}\n </text>\n </ng-container>\n\n <!-- EDGE \u0110ANG HOVER/SELECTED (HI\u1EC2N TH\u1ECA M\u00C0U \u0110\u1ECE) -->\n <ng-container *ngFor=\"let e of hoverEdges; let i = index\">\n <path\n class=\"edge red\"\n [attr.id]=\"'edge-path-hover-' + i\"\n [attr.d]=\"buildPath(e)\"\n marker-end=\"url(#arrow-red)\"\n ></path>\n\n <path\n class=\"edge-hit\"\n [attr.d]=\"buildPath(e)\"\n (mouseleave)=\"onMouseLeaveEdge(e)\"\n (click)=\"onClickEdge(e, $event)\"\n ></path>\n\n <text\n class=\"edge-label\"\n style=\"font-weight: bold; fill: red\"\n [attr.x]=\"getEdgeLabelPosition(e).x\"\n [attr.y]=\"getEdgeLabelPosition(e).y - 8\"\n [attr.text-anchor]=\"'middle'\"\n >\n {{ e.FromStage }} / {{ e.FromAction }} > {{ e.ToStage }} / {{ e.ToAction }}\n </text>\n </ng-container>\n\n <!-- PREVIEW LINE (\u0110\u01AF\u1EDCNG N\u1ED0I \u0110ANG K\u00C9O) -->\n <path\n *ngIf=\"connectingFrom\"\n class=\"edge\"\n [attr.d]=\"buildPreviewPath()\"\n stroke-dasharray=\"5,5\"\n marker-end=\"url(#arrow-blue)\"\n ></path>\n </g>\n </svg>\n\n <!-- BOX V\u00D9NG CH\u1ECCN MULTI -->\n <div\n *ngIf=\"isSelecting && selectStart && selectEnd\"\n class=\"selection-box\"\n [style.left.px]=\"Math.min(selectStart.x, selectEnd.x)\"\n [style.top.px]=\"Math.min(selectStart.y, selectEnd.y)\"\n [style.width.px]=\"Math.abs(selectEnd.x - selectStart.x)\"\n [style.height.px]=\"Math.abs(selectEnd.y - selectStart.y)\"\n ></div>\n\n <!-- NODE (TEMPLATE) L\u1EDAP HI\u1EC2N TH\u1ECA TR\u00CAN C\u00D9NG -->\n @for (n of lstTemplateNode; track n.WF_Template_Id) {\n <nz-card\n class=\"workflow-node\"\n [attr.data-id]=\"n.Code\"\n [class.selected]=\"\n n == selectedTemplateNode || n == hoverTemplateNode || lstSelectedTemplateId.has(n.WF_Template_Id)\n \"\n [style.left.px]=\"n.editorOption.x\"\n [style.top.px]=\"n.editorOption.y\"\n [class.connecting-source]=\"isConnectingFrom(n) || isDraggingFrom(n) || isSelectedNode(n)\"\n nzSize=\"small\"\n (mousedown)=\"onMouseDownNode($event, n)\"\n (click)=\"$event.stopPropagation(); onClickNode(n)\"\n >\n <div class=\"title\" style=\"color: #1890ff; display: flex; justify-content: space-between; align-items: center\">\n <span>{{ n.Code }}</span>\n <nz-icon nzType=\"layout\" nzTheme=\"outline\"></nz-icon>\n </div>\n <div\n style=\"\n font-size: 12px;\n line-height: 1.2;\n font-weight: 500;\n height: 28px;\n overflow: hidden;\n text-overflow: ellipsis;\n \"\n >\n {{ n.Name || \"Ch\u01B0a c\u00F3 t\u00EAn\" }}\n </div>\n <div style=\"font-size: 10px; color: gray; margin-top: 4px\">\n {{ n.DocType }}\n </div>\n\n <!-- CONNECTOR \u0110\u1EC2 K\u00C9O D\u00C2Y -->\n <div class=\"connector connector-right\" (click)=\"onClickConnector($event, n, 'right')\"></div>\n <div class=\"connector connector-left\" (click)=\"onClickConnector($event, n, 'left')\"></div>\n </nz-card>\n }\n\n <!-- C\u00C1C \u0110I\u1EC2M WAYPOINT \u0110\u1EC2 B\u1EBA CONG D\u00C2Y CHU\u1ED8T -->\n @for (p of connectingPoints; track $index) {\n @if (p != draggingPoint) {\n <div\n class=\"waypoint\"\n [style.left.px]=\"p.x\"\n [style.top.px]=\"p.y\"\n (mousedown)=\"onmousedownPoint($event, p)\"\n (contextmenu)=\"onRightClickPoint($event, hoverTemplateEdge!, $index)\"\n ></div>\n } @else {\n <div\n class=\"waypoint dragging\"\n [style.left.px]=\"p.x\"\n [style.top.px]=\"p.y\"\n (mousedown)=\"onmousedownPoint($event, p)\"\n ></div>\n }\n }\n </div>\n</div>\n\n<!-- ==============================================\n 1. DRAWER: GLOBAL TEMPLATE SETTINGS \n=============================================== -->\n<nz-drawer\n [nzTitle]=\"drawTemplateTitle\"\n nzPlacement=\"right\"\n [nzWidth]=\"500\"\n [nzClosable]=\"false\"\n [nzVisible]=\"drawTemplateVisibel\"\n [nzFooter]=\"footerTplTemplate\"\n (nzOnClose)=\"drawTemplateVisibel = false\"\n>\n <ng-template #drawTemplateTitle> <nz-icon nzType=\"global\"></nz-icon> &nbsp; Quy tr\u00ECnh ph\u1ED1i h\u1EE3p </ng-template>\n <ng-container *nzDrawerContent>\n <!-- Gi\u1EEF nguy\u00EAn c\u00E1c th\u00F4ng tin chung to\u00E0n c\u1EE5c c\u1EE7a b\u1EA1n \u1EDF \u0111\u00E2y -->\n\n <extend-input [label]=\"'Code'\" [(_ngModel)]=\"templateCombine.Code\"></extend-input>\n <extend-input [label]=\"'Name'\" [(_ngModel)]=\"templateCombine.Name\"></extend-input>\n <extend-textarea [label]=\"'Description'\" [(_ngModel)]=\"templateCombine.Description\"></extend-textarea>\n <extend-checkbox [label]=\"'Active'\" [(_ngModel)]=\"templateCombine.IsActive\"></extend-checkbox>\n </ng-container>\n\n <ng-template #footerTplTemplate>\n <div nz-flex [nzGap]=\"6\" [nzJustify]=\"'end'\">\n <button nz-button nzDanger [nzLoading]=\"!ready\" (click)=\"save()\">Save</button>\n <button nz-button (click)=\"drawTemplateVisibel = false\">Close</button>\n </div>\n </ng-template>\n</nz-drawer>\n\n<!-- ==============================================\n 2. DRAWER: NODE SETTINGS (CHI TI\u1EBET M\u1ED8T TEMPLATE)\n=============================================== -->\n<nz-drawer\n [nzTitle]=\"drawerTitleNode\"\n [nzPlacement]=\"selectedTemplateNode?.editorOption?.drawerPosition == 'left' ? 'left' : 'right'\"\n [nzVisible]=\"!!selectedTemplateNode\"\n [nzWidth]=\"'90vw'\"\n [nzClosable]=\"false\"\n [nzFooter]=\"footerTplNode\"\n (nzOnClose)=\"selectedTemplateNode = undefined\"\n>\n <ng-template #drawerTitleNode>\n <div nz-row nzJustify=\"space-between\">\n <span style=\"font-weight: bold; color: #1890ff\"\n ><nz-icon nzType=\"layout\"></nz-icon> TEMPLATE NODE: [{{ selectedTemplateNode?.Code }}]\n {{ selectedTemplateNode?.Name }}</span\n >\n <button\n nz-button\n nzSize=\"small\"\n nz-tooltip=\"Chuy\u1EC3n v\u1ECB tr\u00ED Drawer\"\n (click)=\"\n selectedTemplateNode!.editorOption.drawerPosition =\n selectedTemplateNode!.editorOption.drawerPosition === 'left' ? 'right' : 'left'\n \"\n >\n <nz-icon nzType=\"swap\"></nz-icon>\n </button>\n </div>\n </ng-template>\n\n <ng-container *nzDrawerContent>\n <ng-container *ngIf=\"selectedTemplateNode\">\n <wf-template-detail #wftemplatedetail (onSave)=\"getdata.emit()\"></wf-template-detail>\n </ng-container>\n </ng-container>\n\n <ng-template #footerTplNode>\n <div\n nz-flex\n [nzGap]=\"6\"\n [nzJustify]=\"selectedTemplateNode?.editorOption?.drawerPosition == 'left' ? 'start' : 'end'\"\n >\n <button nz-button nzDanger [nzLoading]=\"!ready\" (click)=\"wftemplatedetail.wfeditor.save()\">Save</button>\n <button nz-button (click)=\"selectedTemplateNode = undefined\">Close</button>\n <button nz-button nzDanger (click)=\"deleteTemplateNode()\">Delete Template node</button>\n </div>\n </ng-template>\n</nz-drawer>\n\n<!-- ==============================================\n 3. DRAWER: EDGE SETTINGS (QU\u1EA2N L\u00DD QUY T\u1EAEC CHUY\u1EC2N TEMPLATE)\n=============================================== -->\n<nz-drawer\n [nzTitle]=\"drawerTitleEdge\"\n [nzPlacement]=\"selectedTemplateEdge?.editorOption?.drawerPosition == 'left' ? 'left' : 'right'\"\n [nzClosable]=\"false\"\n [nzWidth]=\"'450px'\"\n [nzVisible]=\"!!selectedTemplateEdge\"\n [nzFooter]=\"footerTplEdge\"\n (nzOnClose)=\"selectedTemplateEdge = undefined\"\n>\n <ng-template #drawerTitleEdge>\n <div nz-row nzJustify=\"space-between\">\n <span style=\"font-weight: bold; color: #ff4d4f\"><nz-icon nzType=\"swap-right\"></nz-icon> TRANSITION RULES </span>\n <button\n nz-button\n nzSize=\"small\"\n nz-tooltip=\"Chuy\u1EC3n v\u1ECB tr\u00ED Drawer\"\n (click)=\"\n selectedTemplateEdge!.editorOption.drawerPosition =\n selectedTemplateEdge!.editorOption.drawerPosition === 'left' ? 'right' : 'left'\n \"\n >\n <nz-icon nzType=\"swap\"></nz-icon>\n </button>\n </div>\n </ng-template>\n\n <ng-container *nzDrawerContent>\n <ng-container *ngIf=\"selectedTemplateEdge\">\n <!-- Th\u00F4ng tin 2 \u0111\u1EA7u n\u1ED1i -->\n <div\n style=\"background: #fdf5f6; padding: 12px; border: 1px solid #ffa39e; border-radius: 6px; margin-bottom: 16px\"\n >\n <div style=\"font-size: 14px\">\n <strong style=\"display: inline-block; width: 70px; color: #555\">From:</strong>\n <span style=\"color: #1890ff; font-weight: 500\">\n [{{ getNode(selectedTemplateEdge.From_WF_Template_Id)?.Code }}]\n {{ getNode(selectedTemplateEdge.From_WF_Template_Id)?.Name }} > {{ selectedTemplateEdge.FromStage }} >\n {{ selectedTemplateEdge.FromAction }}\n </span>\n </div>\n <div style=\"font-size: 14px; margin-top: 8px\">\n <strong style=\"display: inline-block; width: 70px; color: #555\">Taget:</strong>\n <span style=\"color: #1890ff; font-weight: 500\">\n [{{ getNode(selectedTemplateEdge.To_WF_Template_Id)?.Code }}]\n {{ getNode(selectedTemplateEdge.To_WF_Template_Id)?.Name }} > {{ selectedTemplateEdge.ToStage }} >\n {{ selectedTemplateEdge.ToAction }}\n </span>\n </div>\n </div>\n </ng-container>\n </ng-container>\n\n <ng-template #footerTplEdge>\n <div\n nz-flex\n [nzGap]=\"6\"\n [nzJustify]=\"selectedTemplateEdge?.editorOption?.drawerPosition == 'left' ? 'start' : 'end'\"\n >\n <button nz-button nzDanger [nzLoading]=\"!ready\" (click)=\"save()\">Save Rules</button>\n <button\n nz-button\n nzDanger\n (click)=\"\n lstTemplateEdge.splice(lstTemplateEdge.indexOf(selectedTemplateEdge!), 1); selectedTemplateEdge = undefined\n \"\n >\n Delete Transition\n </button>\n <button nz-button (click)=\"selectedTemplateEdge = undefined\">Close</button>\n </div>\n </ng-template>\n</nz-drawer>\n\n<!-- ==============================================\n 4. EDITOR SETTING & INFO\n=============================================== -->\n<nz-drawer\n [nzTitle]=\"drawSettingTitle\"\n nzPlacement=\"right\"\n [nzClosable]=\"false\"\n [nzVisible]=\"settingVisible\"\n (nzOnClose)=\"settingVisible = false\"\n>\n <ng-template #drawSettingTitle> <nz-icon nzType=\"setting\"></nz-icon> &nbsp; C\u00E0i \u0111\u1EB7t Editor </ng-template>\n <ng-container *nzDrawerContent>\n <div class=\"form-item-no-bottom\">\n <extend-checkbox\n [label]=\"'Hi\u1EC3n th\u1ECB L\u01B0\u1EDBi (Grid)'\"\n [labelSpan]=\"0\"\n [(_ngModel)]=\"wfcSetting.ShowGrid\"\n ></extend-checkbox>\n </div>\n </ng-container>\n</nz-drawer>\n\n<nz-drawer\n [nzTitle]=\"drawInfoTitle\"\n nzPlacement=\"right\"\n [nzClosable]=\"false\"\n [nzVisible]=\"infoVisible\"\n (nzOnClose)=\"infoVisible = false\"\n>\n <ng-template #drawInfoTitle> <nz-icon nzType=\"info-circle\"></nz-icon> &nbsp; H\u01B0\u1EDBng d\u1EABn (Infomation) </ng-template>\n <ng-container *nzDrawerContent>\n <p>\n <strong>1. C\u00E1c th\u00E0nh ph\u1EA7n:</strong> C\u00E1c \u00F4 ch\u1EEF nh\u1EADt l\u00E0 Template (Quy tr\u00ECnh nh\u1ECF), c\u00E1c \u0111\u01B0\u1EDDng n\u1ED1i l\u00E0 Transition Rule\n (Quy t\u1EAFc chuy\u1EC3n quy tr\u00ECnh).\n </p>\n <p><strong>2. C\u00E1ch n\u1ED1i 2 Template:</strong></p>\n <ul>\n <li>Click ch\u1EA5m cam b\u00EAn ph\u1EA3i Template A, sau \u0111\u00F3 k\u00E9o v\u00E0 click v\u00E0o Template B \u0111\u1EC3 t\u1EA1o Rule n\u1ED1i.</li>\n <li>C\u00F3 th\u1EC3 click nhi\u1EC1u \u0111i\u1EC3m trong l\u00FAc k\u00E9o \u0111\u1EC3 b\u1EBB \u0111\u01B0\u1EDDng cong tu\u1EF3 \u00FD (Waypoint).</li>\n <li>Click \u0111\u00FAp v\u00E0o c\u1EA1nh (\u0111\u01B0\u1EDDng n\u1ED1i) \u0111ang c\u00F3 \u0111\u1EC3 t\u1EA1o th\u00EAm m\u1ED9t \u0111i\u1EC3m b\u1EBB cong m\u1EDBi.</li>\n <li>Gi\u1EEF v\u00E0 k\u00E9o \u0111i\u1EC3m b\u1EBB cong \u0111\u1EC3 tu\u1EF3 ch\u1EC9nh \u0111\u01B0\u1EDDng \u0111i. Chu\u1ED9t ph\u1EA3i v\u00E0o \u0111i\u1EC3m \u0111\u00F3 \u0111\u1EC3 x\u00F3a n\u00F3.</li>\n </ul>\n <p>\n <strong>3. Qu\u1EA3n l\u00FD Rule:</strong> Click v\u00E0o \u0111\u01B0\u1EDDng n\u1ED1i gi\u1EEFa 2 Node \u0111\u1EC3 c\u1EA5u h\u00ECnh c\u00E1c lu\u1ED3ng th\u1EF1c thi (Stored, Ph\u00E2n\n quy\u1EC1n, G\u1EEDi mail).\n </p>\n </ng-container>\n</nz-drawer>\n\n<nz-modal\n [(nzVisible)]=\"isModalVisible\"\n nzTitle=\"Add template node\"\n [nzWidth]=\"600\"\n (nzOnCancel)=\"isModalVisible = false\"\n (nzOnOk)=\"addTemplateNodes()\"\n nzOkText=\"Add\"\n nzOkDanger\n nzCancelText=\"Cancel\"\n nzMaskClosable=\"false\"\n>\n <ng-container *nzModalContent>\n <extend-select\n label=\"Template\"\n [lstItem]=\"lstTemplateForSelect\"\n [displayField]=\"'Name'\"\n [multiple]=\"true\"\n [(_ngModel)]=\"lstTemplateSelected\"\n ></extend-select>\n </ng-container>\n</nz-modal>\n", styles: ["@charset \"UTF-8\";::ng-deep .workflow-wrapper{border:solid 1px lightgray;overflow:hidden;width:100%}.workflow-canvas{position:relative;background:#f0f2f5;cursor:default;overflow:hidden;outline:1px dashed rgba(0,0,0,.1)}.workflow-canvas .edges-layer{position:absolute;inset:0;width:100%;height:100%;z-index:1}.workflow-canvas .edges-layer path{stroke-width:2;fill:none}.canvas-content{transform-origin:0 0;width:100%;height:100%;transition:transform .05s linear}.canvas-content{outline:1px dashed red}.canvas-content.panning{cursor:grab}.canvas-content.panning:active{cursor:grabbing}.workflow-canvas.panning{cursor:grab}.workflow-canvas.panning:active{cursor:grabbing}.workflow-canvas.connecting,.workflow-canvas.connecting .workflow-node{cursor:crosshair}.workflow-node{position:absolute;width:160px;cursor:grab;-webkit-user-select:none;user-select:none;z-index:2}.workflow-node:active{cursor:grabbing}.workflow-node.connecting-source,.workflow-node.selected,.workflow-node:hover:not(.workflow-node-start,.workflow-node-end){outline:2px dashed #1890ff}.workflow-node .title{font-weight:600;margin-bottom:6px}.workflow-node-start{width:0px}.workflow-node-start.connecting-source,.workflow-node-start.selected,.workflow-node-start:hover{outline:unset}.workflow-node-start.connecting-source nz-tag,.workflow-node-start.selected nz-tag,.workflow-node-start:hover nz-tag{outline:2px dashed}.workflow-node-start nz-tag{position:relative;top:45px;right:35px}.workflow-node-end{width:0px}.workflow-node-end.connecting-source,.workflow-node-end.selected,.workflow-node-end:hover{outline:unset}.workflow-node-end.connecting-source nz-tag,.workflow-node-end.selected nz-tag,.workflow-node-end:hover nz-tag{outline:2px dashed}.workflow-node-end nz-tag{position:relative;top:45px;right:32px}.connector{position:absolute;top:39px;width:12px;height:12px;background:#1890ff;border-radius:50%;transform:translateY(-50%);cursor:crosshair;transition:box-shadow .15s ease-out,transform .15s ease-out}.connector:hover{box-shadow:0 0 0 3px #1890ff4d;transform:translateY(-50%) scale(1.15)}.connector-right{right:-8px;background:orange}.connector-right.reverse,.connector-left{left:-8px}.connector-left.reverse{left:unset;right:-8px}.connector-start{width:16px;height:16px;right:-8px;background:green;box-shadow:0 0 0 3px #1890ff4d}.connector-end{width:16px;height:16px;left:-8px;background:#000;box-shadow:0 0 0 3px #1890ff4d}.edge{cursor:pointer;stroke:#1890ff;stroke-linecap:round;stroke-linejoin:round;stroke-width:2;fill:none;transition:stroke .15s ease}.edge-hit{stroke:transparent;stroke-width:18px!important;fill:none;cursor:pointer}.edge-hit:hover+.edge{stroke:#ff4d4f;stroke-width:2}.workflow-canvas.dragging-point .edge-hit{pointer-events:none}.edge:hover+.edge-label{fill:#1890ff;font-weight:500}.edge-label{font-size:12px;fill:#555;pointer-events:none;-webkit-user-select:none;user-select:none}.blue{stroke:#1890ff!important}.red{stroke:#ff4d4f!important;box-shadow:0 0 0 3px #1890ff4d!important}.workflow-svg{background:transparent;overflow:visible}.waypoint{position:absolute;width:10px;height:10px;background:#ff4d4f;border-radius:50%;transform:translate(-50%,-50%) scale(1);cursor:move;z-index:1;transition:transform .12s ease-out,background-color .12s ease-out,box-shadow .12s ease-out}.waypoint:hover{background:#ff7875;transform:translate(-50%,-50%) scale(1.25);box-shadow:0 0 0 4px #ff787559}.waypoint.dragging{transition:none;transform:translate(-50%,-50%) scale(1.15);pointer-events:none}.workflow-canvas.dragging-point svg{cursor:grabbing}.selection-box{position:absolute;border:1px dashed #1890ff;background:#1890ff1a;pointer-events:none}.toolbar{position:absolute;top:8px;left:8px;display:flex;gap:4px;padding:6px;background:#fff;border-radius:6px;box-shadow:0 2px 8px #00000026;z-index:100}.toolbar .divider{width:1px;background:#e5e5e5;margin:0 2px}nz-tag.selected{outline:2px dashed #1890ff}.grid-layer{position:absolute;inset:0;pointer-events:none;z-index:0;background-image:radial-gradient(rgba(0,0,0,.08) 1px,transparent 1px);background-size:20px 20px}.grid-layer{background-image:linear-gradient(to right,rgba(0,0,0,.06) 1px,transparent 1px),linear-gradient(to bottom,rgba(0,0,0,.06) 1px,transparent 1px);background-size:20px 20px}.editable-tag{background:#fff;border-style:dashed}::ng-deep .minimap,.minimap-combine{position:absolute;width:180px;height:125px;top:0;right:0;background-color:#eee;border:1px solid #aaa;opacity:.9;z-index:1}::ng-deep .minimap{position:absolute;width:200px;height:140px;top:8px;right:8px;background-color:#f8f9fa;border:1px solid #d9d9d9;border-radius:8px;box-shadow:0 4px 12px #0000001a;overflow:hidden;z-index:100;-webkit-user-select:none;user-select:none}::ng-deep .minimap-node{position:absolute;background-color:#bfbfbf;border-radius:2px}::ng-deep .minimap-node-round{position:absolute;background-color:#bfbfbf;border-radius:50%}::ng-deep .minimap-node-round-start{background-color:#52c41a}::ng-deep .minimap-node-round-end{background-color:#ff4d4f}::ng-deep .minimap-viewport{position:absolute;box-sizing:border-box;background-color:#1890ff26;border:1.5px solid #1890ff;border-radius:4px;z-index:2;cursor:grab;transition:none}::ng-deep .minimap-viewport.grabbing,::ng-deep .minimap-viewport:active{cursor:grabbing;background-color:#1890ff40}::ng-deep .has-floating-label.floating-label{position:relative;padding-top:14px}::ng-deep .has-floating-label nz-form-item nz-form-label{position:absolute;top:12px;left:13px;transform:translateY(-50%);background:linear-gradient(to bottom,var(--form-bg-color, #ffffff) 80%,#ffffff 80%);z-index:1;height:auto;line-height:normal;padding:0 4px}::ng-deep .has-floating-label nz-form-item nz-form-label label{font-size:12px;color:var(--darkgray, #565656);font-weight:700;height:auto;line-height:normal;padding:0;display:flex;align-items:center}::ng-deep .has-floating-label .full-width{width:100%}.has-floating-label.floating-label nz-form-item:has(.ant-select-disabled) nz-form-label,.has-floating-label.floating-label nz-form-item:has(input[disabled]) nz-form-label,.has-floating-label.floating-label nz-form-item:has(.ant-input-disabled) nz-form-label{background:linear-gradient(to bottom,var(--form-bg-color, #ffffff) 60%,#f5f5f5 50%)}.has-floating-label.floating-label nz-form-item:has(.ant-select-disabled) nz-form-label label,.has-floating-label.floating-label nz-form-item:has(input[disabled]) nz-form-label label,.has-floating-label.floating-label nz-form-item:has(.ant-input-disabled) nz-form-label label{color:#bfbfbf}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: NzCardModule }, { kind: "component", type: i3$5.NzCardComponent, selector: "nz-card", inputs: ["nzBordered", "nzLoading", "nzHoverable", "nzBodyStyle", "nzCover", "nzActions", "nzType", "nzSize", "nzTitle", "nzExtra"], exportAs: ["nzCard"] }, { kind: "ngmodule", type: NzDrawerModule }, { kind: "component", type: i3$6.NzDrawerComponent, selector: "nz-drawer", inputs: ["nzContent", "nzCloseIcon", "nzClosable", "nzMaskClosable", "nzMask", "nzCloseOnNavigation", "nzNoAnimation", "nzKeyboard", "nzTitle", "nzExtra", "nzFooter", "nzPlacement", "nzSize", "nzMaskStyle", "nzBodyStyle", "nzWrapClassName", "nzWidth", "nzHeight", "nzZIndex", "nzOffsetX", "nzOffsetY", "nzVisible"], outputs: ["nzOnViewInit", "nzOnClose", "nzVisibleChange"], exportAs: ["nzDrawer"] }, { kind: "directive", type: i3$6.NzDrawerContentDirective, selector: "[nzDrawerContent]", exportAs: ["nzDrawerContent"] }, { kind: "ngmodule", type: NzTagModule }, { kind: "ngmodule", type: NzRadioModule }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$2.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "component", type: Box, selector: "box", inputs: ["display", "width", "height"] }, { kind: "ngmodule", type: NzButtonModule }, { kind: "component", type: i2$2.NzButtonComponent, selector: "button[nz-button], a[nz-button]", inputs: ["nzBlock", "nzGhost", "nzSearch", "nzLoading", "nzDanger", "disabled", "tabIndex", "nzType", "nzShape", "nzSize"], exportAs: ["nzButton"] }, { kind: "directive", type: i3$2.ɵNzTransitionPatchDirective, selector: "[nz-button], nz-button-group, [nz-icon], nz-icon, [nz-menu-item], [nz-submenu], nz-select-top-control, nz-select-placeholder, nz-input-group", inputs: ["hidden"] }, { kind: "directive", type: i4$1.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "ngmodule", type: NzToolTipModule }, { kind: "directive", type: i8.NzTooltipDirective, selector: "[nz-tooltip]", inputs: ["nzTooltipTitle", "nzTooltipTitleContext", "nz-tooltip", "nzTooltipTrigger", "nzTooltipPlacement", "nzTooltipOrigin", "nzTooltipVisible", "nzTooltipMouseEnterDelay", "nzTooltipMouseLeaveDelay", "nzTooltipOverlayClassName", "nzTooltipOverlayStyle", "nzTooltipArrowPointAtCenter", "cdkConnectedOverlayPush", "nzTooltipColor"], outputs: ["nzTooltipVisibleChange"], exportAs: ["nzTooltip"] }, { kind: "component", type: ExtendInput, selector: "extend-input", inputs: ["label", "floatingLabel", "placeHolder", "labelAlign", "inputClass", "labelSpan", "labelFlex", "inputFlex", "showClear", "disabled", "readOnly", "required", "noBottom", "selectModeType", "autocomplete", "autofocus", "inputWidth", "inputHeight", "borderBottomOnly", "displayInline", "size", "displayField", "valueField", "formData", "controlName", "_ngModel", "isSubmited"], outputs: ["_ngModelChange", "onclickClearIcon", "onenter"] }, { kind: "component", type: ExtendSelectComponent, selector: "extend-select", inputs: ["label", "floatingLabel", "placeHolder", "labelAlign", "dropdownMatchSelectWidth", "labelSpan", "labelFlex", "disabled", "required", "noBottom", "multiple", "showSelectAll", "maxTagCount", "inputWidth", "inputHeight", "borderBottomOnly", "displayInline", "size", "lstItem", "displayField", "displayFields", "info", "valueField", "formData", "controlName", "_ngModel", "isSubmited"], outputs: ["_ngModelChange", "itemChange", "onFocus"] }, { kind: "component", type: ExtendCheckbox, selector: "extend-checkbox", inputs: ["label", "labelSpan", "labelFlex", "paddingTop", "disabled", "formData", "controlName", "valueType", "_ngModel"], outputs: ["_ngModelChange"] }, { kind: "component", type: ExtendTextArea, selector: "extend-textarea", inputs: ["label", "placeHolder", "labelAlign", "floatingLabel", "displayInline", "formItemNoButtom", "labelSpan", "labelFlex", "inputFlex", "disabled", "required", "noBottom", "selectModeType", "inputClass", "size", "isSubmited", "minRows", "maxRows", "lstItem", "displayField", "valueField", "formData", "controlName", "_ngModel", "isTouched", "inputErrorMessage", "errorMessages"], outputs: ["_ngModelChange"] }, { kind: "ngmodule", type: NzInputModule }, { kind: "ngmodule", type: NzGridModule }, { kind: "directive", type: i2$1.NzRowDirective, selector: "[nz-row],nz-row,nz-form-item", inputs: ["nzAlign", "nzJustify", "nzGutter"], exportAs: ["nzRow"] }, { kind: "ngmodule", type: NzFlexModule }, { kind: "directive", type: i3$3.NzFlexDirective, selector: "[nz-flex],nz-flex", inputs: ["nzVertical", "nzJustify", "nzAlign", "nzGap", "nzWrap", "nzFlex"], exportAs: ["nzFlex"] }, { kind: "ngmodule", type: NzTableModule }, { kind: "ngmodule", type: NzDividerModule }, { kind: "ngmodule", type: NzAutocompleteModule }, { kind: "component", type: NzModalComponent, selector: "nz-modal", inputs: ["nzMask", "nzMaskClosable", "nzCloseOnNavigation", "nzVisible", "nzClosable", "nzOkLoading", "nzOkDisabled", "nzCancelDisabled", "nzCancelLoading", "nzKeyboard", "nzNoAnimation", "nzCentered", "nzDraggable", "nzContent", "nzFooter", "nzZIndex", "nzWidth", "nzWrapClassName", "nzClassName", "nzStyle", "nzTitle", "nzCloseIcon", "nzMaskStyle", "nzBodyStyle", "nzOkText", "nzCancelText", "nzOkType", "nzOkDanger", "nzIconType", "nzModalType", "nzAutofocus", "nzOnOk", "nzOnCancel"], outputs: ["nzOnOk", "nzOnCancel", "nzAfterOpen", "nzAfterClose", "nzVisibleChange"], exportAs: ["nzModal"] }, { kind: "directive", type: NzModalContentDirective, selector: "[nzModalContent]", exportAs: ["nzModalContent"] }, { kind: "component", type: WF_TemplateDetail, selector: "wf-template-detail", outputs: ["onSave"] }] });
19461
19522
  }
19462
19523
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: WF_Template_CombineEditorComponent, decorators: [{
19463
19524
  type: Component,
@@ -19479,29 +19540,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImpor
19479
19540
  NzInputModule,
19480
19541
  NzGridModule,
19481
19542
  NzFlexModule,
19482
- ExtendInputNumber,
19483
19543
  NzTableModule,
19484
19544
  NzDividerModule,
19485
- AutoFocusDirective,
19486
19545
  NzAutocompleteModule,
19487
- IconDelete,
19488
19546
  NzModalComponent,
19489
19547
  NzModalContentDirective,
19490
- NzModalTitleDirective,
19491
- IconAdd,
19492
- NzModalFooterDirective,
19493
- DicDomainSelectComponent$1,
19494
- IconInfo,
19495
19548
  WF_TemplateDetail,
19496
- ], selector: 'app-workflow-combine-editor', template: "<div\n #canvas\n class=\"workflow-canvas\"\n [class.connecting]=\"!!connectingFrom\"\n [class.dragging-point]=\"!!draggingPoint\"\n style=\"width: 100%; height: 100%\"\n (mousedown)=\"onMouseDownCanvas($event)\"\n (mousemove)=\"onMouseMoveCanvas($event)\"\n (mouseup)=\"onMouseUpCanvas($event)\"\n (click)=\"onClickCanvas($event)\"\n (wheel)=\"onWheelCanvas($event)\"\n>\n <!-- TOOLBAR -->\n <div class=\"toolbar\" (mousedown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\">\n <button nz-button nzSize=\"small\" nz-tooltip=\"Editor setting\" (click)=\"settingVisible = true\">\n <nz-icon nzType=\"setting\"></nz-icon>\n </button>\n\n <button nz-button nzSize=\"small\" nz-tooltip=\"Infomation\" (click)=\"infoVisible = true\">\n <nz-icon nzType=\"info-circle\"></nz-icon>\n </button>\n\n <box [width]=\"1\"></box>\n <span class=\"divider\"></span>\n <box [width]=\"1\"></box>\n\n <button nz-button nzSize=\"small\" nz-tooltip=\"Global Setting\" (click)=\"drawTemplateVisibel = true\">\n <nz-icon nzType=\"setting\"></nz-icon> G\n </button>\n\n <box [width]=\"1\"></box>\n <span class=\"divider\"></span>\n <box [width]=\"1\"></box>\n\n <button nz-button nzSize=\"small\" nzDanger [nzLoading]=\"!ready\" nz-tooltip=\"Save (Ctrl + S)\" (click)=\"save()\">\n <nz-icon nzType=\"save\"></nz-icon>\n </button>\n <button nz-button nzSize=\"small\" nz-tooltip=\"Th\u00EAm Template m\u1EDBi\" (click)=\"isModalVisible = true\">\n <nz-icon nzType=\"plus\" class=\"color-primary\"></nz-icon>\n </button>\n\n <box [width]=\"1\"></box>\n <span class=\"divider\"></span>\n <box [width]=\"1\"></box>\n\n <button\n nz-button\n nzSize=\"small\"\n [nzType]=\"isMoveMode ? 'primary' : 'default'\"\n nz-tooltip=\"Move mode\"\n (click)=\"isMoveMode = true\"\n >\n <nz-icon><img src=\"/assets/icon/hand-palm.png\" width=\"19\" height=\"19\" /></nz-icon>\n </button>\n <button\n nz-button\n nzSize=\"small\"\n [nzType]=\"!isMoveMode ? 'primary' : 'default'\"\n nz-tooltip=\"Select mode\"\n (click)=\"isMoveMode = false\"\n >\n <nz-icon><img src=\"/assets/icon/cursor.png\" width=\"19\" height=\"19\" /></nz-icon>\n </button>\n\n <box [width]=\"1\"></box>\n <span class=\"divider\"></span>\n <box [width]=\"1\"></box>\n\n <!-- UNDO / REDO -->\n <button\n nz-button\n nzSize=\"small\"\n nzType=\"default\"\n [disabled]=\"undoStack.length === 0\"\n nz-tooltip=\"Undo\"\n (click)=\"undo()\"\n >\n <nz-icon nzType=\"undo\"></nz-icon>\n </button>\n <button\n nz-button\n nzSize=\"small\"\n nzType=\"default\"\n [disabled]=\"redoStack.length === 0\"\n nz-tooltip=\"Redo\"\n (click)=\"redo()\"\n >\n <nz-icon nzType=\"redo\"></nz-icon>\n </button>\n\n <box [width]=\"1\"></box>\n <span class=\"divider\"></span>\n <box [width]=\"1\"></box>\n\n <!-- ALIGN -->\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 2\" (click)=\"alignLeft()\">\u27F8</button>\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 2\" (click)=\"alignCenter()\">\u2261</button>\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 2\" (click)=\"alignRight()\">\u27F9</button>\n <span class=\"divider\"></span>\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 2\" (click)=\"alignTop()\">\u21D1</button>\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 2\" (click)=\"alignMiddle()\">\u2550</button>\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 2\" (click)=\"alignBottom()\">\u21D3</button>\n <span class=\"divider\"></span>\n <!-- DISTRIBUTE -->\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 3\" (click)=\"distributeHorizontal()\">\n \u21C4\n </button>\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 3\" (click)=\"distributeVertical()\">\n \u21C5\n </button>\n\n <box [width]=\"1\"></box>\n <span class=\"divider\"></span>\n <box [width]=\"1\"></box>\n\n <!-- ZOOM -->\n <button nz-button nzSize=\"small\" nzType=\"default\" (click)=\"zoomOut()\" nz-tooltip=\"Zoom Out\">\n <nz-icon nzType=\"minus\"></nz-icon>\n </button>\n <span>{{ Math.round(zoom * 100) }}%</span>\n <button nz-button nzSize=\"small\" nzType=\"default\" (click)=\"zoomIn()\" nz-tooltip=\"Zoom In\">\n <nz-icon nzType=\"plus\"></nz-icon>\n </button>\n <span class=\"divider\"></span>\n <button nz-button nzSize=\"small\" nzType=\"default\" (click)=\"resetZoom()\" nz-tooltip=\"Reset Zoom (Ctrl+0)\">\n <nz-icon nzType=\"expand\"></nz-icon>\n </button>\n </div>\n\n <div\n class=\"canvas-content\"\n [class.panning]=\"isMoveMode\"\n [style.width.px]=\"getCanvasWidth()\"\n [style.height.px]=\"getCanvasHeight()\"\n [style.transform]=\"\n 'translate(' +\n templateCombine.editorOption.panX +\n 'px,' +\n templateCombine.editorOption.panY +\n 'px) scale(' +\n zoom +\n ')'\n \"\n >\n <!-- GRID -->\n <div *ngIf=\"wfcSetting.ShowGrid\" class=\"grid-layer\"></div>\n\n <!-- SVG EDGES -->\n <svg #svg class=\"edges-layer\" width=\"100%\" height=\"100%\" preserveAspectRatio=\"none\">\n <g>\n <!-- DEFS -->\n <defs>\n <filter id=\"edge-glow\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\n <feGaussianBlur stdDeviation=\"2\" result=\"blur\" />\n <feMerge>\n <feMergeNode in=\"blur\" />\n <feMergeNode in=\"SourceGraphic\" />\n </feMerge>\n </filter>\n\n <marker\n id=\"arrow-blue\"\n markerWidth=\"10\"\n markerHeight=\"10\"\n refX=\"10\"\n refY=\"5\"\n orient=\"auto\"\n markerUnits=\"strokeWidth\"\n >\n <path class=\"blue\" d=\"M0,0 L10,5 L0,10\"></path>\n </marker>\n <marker\n id=\"arrow-red\"\n markerWidth=\"10\"\n markerHeight=\"10\"\n refX=\"10\"\n refY=\"5\"\n orient=\"auto\"\n markerUnits=\"strokeWidth\"\n >\n <path class=\"red\" d=\"M0,0 L10,5 L0,10\"></path>\n </marker>\n </defs>\n\n <!-- EDGES B\u00CCNH TH\u01AF\u1EDCNG -->\n <ng-container *ngFor=\"let e of normalEdges; let i = index\">\n <path class=\"edge\" [attr.id]=\"'edge-path-' + i\" [attr.d]=\"buildPath(e)\" marker-end=\"url(#arrow-blue)\"></path>\n\n <path\n class=\"edge-hit\"\n [attr.d]=\"buildPath(e)\"\n (mouseenter)=\"onMouseEnterEdge(e)\"\n (mouseleave)=\"onMouseLeaveEdge(e)\"\n (click)=\"onClickEdge(e, $event)\"\n ></path>\n\n <!-- \u0110\u00E3 x\u00F3a *ngIf=\"e.RuleLineDetails?.length\" \u1EDF \u0111\u00E2y \u0111\u1EC3 text lu\u00F4n hi\u1EC7n -->\n <text\n class=\"edge-label\"\n style=\"fill: #1890ff; font-weight: 500\"\n [attr.x]=\"getEdgeLabelPosition(e).x\"\n [attr.y]=\"getEdgeLabelPosition(e).y - 8\"\n [attr.text-anchor]=\"'middle'\"\n >\n {{ e.FromStage }} / {{ e.FromAction }} > {{ e.ToStage }} / {{ e.ToAction }}\n </text>\n </ng-container>\n\n <!-- EDGE \u0110ANG HOVER/SELECTED (HI\u1EC2N TH\u1ECA M\u00C0U \u0110\u1ECE) -->\n <ng-container *ngFor=\"let e of hoverEdges; let i = index\">\n <path\n class=\"edge red\"\n [attr.id]=\"'edge-path-hover-' + i\"\n [attr.d]=\"buildPath(e)\"\n marker-end=\"url(#arrow-red)\"\n ></path>\n\n <path\n class=\"edge-hit\"\n [attr.d]=\"buildPath(e)\"\n (mouseleave)=\"onMouseLeaveEdge(e)\"\n (click)=\"onClickEdge(e, $event)\"\n ></path>\n\n <text\n class=\"edge-label\"\n style=\"font-weight: bold; fill: red\"\n [attr.x]=\"getEdgeLabelPosition(e).x\"\n [attr.y]=\"getEdgeLabelPosition(e).y - 8\"\n [attr.text-anchor]=\"'middle'\"\n >\n {{ e.FromStage }} / {{ e.FromAction }} > {{ e.ToStage }} / {{ e.ToAction }}\n </text>\n </ng-container>\n\n <!-- PREVIEW LINE (\u0110\u01AF\u1EDCNG N\u1ED0I \u0110ANG K\u00C9O) -->\n <path\n *ngIf=\"connectingFrom\"\n class=\"edge\"\n [attr.d]=\"buildPreviewPath()\"\n stroke-dasharray=\"5,5\"\n marker-end=\"url(#arrow-blue)\"\n ></path>\n </g>\n </svg>\n\n <!-- BOX V\u00D9NG CH\u1ECCN MULTI -->\n <div\n *ngIf=\"isSelecting && selectStart && selectEnd\"\n class=\"selection-box\"\n [style.left.px]=\"Math.min(selectStart.x, selectEnd.x)\"\n [style.top.px]=\"Math.min(selectStart.y, selectEnd.y)\"\n [style.width.px]=\"Math.abs(selectEnd.x - selectStart.x)\"\n [style.height.px]=\"Math.abs(selectEnd.y - selectStart.y)\"\n ></div>\n\n <!-- NODE (TEMPLATE) L\u1EDAP HI\u1EC2N TH\u1ECA TR\u00CAN C\u00D9NG -->\n @for (n of lstTemplateNode; track n.WF_Template_Id) {\n <nz-card\n class=\"workflow-node\"\n [attr.data-id]=\"n.Code\"\n [class.selected]=\"\n n == selectedTemplateNode || n == hoverTemplateNode || lstSelectedTemplateId.has(n.WF_Template_Id)\n \"\n [style.left.px]=\"n.editorOption.x\"\n [style.top.px]=\"n.editorOption.y\"\n [class.connecting-source]=\"isConnectingFrom(n) || isDraggingFrom(n) || isSelectedNode(n)\"\n nzSize=\"small\"\n (mousedown)=\"onMouseDownNode($event, n)\"\n (click)=\"$event.stopPropagation(); onClickNode(n)\"\n >\n <div class=\"title\" style=\"color: #1890ff; display: flex; justify-content: space-between; align-items: center\">\n <span>{{ n.Code }}</span>\n <nz-icon nzType=\"layout\" nzTheme=\"outline\"></nz-icon>\n </div>\n <div\n style=\"\n font-size: 12px;\n line-height: 1.2;\n font-weight: 500;\n height: 28px;\n overflow: hidden;\n text-overflow: ellipsis;\n \"\n >\n {{ n.Name || \"Ch\u01B0a c\u00F3 t\u00EAn\" }}\n </div>\n <div style=\"font-size: 10px; color: gray; margin-top: 4px\">\n {{ n.DocType }}\n </div>\n\n <!-- CONNECTOR \u0110\u1EC2 K\u00C9O D\u00C2Y -->\n <div class=\"connector connector-right\" (click)=\"onClickConnector($event, n, 'right')\"></div>\n <div class=\"connector connector-left\" (click)=\"onClickConnector($event, n, 'left')\"></div>\n </nz-card>\n }\n\n <!-- C\u00C1C \u0110I\u1EC2M WAYPOINT \u0110\u1EC2 B\u1EBA CONG D\u00C2Y CHU\u1ED8T -->\n @for (p of connectingPoints; track $index) {\n @if (p != draggingPoint) {\n <div\n class=\"waypoint\"\n [style.left.px]=\"p.x\"\n [style.top.px]=\"p.y\"\n (mousedown)=\"onmousedownPoint($event, p)\"\n (contextmenu)=\"onRightClickPoint($event, hoverTemplateEdge!, $index)\"\n ></div>\n } @else {\n <div\n class=\"waypoint dragging\"\n [style.left.px]=\"p.x\"\n [style.top.px]=\"p.y\"\n (mousedown)=\"onmousedownPoint($event, p)\"\n ></div>\n }\n }\n </div>\n</div>\n\n<!-- ==============================================\n 1. DRAWER: GLOBAL TEMPLATE SETTINGS \n=============================================== -->\n<nz-drawer\n [nzTitle]=\"drawTemplateTitle\"\n nzPlacement=\"right\"\n [nzWidth]=\"500\"\n [nzClosable]=\"false\"\n [nzVisible]=\"drawTemplateVisibel\"\n [nzFooter]=\"footerTplTemplate\"\n (nzOnClose)=\"drawTemplateVisibel = false\"\n>\n <ng-template #drawTemplateTitle> <nz-icon nzType=\"global\"></nz-icon> &nbsp; Quy tr\u00ECnh ph\u1ED1i h\u1EE3p </ng-template>\n <ng-container *nzDrawerContent>\n <!-- Gi\u1EEF nguy\u00EAn c\u00E1c th\u00F4ng tin chung to\u00E0n c\u1EE5c c\u1EE7a b\u1EA1n \u1EDF \u0111\u00E2y -->\n\n <extend-input [label]=\"'Code'\" [(_ngModel)]=\"templateCombine.Code\"></extend-input>\n <extend-input [label]=\"'Name'\" [(_ngModel)]=\"templateCombine.Name\"></extend-input>\n <extend-textarea [label]=\"'Description'\" [(_ngModel)]=\"templateCombine.Description\"></extend-textarea>\n <extend-checkbox [label]=\"'Active'\" [(_ngModel)]=\"templateCombine.IsActive\"></extend-checkbox>\n </ng-container>\n\n <ng-template #footerTplTemplate>\n <div nz-flex [nzGap]=\"6\" [nzJustify]=\"'end'\">\n <button nz-button nzDanger [nzLoading]=\"!ready\" (click)=\"save()\">Save</button>\n <button nz-button (click)=\"drawTemplateVisibel = false\">Close</button>\n </div>\n </ng-template>\n</nz-drawer>\n\n<!-- ==============================================\n 2. DRAWER: NODE SETTINGS (CHI TI\u1EBET M\u1ED8T TEMPLATE)\n=============================================== -->\n<nz-drawer\n [nzTitle]=\"drawerTitleNode\"\n [nzPlacement]=\"selectedTemplateNode?.editorOption?.drawerPosition == 'left' ? 'left' : 'right'\"\n [nzVisible]=\"!!selectedTemplateNode\"\n [nzWidth]=\"'90vw'\"\n [nzClosable]=\"false\"\n [nzFooter]=\"footerTplNode\"\n (nzOnClose)=\"selectedTemplateNode = undefined\"\n>\n <ng-template #drawerTitleNode>\n <div nz-row nzJustify=\"space-between\">\n <span style=\"font-weight: bold; color: #1890ff\"\n ><nz-icon nzType=\"layout\"></nz-icon> TEMPLATE NODE: [{{ selectedTemplateNode?.Code }}]\n {{ selectedTemplateNode?.Name }}</span\n >\n <button\n nz-button\n nzSize=\"small\"\n nz-tooltip=\"Chuy\u1EC3n v\u1ECB tr\u00ED Drawer\"\n (click)=\"\n selectedTemplateNode!.editorOption.drawerPosition =\n selectedTemplateNode!.editorOption.drawerPosition === 'left' ? 'right' : 'left'\n \"\n >\n <nz-icon nzType=\"swap\"></nz-icon>\n </button>\n </div>\n </ng-template>\n\n <ng-container *nzDrawerContent>\n <ng-container *ngIf=\"selectedTemplateNode\">\n <wf-template-detail #wftemplatedetail></wf-template-detail>\n </ng-container>\n </ng-container>\n\n <ng-template #footerTplNode>\n <div\n nz-flex\n [nzGap]=\"6\"\n [nzJustify]=\"selectedTemplateNode?.editorOption?.drawerPosition == 'left' ? 'start' : 'end'\"\n >\n <button nz-button nzDanger [nzLoading]=\"!ready\" (click)=\"wftemplatedetail.wfeditor.save()\">Save</button>\n <button nz-button (click)=\"selectedTemplateNode = undefined\">Close</button>\n <button nz-button nzDanger (click)=\"deleteTemplateNode()\">Delete Template node</button>\n </div>\n </ng-template>\n</nz-drawer>\n\n<!-- ==============================================\n 3. DRAWER: EDGE SETTINGS (QU\u1EA2N L\u00DD QUY T\u1EAEC CHUY\u1EC2N TEMPLATE)\n=============================================== -->\n<nz-drawer\n [nzTitle]=\"drawerTitleEdge\"\n [nzPlacement]=\"selectedTemplateEdge?.editorOption?.drawerPosition == 'left' ? 'left' : 'right'\"\n [nzClosable]=\"false\"\n [nzWidth]=\"'450px'\"\n [nzVisible]=\"!!selectedTemplateEdge\"\n [nzFooter]=\"footerTplEdge\"\n (nzOnClose)=\"selectedTemplateEdge = undefined\"\n>\n <ng-template #drawerTitleEdge>\n <div nz-row nzJustify=\"space-between\">\n <span style=\"font-weight: bold; color: #ff4d4f\"><nz-icon nzType=\"swap-right\"></nz-icon> TRANSITION RULES </span>\n <button\n nz-button\n nzSize=\"small\"\n nz-tooltip=\"Chuy\u1EC3n v\u1ECB tr\u00ED Drawer\"\n (click)=\"\n selectedTemplateEdge!.editorOption.drawerPosition =\n selectedTemplateEdge!.editorOption.drawerPosition === 'left' ? 'right' : 'left'\n \"\n >\n <nz-icon nzType=\"swap\"></nz-icon>\n </button>\n </div>\n </ng-template>\n\n <ng-container *nzDrawerContent>\n <ng-container *ngIf=\"selectedTemplateEdge\">\n <!-- Th\u00F4ng tin 2 \u0111\u1EA7u n\u1ED1i -->\n <div\n style=\"background: #fdf5f6; padding: 12px; border: 1px solid #ffa39e; border-radius: 6px; margin-bottom: 16px\"\n >\n <div style=\"font-size: 14px\">\n <strong style=\"display: inline-block; width: 70px; color: #555\">From:</strong>\n <span style=\"color: #1890ff; font-weight: 500\">\n [{{ getNode(selectedTemplateEdge.From_WF_Template_Id)?.Code }}]\n {{ getNode(selectedTemplateEdge.From_WF_Template_Id)?.Name }} > {{ selectedTemplateEdge.FromStage }} >\n {{ selectedTemplateEdge.FromAction }}\n </span>\n </div>\n <div style=\"font-size: 14px; margin-top: 8px\">\n <strong style=\"display: inline-block; width: 70px; color: #555\">Taget:</strong>\n <span style=\"color: #1890ff; font-weight: 500\">\n [{{ getNode(selectedTemplateEdge.To_WF_Template_Id)?.Code }}]\n {{ getNode(selectedTemplateEdge.To_WF_Template_Id)?.Name }} > {{ selectedTemplateEdge.ToStage }} >\n {{ selectedTemplateEdge.ToAction }}\n </span>\n </div>\n </div>\n </ng-container>\n </ng-container>\n\n <ng-template #footerTplEdge>\n <div\n nz-flex\n [nzGap]=\"6\"\n [nzJustify]=\"selectedTemplateEdge?.editorOption?.drawerPosition == 'left' ? 'start' : 'end'\"\n >\n <button nz-button nzDanger [nzLoading]=\"!ready\" (click)=\"save()\">Save Rules</button>\n <button\n nz-button\n nzDanger\n (click)=\"\n lstTemplateEdge.splice(lstTemplateEdge.indexOf(selectedTemplateEdge!), 1); selectedTemplateEdge = undefined\n \"\n >\n Delete Transition\n </button>\n <button nz-button (click)=\"selectedTemplateEdge = undefined\">Close</button>\n </div>\n </ng-template>\n</nz-drawer>\n\n<!-- ==============================================\n 4. EDITOR SETTING & INFO\n=============================================== -->\n<nz-drawer\n [nzTitle]=\"drawSettingTitle\"\n nzPlacement=\"right\"\n [nzClosable]=\"false\"\n [nzVisible]=\"settingVisible\"\n (nzOnClose)=\"settingVisible = false\"\n>\n <ng-template #drawSettingTitle> <nz-icon nzType=\"setting\"></nz-icon> &nbsp; C\u00E0i \u0111\u1EB7t Editor </ng-template>\n <ng-container *nzDrawerContent>\n <div class=\"form-item-no-bottom\">\n <extend-checkbox\n [label]=\"'Hi\u1EC3n th\u1ECB L\u01B0\u1EDBi (Grid)'\"\n [labelSpan]=\"0\"\n [(_ngModel)]=\"wfcSetting.ShowGrid\"\n ></extend-checkbox>\n </div>\n </ng-container>\n</nz-drawer>\n\n<nz-drawer\n [nzTitle]=\"drawInfoTitle\"\n nzPlacement=\"right\"\n [nzClosable]=\"false\"\n [nzVisible]=\"infoVisible\"\n (nzOnClose)=\"infoVisible = false\"\n>\n <ng-template #drawInfoTitle> <nz-icon nzType=\"info-circle\"></nz-icon> &nbsp; H\u01B0\u1EDBng d\u1EABn (Infomation) </ng-template>\n <ng-container *nzDrawerContent>\n <p>\n <strong>1. C\u00E1c th\u00E0nh ph\u1EA7n:</strong> C\u00E1c \u00F4 ch\u1EEF nh\u1EADt l\u00E0 Template (Quy tr\u00ECnh nh\u1ECF), c\u00E1c \u0111\u01B0\u1EDDng n\u1ED1i l\u00E0 Transition Rule\n (Quy t\u1EAFc chuy\u1EC3n quy tr\u00ECnh).\n </p>\n <p><strong>2. C\u00E1ch n\u1ED1i 2 Template:</strong></p>\n <ul>\n <li>Click ch\u1EA5m cam b\u00EAn ph\u1EA3i Template A, sau \u0111\u00F3 k\u00E9o v\u00E0 click v\u00E0o Template B \u0111\u1EC3 t\u1EA1o Rule n\u1ED1i.</li>\n <li>C\u00F3 th\u1EC3 click nhi\u1EC1u \u0111i\u1EC3m trong l\u00FAc k\u00E9o \u0111\u1EC3 b\u1EBB \u0111\u01B0\u1EDDng cong tu\u1EF3 \u00FD (Waypoint).</li>\n <li>Click \u0111\u00FAp v\u00E0o c\u1EA1nh (\u0111\u01B0\u1EDDng n\u1ED1i) \u0111ang c\u00F3 \u0111\u1EC3 t\u1EA1o th\u00EAm m\u1ED9t \u0111i\u1EC3m b\u1EBB cong m\u1EDBi.</li>\n <li>Gi\u1EEF v\u00E0 k\u00E9o \u0111i\u1EC3m b\u1EBB cong \u0111\u1EC3 tu\u1EF3 ch\u1EC9nh \u0111\u01B0\u1EDDng \u0111i. Chu\u1ED9t ph\u1EA3i v\u00E0o \u0111i\u1EC3m \u0111\u00F3 \u0111\u1EC3 x\u00F3a n\u00F3.</li>\n </ul>\n <p>\n <strong>3. Qu\u1EA3n l\u00FD Rule:</strong> Click v\u00E0o \u0111\u01B0\u1EDDng n\u1ED1i gi\u1EEFa 2 Node \u0111\u1EC3 c\u1EA5u h\u00ECnh c\u00E1c lu\u1ED3ng th\u1EF1c thi (Stored, Ph\u00E2n\n quy\u1EC1n, G\u1EEDi mail).\n </p>\n </ng-container>\n</nz-drawer>\n\n<nz-modal\n [(nzVisible)]=\"isModalVisible\"\n nzTitle=\"Add template node\"\n [nzWidth]=\"600\"\n (nzOnCancel)=\"isModalVisible = false\"\n (nzOnOk)=\"addTemplateNodes()\"\n nzOkText=\"Add\"\n nzOkDanger\n nzCancelText=\"Cancel\"\n nzMaskClosable=\"false\"\n>\n <ng-container *nzModalContent>\n <extend-select\n label=\"Template\"\n [lstItem]=\"lstTemplateForSelect\"\n [displayField]=\"'Name'\"\n [multiple]=\"true\"\n [(_ngModel)]=\"lstTemplateSelected\"\n ></extend-select>\n </ng-container>\n</nz-modal>\n", styles: ["@charset \"UTF-8\";::ng-deep .workflow-wrapper{border:solid 1px lightgray;overflow:hidden;width:100%}.workflow-canvas{position:relative;background:#f0f2f5;cursor:default;overflow:hidden;outline:1px dashed rgba(0,0,0,.1)}.workflow-canvas .edges-layer{position:absolute;inset:0;width:100%;height:100%;z-index:1}.workflow-canvas .edges-layer path{stroke-width:2;fill:none}.canvas-content{transform-origin:0 0;width:100%;height:100%;transition:transform .05s linear}.canvas-content{outline:1px dashed red}.canvas-content.panning{cursor:grab}.canvas-content.panning:active{cursor:grabbing}.workflow-canvas.panning{cursor:grab}.workflow-canvas.panning:active{cursor:grabbing}.workflow-canvas.connecting,.workflow-canvas.connecting .workflow-node{cursor:crosshair}.workflow-node{position:absolute;width:160px;cursor:grab;-webkit-user-select:none;user-select:none;z-index:2}.workflow-node:active{cursor:grabbing}.workflow-node.connecting-source,.workflow-node.selected,.workflow-node:hover:not(.workflow-node-start,.workflow-node-end){outline:2px dashed #1890ff}.workflow-node .title{font-weight:600;margin-bottom:6px}.workflow-node-start{width:0px}.workflow-node-start.connecting-source,.workflow-node-start.selected,.workflow-node-start:hover{outline:unset}.workflow-node-start.connecting-source nz-tag,.workflow-node-start.selected nz-tag,.workflow-node-start:hover nz-tag{outline:2px dashed}.workflow-node-start nz-tag{position:relative;top:45px;right:35px}.workflow-node-end{width:0px}.workflow-node-end.connecting-source,.workflow-node-end.selected,.workflow-node-end:hover{outline:unset}.workflow-node-end.connecting-source nz-tag,.workflow-node-end.selected nz-tag,.workflow-node-end:hover nz-tag{outline:2px dashed}.workflow-node-end nz-tag{position:relative;top:45px;right:32px}.connector{position:absolute;top:39px;width:12px;height:12px;background:#1890ff;border-radius:50%;transform:translateY(-50%);cursor:crosshair;transition:box-shadow .15s ease-out,transform .15s ease-out}.connector:hover{box-shadow:0 0 0 3px #1890ff4d;transform:translateY(-50%) scale(1.15)}.connector-right{right:-8px;background:orange}.connector-right.reverse,.connector-left{left:-8px}.connector-left.reverse{left:unset;right:-8px}.connector-start{width:16px;height:16px;right:-8px;background:green;box-shadow:0 0 0 3px #1890ff4d}.connector-end{width:16px;height:16px;left:-8px;background:#000;box-shadow:0 0 0 3px #1890ff4d}.edge{cursor:pointer;stroke:#1890ff;stroke-linecap:round;stroke-linejoin:round;stroke-width:2;fill:none;transition:stroke .15s ease}.edge-hit{stroke:transparent;stroke-width:18px!important;fill:none;cursor:pointer}.edge-hit:hover+.edge{stroke:#ff4d4f;stroke-width:2}.workflow-canvas.dragging-point .edge-hit{pointer-events:none}.edge:hover+.edge-label{fill:#1890ff;font-weight:500}.edge-label{font-size:12px;fill:#555;pointer-events:none;-webkit-user-select:none;user-select:none}.blue{stroke:#1890ff!important}.red{stroke:#ff4d4f!important;box-shadow:0 0 0 3px #1890ff4d!important}.workflow-svg{background:transparent;overflow:visible}.waypoint{position:absolute;width:10px;height:10px;background:#ff4d4f;border-radius:50%;transform:translate(-50%,-50%) scale(1);cursor:move;z-index:1;transition:transform .12s ease-out,background-color .12s ease-out,box-shadow .12s ease-out}.waypoint:hover{background:#ff7875;transform:translate(-50%,-50%) scale(1.25);box-shadow:0 0 0 4px #ff787559}.waypoint.dragging{transition:none;transform:translate(-50%,-50%) scale(1.15);pointer-events:none}.workflow-canvas.dragging-point svg{cursor:grabbing}.selection-box{position:absolute;border:1px dashed #1890ff;background:#1890ff1a;pointer-events:none}.toolbar{position:absolute;top:8px;left:8px;display:flex;gap:4px;padding:6px;background:#fff;border-radius:6px;box-shadow:0 2px 8px #00000026;z-index:100}.toolbar .divider{width:1px;background:#e5e5e5;margin:0 2px}nz-tag.selected{outline:2px dashed #1890ff}.grid-layer{position:absolute;inset:0;pointer-events:none;z-index:0;background-image:radial-gradient(rgba(0,0,0,.08) 1px,transparent 1px);background-size:20px 20px}.grid-layer{background-image:linear-gradient(to right,rgba(0,0,0,.06) 1px,transparent 1px),linear-gradient(to bottom,rgba(0,0,0,.06) 1px,transparent 1px);background-size:20px 20px}.editable-tag{background:#fff;border-style:dashed}::ng-deep .minimap,.minimap-combine{position:absolute;width:180px;height:125px;top:0;right:0;background-color:#eee;border:1px solid #aaa;opacity:.9;z-index:1}::ng-deep .minimap{position:absolute;width:200px;height:140px;top:8px;right:8px;background-color:#f8f9fa;border:1px solid #d9d9d9;border-radius:8px;box-shadow:0 4px 12px #0000001a;overflow:hidden;z-index:100;-webkit-user-select:none;user-select:none}::ng-deep .minimap-node{position:absolute;background-color:#bfbfbf;border-radius:2px}::ng-deep .minimap-node-round{position:absolute;background-color:#bfbfbf;border-radius:50%}::ng-deep .minimap-node-round-start{background-color:#52c41a}::ng-deep .minimap-node-round-end{background-color:#ff4d4f}::ng-deep .minimap-viewport{position:absolute;box-sizing:border-box;background-color:#1890ff26;border:1.5px solid #1890ff;border-radius:4px;z-index:2;cursor:grab;transition:none}::ng-deep .minimap-viewport.grabbing,::ng-deep .minimap-viewport:active{cursor:grabbing;background-color:#1890ff40}::ng-deep .has-floating-label.floating-label{position:relative;padding-top:14px}::ng-deep .has-floating-label nz-form-item nz-form-label{position:absolute;top:12px;left:13px;transform:translateY(-50%);background:linear-gradient(to bottom,var(--form-bg-color, #ffffff) 80%,#ffffff 80%);z-index:1;height:auto;line-height:normal;padding:0 4px}::ng-deep .has-floating-label nz-form-item nz-form-label label{font-size:12px;color:var(--darkgray, #565656);font-weight:700;height:auto;line-height:normal;padding:0;display:flex;align-items:center}::ng-deep .has-floating-label .full-width{width:100%}.has-floating-label.floating-label nz-form-item:has(.ant-select-disabled) nz-form-label,.has-floating-label.floating-label nz-form-item:has(input[disabled]) nz-form-label,.has-floating-label.floating-label nz-form-item:has(.ant-input-disabled) nz-form-label{background:linear-gradient(to bottom,var(--form-bg-color, #ffffff) 60%,#f5f5f5 50%)}.has-floating-label.floating-label nz-form-item:has(.ant-select-disabled) nz-form-label label,.has-floating-label.floating-label nz-form-item:has(input[disabled]) nz-form-label label,.has-floating-label.floating-label nz-form-item:has(.ant-input-disabled) nz-form-label label{color:#bfbfbf}\n"] }]
19549
+ ], selector: 'app-workflow-combine-editor', template: "<div\n #canvas\n class=\"workflow-canvas\"\n [class.connecting]=\"!!connectingFrom\"\n [class.dragging-point]=\"!!draggingPoint\"\n style=\"width: 100%; height: 100%\"\n (mousedown)=\"onMouseDownCanvas($event)\"\n (mousemove)=\"onMouseMoveCanvas($event)\"\n (mouseup)=\"onMouseUpCanvas($event)\"\n (click)=\"onClickCanvas($event)\"\n (wheel)=\"onWheelCanvas($event)\"\n>\n <!-- TOOLBAR -->\n <div class=\"toolbar\" (mousedown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\">\n <button nz-button nzSize=\"small\" nz-tooltip=\"Editor setting\" (click)=\"settingVisible = true\">\n <nz-icon nzType=\"setting\"></nz-icon>\n </button>\n\n <button nz-button nzSize=\"small\" nz-tooltip=\"Infomation\" (click)=\"infoVisible = true\">\n <nz-icon nzType=\"info-circle\"></nz-icon>\n </button>\n\n <box [width]=\"1\"></box>\n <span class=\"divider\"></span>\n <box [width]=\"1\"></box>\n\n <button nz-button nzSize=\"small\" nz-tooltip=\"Global Setting\" (click)=\"drawTemplateVisibel = true\">\n <nz-icon nzType=\"setting\"></nz-icon> G\n </button>\n\n <box [width]=\"1\"></box>\n <span class=\"divider\"></span>\n <box [width]=\"1\"></box>\n\n <button nz-button nzSize=\"small\" nzDanger [nzLoading]=\"!ready\" nz-tooltip=\"Save (Ctrl + S)\" (click)=\"save()\">\n <nz-icon nzType=\"save\"></nz-icon>\n </button>\n <button nz-button nzSize=\"small\" nz-tooltip=\"Th\u00EAm Template m\u1EDBi\" (click)=\"isModalVisible = true\">\n <nz-icon nzType=\"plus\" class=\"color-primary\"></nz-icon>\n </button>\n\n <box [width]=\"1\"></box>\n <span class=\"divider\"></span>\n <box [width]=\"1\"></box>\n\n <button\n nz-button\n nzSize=\"small\"\n [nzType]=\"isMoveMode ? 'primary' : 'default'\"\n nz-tooltip=\"Move mode\"\n (click)=\"isMoveMode = true\"\n >\n <nz-icon><img src=\"/assets/icon/hand-palm.png\" width=\"19\" height=\"19\" /></nz-icon>\n </button>\n <button\n nz-button\n nzSize=\"small\"\n [nzType]=\"!isMoveMode ? 'primary' : 'default'\"\n nz-tooltip=\"Select mode\"\n (click)=\"isMoveMode = false\"\n >\n <nz-icon><img src=\"/assets/icon/cursor.png\" width=\"19\" height=\"19\" /></nz-icon>\n </button>\n\n <box [width]=\"1\"></box>\n <span class=\"divider\"></span>\n <box [width]=\"1\"></box>\n\n <!-- UNDO / REDO -->\n <button\n nz-button\n nzSize=\"small\"\n nzType=\"default\"\n [disabled]=\"undoStack.length === 0\"\n nz-tooltip=\"Undo\"\n (click)=\"undo()\"\n >\n <nz-icon nzType=\"undo\"></nz-icon>\n </button>\n <button\n nz-button\n nzSize=\"small\"\n nzType=\"default\"\n [disabled]=\"redoStack.length === 0\"\n nz-tooltip=\"Redo\"\n (click)=\"redo()\"\n >\n <nz-icon nzType=\"redo\"></nz-icon>\n </button>\n\n <box [width]=\"1\"></box>\n <span class=\"divider\"></span>\n <box [width]=\"1\"></box>\n\n <!-- ALIGN -->\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 2\" (click)=\"alignLeft()\">\u27F8</button>\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 2\" (click)=\"alignCenter()\">\u2261</button>\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 2\" (click)=\"alignRight()\">\u27F9</button>\n <span class=\"divider\"></span>\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 2\" (click)=\"alignTop()\">\u21D1</button>\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 2\" (click)=\"alignMiddle()\">\u2550</button>\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 2\" (click)=\"alignBottom()\">\u21D3</button>\n <span class=\"divider\"></span>\n <!-- DISTRIBUTE -->\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 3\" (click)=\"distributeHorizontal()\">\n \u21C4\n </button>\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedTemplateId.size < 3\" (click)=\"distributeVertical()\">\n \u21C5\n </button>\n\n <box [width]=\"1\"></box>\n <span class=\"divider\"></span>\n <box [width]=\"1\"></box>\n\n <!-- ZOOM -->\n <button nz-button nzSize=\"small\" nzType=\"default\" (click)=\"zoomOut()\" nz-tooltip=\"Zoom Out\">\n <nz-icon nzType=\"minus\"></nz-icon>\n </button>\n <span>{{ Math.round(zoom * 100) }}%</span>\n <button nz-button nzSize=\"small\" nzType=\"default\" (click)=\"zoomIn()\" nz-tooltip=\"Zoom In\">\n <nz-icon nzType=\"plus\"></nz-icon>\n </button>\n <span class=\"divider\"></span>\n <button nz-button nzSize=\"small\" nzType=\"default\" (click)=\"resetZoom()\" nz-tooltip=\"Reset Zoom (Ctrl+0)\">\n <nz-icon nzType=\"expand\"></nz-icon>\n </button>\n </div>\n\n <div\n class=\"canvas-content\"\n [class.panning]=\"isMoveMode\"\n [style.width.px]=\"getCanvasWidth()\"\n [style.height.px]=\"getCanvasHeight()\"\n [style.transform]=\"\n 'translate(' +\n templateCombine.editorOption.panX +\n 'px,' +\n templateCombine.editorOption.panY +\n 'px) scale(' +\n zoom +\n ')'\n \"\n >\n <!-- GRID -->\n <div *ngIf=\"wfcSetting.ShowGrid\" class=\"grid-layer\"></div>\n\n <!-- SVG EDGES -->\n <svg #svg class=\"edges-layer\" width=\"100%\" height=\"100%\" preserveAspectRatio=\"none\">\n <g>\n <!-- DEFS -->\n <defs>\n <filter id=\"edge-glow\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\n <feGaussianBlur stdDeviation=\"2\" result=\"blur\" />\n <feMerge>\n <feMergeNode in=\"blur\" />\n <feMergeNode in=\"SourceGraphic\" />\n </feMerge>\n </filter>\n\n <marker\n id=\"arrow-blue\"\n markerWidth=\"10\"\n markerHeight=\"10\"\n refX=\"10\"\n refY=\"5\"\n orient=\"auto\"\n markerUnits=\"strokeWidth\"\n >\n <path class=\"blue\" d=\"M0,0 L10,5 L0,10\"></path>\n </marker>\n <marker\n id=\"arrow-red\"\n markerWidth=\"10\"\n markerHeight=\"10\"\n refX=\"10\"\n refY=\"5\"\n orient=\"auto\"\n markerUnits=\"strokeWidth\"\n >\n <path class=\"red\" d=\"M0,0 L10,5 L0,10\"></path>\n </marker>\n </defs>\n\n <!-- EDGES B\u00CCNH TH\u01AF\u1EDCNG -->\n <ng-container *ngFor=\"let e of normalEdges; let i = index\">\n <path class=\"edge\" [attr.id]=\"'edge-path-' + i\" [attr.d]=\"buildPath(e)\" marker-end=\"url(#arrow-blue)\"></path>\n\n <path\n class=\"edge-hit\"\n [attr.d]=\"buildPath(e)\"\n (mouseenter)=\"onMouseEnterEdge(e)\"\n (mouseleave)=\"onMouseLeaveEdge(e)\"\n (click)=\"onClickEdge(e, $event)\"\n ></path>\n\n <!-- \u0110\u00E3 x\u00F3a *ngIf=\"e.RuleLineDetails?.length\" \u1EDF \u0111\u00E2y \u0111\u1EC3 text lu\u00F4n hi\u1EC7n -->\n <text\n class=\"edge-label\"\n style=\"fill: #1890ff; font-weight: 500\"\n [attr.x]=\"getEdgeLabelPosition(e).x\"\n [attr.y]=\"getEdgeLabelPosition(e).y - 8\"\n [attr.text-anchor]=\"'middle'\"\n >\n {{ e.FromStage }} / {{ e.FromAction }} > {{ e.ToStage }} / {{ e.ToAction }}\n </text>\n </ng-container>\n\n <!-- EDGE \u0110ANG HOVER/SELECTED (HI\u1EC2N TH\u1ECA M\u00C0U \u0110\u1ECE) -->\n <ng-container *ngFor=\"let e of hoverEdges; let i = index\">\n <path\n class=\"edge red\"\n [attr.id]=\"'edge-path-hover-' + i\"\n [attr.d]=\"buildPath(e)\"\n marker-end=\"url(#arrow-red)\"\n ></path>\n\n <path\n class=\"edge-hit\"\n [attr.d]=\"buildPath(e)\"\n (mouseleave)=\"onMouseLeaveEdge(e)\"\n (click)=\"onClickEdge(e, $event)\"\n ></path>\n\n <text\n class=\"edge-label\"\n style=\"font-weight: bold; fill: red\"\n [attr.x]=\"getEdgeLabelPosition(e).x\"\n [attr.y]=\"getEdgeLabelPosition(e).y - 8\"\n [attr.text-anchor]=\"'middle'\"\n >\n {{ e.FromStage }} / {{ e.FromAction }} > {{ e.ToStage }} / {{ e.ToAction }}\n </text>\n </ng-container>\n\n <!-- PREVIEW LINE (\u0110\u01AF\u1EDCNG N\u1ED0I \u0110ANG K\u00C9O) -->\n <path\n *ngIf=\"connectingFrom\"\n class=\"edge\"\n [attr.d]=\"buildPreviewPath()\"\n stroke-dasharray=\"5,5\"\n marker-end=\"url(#arrow-blue)\"\n ></path>\n </g>\n </svg>\n\n <!-- BOX V\u00D9NG CH\u1ECCN MULTI -->\n <div\n *ngIf=\"isSelecting && selectStart && selectEnd\"\n class=\"selection-box\"\n [style.left.px]=\"Math.min(selectStart.x, selectEnd.x)\"\n [style.top.px]=\"Math.min(selectStart.y, selectEnd.y)\"\n [style.width.px]=\"Math.abs(selectEnd.x - selectStart.x)\"\n [style.height.px]=\"Math.abs(selectEnd.y - selectStart.y)\"\n ></div>\n\n <!-- NODE (TEMPLATE) L\u1EDAP HI\u1EC2N TH\u1ECA TR\u00CAN C\u00D9NG -->\n @for (n of lstTemplateNode; track n.WF_Template_Id) {\n <nz-card\n class=\"workflow-node\"\n [attr.data-id]=\"n.Code\"\n [class.selected]=\"\n n == selectedTemplateNode || n == hoverTemplateNode || lstSelectedTemplateId.has(n.WF_Template_Id)\n \"\n [style.left.px]=\"n.editorOption.x\"\n [style.top.px]=\"n.editorOption.y\"\n [class.connecting-source]=\"isConnectingFrom(n) || isDraggingFrom(n) || isSelectedNode(n)\"\n nzSize=\"small\"\n (mousedown)=\"onMouseDownNode($event, n)\"\n (click)=\"$event.stopPropagation(); onClickNode(n)\"\n >\n <div class=\"title\" style=\"color: #1890ff; display: flex; justify-content: space-between; align-items: center\">\n <span>{{ n.Code }}</span>\n <nz-icon nzType=\"layout\" nzTheme=\"outline\"></nz-icon>\n </div>\n <div\n style=\"\n font-size: 12px;\n line-height: 1.2;\n font-weight: 500;\n height: 28px;\n overflow: hidden;\n text-overflow: ellipsis;\n \"\n >\n {{ n.Name || \"Ch\u01B0a c\u00F3 t\u00EAn\" }}\n </div>\n <div style=\"font-size: 10px; color: gray; margin-top: 4px\">\n {{ n.DocType }}\n </div>\n\n <!-- CONNECTOR \u0110\u1EC2 K\u00C9O D\u00C2Y -->\n <div class=\"connector connector-right\" (click)=\"onClickConnector($event, n, 'right')\"></div>\n <div class=\"connector connector-left\" (click)=\"onClickConnector($event, n, 'left')\"></div>\n </nz-card>\n }\n\n <!-- C\u00C1C \u0110I\u1EC2M WAYPOINT \u0110\u1EC2 B\u1EBA CONG D\u00C2Y CHU\u1ED8T -->\n @for (p of connectingPoints; track $index) {\n @if (p != draggingPoint) {\n <div\n class=\"waypoint\"\n [style.left.px]=\"p.x\"\n [style.top.px]=\"p.y\"\n (mousedown)=\"onmousedownPoint($event, p)\"\n (contextmenu)=\"onRightClickPoint($event, hoverTemplateEdge!, $index)\"\n ></div>\n } @else {\n <div\n class=\"waypoint dragging\"\n [style.left.px]=\"p.x\"\n [style.top.px]=\"p.y\"\n (mousedown)=\"onmousedownPoint($event, p)\"\n ></div>\n }\n }\n </div>\n</div>\n\n<!-- ==============================================\n 1. DRAWER: GLOBAL TEMPLATE SETTINGS \n=============================================== -->\n<nz-drawer\n [nzTitle]=\"drawTemplateTitle\"\n nzPlacement=\"right\"\n [nzWidth]=\"500\"\n [nzClosable]=\"false\"\n [nzVisible]=\"drawTemplateVisibel\"\n [nzFooter]=\"footerTplTemplate\"\n (nzOnClose)=\"drawTemplateVisibel = false\"\n>\n <ng-template #drawTemplateTitle> <nz-icon nzType=\"global\"></nz-icon> &nbsp; Quy tr\u00ECnh ph\u1ED1i h\u1EE3p </ng-template>\n <ng-container *nzDrawerContent>\n <!-- Gi\u1EEF nguy\u00EAn c\u00E1c th\u00F4ng tin chung to\u00E0n c\u1EE5c c\u1EE7a b\u1EA1n \u1EDF \u0111\u00E2y -->\n\n <extend-input [label]=\"'Code'\" [(_ngModel)]=\"templateCombine.Code\"></extend-input>\n <extend-input [label]=\"'Name'\" [(_ngModel)]=\"templateCombine.Name\"></extend-input>\n <extend-textarea [label]=\"'Description'\" [(_ngModel)]=\"templateCombine.Description\"></extend-textarea>\n <extend-checkbox [label]=\"'Active'\" [(_ngModel)]=\"templateCombine.IsActive\"></extend-checkbox>\n </ng-container>\n\n <ng-template #footerTplTemplate>\n <div nz-flex [nzGap]=\"6\" [nzJustify]=\"'end'\">\n <button nz-button nzDanger [nzLoading]=\"!ready\" (click)=\"save()\">Save</button>\n <button nz-button (click)=\"drawTemplateVisibel = false\">Close</button>\n </div>\n </ng-template>\n</nz-drawer>\n\n<!-- ==============================================\n 2. DRAWER: NODE SETTINGS (CHI TI\u1EBET M\u1ED8T TEMPLATE)\n=============================================== -->\n<nz-drawer\n [nzTitle]=\"drawerTitleNode\"\n [nzPlacement]=\"selectedTemplateNode?.editorOption?.drawerPosition == 'left' ? 'left' : 'right'\"\n [nzVisible]=\"!!selectedTemplateNode\"\n [nzWidth]=\"'90vw'\"\n [nzClosable]=\"false\"\n [nzFooter]=\"footerTplNode\"\n (nzOnClose)=\"selectedTemplateNode = undefined\"\n>\n <ng-template #drawerTitleNode>\n <div nz-row nzJustify=\"space-between\">\n <span style=\"font-weight: bold; color: #1890ff\"\n ><nz-icon nzType=\"layout\"></nz-icon> TEMPLATE NODE: [{{ selectedTemplateNode?.Code }}]\n {{ selectedTemplateNode?.Name }}</span\n >\n <button\n nz-button\n nzSize=\"small\"\n nz-tooltip=\"Chuy\u1EC3n v\u1ECB tr\u00ED Drawer\"\n (click)=\"\n selectedTemplateNode!.editorOption.drawerPosition =\n selectedTemplateNode!.editorOption.drawerPosition === 'left' ? 'right' : 'left'\n \"\n >\n <nz-icon nzType=\"swap\"></nz-icon>\n </button>\n </div>\n </ng-template>\n\n <ng-container *nzDrawerContent>\n <ng-container *ngIf=\"selectedTemplateNode\">\n <wf-template-detail #wftemplatedetail (onSave)=\"getdata.emit()\"></wf-template-detail>\n </ng-container>\n </ng-container>\n\n <ng-template #footerTplNode>\n <div\n nz-flex\n [nzGap]=\"6\"\n [nzJustify]=\"selectedTemplateNode?.editorOption?.drawerPosition == 'left' ? 'start' : 'end'\"\n >\n <button nz-button nzDanger [nzLoading]=\"!ready\" (click)=\"wftemplatedetail.wfeditor.save()\">Save</button>\n <button nz-button (click)=\"selectedTemplateNode = undefined\">Close</button>\n <button nz-button nzDanger (click)=\"deleteTemplateNode()\">Delete Template node</button>\n </div>\n </ng-template>\n</nz-drawer>\n\n<!-- ==============================================\n 3. DRAWER: EDGE SETTINGS (QU\u1EA2N L\u00DD QUY T\u1EAEC CHUY\u1EC2N TEMPLATE)\n=============================================== -->\n<nz-drawer\n [nzTitle]=\"drawerTitleEdge\"\n [nzPlacement]=\"selectedTemplateEdge?.editorOption?.drawerPosition == 'left' ? 'left' : 'right'\"\n [nzClosable]=\"false\"\n [nzWidth]=\"'450px'\"\n [nzVisible]=\"!!selectedTemplateEdge\"\n [nzFooter]=\"footerTplEdge\"\n (nzOnClose)=\"selectedTemplateEdge = undefined\"\n>\n <ng-template #drawerTitleEdge>\n <div nz-row nzJustify=\"space-between\">\n <span style=\"font-weight: bold; color: #ff4d4f\"><nz-icon nzType=\"swap-right\"></nz-icon> TRANSITION RULES </span>\n <button\n nz-button\n nzSize=\"small\"\n nz-tooltip=\"Chuy\u1EC3n v\u1ECB tr\u00ED Drawer\"\n (click)=\"\n selectedTemplateEdge!.editorOption.drawerPosition =\n selectedTemplateEdge!.editorOption.drawerPosition === 'left' ? 'right' : 'left'\n \"\n >\n <nz-icon nzType=\"swap\"></nz-icon>\n </button>\n </div>\n </ng-template>\n\n <ng-container *nzDrawerContent>\n <ng-container *ngIf=\"selectedTemplateEdge\">\n <!-- Th\u00F4ng tin 2 \u0111\u1EA7u n\u1ED1i -->\n <div\n style=\"background: #fdf5f6; padding: 12px; border: 1px solid #ffa39e; border-radius: 6px; margin-bottom: 16px\"\n >\n <div style=\"font-size: 14px\">\n <strong style=\"display: inline-block; width: 70px; color: #555\">From:</strong>\n <span style=\"color: #1890ff; font-weight: 500\">\n [{{ getNode(selectedTemplateEdge.From_WF_Template_Id)?.Code }}]\n {{ getNode(selectedTemplateEdge.From_WF_Template_Id)?.Name }} > {{ selectedTemplateEdge.FromStage }} >\n {{ selectedTemplateEdge.FromAction }}\n </span>\n </div>\n <div style=\"font-size: 14px; margin-top: 8px\">\n <strong style=\"display: inline-block; width: 70px; color: #555\">Taget:</strong>\n <span style=\"color: #1890ff; font-weight: 500\">\n [{{ getNode(selectedTemplateEdge.To_WF_Template_Id)?.Code }}]\n {{ getNode(selectedTemplateEdge.To_WF_Template_Id)?.Name }} > {{ selectedTemplateEdge.ToStage }} >\n {{ selectedTemplateEdge.ToAction }}\n </span>\n </div>\n </div>\n </ng-container>\n </ng-container>\n\n <ng-template #footerTplEdge>\n <div\n nz-flex\n [nzGap]=\"6\"\n [nzJustify]=\"selectedTemplateEdge?.editorOption?.drawerPosition == 'left' ? 'start' : 'end'\"\n >\n <button nz-button nzDanger [nzLoading]=\"!ready\" (click)=\"save()\">Save Rules</button>\n <button\n nz-button\n nzDanger\n (click)=\"\n lstTemplateEdge.splice(lstTemplateEdge.indexOf(selectedTemplateEdge!), 1); selectedTemplateEdge = undefined\n \"\n >\n Delete Transition\n </button>\n <button nz-button (click)=\"selectedTemplateEdge = undefined\">Close</button>\n </div>\n </ng-template>\n</nz-drawer>\n\n<!-- ==============================================\n 4. EDITOR SETTING & INFO\n=============================================== -->\n<nz-drawer\n [nzTitle]=\"drawSettingTitle\"\n nzPlacement=\"right\"\n [nzClosable]=\"false\"\n [nzVisible]=\"settingVisible\"\n (nzOnClose)=\"settingVisible = false\"\n>\n <ng-template #drawSettingTitle> <nz-icon nzType=\"setting\"></nz-icon> &nbsp; C\u00E0i \u0111\u1EB7t Editor </ng-template>\n <ng-container *nzDrawerContent>\n <div class=\"form-item-no-bottom\">\n <extend-checkbox\n [label]=\"'Hi\u1EC3n th\u1ECB L\u01B0\u1EDBi (Grid)'\"\n [labelSpan]=\"0\"\n [(_ngModel)]=\"wfcSetting.ShowGrid\"\n ></extend-checkbox>\n </div>\n </ng-container>\n</nz-drawer>\n\n<nz-drawer\n [nzTitle]=\"drawInfoTitle\"\n nzPlacement=\"right\"\n [nzClosable]=\"false\"\n [nzVisible]=\"infoVisible\"\n (nzOnClose)=\"infoVisible = false\"\n>\n <ng-template #drawInfoTitle> <nz-icon nzType=\"info-circle\"></nz-icon> &nbsp; H\u01B0\u1EDBng d\u1EABn (Infomation) </ng-template>\n <ng-container *nzDrawerContent>\n <p>\n <strong>1. C\u00E1c th\u00E0nh ph\u1EA7n:</strong> C\u00E1c \u00F4 ch\u1EEF nh\u1EADt l\u00E0 Template (Quy tr\u00ECnh nh\u1ECF), c\u00E1c \u0111\u01B0\u1EDDng n\u1ED1i l\u00E0 Transition Rule\n (Quy t\u1EAFc chuy\u1EC3n quy tr\u00ECnh).\n </p>\n <p><strong>2. C\u00E1ch n\u1ED1i 2 Template:</strong></p>\n <ul>\n <li>Click ch\u1EA5m cam b\u00EAn ph\u1EA3i Template A, sau \u0111\u00F3 k\u00E9o v\u00E0 click v\u00E0o Template B \u0111\u1EC3 t\u1EA1o Rule n\u1ED1i.</li>\n <li>C\u00F3 th\u1EC3 click nhi\u1EC1u \u0111i\u1EC3m trong l\u00FAc k\u00E9o \u0111\u1EC3 b\u1EBB \u0111\u01B0\u1EDDng cong tu\u1EF3 \u00FD (Waypoint).</li>\n <li>Click \u0111\u00FAp v\u00E0o c\u1EA1nh (\u0111\u01B0\u1EDDng n\u1ED1i) \u0111ang c\u00F3 \u0111\u1EC3 t\u1EA1o th\u00EAm m\u1ED9t \u0111i\u1EC3m b\u1EBB cong m\u1EDBi.</li>\n <li>Gi\u1EEF v\u00E0 k\u00E9o \u0111i\u1EC3m b\u1EBB cong \u0111\u1EC3 tu\u1EF3 ch\u1EC9nh \u0111\u01B0\u1EDDng \u0111i. Chu\u1ED9t ph\u1EA3i v\u00E0o \u0111i\u1EC3m \u0111\u00F3 \u0111\u1EC3 x\u00F3a n\u00F3.</li>\n </ul>\n <p>\n <strong>3. Qu\u1EA3n l\u00FD Rule:</strong> Click v\u00E0o \u0111\u01B0\u1EDDng n\u1ED1i gi\u1EEFa 2 Node \u0111\u1EC3 c\u1EA5u h\u00ECnh c\u00E1c lu\u1ED3ng th\u1EF1c thi (Stored, Ph\u00E2n\n quy\u1EC1n, G\u1EEDi mail).\n </p>\n </ng-container>\n</nz-drawer>\n\n<nz-modal\n [(nzVisible)]=\"isModalVisible\"\n nzTitle=\"Add template node\"\n [nzWidth]=\"600\"\n (nzOnCancel)=\"isModalVisible = false\"\n (nzOnOk)=\"addTemplateNodes()\"\n nzOkText=\"Add\"\n nzOkDanger\n nzCancelText=\"Cancel\"\n nzMaskClosable=\"false\"\n>\n <ng-container *nzModalContent>\n <extend-select\n label=\"Template\"\n [lstItem]=\"lstTemplateForSelect\"\n [displayField]=\"'Name'\"\n [multiple]=\"true\"\n [(_ngModel)]=\"lstTemplateSelected\"\n ></extend-select>\n </ng-container>\n</nz-modal>\n", styles: ["@charset \"UTF-8\";::ng-deep .workflow-wrapper{border:solid 1px lightgray;overflow:hidden;width:100%}.workflow-canvas{position:relative;background:#f0f2f5;cursor:default;overflow:hidden;outline:1px dashed rgba(0,0,0,.1)}.workflow-canvas .edges-layer{position:absolute;inset:0;width:100%;height:100%;z-index:1}.workflow-canvas .edges-layer path{stroke-width:2;fill:none}.canvas-content{transform-origin:0 0;width:100%;height:100%;transition:transform .05s linear}.canvas-content{outline:1px dashed red}.canvas-content.panning{cursor:grab}.canvas-content.panning:active{cursor:grabbing}.workflow-canvas.panning{cursor:grab}.workflow-canvas.panning:active{cursor:grabbing}.workflow-canvas.connecting,.workflow-canvas.connecting .workflow-node{cursor:crosshair}.workflow-node{position:absolute;width:160px;cursor:grab;-webkit-user-select:none;user-select:none;z-index:2}.workflow-node:active{cursor:grabbing}.workflow-node.connecting-source,.workflow-node.selected,.workflow-node:hover:not(.workflow-node-start,.workflow-node-end){outline:2px dashed #1890ff}.workflow-node .title{font-weight:600;margin-bottom:6px}.workflow-node-start{width:0px}.workflow-node-start.connecting-source,.workflow-node-start.selected,.workflow-node-start:hover{outline:unset}.workflow-node-start.connecting-source nz-tag,.workflow-node-start.selected nz-tag,.workflow-node-start:hover nz-tag{outline:2px dashed}.workflow-node-start nz-tag{position:relative;top:45px;right:35px}.workflow-node-end{width:0px}.workflow-node-end.connecting-source,.workflow-node-end.selected,.workflow-node-end:hover{outline:unset}.workflow-node-end.connecting-source nz-tag,.workflow-node-end.selected nz-tag,.workflow-node-end:hover nz-tag{outline:2px dashed}.workflow-node-end nz-tag{position:relative;top:45px;right:32px}.connector{position:absolute;top:39px;width:12px;height:12px;background:#1890ff;border-radius:50%;transform:translateY(-50%);cursor:crosshair;transition:box-shadow .15s ease-out,transform .15s ease-out}.connector:hover{box-shadow:0 0 0 3px #1890ff4d;transform:translateY(-50%) scale(1.15)}.connector-right{right:-8px;background:orange}.connector-right.reverse,.connector-left{left:-8px}.connector-left.reverse{left:unset;right:-8px}.connector-start{width:16px;height:16px;right:-8px;background:green;box-shadow:0 0 0 3px #1890ff4d}.connector-end{width:16px;height:16px;left:-8px;background:#000;box-shadow:0 0 0 3px #1890ff4d}.edge{cursor:pointer;stroke:#1890ff;stroke-linecap:round;stroke-linejoin:round;stroke-width:2;fill:none;transition:stroke .15s ease}.edge-hit{stroke:transparent;stroke-width:18px!important;fill:none;cursor:pointer}.edge-hit:hover+.edge{stroke:#ff4d4f;stroke-width:2}.workflow-canvas.dragging-point .edge-hit{pointer-events:none}.edge:hover+.edge-label{fill:#1890ff;font-weight:500}.edge-label{font-size:12px;fill:#555;pointer-events:none;-webkit-user-select:none;user-select:none}.blue{stroke:#1890ff!important}.red{stroke:#ff4d4f!important;box-shadow:0 0 0 3px #1890ff4d!important}.workflow-svg{background:transparent;overflow:visible}.waypoint{position:absolute;width:10px;height:10px;background:#ff4d4f;border-radius:50%;transform:translate(-50%,-50%) scale(1);cursor:move;z-index:1;transition:transform .12s ease-out,background-color .12s ease-out,box-shadow .12s ease-out}.waypoint:hover{background:#ff7875;transform:translate(-50%,-50%) scale(1.25);box-shadow:0 0 0 4px #ff787559}.waypoint.dragging{transition:none;transform:translate(-50%,-50%) scale(1.15);pointer-events:none}.workflow-canvas.dragging-point svg{cursor:grabbing}.selection-box{position:absolute;border:1px dashed #1890ff;background:#1890ff1a;pointer-events:none}.toolbar{position:absolute;top:8px;left:8px;display:flex;gap:4px;padding:6px;background:#fff;border-radius:6px;box-shadow:0 2px 8px #00000026;z-index:100}.toolbar .divider{width:1px;background:#e5e5e5;margin:0 2px}nz-tag.selected{outline:2px dashed #1890ff}.grid-layer{position:absolute;inset:0;pointer-events:none;z-index:0;background-image:radial-gradient(rgba(0,0,0,.08) 1px,transparent 1px);background-size:20px 20px}.grid-layer{background-image:linear-gradient(to right,rgba(0,0,0,.06) 1px,transparent 1px),linear-gradient(to bottom,rgba(0,0,0,.06) 1px,transparent 1px);background-size:20px 20px}.editable-tag{background:#fff;border-style:dashed}::ng-deep .minimap,.minimap-combine{position:absolute;width:180px;height:125px;top:0;right:0;background-color:#eee;border:1px solid #aaa;opacity:.9;z-index:1}::ng-deep .minimap{position:absolute;width:200px;height:140px;top:8px;right:8px;background-color:#f8f9fa;border:1px solid #d9d9d9;border-radius:8px;box-shadow:0 4px 12px #0000001a;overflow:hidden;z-index:100;-webkit-user-select:none;user-select:none}::ng-deep .minimap-node{position:absolute;background-color:#bfbfbf;border-radius:2px}::ng-deep .minimap-node-round{position:absolute;background-color:#bfbfbf;border-radius:50%}::ng-deep .minimap-node-round-start{background-color:#52c41a}::ng-deep .minimap-node-round-end{background-color:#ff4d4f}::ng-deep .minimap-viewport{position:absolute;box-sizing:border-box;background-color:#1890ff26;border:1.5px solid #1890ff;border-radius:4px;z-index:2;cursor:grab;transition:none}::ng-deep .minimap-viewport.grabbing,::ng-deep .minimap-viewport:active{cursor:grabbing;background-color:#1890ff40}::ng-deep .has-floating-label.floating-label{position:relative;padding-top:14px}::ng-deep .has-floating-label nz-form-item nz-form-label{position:absolute;top:12px;left:13px;transform:translateY(-50%);background:linear-gradient(to bottom,var(--form-bg-color, #ffffff) 80%,#ffffff 80%);z-index:1;height:auto;line-height:normal;padding:0 4px}::ng-deep .has-floating-label nz-form-item nz-form-label label{font-size:12px;color:var(--darkgray, #565656);font-weight:700;height:auto;line-height:normal;padding:0;display:flex;align-items:center}::ng-deep .has-floating-label .full-width{width:100%}.has-floating-label.floating-label nz-form-item:has(.ant-select-disabled) nz-form-label,.has-floating-label.floating-label nz-form-item:has(input[disabled]) nz-form-label,.has-floating-label.floating-label nz-form-item:has(.ant-input-disabled) nz-form-label{background:linear-gradient(to bottom,var(--form-bg-color, #ffffff) 60%,#f5f5f5 50%)}.has-floating-label.floating-label nz-form-item:has(.ant-select-disabled) nz-form-label label,.has-floating-label.floating-label nz-form-item:has(input[disabled]) nz-form-label label,.has-floating-label.floating-label nz-form-item:has(.ant-input-disabled) nz-form-label label{color:#bfbfbf}\n"] }]
19497
19550
  }], propDecorators: { lstTemplateForSelect: [{
19498
19551
  type: Input
19552
+ }], getdata: [{
19553
+ type: Output
19499
19554
  }], onSave: [{
19500
- type: Output,
19501
- args: ['onSave']
19555
+ type: Output
19502
19556
  }], onDeleteTempldateNode: [{
19503
- type: Output,
19504
- args: ['onDeleteTempldateNode']
19557
+ type: Output
19505
19558
  }], canvasRef: [{
19506
19559
  type: ViewChild,
19507
19560
  args: ['canvas', { static: true }]
@@ -19523,10 +19576,12 @@ class WF_Template_CombineDetailComponent extends BaseComponent {
19523
19576
  wfeditor;
19524
19577
  ngOnInit() {
19525
19578
  this.updateBC();
19526
- const id = this.getUrlParam('id');
19527
- this.getData(id);
19579
+ this.getData();
19528
19580
  }
19529
19581
  getData(id) {
19582
+ id = id || this.getUrlParam('id');
19583
+ if (!id)
19584
+ return;
19530
19585
  this.service.getLstTemplate().then((res) => (this.lstTemplate = res.Data));
19531
19586
  this.service.getWFCombine(id).then((res) => {
19532
19587
  this.templateCombine = new WFTemplate_Combine(res.Data);
@@ -19571,11 +19626,11 @@ class WF_Template_CombineDetailComponent extends BaseComponent {
19571
19626
  });
19572
19627
  }
19573
19628
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: WF_Template_CombineDetailComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
19574
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.7", type: WF_Template_CombineDetailComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "wfeditor", first: true, predicate: ["wfeditor"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"workflow-wrapper\" style=\"height: calc(100vh - 110px)\">\n <app-workflow-combine-editor\n #wfeditor\n [lstTemplateForSelect]=\"lstTemplate\"\n (onSave)=\"save($event)\"\n (onDeleteTempldateNode)=\"deleteTempldateNode($event)\"\n ></app-workflow-combine-editor>\n</div>\n\n<!-- (onDeleteStage)=\"deleteStage($event)\"\n (onDeleteAction)=\"deleteAction($event)\"\n (onDeleteRule)=\"deleteRule($event)\"\n (onDeleteRuleLine)=\"deleteRuleLine($event)\"\n (onCheckRule)=\"onCheckRule($event)\"\n (onCheckAllRule)=\"onCheckAllRule($event)\" -->\n", styles: [".workflow-wrapper{position:relative}\n"], dependencies: [{ kind: "component", type: WF_Template_CombineEditorComponent, selector: "app-workflow-combine-editor", inputs: ["lstTemplateForSelect"], outputs: ["onSave", "onDeleteTempldateNode"] }] });
19629
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.7", type: WF_Template_CombineDetailComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "wfeditor", first: true, predicate: ["wfeditor"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"workflow-wrapper\" style=\"height: calc(100vh - 110px)\">\n <app-workflow-combine-editor\n #wfeditor\n [lstTemplateForSelect]=\"lstTemplate\"\n (onSave)=\"save($event)\"\n (getdata)=\"getData()\"\n (onDeleteTempldateNode)=\"deleteTempldateNode($event)\"\n ></app-workflow-combine-editor>\n</div>\n", styles: [".workflow-wrapper{position:relative}\n"], dependencies: [{ kind: "component", type: WF_Template_CombineEditorComponent, selector: "app-workflow-combine-editor", inputs: ["lstTemplateForSelect"], outputs: ["getdata", "onSave", "onDeleteTempldateNode"] }] });
19575
19630
  }
19576
19631
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: WF_Template_CombineDetailComponent, decorators: [{
19577
19632
  type: Component,
19578
- args: [{ imports: [WF_Template_CombineEditorComponent], template: "<div class=\"workflow-wrapper\" style=\"height: calc(100vh - 110px)\">\n <app-workflow-combine-editor\n #wfeditor\n [lstTemplateForSelect]=\"lstTemplate\"\n (onSave)=\"save($event)\"\n (onDeleteTempldateNode)=\"deleteTempldateNode($event)\"\n ></app-workflow-combine-editor>\n</div>\n\n<!-- (onDeleteStage)=\"deleteStage($event)\"\n (onDeleteAction)=\"deleteAction($event)\"\n (onDeleteRule)=\"deleteRule($event)\"\n (onDeleteRuleLine)=\"deleteRuleLine($event)\"\n (onCheckRule)=\"onCheckRule($event)\"\n (onCheckAllRule)=\"onCheckAllRule($event)\" -->\n", styles: [".workflow-wrapper{position:relative}\n"] }]
19633
+ args: [{ imports: [WF_Template_CombineEditorComponent], template: "<div class=\"workflow-wrapper\" style=\"height: calc(100vh - 110px)\">\n <app-workflow-combine-editor\n #wfeditor\n [lstTemplateForSelect]=\"lstTemplate\"\n (onSave)=\"save($event)\"\n (getdata)=\"getData()\"\n (onDeleteTempldateNode)=\"deleteTempldateNode($event)\"\n ></app-workflow-combine-editor>\n</div>\n", styles: [".workflow-wrapper{position:relative}\n"] }]
19579
19634
  }], propDecorators: { wfeditor: [{
19580
19635
  type: ViewChild,
19581
19636
  args: ['wfeditor']