@brggroup/share-lib 0.1.50 → 0.1.52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/README.md +3 -1
  2. package/fesm2022/brggroup-share-lib.mjs +1010 -631
  3. package/fesm2022/brggroup-share-lib.mjs.map +1 -1
  4. package/lib/{ADMIN → admin}/component/permission/permission.component.d.ts.map +1 -1
  5. package/lib/{ADMIN → admin}/component/permission/permission.model.d.ts.map +1 -1
  6. package/lib/{ADMIN → admin}/component/permission/permission.service.d.ts +3 -6
  7. package/lib/admin/component/permission/permission.service.d.ts.map +1 -0
  8. package/lib/{ADMIN → admin}/component/permission/resource-permission/resource-permission.component.d.ts +0 -1
  9. package/lib/admin/component/permission/resource-permission/resource-permission.component.d.ts.map +1 -0
  10. package/lib/{ADMIN → admin}/component/permission/role-menu/role-menu.d.ts +4 -2
  11. package/lib/admin/component/permission/role-menu/role-menu.d.ts.map +1 -0
  12. package/lib/{ADMIN → admin}/component/permission/role-permission/role-permission.component.d.ts +3 -6
  13. package/lib/admin/component/permission/role-permission/role-permission.component.d.ts.map +1 -0
  14. package/lib/{ADMIN → admin}/component/permission/role-permission/role-permission.model.d.ts +1 -1
  15. package/lib/{ADMIN → admin}/component/permission/role-permission/role-permission.model.d.ts.map +1 -1
  16. package/lib/{ADMIN → admin}/component/permission/user-role/user-role.d.ts +4 -2
  17. package/lib/admin/component/permission/user-role/user-role.d.ts.map +1 -0
  18. package/lib/admin/model/dic-domain.model.d.ts +27 -0
  19. package/lib/admin/model/dic-domain.model.d.ts.map +1 -0
  20. package/lib/{ADMIN → admin}/model/menu.model.d.ts.map +1 -1
  21. package/lib/admin/model/org.model.d.ts +29 -0
  22. package/lib/admin/model/org.model.d.ts.map +1 -0
  23. package/lib/{ADMIN → admin}/model/role.model.d.ts +3 -2
  24. package/lib/{ADMIN → admin}/model/role.model.d.ts.map +1 -1
  25. package/lib/{ADMIN → admin}/model/user.model.d.ts +5 -2
  26. package/lib/admin/model/user.model.d.ts.map +1 -0
  27. package/lib/{pipe → admin/pipe}/dic-domain.pipe.d.ts +1 -1
  28. package/lib/admin/pipe/dic-domain.pipe.d.ts.map +1 -0
  29. package/lib/admin/service/dic-domain.service.d.ts +22 -0
  30. package/lib/admin/service/dic-domain.service.d.ts.map +1 -0
  31. package/lib/{ADMIN → admin}/service/menu.service.d.ts +2 -4
  32. package/lib/admin/service/menu.service.d.ts.map +1 -0
  33. package/lib/{services → admin/service}/org.service.d.ts +4 -8
  34. package/lib/admin/service/org.service.d.ts.map +1 -0
  35. package/lib/{ADMIN → admin}/service/role.service.d.ts.map +1 -1
  36. package/lib/{ADMIN → admin}/service/user.service.d.ts +0 -1
  37. package/lib/{ADMIN → admin}/service/user.service.d.ts.map +1 -1
  38. package/lib/auth/auth.service.d.ts.map +1 -1
  39. package/lib/components/base.component.d.ts +15 -5
  40. package/lib/components/base.component.d.ts.map +1 -1
  41. package/lib/components/button.d.ts +30 -0
  42. package/lib/components/button.d.ts.map +1 -0
  43. package/lib/components/{extend-checkbox → extend/extend-checkbox}/extend-checkbox.d.ts +2 -1
  44. package/lib/components/extend/extend-checkbox/extend-checkbox.d.ts.map +1 -0
  45. package/lib/components/extend/extend-date-picker/extend-date-picker.d.ts.map +1 -0
  46. package/lib/components/extend/extend-date-range-picker/extend-date-range-picker.d.ts.map +1 -0
  47. package/lib/components/{extend-input → extend/extend-input}/extend-input.d.ts +2 -2
  48. package/lib/components/extend/extend-input/extend-input.d.ts.map +1 -0
  49. package/lib/components/extend/extend-input-number/extend-input-number.d.ts.map +1 -0
  50. package/lib/components/extend/extend-select/extend-select.d.ts.map +1 -0
  51. package/lib/components/{extend-table → extend/extend-table}/extend-pagination.component.d.ts +2 -2
  52. package/lib/components/extend/extend-table/extend-pagination.component.d.ts.map +1 -0
  53. package/lib/components/{extend-table → extend/extend-table}/extend-table.component.d.ts +2 -2
  54. package/lib/components/extend/extend-table/extend-table.component.d.ts.map +1 -0
  55. package/lib/components/extend/extend-textarea/extend-textarea.d.ts.map +1 -0
  56. package/lib/{icon.d.ts → components/icon.d.ts} +18 -0
  57. package/lib/components/icon.d.ts.map +1 -0
  58. package/lib/components/layout/header/notification/notification-center.component.d.ts +15 -0
  59. package/lib/components/layout/header/notification/notification-center.component.d.ts.map +1 -0
  60. package/lib/components/layout/header/notification/notification.service.d.ts +26 -0
  61. package/lib/components/layout/header/notification/notification.service.d.ts.map +1 -0
  62. package/lib/components/layout/header/search/search.component.d.ts +19 -0
  63. package/lib/components/layout/header/search/search.component.d.ts.map +1 -0
  64. package/lib/components/layout/{layout-user/layout-user.d.ts → header/user/user.d.ts} +9 -9
  65. package/lib/components/layout/header/user/user.d.ts.map +1 -0
  66. package/lib/components/layout/layout.component.d.ts +1 -2
  67. package/lib/components/layout/layout.component.d.ts.map +1 -1
  68. package/lib/components/login/login.component.d.ts +2 -4
  69. package/lib/components/login/login.component.d.ts.map +1 -1
  70. package/lib/services/api-service/common.service.d.ts +3 -1
  71. package/lib/services/api-service/common.service.d.ts.map +1 -1
  72. package/lib/services/noti.service.d.ts.map +1 -1
  73. package/lib/services/setting.service.d.ts +2 -1
  74. package/lib/services/setting.service.d.ts.map +1 -1
  75. package/lib/services/signalr.service.d.ts +1 -1
  76. package/lib/services/signalr.service.d.ts.map +1 -1
  77. package/package.json +1 -1
  78. package/public-api.d.ts +12 -12
  79. package/public-api.d.ts.map +1 -1
  80. package/lib/ADMIN/component/permission/permission.service.d.ts.map +0 -1
  81. package/lib/ADMIN/component/permission/resource-permission/resource-permission.component.d.ts.map +0 -1
  82. package/lib/ADMIN/component/permission/role-menu/role-menu.d.ts.map +0 -1
  83. package/lib/ADMIN/component/permission/role-permission/role-permission.component.d.ts.map +0 -1
  84. package/lib/ADMIN/component/permission/user-role/user-role.d.ts.map +0 -1
  85. package/lib/ADMIN/model/user.model.d.ts.map +0 -1
  86. package/lib/ADMIN/service/menu.service.d.ts.map +0 -1
  87. package/lib/components/extend-checkbox/extend-checkbox.d.ts.map +0 -1
  88. package/lib/components/extend-date-picker/extend-date-picker.d.ts.map +0 -1
  89. package/lib/components/extend-date-range-picker/extend-date-range-picker.d.ts.map +0 -1
  90. package/lib/components/extend-input/extend-input.d.ts.map +0 -1
  91. package/lib/components/extend-input-number/extend-input-number.d.ts.map +0 -1
  92. package/lib/components/extend-select/extend-select.d.ts.map +0 -1
  93. package/lib/components/extend-table/extend-pagination.component.d.ts.map +0 -1
  94. package/lib/components/extend-table/extend-table.component.d.ts.map +0 -1
  95. package/lib/components/extend-textarea/extend-textarea.d.ts.map +0 -1
  96. package/lib/components/layout/layout-user/layout-user.d.ts.map +0 -1
  97. package/lib/icon.d.ts.map +0 -1
  98. package/lib/pipe/dic-domain.pipe.d.ts.map +0 -1
  99. package/lib/services/dic-domain.service.d.ts +0 -40
  100. package/lib/services/dic-domain.service.d.ts.map +0 -1
  101. package/lib/services/org.service.d.ts.map +0 -1
  102. /package/lib/{ADMIN → admin}/component/permission/permission.component.d.ts +0 -0
  103. /package/lib/{ADMIN → admin}/component/permission/permission.model.d.ts +0 -0
  104. /package/lib/{ADMIN → admin}/model/menu.model.d.ts +0 -0
  105. /package/lib/{ADMIN → admin}/service/role.service.d.ts +0 -0
  106. /package/lib/components/{extend-date-picker → extend/extend-date-picker}/extend-date-picker.d.ts +0 -0
  107. /package/lib/components/{extend-date-range-picker → extend/extend-date-range-picker}/extend-date-range-picker.d.ts +0 -0
  108. /package/lib/components/{extend-input-number → extend/extend-input-number}/extend-input-number.d.ts +0 -0
  109. /package/lib/components/{extend-select → extend/extend-select}/extend-select.d.ts +0 -0
  110. /package/lib/components/{extend-textarea → extend/extend-textarea}/extend-textarea.d.ts +0 -0
@@ -1,10 +1,11 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, Injectable, InjectionToken, NgZone, Component, HostListener, ViewContainerRef, Input, ViewChild, EventEmitter, Output, Directive, Optional, Self, HostBinding, Pipe, forwardRef } from '@angular/core';
2
+ import { inject, Injectable, InjectionToken, NgZone, DestroyRef, Component, HostListener, ViewContainerRef, Input, ViewChild, EventEmitter, Output, Directive, Optional, Self, HostBinding, Pipe, forwardRef, ChangeDetectionStrategy } from '@angular/core';
3
3
  import * as i1$7 from '@angular/router';
4
4
  import { Router, ActivatedRoute, NavigationEnd, RouterLink, RouterOutlet } from '@angular/router';
5
+ import * as i1$a from '@angular/common/http';
5
6
  import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
6
7
  import * as i3$1 from '@ngx-translate/core';
7
- import { TranslateService, TranslateModule } from '@ngx-translate/core';
8
+ import { TranslateService, TranslateModule, TranslatePipe } from '@ngx-translate/core';
8
9
  import { firstValueFrom, fromEvent, startWith, map, BehaviorSubject, of, catchError, throwError, finalize, from, switchMap as switchMap$1, take, filter, Subject, takeUntil as takeUntil$1, debounceTime, distinctUntilChanged as distinctUntilChanged$1 } from 'rxjs';
9
10
  import * as i1$1 from 'ng-zorro-antd/modal';
10
11
  import { NzModalService, NzModalComponent, NzModalContentDirective, NzModalTitleDirective, NzModalFooterDirective, NzModalModule } from 'ng-zorro-antd/modal';
@@ -39,42 +40,42 @@ import * as i6$2 from 'ng-zorro-antd/select';
39
40
  import { NzSelectModule } from 'ng-zorro-antd/select';
40
41
  import * as i1$5 from 'ng-zorro-antd/table';
41
42
  import { NzTableModule } from 'ng-zorro-antd/table';
42
- import * as i5$3 from 'ng-zorro-antd/button';
43
+ import * as i2$2 from 'ng-zorro-antd/button';
43
44
  import { NzButtonModule } from 'ng-zorro-antd/button';
44
- import * as i6$3 from 'ng-zorro-antd/core/transition-patch';
45
+ import * as i3$2 from 'ng-zorro-antd/core/transition-patch';
45
46
  import * as i1$6 from 'ng-zorro-antd/pagination';
46
47
  import { NzPaginationModule } from 'ng-zorro-antd/pagination';
47
48
  import * as i1$8 from 'ngx-extended-pdf-viewer';
48
49
  import { NgxExtendedPdfViewerModule } from 'ngx-extended-pdf-viewer';
49
50
  import { trigger, transition, style, animate } from '@angular/animations';
50
51
  import * as i2$1 from 'ng-zorro-antd/spin';
51
- import { NzSpinModule } from 'ng-zorro-antd/spin';
52
- import * as i3$2 from 'ng-zorro-antd/card';
52
+ import { NzSpinModule, NzSpinComponent } from 'ng-zorro-antd/spin';
53
+ import * as i3$3 from 'ng-zorro-antd/card';
53
54
  import { NzCardModule } from 'ng-zorro-antd/card';
54
55
  import * as i4$1 from 'ng-zorro-antd/drawer';
55
56
  import { NzDrawerModule } from 'ng-zorro-antd/drawer';
56
57
  import * as i5$2 from 'ng-zorro-antd/tag';
57
58
  import { NzTagModule } from 'ng-zorro-antd/tag';
58
- import * as i6$4 from 'ng-zorro-antd/radio';
59
+ import * as i6$3 from 'ng-zorro-antd/radio';
59
60
  import { NzRadioModule } from 'ng-zorro-antd/radio';
60
61
  import * as i11 from 'ng-zorro-antd/tooltip';
61
62
  import { NzToolTipModule } from 'ng-zorro-antd/tooltip';
62
- import * as i9 from 'ng-zorro-antd/flex';
63
+ import * as i5$3 from 'ng-zorro-antd/flex';
63
64
  import { NzFlexModule, NzFlexDirective } from 'ng-zorro-antd/flex';
64
65
  import * as i8 from 'ng-zorro-antd/divider';
65
66
  import { NzDividerModule } from 'ng-zorro-antd/divider';
66
67
  import * as i17 from 'ng-zorro-antd/auto-complete';
67
68
  import { NzAutocompleteModule } from 'ng-zorro-antd/auto-complete';
68
- import * as i7 from 'ng-zorro-antd/core/wave';
69
+ import * as i4$2 from 'ng-zorro-antd/core/wave';
69
70
  import * as i1$9 from 'ng-zorro-antd/tabs';
70
71
  import { NzTabsModule } from 'ng-zorro-antd/tabs';
71
72
  import * as i18 from 'ng-zorro-antd/popconfirm';
72
73
  import { NzPopconfirmModule } from 'ng-zorro-antd/popconfirm';
73
74
  import * as XLSX from 'xlsx';
74
- import * as i2$2 from 'ng-zorro-antd/layout';
75
+ import * as i2$3 from 'ng-zorro-antd/layout';
75
76
  import { NzLayoutModule } from 'ng-zorro-antd/layout';
76
77
  import { Title } from '@angular/platform-browser';
77
- import * as i5$4 from 'ng-zorro-antd/dropdown';
78
+ import * as i5$5 from 'ng-zorro-antd/dropdown';
78
79
  import { NzDropDownModule } from 'ng-zorro-antd/dropdown';
79
80
  import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
80
81
  import * as i10 from 'ng-zorro-antd/tree';
@@ -82,10 +83,20 @@ import { NzTreeModule } from 'ng-zorro-antd/tree';
82
83
  import { NzBackTopModule } from 'ng-zorro-antd/back-top';
83
84
  import * as i14 from 'ng-zorro-antd/segmented';
84
85
  import { NzSegmentedModule } from 'ng-zorro-antd/segmented';
85
- import * as i8$1 from 'ng-zorro-antd/badge';
86
- import { NzBadgeModule } from 'ng-zorro-antd/badge';
87
- import * as i4$2 from 'ng-zorro-antd/menu';
88
86
  import * as signalR from '@microsoft/signalr';
87
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
88
+ import * as i4$3 from 'ng-zorro-antd/badge';
89
+ import { NzBadgeModule } from 'ng-zorro-antd/badge';
90
+ import * as i3$4 from 'ng-zorro-antd/popover';
91
+ import { NzPopoverModule } from 'ng-zorro-antd/popover';
92
+ import { NzSkeletonModule } from 'ng-zorro-antd/skeleton';
93
+ import * as i5$4 from 'ng-zorro-antd/empty';
94
+ import { NzEmptyModule } from 'ng-zorro-antd/empty';
95
+ import * as i6$4 from 'ng-zorro-antd/list';
96
+ import { NzListModule } from 'ng-zorro-antd/list';
97
+ import * as i7 from 'ng-zorro-antd/avatar';
98
+ import { NzAvatarModule } from 'ng-zorro-antd/avatar';
99
+ import * as i4$4 from 'ng-zorro-antd/menu';
89
100
  import { NzSwitchModule } from 'ng-zorro-antd/switch';
90
101
 
91
102
  var TranslateKey;
@@ -403,7 +414,7 @@ class NotiService {
403
414
  }
404
415
  handleError(err) {
405
416
  if (err?.status == 0) {
406
- this.notification.error(this.translate.instant('NO_CONNECT_TO_SERVER'), '', { duration: 0 });
417
+ this.notification.error(this.translate.instant('NO_CONNECT_TO_SERVER'), '', { duration: 30 * 1000 });
407
418
  return;
408
419
  }
409
420
  let _data = null;
@@ -420,14 +431,17 @@ class NotiService {
420
431
  try {
421
432
  const text = reader.result;
422
433
  _data = JSON.parse(text);
434
+ if (err.url) {
435
+ _data.url = err.url;
436
+ }
423
437
  this.handleError(_data);
424
438
  }
425
439
  catch (e) {
426
- this.notification.error(this.translate.instant('UNKNOWN_ERROR'), '', { duration: 0 });
440
+ this.notification.error(this.translate.instant('UNKNOWN_ERROR'), '', { duration: 30 * 1000 });
427
441
  }
428
442
  };
429
443
  reader.onerror = () => {
430
- this.notification.error(this.translate.instant('UNKNOWN_ERROR'), '', { duration: 0 });
444
+ this.notification.error(this.translate.instant('UNKNOWN_ERROR'), '', { duration: 30 * 1000 });
431
445
  };
432
446
  reader.readAsText(err.error);
433
447
  return;
@@ -465,9 +479,13 @@ class NotiService {
465
479
  this.notification.error('Lỗi phát sinh', errorMsg, {
466
480
  showDetail: !!_data?.Data,
467
481
  onDetail: () => {
482
+ const detailContent = {
483
+ API_URL: err?.url || 'Không xác định',
484
+ Details: _data,
485
+ };
468
486
  this.modal.error({
469
487
  nzTitle: 'Chi tiết lỗi',
470
- nzContent: escapeHtml(JSON.stringify(_data, null, 2)),
488
+ nzContent: escapeHtml(JSON.stringify(detailContent, null, 2)),
471
489
  nzWidth: this.device.isMobile ? '90vw' : '60vw',
472
490
  nzDraggable: true,
473
491
  nzCentered: true,
@@ -495,9 +513,9 @@ var ENUM_ResponseType;
495
513
  ENUM_ResponseType["BLOB"] = "blob";
496
514
  })(ENUM_ResponseType || (ENUM_ResponseType = {}));
497
515
  class CommonService extends HTTPService {
498
- ESP(obj) {
516
+ ESP(obj, options) {
499
517
  const params = new HttpParams().append('SPN', obj.SPN);
500
- return this.postDataWithParams(AppGlobals.apiEndpoint + '/api/Common/ESP', obj, params);
518
+ return this.postDataWithParams(AppGlobals.apiEndpoint + '/api/Common/ESP', obj, params, options?.noLoadingMark);
501
519
  }
502
520
  ExportExcel(data) {
503
521
  return firstValueFrom(this.httpClient.post(AppGlobals.apiEndpoint + '/api/Common/ExportExcel', data, {
@@ -661,7 +679,7 @@ class AuthService extends HTTPService {
661
679
  }
662
680
  async sendSignIn(body) {
663
681
  return firstValueFrom(this.httpClient.post(AppGlobals.apiEndpoint + URLs$7.login, body, {
664
- headers: new HttpHeaders().set('Content-Type', 'application/json'),
682
+ headers: new HttpHeaders().set('Content-Type', 'application/json').set('No-Loading-Mark', '1'),
665
683
  }));
666
684
  }
667
685
  /* ----------------------------------------
@@ -691,17 +709,11 @@ class AuthService extends HTTPService {
691
709
  MENU
692
710
  ---------------------------------------- */
693
711
  getUserMenu(headerMenuId) {
694
- let data = {
695
- SPN: `App_User_getUserMenu`,
696
- Params: [headerMenuId],
697
- };
698
- return this.cms.ESP(data);
712
+ let pr = new HttpParams().append('headerMenuId', headerMenuId);
713
+ return this.postParams(AppGlobals.apiEndpoint + '/api/Auth/getUserMenu', pr);
699
714
  }
700
715
  getUserHeaderMenu() {
701
- let data = {
702
- SPN: `App_User_getUserHeaderMenu`,
703
- };
704
- return this.cms.ESP(data);
716
+ return this.post(AppGlobals.apiEndpoint + '/api/Auth/getUserHeaderMenu');
705
717
  }
706
718
  async checkUserMenu(url) {
707
719
  try {
@@ -1363,20 +1375,17 @@ class BaseComponent {
1363
1375
  notiService = inject(NotiService);
1364
1376
  translate = inject(TranslateService);
1365
1377
  modal = inject(CustomModalService);
1366
- routeSub;
1367
1378
  backURL = '';
1379
+ selectedId;
1380
+ isLoading = false;
1381
+ isSaving = false;
1382
+ destroyRef = inject(DestroyRef);
1368
1383
  /**
1369
- * Khi dùng onRouteChange nhớ dùng unSubRouteChange
1384
+ * import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
1385
+ * this.routeChange$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((url) => {});
1370
1386
  */
1371
- onRouteChange(callback) {
1372
- this.routeSub = this.router.events
1373
- .pipe(filter((e) => e instanceof NavigationEnd))
1374
- .subscribe((e) => {
1375
- callback(e.urlAfterRedirects);
1376
- });
1377
- }
1378
- unSubRouteChange() {
1379
- this.routeSub?.unsubscribe();
1387
+ get routeChange$() {
1388
+ return this.router.events.pipe(filter((e) => e instanceof NavigationEnd), map((e) => e.urlAfterRedirects));
1380
1389
  }
1381
1390
  goback() {
1382
1391
  if (this.backURL) {
@@ -1403,6 +1412,7 @@ class BaseComponent {
1403
1412
  }
1404
1413
  /**
1405
1414
  * /:id
1415
+ * '0' || 'new' || 'them-moi' return null
1406
1416
  */
1407
1417
  getUrlParam(paramName) {
1408
1418
  const paramValue = this.route.snapshot.params[paramName];
@@ -1440,6 +1450,15 @@ class BaseComponent {
1440
1450
  get urlPath() {
1441
1451
  return this.router.url.split('?')[0];
1442
1452
  }
1453
+ success(title, content = '', showPopup = false) {
1454
+ this.notiService.success(title, content, showPopup);
1455
+ }
1456
+ warning(title, content = '', showPopup = false) {
1457
+ this.notiService.warning(title, content, showPopup);
1458
+ }
1459
+ error(title, content = '', showPopup = false) {
1460
+ this.notiService.error(title, content, showPopup);
1461
+ }
1443
1462
  handleError(err) {
1444
1463
  this.notiService.handleError(err);
1445
1464
  }
@@ -1489,6 +1508,9 @@ class BaseComponent {
1489
1508
  });
1490
1509
  });
1491
1510
  }
1511
+ confirmDelete() {
1512
+ return this.confirm('Xác nhận xóa?');
1513
+ }
1492
1514
  backToTop() {
1493
1515
  // go to top
1494
1516
  window.scrollTo({
@@ -1544,7 +1566,7 @@ class BaseGuardChangeComponent extends BaseComponent {
1544
1566
  .filter(Boolean); // Loại bỏ các giá trị null
1545
1567
  console.log('fields dirty:', dirtyDetails);
1546
1568
  // --------------------------------------
1547
- return await this.confirm('Dữ liệu chưa được lưu. Bạn có chắc chắn muốn rời khỏi trang?');
1569
+ return await this.confirm('Dữ liệu chưa được lưu!', 'Bạn có chắc chắn muốn rời khỏi trang?');
1548
1570
  }
1549
1571
  return true;
1550
1572
  }
@@ -1967,6 +1989,7 @@ class ExtendCheckbox {
1967
1989
  */
1968
1990
  labelSpan = 8;
1969
1991
  labelFlex = null;
1992
+ paddingTop = '0px';
1970
1993
  disabled = false;
1971
1994
  formData;
1972
1995
  controlName;
@@ -2059,17 +2082,19 @@ class ExtendCheckbox {
2059
2082
  }
2060
2083
  }
2061
2084
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: ExtendCheckbox, deps: [], target: i0.ɵɵFactoryTarget.Component });
2062
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.7", type: ExtendCheckbox, isStandalone: true, selector: "extend-checkbox", inputs: { label: "label", labelSpan: "labelSpan", labelFlex: "labelFlex", disabled: "disabled", formData: "formData", controlName: "controlName", valueType: "valueType", _ngModel: "_ngModel" }, outputs: { _ngModelChange: "_ngModelChange" }, ngImport: i0, template: "@if (label) {\r\n <div nz-row>\r\n <div nz-col [nzSpan]=\"!labelFlex ? labelSpan : null\" [nzFlex]=\"labelFlex\"></div>\r\n <div nz-col nzFlex=\"auto\">\r\n <label\r\n style=\"position: relative; top: 5px\"\r\n nz-checkbox\r\n [nzDisabled]=\"disabled\"\r\n [(nzChecked)]=\"checked\"\r\n (nzCheckedChange)=\"onCheckChange($event)\"\r\n >\r\n {{ label }}\r\n </label>\r\n </div>\r\n </div>\r\n} @else {\r\n <label\r\n nz-checkbox\r\n [nzDisabled]=\"disabled\"\r\n [(nzChecked)]=\"checked\"\r\n (nzCheckedChange)=\"onCheckChange($event)\"\r\n style=\"width: 16px\"\r\n >\r\n {{ label }}\r\n </label>\r\n}\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: NzFormModule }, { kind: "directive", type: i4.NzColDirective, selector: "[nz-col],nz-col,nz-form-control,nz-form-label", inputs: ["nzFlex", "nzSpan", "nzOrder", "nzOffset", "nzPush", "nzPull", "nzXs", "nzSm", "nzMd", "nzLg", "nzXl", "nzXXl"], exportAs: ["nzCol"] }, { kind: "directive", type: i4.NzRowDirective, selector: "[nz-row],nz-row,nz-form-item", inputs: ["nzAlign", "nzJustify", "nzGutter"], exportAs: ["nzRow"] }, { kind: "ngmodule", type: NzCheckboxModule }, { kind: "component", type: i3.NzCheckboxComponent, selector: "[nz-checkbox]", inputs: ["nzValue", "nzAutoFocus", "nzDisabled", "nzIndeterminate", "nzChecked", "nzId", "nzName"], outputs: ["nzCheckedChange"], exportAs: ["nzCheckbox"] }] });
2085
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.7", type: ExtendCheckbox, isStandalone: true, selector: "extend-checkbox", inputs: { label: "label", labelSpan: "labelSpan", labelFlex: "labelFlex", paddingTop: "paddingTop", disabled: "disabled", formData: "formData", controlName: "controlName", valueType: "valueType", _ngModel: "_ngModel" }, outputs: { _ngModelChange: "_ngModelChange" }, ngImport: i0, template: "@if (label) {\r\n <div nz-row>\r\n <div nz-col [nzSpan]=\"!labelFlex ? labelSpan : null\" [nzFlex]=\"labelFlex\"></div>\r\n <div nz-col nzFlex=\"auto\" [ngStyle]=\"{ 'padding-top': paddingTop }\">\r\n <label\r\n style=\"position: relative; top: 5px\"\r\n nz-checkbox\r\n [nzDisabled]=\"disabled\"\r\n [(nzChecked)]=\"checked\"\r\n (nzCheckedChange)=\"onCheckChange($event)\"\r\n >\r\n {{ label }}\r\n </label>\r\n </div>\r\n </div>\r\n} @else {\r\n <label\r\n nz-checkbox\r\n [nzDisabled]=\"disabled\"\r\n [(nzChecked)]=\"checked\"\r\n (nzCheckedChange)=\"onCheckChange($event)\"\r\n style=\"width: 16px\"\r\n >\r\n {{ label }}\r\n </label>\r\n}\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: NzFormModule }, { kind: "directive", type: i4.NzColDirective, selector: "[nz-col],nz-col,nz-form-control,nz-form-label", inputs: ["nzFlex", "nzSpan", "nzOrder", "nzOffset", "nzPush", "nzPull", "nzXs", "nzSm", "nzMd", "nzLg", "nzXl", "nzXXl"], exportAs: ["nzCol"] }, { kind: "directive", type: i4.NzRowDirective, selector: "[nz-row],nz-row,nz-form-item", inputs: ["nzAlign", "nzJustify", "nzGutter"], exportAs: ["nzRow"] }, { kind: "ngmodule", type: NzCheckboxModule }, { kind: "component", type: i3.NzCheckboxComponent, selector: "[nz-checkbox]", inputs: ["nzValue", "nzAutoFocus", "nzDisabled", "nzIndeterminate", "nzChecked", "nzId", "nzName"], outputs: ["nzCheckedChange"], exportAs: ["nzCheckbox"] }] });
2063
2086
  }
2064
2087
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: ExtendCheckbox, decorators: [{
2065
2088
  type: Component,
2066
- args: [{ selector: 'extend-checkbox', imports: [CommonModule, FormsModule, ReactiveFormsModule, NzFormModule, NzCheckboxModule], template: "@if (label) {\r\n <div nz-row>\r\n <div nz-col [nzSpan]=\"!labelFlex ? labelSpan : null\" [nzFlex]=\"labelFlex\"></div>\r\n <div nz-col nzFlex=\"auto\">\r\n <label\r\n style=\"position: relative; top: 5px\"\r\n nz-checkbox\r\n [nzDisabled]=\"disabled\"\r\n [(nzChecked)]=\"checked\"\r\n (nzCheckedChange)=\"onCheckChange($event)\"\r\n >\r\n {{ label }}\r\n </label>\r\n </div>\r\n </div>\r\n} @else {\r\n <label\r\n nz-checkbox\r\n [nzDisabled]=\"disabled\"\r\n [(nzChecked)]=\"checked\"\r\n (nzCheckedChange)=\"onCheckChange($event)\"\r\n style=\"width: 16px\"\r\n >\r\n {{ label }}\r\n </label>\r\n}\r\n" }]
2089
+ args: [{ selector: 'extend-checkbox', imports: [CommonModule, FormsModule, ReactiveFormsModule, NzFormModule, NzCheckboxModule], template: "@if (label) {\r\n <div nz-row>\r\n <div nz-col [nzSpan]=\"!labelFlex ? labelSpan : null\" [nzFlex]=\"labelFlex\"></div>\r\n <div nz-col nzFlex=\"auto\" [ngStyle]=\"{ 'padding-top': paddingTop }\">\r\n <label\r\n style=\"position: relative; top: 5px\"\r\n nz-checkbox\r\n [nzDisabled]=\"disabled\"\r\n [(nzChecked)]=\"checked\"\r\n (nzCheckedChange)=\"onCheckChange($event)\"\r\n >\r\n {{ label }}\r\n </label>\r\n </div>\r\n </div>\r\n} @else {\r\n <label\r\n nz-checkbox\r\n [nzDisabled]=\"disabled\"\r\n [(nzChecked)]=\"checked\"\r\n (nzCheckedChange)=\"onCheckChange($event)\"\r\n style=\"width: 16px\"\r\n >\r\n {{ label }}\r\n </label>\r\n}\r\n" }]
2067
2090
  }], propDecorators: { label: [{
2068
2091
  type: Input
2069
2092
  }], labelSpan: [{
2070
2093
  type: Input
2071
2094
  }], labelFlex: [{
2072
2095
  type: Input
2096
+ }], paddingTop: [{
2097
+ type: Input
2073
2098
  }], disabled: [{
2074
2099
  type: Input
2075
2100
  }], formData: [{
@@ -2907,7 +2932,7 @@ class ExtendInput {
2907
2932
  labelSpan = 8;
2908
2933
  labelFlex = null;
2909
2934
  inputFlex = null;
2910
- allowClear = false;
2935
+ showClear = true;
2911
2936
  get disabled() {
2912
2937
  return this._disabled;
2913
2938
  }
@@ -2987,11 +3012,11 @@ class ExtendInput {
2987
3012
  return '';
2988
3013
  }
2989
3014
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: ExtendInput, deps: [], target: i0.ɵɵFactoryTarget.Component });
2990
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.7", type: ExtendInput, isStandalone: true, selector: "extend-input", inputs: { label: "label", floatingLabel: "floatingLabel", placeHolder: "placeHolder", labelAlign: "labelAlign", inputClass: "inputClass", labelSpan: "labelSpan", labelFlex: "labelFlex", inputFlex: "inputFlex", allowClear: "allowClear", disabled: "disabled", readOnly: "readOnly", required: "required", noBottom: "noBottom", selectModeType: "selectModeType", autocomplete: "autocomplete", autofocus: "autofocus", inputWidth: "inputWidth", inputHeight: "inputHeight", borderBottomOnly: "borderBottomOnly", displayInline: "displayInline", size: "size", lstItem: "lstItem", displayField: "displayField", valueField: "valueField", formData: "formData", controlName: "controlName", _ngModel: "_ngModel", isSubmited: "isSubmited" }, outputs: { _ngModelChange: "_ngModelChange", onclickClearIcon: "onclickClearIcon", onenter: "onenter" }, viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["inputElement"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\r\n class=\"extend-input-wrapper\"\r\n [ngClass]=\"[floatingLabel && label ? 'floating-label' : '']\"\r\n [ngStyle]=\"{ display: displayInline ? 'inline' : null }\"\r\n>\r\n @if (controlName) {\r\n <div [formGroup]=\"formData\">\r\n <nz-form-item>\r\n <nz-form-label\r\n [nzSpan]=\"floatingLabel || labelFlex ? null : labelSpan\"\r\n [nzFlex]=\"labelFlex\"\r\n [nzLabelAlign]=\"labelAlign\"\r\n [nzRequired]=\"required\"\r\n [nzFor]=\"controlName\"\r\n nzNoColon\r\n nzLabelWrap\r\n >\r\n {{ label }}\r\n </nz-form-label>\r\n <nz-form-control\r\n [nzSpan]=\"floatingLabel || labelFlex ? null : 24 - labelSpan\"\r\n [nzFlex]=\"inputFlex\"\r\n [ngClass]=\"{ 'full-width': floatingLabel }\"\r\n [nzErrorTip]=\"'REQUIRED_FIELD' | translate\"\r\n >\r\n <input\r\n #inputElement\r\n nz-input\r\n [nzSize]=\"size\"\r\n [id]=\"controlName\"\r\n [name]=\"controlName\"\r\n [formControlName]=\"controlName\"\r\n [autocomplete]=\"autocomplete\"\r\n [placeholder]=\"placeHolder\"\r\n [ngClass]=\"inputClass\"\r\n (keyup.enter)=\"onenter.emit()\"\r\n />\r\n </nz-form-control>\r\n </nz-form-item>\r\n </div>\r\n } @else {\r\n @if (label) {\r\n <nz-form-item>\r\n <nz-form-label\r\n [nzSpan]=\"floatingLabel || labelFlex ? null : labelSpan\"\r\n [nzFlex]=\"labelFlex\"\r\n [nzLabelAlign]=\"labelAlign\"\r\n [nzRequired]=\"required\"\r\n [nzFor]=\"controlName\"\r\n nzNoColon\r\n nzLabelWrap\r\n >\r\n {{ label }}\r\n </nz-form-label>\r\n <nz-form-control\r\n [nzSpan]=\"floatingLabel || labelFlex ? null : 24 - labelSpan\"\r\n [nzFlex]=\"inputFlex\"\r\n [ngClass]=\"{ 'full-width': floatingLabel }\"\r\n [nzValidateStatus]=\"customValidateStatus\"\r\n [nzErrorTip]=\"'REQUIRED_FIELD' | translate\"\r\n >\r\n <nz-input-group [nzSize]=\"size\" [nzSuffix]=\"allowClear ? clearIcon : undefined\">\r\n <input\r\n #inputElement\r\n nz-input\r\n [nzSize]=\"size\"\r\n [id]=\"controlName\"\r\n [name]=\"controlName\"\r\n [(ngModel)]=\"_ngModel\"\r\n [autocomplete]=\"autocomplete\"\r\n (ngModelChange)=\"_onNgModelChange()\"\r\n [disabled]=\"disabled\"\r\n [readOnly]=\"readOnly\"\r\n [placeholder]=\"placeHolder\"\r\n [ngClass]=\"inputClass\"\r\n (keyup.enter)=\"onenter.emit()\"\r\n />\r\n </nz-input-group>\r\n </nz-form-control>\r\n </nz-form-item>\r\n } @else {\r\n <input\r\n #inputElement\r\n nz-input\r\n [nzSize]=\"size\"\r\n [ngStyle]=\"{\r\n width: inputWidth,\r\n height: inputHeight,\r\n }\"\r\n [id]=\"controlName\"\r\n [name]=\"controlName\"\r\n [(ngModel)]=\"_ngModel\"\r\n (ngModelChange)=\"_onNgModelChange()\"\r\n [autocomplete]=\"autocomplete\"\r\n [disabled]=\"disabled\"\r\n [readOnly]=\"readOnly\"\r\n [placeholder]=\"placeHolder\"\r\n [ngClass]=\"inputClass + ' ' + (borderBottomOnly ? 'border-bottom-only' : '')\"\r\n (keyup.enter)=\"onenter.emit()\"\r\n />\r\n }\r\n }\r\n</div>\r\n\r\n<ng-template #clearIcon>\r\n <i\r\n nz-icon\r\n nzType=\"close-circle\"\r\n nzTheme=\"twotone\"\r\n nzTwotoneColor=\"#999\"\r\n *ngIf=\"_ngModel\"\r\n (click)=\"_ngModel = null; _onNgModelChange(); onclickClearIcon.emit()\"\r\n style=\"cursor: pointer\"\r\n ></i>\r\n</ng-template>\r\n", styles: ["::ng-deep .extend-input-wrapper.floating-label{position:relative;padding-top:14px}::ng-deep .extend-input-wrapper nz-form-item nz-form-label{position:absolute;top:12px;left:10px;transform:translateY(-50%);background:linear-gradient(to bottom,var(--form-bg-color, #ffffff) 80%,#ffffff 80%);z-index:2;height:auto;line-height:normal;padding:0 4px}::ng-deep .extend-input-wrapper 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 .extend-input-wrapper .full-width{width:100%}.extend-input-wrapper.floating-label nz-form-item:has(.ant-select-disabled) nz-form-label,.extend-input-wrapper.floating-label nz-form-item:has(input[disabled]) nz-form-label,.extend-input-wrapper.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%)}.extend-input-wrapper.floating-label nz-form-item:has(.ant-select-disabled) nz-form-label label,.extend-input-wrapper.floating-label nz-form-item:has(input[disabled]) nz-form-label label,.extend-input-wrapper.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$4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3$1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: NzFormModule }, { kind: "directive", type: i4.NzColDirective, selector: "[nz-col],nz-col,nz-form-control,nz-form-label", inputs: ["nzFlex", "nzSpan", "nzOrder", "nzOffset", "nzPush", "nzPull", "nzXs", "nzSm", "nzMd", "nzLg", "nzXl", "nzXXl"], exportAs: ["nzCol"] }, { kind: "directive", type: i4.NzRowDirective, selector: "[nz-row],nz-row,nz-form-item", inputs: ["nzAlign", "nzJustify", "nzGutter"], exportAs: ["nzRow"] }, { kind: "component", type: i5.NzFormItemComponent, selector: "nz-form-item", exportAs: ["nzFormItem"] }, { kind: "component", type: i5.NzFormLabelComponent, selector: "nz-form-label", inputs: ["nzFor", "nzRequired", "nzNoColon", "nzTooltipTitle", "nzTooltipIcon", "nzLabelAlign", "nzLabelWrap"], exportAs: ["nzFormLabel"] }, { kind: "component", type: i5.NzFormControlComponent, selector: "nz-form-control", inputs: ["nzSuccessTip", "nzWarningTip", "nzErrorTip", "nzValidatingTip", "nzExtra", "nzAutoTips", "nzDisableAutoTips", "nzHasFeedback", "nzValidateStatus"], exportAs: ["nzFormControl"] }, { kind: "ngmodule", type: NzInputModule }, { kind: "directive", type: i6$1.NzInputDirective, selector: "input[nz-input],textarea[nz-input]", inputs: ["nzBorderless", "nzSize", "nzStepperless", "nzStatus", "disabled"], exportAs: ["nzInput"] }, { kind: "component", type: i6$1.NzInputGroupComponent, selector: "nz-input-group", inputs: ["nzAddOnBeforeIcon", "nzAddOnAfterIcon", "nzPrefixIcon", "nzSuffixIcon", "nzAddOnBefore", "nzAddOnAfter", "nzPrefix", "nzStatus", "nzSuffix", "nzSize", "nzSearch", "nzCompact"], exportAs: ["nzInputGroup"] }, { kind: "directive", type: i6$1.NzInputGroupWhitSuffixOrPrefixDirective, selector: "nz-input-group[nzSuffix], nz-input-group[nzPrefix]" }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }] });
3015
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.7", type: ExtendInput, isStandalone: true, selector: "extend-input", inputs: { label: "label", floatingLabel: "floatingLabel", placeHolder: "placeHolder", labelAlign: "labelAlign", inputClass: "inputClass", labelSpan: "labelSpan", labelFlex: "labelFlex", inputFlex: "inputFlex", showClear: "showClear", disabled: "disabled", readOnly: "readOnly", required: "required", noBottom: "noBottom", selectModeType: "selectModeType", autocomplete: "autocomplete", autofocus: "autofocus", inputWidth: "inputWidth", inputHeight: "inputHeight", borderBottomOnly: "borderBottomOnly", displayInline: "displayInline", size: "size", lstItem: "lstItem", displayField: "displayField", valueField: "valueField", formData: "formData", controlName: "controlName", _ngModel: "_ngModel", isSubmited: "isSubmited" }, outputs: { _ngModelChange: "_ngModelChange", onclickClearIcon: "onclickClearIcon", onenter: "onenter" }, viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["inputElement"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\r\n class=\"extend-input-wrapper\"\r\n [ngClass]=\"[floatingLabel && label ? 'floating-label' : '']\"\r\n [ngStyle]=\"{ display: displayInline ? 'inline' : null }\"\r\n>\r\n @if (controlName) {\r\n <div [formGroup]=\"formData\">\r\n <nz-form-item>\r\n <nz-form-label\r\n [nzSpan]=\"floatingLabel || labelFlex ? null : labelSpan\"\r\n [nzFlex]=\"labelFlex\"\r\n [nzLabelAlign]=\"labelAlign\"\r\n [nzRequired]=\"required\"\r\n [nzFor]=\"controlName\"\r\n nzNoColon\r\n nzLabelWrap\r\n >\r\n {{ label }}\r\n </nz-form-label>\r\n <nz-form-control\r\n [nzSpan]=\"floatingLabel || labelFlex ? null : 24 - labelSpan\"\r\n [nzFlex]=\"inputFlex\"\r\n [ngClass]=\"{ 'full-width': floatingLabel }\"\r\n [nzErrorTip]=\"'REQUIRED_FIELD' | translate\"\r\n >\r\n <input\r\n #inputElement\r\n nz-input\r\n [nzSize]=\"size\"\r\n [id]=\"controlName\"\r\n [name]=\"controlName\"\r\n [formControlName]=\"controlName\"\r\n [autocomplete]=\"autocomplete\"\r\n [placeholder]=\"placeHolder\"\r\n [ngClass]=\"inputClass\"\r\n (keyup.enter)=\"onenter.emit()\"\r\n />\r\n </nz-form-control>\r\n </nz-form-item>\r\n </div>\r\n } @else {\r\n @if (label) {\r\n <nz-form-item>\r\n <nz-form-label\r\n [nzSpan]=\"floatingLabel || labelFlex ? null : labelSpan\"\r\n [nzFlex]=\"labelFlex\"\r\n [nzLabelAlign]=\"labelAlign\"\r\n [nzRequired]=\"required\"\r\n [nzFor]=\"controlName\"\r\n nzNoColon\r\n nzLabelWrap\r\n >\r\n {{ label }}\r\n </nz-form-label>\r\n <nz-form-control\r\n [nzSpan]=\"floatingLabel || labelFlex ? null : 24 - labelSpan\"\r\n [nzFlex]=\"inputFlex\"\r\n [ngClass]=\"{ 'full-width': floatingLabel }\"\r\n [nzValidateStatus]=\"customValidateStatus\"\r\n [nzErrorTip]=\"'REQUIRED_FIELD' | translate\"\r\n >\r\n <nz-input-group [nzSize]=\"size\" [nzSuffix]=\"showClear ? clearIcon : undefined\">\r\n <input\r\n #inputElement\r\n nz-input\r\n [nzSize]=\"size\"\r\n [id]=\"controlName\"\r\n [name]=\"controlName\"\r\n [(ngModel)]=\"_ngModel\"\r\n [autocomplete]=\"autocomplete\"\r\n (ngModelChange)=\"_onNgModelChange()\"\r\n [disabled]=\"disabled\"\r\n [readOnly]=\"readOnly\"\r\n [placeholder]=\"placeHolder\"\r\n [ngClass]=\"inputClass\"\r\n (keyup.enter)=\"onenter.emit()\"\r\n />\r\n </nz-input-group>\r\n </nz-form-control>\r\n </nz-form-item>\r\n } @else {\r\n <nz-input-group [nzSize]=\"size\" [nzSuffix]=\"showClear ? clearIcon : undefined\">\r\n <input\r\n #inputElement\r\n nz-input\r\n [nzSize]=\"size\"\r\n [ngStyle]=\"{\r\n width: inputWidth,\r\n height: inputHeight,\r\n }\"\r\n [id]=\"controlName\"\r\n [name]=\"controlName\"\r\n [(ngModel)]=\"_ngModel\"\r\n (ngModelChange)=\"_onNgModelChange()\"\r\n [autocomplete]=\"autocomplete\"\r\n [disabled]=\"disabled\"\r\n [readOnly]=\"readOnly\"\r\n [placeholder]=\"placeHolder\"\r\n [ngClass]=\"inputClass + ' ' + (borderBottomOnly ? 'border-bottom-only' : '')\"\r\n (keyup.enter)=\"onenter.emit()\"\r\n />\r\n </nz-input-group>\r\n }\r\n }\r\n</div>\r\n\r\n<ng-template #clearIcon>\r\n <i\r\n nz-icon\r\n nzType=\"close-circle\"\r\n nzTheme=\"twotone\"\r\n nzTwotoneColor=\"#999\"\r\n *ngIf=\"_ngModel\"\r\n (click)=\"_ngModel = null; _onNgModelChange(); onclickClearIcon.emit()\"\r\n style=\"cursor: pointer; font-size: 13px\"\r\n ></i>\r\n</ng-template>\r\n", styles: ["::ng-deep .extend-input-wrapper.floating-label{position:relative;padding-top:14px}::ng-deep .extend-input-wrapper nz-form-item nz-form-label{position:absolute;top:12px;left:10px;transform:translateY(-50%);background:linear-gradient(to bottom,var(--form-bg-color, #ffffff) 80%,#ffffff 80%);z-index:2;height:auto;line-height:normal;padding:0 4px}::ng-deep .extend-input-wrapper 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 .extend-input-wrapper .full-width{width:100%}.extend-input-wrapper.floating-label nz-form-item:has(.ant-select-disabled) nz-form-label,.extend-input-wrapper.floating-label nz-form-item:has(input[disabled]) nz-form-label,.extend-input-wrapper.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%)}.extend-input-wrapper.floating-label nz-form-item:has(.ant-select-disabled) nz-form-label label,.extend-input-wrapper.floating-label nz-form-item:has(input[disabled]) nz-form-label label,.extend-input-wrapper.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$4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3$1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: NzFormModule }, { kind: "directive", type: i4.NzColDirective, selector: "[nz-col],nz-col,nz-form-control,nz-form-label", inputs: ["nzFlex", "nzSpan", "nzOrder", "nzOffset", "nzPush", "nzPull", "nzXs", "nzSm", "nzMd", "nzLg", "nzXl", "nzXXl"], exportAs: ["nzCol"] }, { kind: "directive", type: i4.NzRowDirective, selector: "[nz-row],nz-row,nz-form-item", inputs: ["nzAlign", "nzJustify", "nzGutter"], exportAs: ["nzRow"] }, { kind: "component", type: i5.NzFormItemComponent, selector: "nz-form-item", exportAs: ["nzFormItem"] }, { kind: "component", type: i5.NzFormLabelComponent, selector: "nz-form-label", inputs: ["nzFor", "nzRequired", "nzNoColon", "nzTooltipTitle", "nzTooltipIcon", "nzLabelAlign", "nzLabelWrap"], exportAs: ["nzFormLabel"] }, { kind: "component", type: i5.NzFormControlComponent, selector: "nz-form-control", inputs: ["nzSuccessTip", "nzWarningTip", "nzErrorTip", "nzValidatingTip", "nzExtra", "nzAutoTips", "nzDisableAutoTips", "nzHasFeedback", "nzValidateStatus"], exportAs: ["nzFormControl"] }, { kind: "ngmodule", type: NzInputModule }, { kind: "directive", type: i6$1.NzInputDirective, selector: "input[nz-input],textarea[nz-input]", inputs: ["nzBorderless", "nzSize", "nzStepperless", "nzStatus", "disabled"], exportAs: ["nzInput"] }, { kind: "component", type: i6$1.NzInputGroupComponent, selector: "nz-input-group", inputs: ["nzAddOnBeforeIcon", "nzAddOnAfterIcon", "nzPrefixIcon", "nzSuffixIcon", "nzAddOnBefore", "nzAddOnAfter", "nzPrefix", "nzStatus", "nzSuffix", "nzSize", "nzSearch", "nzCompact"], exportAs: ["nzInputGroup"] }, { kind: "directive", type: i6$1.NzInputGroupWhitSuffixOrPrefixDirective, selector: "nz-input-group[nzSuffix], nz-input-group[nzPrefix]" }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }] });
2991
3016
  }
2992
3017
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: ExtendInput, decorators: [{
2993
3018
  type: Component,
2994
- args: [{ selector: 'extend-input', imports: [CommonModule, FormsModule, ReactiveFormsModule, TranslateModule, NzFormModule, NzInputModule, NzIconModule], template: "<div\r\n class=\"extend-input-wrapper\"\r\n [ngClass]=\"[floatingLabel && label ? 'floating-label' : '']\"\r\n [ngStyle]=\"{ display: displayInline ? 'inline' : null }\"\r\n>\r\n @if (controlName) {\r\n <div [formGroup]=\"formData\">\r\n <nz-form-item>\r\n <nz-form-label\r\n [nzSpan]=\"floatingLabel || labelFlex ? null : labelSpan\"\r\n [nzFlex]=\"labelFlex\"\r\n [nzLabelAlign]=\"labelAlign\"\r\n [nzRequired]=\"required\"\r\n [nzFor]=\"controlName\"\r\n nzNoColon\r\n nzLabelWrap\r\n >\r\n {{ label }}\r\n </nz-form-label>\r\n <nz-form-control\r\n [nzSpan]=\"floatingLabel || labelFlex ? null : 24 - labelSpan\"\r\n [nzFlex]=\"inputFlex\"\r\n [ngClass]=\"{ 'full-width': floatingLabel }\"\r\n [nzErrorTip]=\"'REQUIRED_FIELD' | translate\"\r\n >\r\n <input\r\n #inputElement\r\n nz-input\r\n [nzSize]=\"size\"\r\n [id]=\"controlName\"\r\n [name]=\"controlName\"\r\n [formControlName]=\"controlName\"\r\n [autocomplete]=\"autocomplete\"\r\n [placeholder]=\"placeHolder\"\r\n [ngClass]=\"inputClass\"\r\n (keyup.enter)=\"onenter.emit()\"\r\n />\r\n </nz-form-control>\r\n </nz-form-item>\r\n </div>\r\n } @else {\r\n @if (label) {\r\n <nz-form-item>\r\n <nz-form-label\r\n [nzSpan]=\"floatingLabel || labelFlex ? null : labelSpan\"\r\n [nzFlex]=\"labelFlex\"\r\n [nzLabelAlign]=\"labelAlign\"\r\n [nzRequired]=\"required\"\r\n [nzFor]=\"controlName\"\r\n nzNoColon\r\n nzLabelWrap\r\n >\r\n {{ label }}\r\n </nz-form-label>\r\n <nz-form-control\r\n [nzSpan]=\"floatingLabel || labelFlex ? null : 24 - labelSpan\"\r\n [nzFlex]=\"inputFlex\"\r\n [ngClass]=\"{ 'full-width': floatingLabel }\"\r\n [nzValidateStatus]=\"customValidateStatus\"\r\n [nzErrorTip]=\"'REQUIRED_FIELD' | translate\"\r\n >\r\n <nz-input-group [nzSize]=\"size\" [nzSuffix]=\"allowClear ? clearIcon : undefined\">\r\n <input\r\n #inputElement\r\n nz-input\r\n [nzSize]=\"size\"\r\n [id]=\"controlName\"\r\n [name]=\"controlName\"\r\n [(ngModel)]=\"_ngModel\"\r\n [autocomplete]=\"autocomplete\"\r\n (ngModelChange)=\"_onNgModelChange()\"\r\n [disabled]=\"disabled\"\r\n [readOnly]=\"readOnly\"\r\n [placeholder]=\"placeHolder\"\r\n [ngClass]=\"inputClass\"\r\n (keyup.enter)=\"onenter.emit()\"\r\n />\r\n </nz-input-group>\r\n </nz-form-control>\r\n </nz-form-item>\r\n } @else {\r\n <input\r\n #inputElement\r\n nz-input\r\n [nzSize]=\"size\"\r\n [ngStyle]=\"{\r\n width: inputWidth,\r\n height: inputHeight,\r\n }\"\r\n [id]=\"controlName\"\r\n [name]=\"controlName\"\r\n [(ngModel)]=\"_ngModel\"\r\n (ngModelChange)=\"_onNgModelChange()\"\r\n [autocomplete]=\"autocomplete\"\r\n [disabled]=\"disabled\"\r\n [readOnly]=\"readOnly\"\r\n [placeholder]=\"placeHolder\"\r\n [ngClass]=\"inputClass + ' ' + (borderBottomOnly ? 'border-bottom-only' : '')\"\r\n (keyup.enter)=\"onenter.emit()\"\r\n />\r\n }\r\n }\r\n</div>\r\n\r\n<ng-template #clearIcon>\r\n <i\r\n nz-icon\r\n nzType=\"close-circle\"\r\n nzTheme=\"twotone\"\r\n nzTwotoneColor=\"#999\"\r\n *ngIf=\"_ngModel\"\r\n (click)=\"_ngModel = null; _onNgModelChange(); onclickClearIcon.emit()\"\r\n style=\"cursor: pointer\"\r\n ></i>\r\n</ng-template>\r\n", styles: ["::ng-deep .extend-input-wrapper.floating-label{position:relative;padding-top:14px}::ng-deep .extend-input-wrapper nz-form-item nz-form-label{position:absolute;top:12px;left:10px;transform:translateY(-50%);background:linear-gradient(to bottom,var(--form-bg-color, #ffffff) 80%,#ffffff 80%);z-index:2;height:auto;line-height:normal;padding:0 4px}::ng-deep .extend-input-wrapper 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 .extend-input-wrapper .full-width{width:100%}.extend-input-wrapper.floating-label nz-form-item:has(.ant-select-disabled) nz-form-label,.extend-input-wrapper.floating-label nz-form-item:has(input[disabled]) nz-form-label,.extend-input-wrapper.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%)}.extend-input-wrapper.floating-label nz-form-item:has(.ant-select-disabled) nz-form-label label,.extend-input-wrapper.floating-label nz-form-item:has(input[disabled]) nz-form-label label,.extend-input-wrapper.floating-label nz-form-item:has(.ant-input-disabled) nz-form-label label{color:#bfbfbf}\n"] }]
3019
+ args: [{ selector: 'extend-input', imports: [CommonModule, FormsModule, ReactiveFormsModule, TranslateModule, NzFormModule, NzInputModule, NzIconModule], template: "<div\r\n class=\"extend-input-wrapper\"\r\n [ngClass]=\"[floatingLabel && label ? 'floating-label' : '']\"\r\n [ngStyle]=\"{ display: displayInline ? 'inline' : null }\"\r\n>\r\n @if (controlName) {\r\n <div [formGroup]=\"formData\">\r\n <nz-form-item>\r\n <nz-form-label\r\n [nzSpan]=\"floatingLabel || labelFlex ? null : labelSpan\"\r\n [nzFlex]=\"labelFlex\"\r\n [nzLabelAlign]=\"labelAlign\"\r\n [nzRequired]=\"required\"\r\n [nzFor]=\"controlName\"\r\n nzNoColon\r\n nzLabelWrap\r\n >\r\n {{ label }}\r\n </nz-form-label>\r\n <nz-form-control\r\n [nzSpan]=\"floatingLabel || labelFlex ? null : 24 - labelSpan\"\r\n [nzFlex]=\"inputFlex\"\r\n [ngClass]=\"{ 'full-width': floatingLabel }\"\r\n [nzErrorTip]=\"'REQUIRED_FIELD' | translate\"\r\n >\r\n <input\r\n #inputElement\r\n nz-input\r\n [nzSize]=\"size\"\r\n [id]=\"controlName\"\r\n [name]=\"controlName\"\r\n [formControlName]=\"controlName\"\r\n [autocomplete]=\"autocomplete\"\r\n [placeholder]=\"placeHolder\"\r\n [ngClass]=\"inputClass\"\r\n (keyup.enter)=\"onenter.emit()\"\r\n />\r\n </nz-form-control>\r\n </nz-form-item>\r\n </div>\r\n } @else {\r\n @if (label) {\r\n <nz-form-item>\r\n <nz-form-label\r\n [nzSpan]=\"floatingLabel || labelFlex ? null : labelSpan\"\r\n [nzFlex]=\"labelFlex\"\r\n [nzLabelAlign]=\"labelAlign\"\r\n [nzRequired]=\"required\"\r\n [nzFor]=\"controlName\"\r\n nzNoColon\r\n nzLabelWrap\r\n >\r\n {{ label }}\r\n </nz-form-label>\r\n <nz-form-control\r\n [nzSpan]=\"floatingLabel || labelFlex ? null : 24 - labelSpan\"\r\n [nzFlex]=\"inputFlex\"\r\n [ngClass]=\"{ 'full-width': floatingLabel }\"\r\n [nzValidateStatus]=\"customValidateStatus\"\r\n [nzErrorTip]=\"'REQUIRED_FIELD' | translate\"\r\n >\r\n <nz-input-group [nzSize]=\"size\" [nzSuffix]=\"showClear ? clearIcon : undefined\">\r\n <input\r\n #inputElement\r\n nz-input\r\n [nzSize]=\"size\"\r\n [id]=\"controlName\"\r\n [name]=\"controlName\"\r\n [(ngModel)]=\"_ngModel\"\r\n [autocomplete]=\"autocomplete\"\r\n (ngModelChange)=\"_onNgModelChange()\"\r\n [disabled]=\"disabled\"\r\n [readOnly]=\"readOnly\"\r\n [placeholder]=\"placeHolder\"\r\n [ngClass]=\"inputClass\"\r\n (keyup.enter)=\"onenter.emit()\"\r\n />\r\n </nz-input-group>\r\n </nz-form-control>\r\n </nz-form-item>\r\n } @else {\r\n <nz-input-group [nzSize]=\"size\" [nzSuffix]=\"showClear ? clearIcon : undefined\">\r\n <input\r\n #inputElement\r\n nz-input\r\n [nzSize]=\"size\"\r\n [ngStyle]=\"{\r\n width: inputWidth,\r\n height: inputHeight,\r\n }\"\r\n [id]=\"controlName\"\r\n [name]=\"controlName\"\r\n [(ngModel)]=\"_ngModel\"\r\n (ngModelChange)=\"_onNgModelChange()\"\r\n [autocomplete]=\"autocomplete\"\r\n [disabled]=\"disabled\"\r\n [readOnly]=\"readOnly\"\r\n [placeholder]=\"placeHolder\"\r\n [ngClass]=\"inputClass + ' ' + (borderBottomOnly ? 'border-bottom-only' : '')\"\r\n (keyup.enter)=\"onenter.emit()\"\r\n />\r\n </nz-input-group>\r\n }\r\n }\r\n</div>\r\n\r\n<ng-template #clearIcon>\r\n <i\r\n nz-icon\r\n nzType=\"close-circle\"\r\n nzTheme=\"twotone\"\r\n nzTwotoneColor=\"#999\"\r\n *ngIf=\"_ngModel\"\r\n (click)=\"_ngModel = null; _onNgModelChange(); onclickClearIcon.emit()\"\r\n style=\"cursor: pointer; font-size: 13px\"\r\n ></i>\r\n</ng-template>\r\n", styles: ["::ng-deep .extend-input-wrapper.floating-label{position:relative;padding-top:14px}::ng-deep .extend-input-wrapper nz-form-item nz-form-label{position:absolute;top:12px;left:10px;transform:translateY(-50%);background:linear-gradient(to bottom,var(--form-bg-color, #ffffff) 80%,#ffffff 80%);z-index:2;height:auto;line-height:normal;padding:0 4px}::ng-deep .extend-input-wrapper 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 .extend-input-wrapper .full-width{width:100%}.extend-input-wrapper.floating-label nz-form-item:has(.ant-select-disabled) nz-form-label,.extend-input-wrapper.floating-label nz-form-item:has(input[disabled]) nz-form-label,.extend-input-wrapper.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%)}.extend-input-wrapper.floating-label nz-form-item:has(.ant-select-disabled) nz-form-label label,.extend-input-wrapper.floating-label nz-form-item:has(input[disabled]) nz-form-label label,.extend-input-wrapper.floating-label nz-form-item:has(.ant-input-disabled) nz-form-label label{color:#bfbfbf}\n"] }]
2995
3020
  }], propDecorators: { label: [{
2996
3021
  type: Input
2997
3022
  }], floatingLabel: [{
@@ -3008,7 +3033,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImpor
3008
3033
  type: Input
3009
3034
  }], inputFlex: [{
3010
3035
  type: Input
3011
- }], allowClear: [{
3036
+ }], showClear: [{
3012
3037
  type: Input
3013
3038
  }], disabled: [{
3014
3039
  type: Input
@@ -3400,85 +3425,27 @@ const URLs$6 = {
3400
3425
  getPaging: '/api/App_Dic_Domain/GetPaging',
3401
3426
  addOrEdit: '/api/App_Dic_Domain/AddOrEdit',
3402
3427
  delete: '/api/App_Dic_Domain/Delete',
3428
+ getByDomain: '/api/App_Dic_Domain/getByDomain',
3403
3429
  };
3404
- class App_Dic_Domain {
3405
- // #region properties
3406
- App_Dic_Domain_Id;
3407
- App_Org_Id;
3408
- IsActive;
3409
- CreatedDate;
3410
- CreatedUser;
3411
- UpdatedDate;
3412
- UpdatedUser;
3413
- DomainCode;
3414
- ItemCode;
3415
- ItemValue;
3416
- OrderValue;
3417
- Description;
3418
- ChildDomainCode;
3419
- ParentItemCode;
3420
- // #endregion properties
3421
- constructor(obj) {
3422
- obj = obj || {};
3423
- this.App_Dic_Domain_Id = obj.App_Dic_Domain_Id || '';
3424
- this.App_Org_Id = obj.App_Org_Id || '';
3425
- this.App_Org_Id = obj.App_Org_Id || '';
3426
- this.IsActive = obj.IsActive || false;
3427
- this.CreatedDate = obj.CreatedDate || null;
3428
- this.CreatedUser = obj.CreatedUser || '';
3429
- this.UpdatedDate = obj.UpdatedDate || null;
3430
- this.UpdatedUser = obj.UpdatedUser || '';
3431
- this.DomainCode = obj.DomainCode || '';
3432
- this.ItemCode = obj.ItemCode || '';
3433
- this.ItemValue = obj.ItemValue || '';
3434
- this.OrderValue = obj.OrderValue || null;
3435
- this.Description = obj.Description || '';
3436
- this.ChildDomainCode = obj.ChildDomainCode || '';
3437
- this.ParentItemCode = obj.ParentItemCode || '';
3438
- }
3439
- }
3440
3430
  class DicDomainService extends HTTPService {
3441
- cms = inject(CommonService);
3431
+ getById(id) {
3432
+ let pr = new HttpParams().append('id', id);
3433
+ return this.postParams(AppGlobals.apiEndpoint + URLs$6.getById, pr);
3434
+ }
3435
+ getPaging(filter) {
3436
+ return this.postData(AppGlobals.apiEndpoint + URLs$6.getPaging, filter);
3437
+ }
3438
+ addOrEdit(obj) {
3439
+ return this.postData(AppGlobals.apiEndpoint + URLs$6.addOrEdit, obj);
3440
+ }
3441
+ delete(id) {
3442
+ const params = new HttpParams().append('id', id);
3443
+ return this.postParams(AppGlobals.apiEndpoint + URLs$6.delete, params);
3444
+ }
3442
3445
  async getByDomain(DomainCode) {
3443
- // 1. Nếu đã dữ liệu trong cache → dùng ngay
3444
- const cached = DicDomainService.dataCache.get(DomainCode);
3445
- if (cached && cached.length) {
3446
- return cached;
3447
- }
3448
- // 2. Nếu đang load dữ liệu này → trả về Promise cũ
3449
- const loading = DicDomainService.loadingCache.get(DomainCode);
3450
- if (loading) {
3451
- return loading;
3452
- }
3453
- // 3. Nếu chưa load thì bắt đầu load và lưu Promise
3454
- const loadPromise = this.loadDomainFromServer(DomainCode);
3455
- DicDomainService.loadingCache.set(DomainCode, loadPromise);
3456
- try {
3457
- const result = await loadPromise;
3458
- DicDomainService.dataCache.set(DomainCode, result);
3459
- DicDomainService.loadingCache.delete(DomainCode);
3460
- return result;
3461
- }
3462
- catch (err) {
3463
- // Nếu lỗi → xoá promise để lần sau gọi lại
3464
- DicDomainService.loadingCache.delete(DomainCode);
3465
- throw err;
3466
- }
3467
- }
3468
- clearCache() {
3469
- DicDomainService.dataCache = new Map();
3470
- DicDomainService.loadingCache = new Map();
3471
- }
3472
- // Map cache: DomainCode → dữ liệu
3473
- static dataCache = new Map();
3474
- // Map load state: DomainCode → Promise đang tải
3475
- static loadingCache = new Map();
3476
- async loadDomainFromServer(DomainCode) {
3477
- const ret = await this.cms.ESP({
3478
- SPN: 'App_Dic_Domain_getByDomain',
3479
- Params: [DomainCode],
3480
- });
3481
- return ret.Data || [];
3446
+ var pr = new HttpParams().append('DomainCode', DomainCode);
3447
+ const ret = await this.postParams(AppGlobals.apiEndpoint + URLs$6.getByDomain, pr);
3448
+ return ret.Data;
3482
3449
  }
3483
3450
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: DicDomainService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
3484
3451
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: DicDomainService, providedIn: 'root' });
@@ -3660,7 +3627,7 @@ class ExtendTableComponent extends BaseComponent {
3660
3627
  this.filterChange.emit(this.filter);
3661
3628
  }
3662
3629
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: ExtendTableComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
3663
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.7", type: ExtendTableComponent, isStandalone: true, selector: "extend-table", inputs: { data: "data", filter: "filter", isLoading: "isLoading", idKey: "idKey", detailKey: "detailKey", selectedIdKey: "selectedIdKey", scroll: "scroll", actionTemplate: "actionTemplate" }, outputs: { filterChange: "filterChange", ondblclickrow: "ondblclickrow" }, usesInheritance: true, ngImport: i0, template: "<nz-table\r\n class=\"extend-table\"\r\n [nzData]=\"data.LstItem || []\"\r\n [nzBordered]=\"true\"\r\n [nzSize]=\"'small'\"\r\n [nzLoading]=\"isLoading\"\r\n [nzFrontPagination]=\"false\"\r\n [nzShowPagination]=\"false\"\r\n [nzTotal]=\"data.TotalCount || 0\"\r\n [(nzPageIndex)]=\"filter.PageIndex\"\r\n [(nzPageSize)]=\"filter.PageSize\"\r\n [nzScroll]=\"scroll || {}\"\r\n (nzPageIndexChange)=\"onPageIndexChange($event)\"\r\n (nzPageSizeChange)=\"onPageSizeChange($event)\"\r\n>\r\n <thead>\r\n <tr>\r\n @for (header of data.LstHeader; track $index) {\r\n <th\r\n [nzWidth]=\"header.Width\"\r\n [nzShowSort]=\"header.ShowSort\"\r\n [nzSortOrder]=\"header.SortOrder\"\r\n [nzLeft]=\"header.Fixed == 'left'\"\r\n [nzRight]=\"header.Fixed == 'right'\"\r\n (nzSortOrderChange)=\"onSortChange(header.Code, $event)\"\r\n >\r\n {{ header.Name }}\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (item of data.LstItem; track $index; let i = $index) {\r\n <tr\r\n tabindex=\"0\"\r\n class=\"selectable-row\"\r\n [ngClass]=\"selectedIdKey && item[idKey] == selectedIdKey ? 'selected-row' : ''\"\r\n (dblclick)=\"ondblclickrow.emit(item)\"\r\n >\r\n @for (header of data.LstHeader; track $index) {\r\n @if (header.Code === \"NO\") {\r\n <td [class]=\"header.Class\" [nzLeft]=\"header.Fixed == 'left'\" [nzRight]=\"header.Fixed == 'right'\">\r\n {{ i + 1 + filter.PageIndex * filter.PageSize }}\r\n </td>\r\n } @else if (header.Code === \"ACTION\") {\r\n <td [class]=\"header.Class\" [nzLeft]=\"header.Fixed == 'left'\" [nzRight]=\"header.Fixed == 'right'\">\r\n @if (actionTemplate) {\r\n <ng-container *ngTemplateOutlet=\"actionTemplate; context: { $implicit: item, index: i }\">\r\n </ng-container>\r\n }\r\n </td>\r\n } @else if (header.Type === \"CHECKBOX\") {\r\n <td [class]=\"header.Class\" [nzLeft]=\"header.Fixed == 'left'\" [nzRight]=\"header.Fixed == 'right'\">\r\n @if (item[header.Code]) {\r\n <nz-icon nzType=\"check-circle\" nzTheme=\"outline\" class=\"color-primary\" />\r\n }\r\n <!-- @else {\r\n <nz-icon nzType=\"close\" nzTheme=\"outline\" class=\"color-warn\" />\r\n } -->\r\n </td>\r\n } @else if (header.Code == detailKey) {\r\n <td [class]=\"header.Class\" [nzLeft]=\"header.Fixed == 'left'\" [nzRight]=\"header.Fixed == 'right'\">\r\n <span\r\n class=\"link-detail\"\r\n (click)=\"goto(item[idKey])\"\r\n [innerHTML]=\"item[header.Code] | highlight: filter.Keyword || ''\"\r\n ></span>\r\n </td>\r\n } @else {\r\n @if (header.DomainCode) {\r\n <td\r\n [class]=\"header.Class\"\r\n [innerHTML]=\"item[header.Code] | dicDomain: header.DomainCode | async | highlight: filter.Keyword || ''\"\r\n [nzLeft]=\"header.Fixed == 'left'\"\r\n [nzRight]=\"header.Fixed == 'right'\"\r\n ></td>\r\n } @else if (header.MaxLines) {\r\n <td [nzLeft]=\"header.Fixed == 'left'\" [nzRight]=\"header.Fixed == 'right'\">\r\n <read-more [text]=\"item[header.Code]\" [lines]=\"header.MaxLines\"></read-more>\r\n </td>\r\n } @else {\r\n <td\r\n [nzLeft]=\"header.Fixed == 'left'\"\r\n [nzRight]=\"header.Fixed == 'right'\"\r\n [class]=\"header.Class\"\r\n [innerHTML]=\"item[header.Code] | highlight: filter.Keyword || ''\"\r\n ></td>\r\n }\r\n }\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n</nz-table>\r\n", styles: ["@charset \"UTF-8\";.extend-table .ant-table-tbody>tr:nth-child(odd)>td{background-color:#fff}.extend-table .ant-table-tbody>tr:nth-child(2n)>td{background-color:#f6f6f6}.extend-table .selectable-row:hover td{background-color:#bae8fd!important}.extend-table .selectable-row:focus td{background-color:#bae8fd!important}.extend-table .selected-row td{background-color:#bae8fd!important;font-weight:700}.extend-table .link-detail{color:var(--primary-color);cursor:pointer}.extend-table .link-detail:hover{text-decoration:underline}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1$4.AsyncPipe, name: "async" }, { kind: "ngmodule", type: NzTableModule }, { kind: "component", type: i1$5.NzTableComponent, selector: "nz-table", inputs: ["nzTableLayout", "nzShowTotal", "nzItemRender", "nzTitle", "nzFooter", "nzNoResult", "nzPageSizeOptions", "nzVirtualItemSize", "nzVirtualMaxBufferPx", "nzVirtualMinBufferPx", "nzVirtualForTrackBy", "nzLoadingDelay", "nzPageIndex", "nzPageSize", "nzTotal", "nzWidthConfig", "nzData", "nzCustomColumn", "nzPaginationPosition", "nzScroll", "noDataVirtualHeight", "nzPaginationType", "nzFrontPagination", "nzTemplateMode", "nzShowPagination", "nzLoading", "nzOuterBordered", "nzLoadingIndicator", "nzBordered", "nzSize", "nzShowSizeChanger", "nzHideOnSinglePage", "nzShowQuickJumper", "nzSimple"], outputs: ["nzPageSizeChange", "nzPageIndexChange", "nzQueryParams", "nzCurrentPageDataChange", "nzCustomColumnChange"], exportAs: ["nzTable"] }, { kind: "component", type: i1$5.NzThAddOnComponent, selector: "th[nzColumnKey], th[nzSortFn], th[nzSortOrder], th[nzFilters], th[nzShowSort], th[nzShowFilter], th[nzCustomFilter]", inputs: ["nzColumnKey", "nzFilterMultiple", "nzSortOrder", "nzSortPriority", "nzSortDirections", "nzFilters", "nzSortFn", "nzFilterFn", "nzShowSort", "nzShowFilter", "nzCustomFilter"], outputs: ["nzCheckedChange", "nzSortOrderChange", "nzFilterChange"] }, { kind: "directive", type: i1$5.NzTableCellDirective, selector: "th:not(.nz-disable-th):not([mat-cell]), td:not(.nz-disable-td):not([mat-cell])" }, { kind: "directive", type: i1$5.NzThMeasureDirective, selector: "th", inputs: ["nzWidth", "colspan", "colSpan", "rowspan", "rowSpan"] }, { kind: "component", type: i1$5.NzTheadComponent, selector: "thead:not(.ant-table-thead)", outputs: ["nzSortOrderChange"] }, { kind: "component", type: i1$5.NzTbodyComponent, selector: "tbody" }, { kind: "directive", type: i1$5.NzTrDirective, selector: "tr:not([mat-row]):not([mat-header-row]):not([nz-table-measure-row]):not([nzExpand]):not([nz-table-fixed-row])" }, { kind: "directive", type: i1$5.NzCellFixedDirective, selector: "td[nzRight],th[nzRight],td[nzLeft],th[nzLeft]", inputs: ["nzRight", "nzLeft", "colspan", "colSpan"] }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "ngmodule", type: NzButtonModule }, { kind: "directive", type: i6$3.ɵ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: "pipe", type: HighlightPipe, name: "highlight" }, { kind: "pipe", type: DicDomainPipe, name: "dicDomain" }, { kind: "component", type: ReadMoreProComponent, selector: "read-more", inputs: ["text", "lines"] }] });
3630
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.7", type: ExtendTableComponent, isStandalone: true, selector: "extend-table", inputs: { data: "data", filter: "filter", isLoading: "isLoading", idKey: "idKey", detailKey: "detailKey", selectedIdKey: "selectedIdKey", scroll: "scroll", actionTemplate: "actionTemplate" }, outputs: { filterChange: "filterChange", ondblclickrow: "ondblclickrow" }, usesInheritance: true, ngImport: i0, template: "<nz-table\r\n class=\"extend-table\"\r\n [nzData]=\"data.LstItem || []\"\r\n [nzBordered]=\"true\"\r\n [nzSize]=\"'small'\"\r\n [nzLoading]=\"isLoading\"\r\n [nzFrontPagination]=\"false\"\r\n [nzShowPagination]=\"false\"\r\n [nzTotal]=\"data.TotalCount || 0\"\r\n [(nzPageIndex)]=\"filter.PageIndex\"\r\n [(nzPageSize)]=\"filter.PageSize\"\r\n [nzScroll]=\"scroll || {}\"\r\n (nzPageIndexChange)=\"onPageIndexChange($event)\"\r\n (nzPageSizeChange)=\"onPageSizeChange($event)\"\r\n>\r\n <thead>\r\n <tr>\r\n @for (header of data.LstHeader; track $index) {\r\n <th\r\n [nzWidth]=\"header.Width\"\r\n [nzShowSort]=\"header.ShowSort\"\r\n [nzSortOrder]=\"header.SortOrder\"\r\n [nzLeft]=\"header.Fixed == 'left'\"\r\n [nzRight]=\"header.Fixed == 'right'\"\r\n (nzSortOrderChange)=\"onSortChange(header.Code, $event)\"\r\n >\r\n {{ header.Name }}\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (item of data.LstItem; track $index; let i = $index) {\r\n <tr\r\n tabindex=\"0\"\r\n class=\"selectable-row\"\r\n [ngClass]=\"selectedIdKey && item[idKey] == selectedIdKey ? 'selected-row' : ''\"\r\n (dblclick)=\"ondblclickrow.emit(item)\"\r\n >\r\n @for (header of data.LstHeader; track $index) {\r\n @if (header.Code === \"NO\") {\r\n <td [class]=\"header.Class\" [nzLeft]=\"header.Fixed == 'left'\" [nzRight]=\"header.Fixed == 'right'\">\r\n {{ i + 1 + filter.PageIndex * filter.PageSize }}\r\n </td>\r\n } @else if (header.Code === \"ACTION\") {\r\n <td [class]=\"header.Class\" [nzLeft]=\"header.Fixed == 'left'\" [nzRight]=\"header.Fixed == 'right'\">\r\n @if (actionTemplate) {\r\n <ng-container *ngTemplateOutlet=\"actionTemplate; context: { $implicit: item, index: i }\">\r\n </ng-container>\r\n }\r\n </td>\r\n } @else if (header.Type === \"CHECKBOX\") {\r\n <td [class]=\"header.Class\" [nzLeft]=\"header.Fixed == 'left'\" [nzRight]=\"header.Fixed == 'right'\">\r\n @if (item[header.Code]) {\r\n <nz-icon nzType=\"check-circle\" nzTheme=\"outline\" class=\"color-primary\" />\r\n }\r\n <!-- @else {\r\n <nz-icon nzType=\"close\" nzTheme=\"outline\" class=\"color-warn\" />\r\n } -->\r\n </td>\r\n } @else if (header.Code == detailKey) {\r\n <td [class]=\"header.Class\" [nzLeft]=\"header.Fixed == 'left'\" [nzRight]=\"header.Fixed == 'right'\">\r\n <span\r\n class=\"link-detail\"\r\n (click)=\"goto(item[idKey])\"\r\n [innerHTML]=\"item[header.Code] | highlight: filter.Keyword || ''\"\r\n ></span>\r\n </td>\r\n } @else {\r\n @if (header.DomainCode) {\r\n <td\r\n [class]=\"header.Class\"\r\n [innerHTML]=\"item[header.Code] | dicDomain: header.DomainCode | async | highlight: filter.Keyword || ''\"\r\n [nzLeft]=\"header.Fixed == 'left'\"\r\n [nzRight]=\"header.Fixed == 'right'\"\r\n ></td>\r\n } @else if (header.MaxLines) {\r\n <td [nzLeft]=\"header.Fixed == 'left'\" [nzRight]=\"header.Fixed == 'right'\">\r\n <read-more [text]=\"item[header.Code]\" [lines]=\"header.MaxLines\"></read-more>\r\n </td>\r\n } @else {\r\n <td\r\n [nzLeft]=\"header.Fixed == 'left'\"\r\n [nzRight]=\"header.Fixed == 'right'\"\r\n [class]=\"header.Class\"\r\n [innerHTML]=\"item[header.Code] | highlight: filter.Keyword || ''\"\r\n ></td>\r\n }\r\n }\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n</nz-table>\r\n", styles: ["@charset \"UTF-8\";.extend-table .ant-table-tbody>tr:nth-child(odd)>td{background-color:#f6f6f6}.extend-table .ant-table-tbody>tr:nth-child(2n)>td{background-color:#fff}.extend-table .selectable-row:hover td{background-color:#bae8fd!important}.extend-table .selectable-row:focus td{background-color:#bae8fd!important}.extend-table .selected-row td{background-color:#bae8fd!important;font-weight:700}.extend-table .link-detail{color:var(--primary-color);cursor:pointer}.extend-table .link-detail:hover{text-decoration:underline}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1$4.AsyncPipe, name: "async" }, { kind: "ngmodule", type: NzTableModule }, { kind: "component", type: i1$5.NzTableComponent, selector: "nz-table", inputs: ["nzTableLayout", "nzShowTotal", "nzItemRender", "nzTitle", "nzFooter", "nzNoResult", "nzPageSizeOptions", "nzVirtualItemSize", "nzVirtualMaxBufferPx", "nzVirtualMinBufferPx", "nzVirtualForTrackBy", "nzLoadingDelay", "nzPageIndex", "nzPageSize", "nzTotal", "nzWidthConfig", "nzData", "nzCustomColumn", "nzPaginationPosition", "nzScroll", "noDataVirtualHeight", "nzPaginationType", "nzFrontPagination", "nzTemplateMode", "nzShowPagination", "nzLoading", "nzOuterBordered", "nzLoadingIndicator", "nzBordered", "nzSize", "nzShowSizeChanger", "nzHideOnSinglePage", "nzShowQuickJumper", "nzSimple"], outputs: ["nzPageSizeChange", "nzPageIndexChange", "nzQueryParams", "nzCurrentPageDataChange", "nzCustomColumnChange"], exportAs: ["nzTable"] }, { kind: "component", type: i1$5.NzThAddOnComponent, selector: "th[nzColumnKey], th[nzSortFn], th[nzSortOrder], th[nzFilters], th[nzShowSort], th[nzShowFilter], th[nzCustomFilter]", inputs: ["nzColumnKey", "nzFilterMultiple", "nzSortOrder", "nzSortPriority", "nzSortDirections", "nzFilters", "nzSortFn", "nzFilterFn", "nzShowSort", "nzShowFilter", "nzCustomFilter"], outputs: ["nzCheckedChange", "nzSortOrderChange", "nzFilterChange"] }, { kind: "directive", type: i1$5.NzTableCellDirective, selector: "th:not(.nz-disable-th):not([mat-cell]), td:not(.nz-disable-td):not([mat-cell])" }, { kind: "directive", type: i1$5.NzThMeasureDirective, selector: "th", inputs: ["nzWidth", "colspan", "colSpan", "rowspan", "rowSpan"] }, { kind: "component", type: i1$5.NzTheadComponent, selector: "thead:not(.ant-table-thead)", outputs: ["nzSortOrderChange"] }, { kind: "component", type: i1$5.NzTbodyComponent, selector: "tbody" }, { kind: "directive", type: i1$5.NzTrDirective, selector: "tr:not([mat-row]):not([mat-header-row]):not([nz-table-measure-row]):not([nzExpand]):not([nz-table-fixed-row])" }, { kind: "directive", type: i1$5.NzCellFixedDirective, selector: "td[nzRight],th[nzRight],td[nzLeft],th[nzLeft]", inputs: ["nzRight", "nzLeft", "colspan", "colSpan"] }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "ngmodule", type: NzButtonModule }, { 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: "pipe", type: HighlightPipe, name: "highlight" }, { kind: "pipe", type: DicDomainPipe, name: "dicDomain" }, { kind: "component", type: ReadMoreProComponent, selector: "read-more", inputs: ["text", "lines"] }] });
3664
3631
  }
3665
3632
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: ExtendTableComponent, decorators: [{
3666
3633
  type: Component,
@@ -3673,7 +3640,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImpor
3673
3640
  HighlightPipe,
3674
3641
  DicDomainPipe,
3675
3642
  ReadMoreProComponent,
3676
- ], template: "<nz-table\r\n class=\"extend-table\"\r\n [nzData]=\"data.LstItem || []\"\r\n [nzBordered]=\"true\"\r\n [nzSize]=\"'small'\"\r\n [nzLoading]=\"isLoading\"\r\n [nzFrontPagination]=\"false\"\r\n [nzShowPagination]=\"false\"\r\n [nzTotal]=\"data.TotalCount || 0\"\r\n [(nzPageIndex)]=\"filter.PageIndex\"\r\n [(nzPageSize)]=\"filter.PageSize\"\r\n [nzScroll]=\"scroll || {}\"\r\n (nzPageIndexChange)=\"onPageIndexChange($event)\"\r\n (nzPageSizeChange)=\"onPageSizeChange($event)\"\r\n>\r\n <thead>\r\n <tr>\r\n @for (header of data.LstHeader; track $index) {\r\n <th\r\n [nzWidth]=\"header.Width\"\r\n [nzShowSort]=\"header.ShowSort\"\r\n [nzSortOrder]=\"header.SortOrder\"\r\n [nzLeft]=\"header.Fixed == 'left'\"\r\n [nzRight]=\"header.Fixed == 'right'\"\r\n (nzSortOrderChange)=\"onSortChange(header.Code, $event)\"\r\n >\r\n {{ header.Name }}\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (item of data.LstItem; track $index; let i = $index) {\r\n <tr\r\n tabindex=\"0\"\r\n class=\"selectable-row\"\r\n [ngClass]=\"selectedIdKey && item[idKey] == selectedIdKey ? 'selected-row' : ''\"\r\n (dblclick)=\"ondblclickrow.emit(item)\"\r\n >\r\n @for (header of data.LstHeader; track $index) {\r\n @if (header.Code === \"NO\") {\r\n <td [class]=\"header.Class\" [nzLeft]=\"header.Fixed == 'left'\" [nzRight]=\"header.Fixed == 'right'\">\r\n {{ i + 1 + filter.PageIndex * filter.PageSize }}\r\n </td>\r\n } @else if (header.Code === \"ACTION\") {\r\n <td [class]=\"header.Class\" [nzLeft]=\"header.Fixed == 'left'\" [nzRight]=\"header.Fixed == 'right'\">\r\n @if (actionTemplate) {\r\n <ng-container *ngTemplateOutlet=\"actionTemplate; context: { $implicit: item, index: i }\">\r\n </ng-container>\r\n }\r\n </td>\r\n } @else if (header.Type === \"CHECKBOX\") {\r\n <td [class]=\"header.Class\" [nzLeft]=\"header.Fixed == 'left'\" [nzRight]=\"header.Fixed == 'right'\">\r\n @if (item[header.Code]) {\r\n <nz-icon nzType=\"check-circle\" nzTheme=\"outline\" class=\"color-primary\" />\r\n }\r\n <!-- @else {\r\n <nz-icon nzType=\"close\" nzTheme=\"outline\" class=\"color-warn\" />\r\n } -->\r\n </td>\r\n } @else if (header.Code == detailKey) {\r\n <td [class]=\"header.Class\" [nzLeft]=\"header.Fixed == 'left'\" [nzRight]=\"header.Fixed == 'right'\">\r\n <span\r\n class=\"link-detail\"\r\n (click)=\"goto(item[idKey])\"\r\n [innerHTML]=\"item[header.Code] | highlight: filter.Keyword || ''\"\r\n ></span>\r\n </td>\r\n } @else {\r\n @if (header.DomainCode) {\r\n <td\r\n [class]=\"header.Class\"\r\n [innerHTML]=\"item[header.Code] | dicDomain: header.DomainCode | async | highlight: filter.Keyword || ''\"\r\n [nzLeft]=\"header.Fixed == 'left'\"\r\n [nzRight]=\"header.Fixed == 'right'\"\r\n ></td>\r\n } @else if (header.MaxLines) {\r\n <td [nzLeft]=\"header.Fixed == 'left'\" [nzRight]=\"header.Fixed == 'right'\">\r\n <read-more [text]=\"item[header.Code]\" [lines]=\"header.MaxLines\"></read-more>\r\n </td>\r\n } @else {\r\n <td\r\n [nzLeft]=\"header.Fixed == 'left'\"\r\n [nzRight]=\"header.Fixed == 'right'\"\r\n [class]=\"header.Class\"\r\n [innerHTML]=\"item[header.Code] | highlight: filter.Keyword || ''\"\r\n ></td>\r\n }\r\n }\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n</nz-table>\r\n", styles: ["@charset \"UTF-8\";.extend-table .ant-table-tbody>tr:nth-child(odd)>td{background-color:#fff}.extend-table .ant-table-tbody>tr:nth-child(2n)>td{background-color:#f6f6f6}.extend-table .selectable-row:hover td{background-color:#bae8fd!important}.extend-table .selectable-row:focus td{background-color:#bae8fd!important}.extend-table .selected-row td{background-color:#bae8fd!important;font-weight:700}.extend-table .link-detail{color:var(--primary-color);cursor:pointer}.extend-table .link-detail:hover{text-decoration:underline}\n"] }]
3643
+ ], template: "<nz-table\r\n class=\"extend-table\"\r\n [nzData]=\"data.LstItem || []\"\r\n [nzBordered]=\"true\"\r\n [nzSize]=\"'small'\"\r\n [nzLoading]=\"isLoading\"\r\n [nzFrontPagination]=\"false\"\r\n [nzShowPagination]=\"false\"\r\n [nzTotal]=\"data.TotalCount || 0\"\r\n [(nzPageIndex)]=\"filter.PageIndex\"\r\n [(nzPageSize)]=\"filter.PageSize\"\r\n [nzScroll]=\"scroll || {}\"\r\n (nzPageIndexChange)=\"onPageIndexChange($event)\"\r\n (nzPageSizeChange)=\"onPageSizeChange($event)\"\r\n>\r\n <thead>\r\n <tr>\r\n @for (header of data.LstHeader; track $index) {\r\n <th\r\n [nzWidth]=\"header.Width\"\r\n [nzShowSort]=\"header.ShowSort\"\r\n [nzSortOrder]=\"header.SortOrder\"\r\n [nzLeft]=\"header.Fixed == 'left'\"\r\n [nzRight]=\"header.Fixed == 'right'\"\r\n (nzSortOrderChange)=\"onSortChange(header.Code, $event)\"\r\n >\r\n {{ header.Name }}\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (item of data.LstItem; track $index; let i = $index) {\r\n <tr\r\n tabindex=\"0\"\r\n class=\"selectable-row\"\r\n [ngClass]=\"selectedIdKey && item[idKey] == selectedIdKey ? 'selected-row' : ''\"\r\n (dblclick)=\"ondblclickrow.emit(item)\"\r\n >\r\n @for (header of data.LstHeader; track $index) {\r\n @if (header.Code === \"NO\") {\r\n <td [class]=\"header.Class\" [nzLeft]=\"header.Fixed == 'left'\" [nzRight]=\"header.Fixed == 'right'\">\r\n {{ i + 1 + filter.PageIndex * filter.PageSize }}\r\n </td>\r\n } @else if (header.Code === \"ACTION\") {\r\n <td [class]=\"header.Class\" [nzLeft]=\"header.Fixed == 'left'\" [nzRight]=\"header.Fixed == 'right'\">\r\n @if (actionTemplate) {\r\n <ng-container *ngTemplateOutlet=\"actionTemplate; context: { $implicit: item, index: i }\">\r\n </ng-container>\r\n }\r\n </td>\r\n } @else if (header.Type === \"CHECKBOX\") {\r\n <td [class]=\"header.Class\" [nzLeft]=\"header.Fixed == 'left'\" [nzRight]=\"header.Fixed == 'right'\">\r\n @if (item[header.Code]) {\r\n <nz-icon nzType=\"check-circle\" nzTheme=\"outline\" class=\"color-primary\" />\r\n }\r\n <!-- @else {\r\n <nz-icon nzType=\"close\" nzTheme=\"outline\" class=\"color-warn\" />\r\n } -->\r\n </td>\r\n } @else if (header.Code == detailKey) {\r\n <td [class]=\"header.Class\" [nzLeft]=\"header.Fixed == 'left'\" [nzRight]=\"header.Fixed == 'right'\">\r\n <span\r\n class=\"link-detail\"\r\n (click)=\"goto(item[idKey])\"\r\n [innerHTML]=\"item[header.Code] | highlight: filter.Keyword || ''\"\r\n ></span>\r\n </td>\r\n } @else {\r\n @if (header.DomainCode) {\r\n <td\r\n [class]=\"header.Class\"\r\n [innerHTML]=\"item[header.Code] | dicDomain: header.DomainCode | async | highlight: filter.Keyword || ''\"\r\n [nzLeft]=\"header.Fixed == 'left'\"\r\n [nzRight]=\"header.Fixed == 'right'\"\r\n ></td>\r\n } @else if (header.MaxLines) {\r\n <td [nzLeft]=\"header.Fixed == 'left'\" [nzRight]=\"header.Fixed == 'right'\">\r\n <read-more [text]=\"item[header.Code]\" [lines]=\"header.MaxLines\"></read-more>\r\n </td>\r\n } @else {\r\n <td\r\n [nzLeft]=\"header.Fixed == 'left'\"\r\n [nzRight]=\"header.Fixed == 'right'\"\r\n [class]=\"header.Class\"\r\n [innerHTML]=\"item[header.Code] | highlight: filter.Keyword || ''\"\r\n ></td>\r\n }\r\n }\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n</nz-table>\r\n", styles: ["@charset \"UTF-8\";.extend-table .ant-table-tbody>tr:nth-child(odd)>td{background-color:#f6f6f6}.extend-table .ant-table-tbody>tr:nth-child(2n)>td{background-color:#fff}.extend-table .selectable-row:hover td{background-color:#bae8fd!important}.extend-table .selectable-row:focus td{background-color:#bae8fd!important}.extend-table .selected-row td{background-color:#bae8fd!important;font-weight:700}.extend-table .link-detail{color:var(--primary-color);cursor:pointer}.extend-table .link-detail:hover{text-decoration:underline}\n"] }]
3677
3644
  }], propDecorators: { data: [{
3678
3645
  type: Input
3679
3646
  }], filter: [{
@@ -4327,6 +4294,80 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImpor
4327
4294
  }], size: [{
4328
4295
  type: Input
4329
4296
  }] } });
4297
+ class IconCheck {
4298
+ click = new EventEmitter();
4299
+ /**
4300
+ * default = 16
4301
+ */
4302
+ size = 16;
4303
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: IconCheck, deps: [], target: i0.ɵɵFactoryTarget.Component });
4304
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.7", type: IconCheck, isStandalone: true, selector: "icon-check", inputs: { size: "size" }, outputs: { click: "click" }, ngImport: i0, template: `
4305
+ <nz-icon
4306
+ nzType="check-circle"
4307
+ nzTheme="outline"
4308
+ class="color-primary cursor-pointer"
4309
+ [ngStyle]="{ 'font-size.px': size }"
4310
+ (click)="$event.stopPropagation(); click.emit()"
4311
+ ></nz-icon>
4312
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }] });
4313
+ }
4314
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: IconCheck, decorators: [{
4315
+ type: Component,
4316
+ args: [{
4317
+ selector: 'icon-check',
4318
+ template: `
4319
+ <nz-icon
4320
+ nzType="check-circle"
4321
+ nzTheme="outline"
4322
+ class="color-primary cursor-pointer"
4323
+ [ngStyle]="{ 'font-size.px': size }"
4324
+ (click)="$event.stopPropagation(); click.emit()"
4325
+ ></nz-icon>
4326
+ `,
4327
+ imports: [CommonModule, NzIconModule],
4328
+ }]
4329
+ }], propDecorators: { click: [{
4330
+ type: Output
4331
+ }], size: [{
4332
+ type: Input
4333
+ }] } });
4334
+ class IconClose {
4335
+ click = new EventEmitter();
4336
+ /**
4337
+ * default = 16
4338
+ */
4339
+ size = 16;
4340
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: IconClose, deps: [], target: i0.ɵɵFactoryTarget.Component });
4341
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.7", type: IconClose, isStandalone: true, selector: "icon-close", inputs: { size: "size" }, outputs: { click: "click" }, ngImport: i0, template: `
4342
+ <nz-icon
4343
+ nzType="close"
4344
+ nzTheme="outline"
4345
+ class="color-primary cursor-pointer"
4346
+ [ngStyle]="{ 'font-size.px': size }"
4347
+ (click)="$event.stopPropagation(); click.emit()"
4348
+ ></nz-icon>
4349
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }] });
4350
+ }
4351
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: IconClose, decorators: [{
4352
+ type: Component,
4353
+ args: [{
4354
+ selector: 'icon-close',
4355
+ template: `
4356
+ <nz-icon
4357
+ nzType="close"
4358
+ nzTheme="outline"
4359
+ class="color-primary cursor-pointer"
4360
+ [ngStyle]="{ 'font-size.px': size }"
4361
+ (click)="$event.stopPropagation(); click.emit()"
4362
+ ></nz-icon>
4363
+ `,
4364
+ imports: [CommonModule, NzIconModule],
4365
+ }]
4366
+ }], propDecorators: { click: [{
4367
+ type: Output
4368
+ }], size: [{
4369
+ type: Input
4370
+ }] } });
4330
4371
 
4331
4372
  // import {
4332
4373
  // Box,
@@ -6304,7 +6345,7 @@ class WorkflowEditorComponent extends BaseComponent {
6304
6345
  }
6305
6346
  }
6306
6347
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: WorkflowEditorComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
6307
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.7", type: WorkflowEditorComponent, isStandalone: true, selector: "app-workflow-editor", inputs: { lstOrg: "lstOrg", lstRole: "lstRole", lstEmailTemplate: "lstEmailTemplate" }, outputs: { onSave: "onSave", onDeleteStage: "onDeleteStage", onDeleteAction: "onDeleteAction", onDeleteRule: "onDeleteRule", onDeleteRuleLine: "onDeleteRuleLine" }, 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: "inputStageStatusElement", first: true, predicate: ["inputStageStatusElement"], descendants: true }, { propertyName: "inputActionTypeElement", first: true, predicate: ["inputActionTypeElement"], descendants: true }, { propertyName: "inputElement", first: true, predicate: ["inputElement"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div\r\n #canvasRef\r\n class=\"workflow-canvas\"\r\n [class.connecting]=\"!!connectingFrom\"\r\n [class.dragging-point]=\"!!draggingPoint\"\r\n [style.width.px]=\"getCanvasWidth()\"\r\n [style.height.px]=\"getCanvasHeight()\"\r\n (mousedown)=\"onMouseDownCanvas($event)\"\r\n (mousemove)=\"onMouseMoveCanvas($event)\"\r\n (mouseup)=\"onMouseUpCanvas($event)\"\r\n (click)=\"onClickCanvas($event)\"\r\n>\r\n <!-- \r\n\r\n [style.width.px]=\"getCanvasWidth()\"\r\n [style.height.px]=\"getCanvasHeight()\" \r\n\r\n [style.width.px]=\"CANVAS_WIDTH\"\r\n [style.height.px]=\"CANVAS_HEIGHT\"\r\n\r\n style=\"width: 100%; height: calc(100vh - 120px)\"\r\n \r\n -->\r\n\r\n <div class=\"toolbar\" (mousedown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\">\r\n <button nz-button nzSize=\"small\" nz-tooltip=\"Editor setting\" (click)=\"settingVisible = true\">\r\n <nz-icon nzType=\"setting\"></nz-icon>\r\n </button>\r\n\r\n <button nz-button nzSize=\"small\" nz-tooltip=\"Infomation\" (click)=\"infoVisible = true\">\r\n <nz-icon nzType=\"info-circle\"></nz-icon>\r\n </button>\r\n\r\n <box [width]=\"1\"></box>\r\n <span class=\"divider\"></span>\r\n <box [width]=\"1\"></box>\r\n\r\n <button nz-button nzSize=\"small\" nz-tooltip=\"Template setting\" (click)=\"drawTemplateVisibel = true\">\r\n <nz-icon nzType=\"setting\"></nz-icon> T\r\n </button>\r\n\r\n <box [width]=\"1\"></box>\r\n <span class=\"divider\"></span>\r\n <box [width]=\"1\"></box>\r\n\r\n <button nz-button nzSize=\"small\" nzDanger [nzLoading]=\"!ready\" nz-tooltip=\"Save (Ctrl + S)\" (click)=\"save()\">\r\n <nz-icon nzType=\"save\"></nz-icon>\r\n </button>\r\n <button nz-button nzSize=\"small\" nz-tooltip=\"Add stage\" (click)=\"addStage()\">\r\n <nz-icon nzType=\"plus\" class=\"color-primary\"></nz-icon>\r\n </button>\r\n\r\n <box [width]=\"1\"></box>\r\n <span class=\"divider\"></span>\r\n <box [width]=\"1\"></box>\r\n\r\n <button\r\n nz-button\r\n nzSize=\"small\"\r\n [nzType]=\"isMoveMode ? 'primary' : 'default'\"\r\n nz-tooltip=\"Move mode\"\r\n (click)=\"isMoveMode = true\"\r\n >\r\n <nz-icon><img src=\"/assets/icon/hand-palm.png\" width=\"19\" height=\"19\" /></nz-icon>\r\n </button>\r\n <button\r\n nz-button\r\n nzSize=\"small\"\r\n [nzType]=\"!isMoveMode ? 'primary' : 'default'\"\r\n nz-tooltip=\"Select mode\"\r\n (click)=\"isMoveMode = false\"\r\n >\r\n <nz-icon><img src=\"/assets/icon/cursor.png\" width=\"19\" height=\"19\" /></nz-icon>\r\n </button>\r\n\r\n <box [width]=\"1\"></box>\r\n <span class=\"divider\"></span>\r\n <box [width]=\"1\"></box>\r\n\r\n <!-- UNDO / REDO -->\r\n <button\r\n nz-button\r\n nzSize=\"small\"\r\n nzType=\"default\"\r\n [disabled]=\"undoStack.length === 0\"\r\n nz-tooltip=\"Undo\"\r\n (click)=\"undo()\"\r\n >\r\n <nz-icon nzType=\"undo\"></nz-icon>\r\n </button>\r\n\r\n <button\r\n nz-button\r\n nzSize=\"small\"\r\n nzType=\"default\"\r\n [disabled]=\"redoStack.length === 0\"\r\n nz-tooltip=\"Redo\"\r\n (click)=\"redo()\"\r\n >\r\n <nz-icon nzType=\"redo\"></nz-icon>\r\n </button>\r\n\r\n <box [width]=\"1\"></box>\r\n <span class=\"divider\"></span>\r\n <box [width]=\"1\"></box>\r\n\r\n <!-- ALIGN -->\r\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedStageId.size < 2\" (click)=\"alignLeft()\">\u27F8</button>\r\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedStageId.size < 2\" (click)=\"alignCenter()\">\u2261</button>\r\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedStageId.size < 2\" (click)=\"alignRight()\">\u27F9</button>\r\n\r\n <span class=\"divider\"></span>\r\n\r\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedStageId.size < 2\" (click)=\"alignTop()\">\u21D1</button>\r\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedStageId.size < 2\" (click)=\"alignMiddle()\">\u2550</button>\r\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedStageId.size < 2\" (click)=\"alignBottom()\">\u21D3</button>\r\n\r\n <span class=\"divider\"></span>\r\n\r\n <!-- DISTRIBUTE -->\r\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedStageId.size < 3\" (click)=\"distributeHorizontal()\">\r\n \u21C4\r\n </button>\r\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedStageId.size < 3\" (click)=\"distributeVertical()\">\u21C5</button>\r\n </div>\r\n\r\n <div\r\n class=\"canvas-content\"\r\n [class.panning]=\"isMoveMode\"\r\n [style.transform]=\"'translate(' + template.editorOption.panX + 'px,' + template.editorOption.panY + 'px)'\"\r\n >\r\n <!-- GRID -->\r\n <div *ngIf=\"wfcSetting.ShowGrid\" class=\"grid-layer\"></div>\r\n\r\n <!-- <div class=\"zoom-toolbar\">\r\n <button nz-button nzSize=\"small\" (click)=\"zoomOut()\">\u2212</button>\r\n <span>{{ zoom * 100 | number: \"1.0-0\" }}%</span>\r\n <button nz-button nzSize=\"small\" (click)=\"zoomIn()\">+</button>\r\n </div> -->\r\n\r\n <!-- SVG EDGES -->\r\n <svg #svg class=\"edges-layer\" width=\"100%\" height=\"100%\" preserveAspectRatio=\"none\">\r\n <g [attr.transform]=\"svgTransform\">\r\n <!-- DEFS -->\r\n <defs>\r\n <!-- glow effect -->\r\n <filter id=\"edge-glow\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\r\n <feGaussianBlur stdDeviation=\"2\" result=\"blur\" />\r\n <feMerge>\r\n <feMergeNode in=\"blur\" />\r\n <feMergeNode in=\"SourceGraphic\" />\r\n </feMerge>\r\n </filter>\r\n\r\n <!-- arrow markers -->\r\n <marker\r\n id=\"arrow-blue\"\r\n markerWidth=\"10\"\r\n markerHeight=\"10\"\r\n refX=\"10\"\r\n refY=\"5\"\r\n orient=\"auto\"\r\n markerUnits=\"strokeWidth\"\r\n >\r\n <path class=\"blue\" d=\"M0,0 L10,5 L0,10\"></path>\r\n </marker>\r\n\r\n <marker\r\n id=\"arrow-red\"\r\n markerWidth=\"10\"\r\n markerHeight=\"10\"\r\n refX=\"10\"\r\n refY=\"5\"\r\n orient=\"auto\"\r\n markerUnits=\"strokeWidth\"\r\n >\r\n <path class=\"red\" d=\"M0,0 L10,5 L0,10\"></path>\r\n </marker>\r\n\r\n <marker\r\n id=\"arrow-blue-start\"\r\n markerWidth=\"10\"\r\n markerHeight=\"10\"\r\n viewBox=\"0 0 10 10\"\r\n refX=\"0\"\r\n refY=\"5\"\r\n orient=\"auto\"\r\n markerUnits=\"strokeWidth\"\r\n >\r\n <path class=\"blue\" d=\"M10,0 L0,5 L10,10\"></path>\r\n </marker>\r\n\r\n <marker\r\n id=\"arrow-red-start\"\r\n markerWidth=\"10\"\r\n markerHeight=\"10\"\r\n viewBox=\"0 0 10 10\"\r\n refX=\"0\"\r\n refY=\"5\"\r\n orient=\"auto\"\r\n markerUnits=\"strokeWidth\"\r\n >\r\n <path class=\"red\" d=\"M10,0 L0,5 L10,10\"></path>\r\n </marker>\r\n </defs>\r\n\r\n <!-- EDGES B\u00CCNH TH\u01AF\u1EDCNG -->\r\n <ng-container *ngFor=\"let e of normalEdges; let i = index\">\r\n <path\r\n class=\"edge\"\r\n [attr.id]=\"'edge-path-' + i\"\r\n [attr.d]=\"buildPath(e)\"\r\n marker-end=\"url(#arrow-blue)\"\r\n [attr.marker-start]=\"e.allowBack ? 'url(#arrow-blue-start)' : ''\"\r\n ></path>\r\n\r\n <path\r\n class=\"edge-hit\"\r\n [attr.d]=\"buildPath(e)\"\r\n (mouseenter)=\"onMouseEnterEdge(e)\"\r\n (mouseleave)=\"onMouseLeaveEdge(e)\"\r\n (click)=\"onClickEdge(e, $event)\"\r\n ></path>\r\n\r\n <!-- LABEL -->\r\n <!-- text b\u00E1m theo line -->\r\n <!-- \r\n <text *ngIf=\"e.ActionText\" class=\"edge-label\" dy=\"-6\">\r\n <textPath [attr.href]=\"'#edge-path-' + i\" startOffset=\"50%\" text-anchor=\"middle\">\r\n {{ e.ActionText }}\r\n </textPath>\r\n </text> \r\n \r\n <text *ngIf=\"e.allowBack && e.labelBack\" class=\"edge-label\" dy=\"14\">\r\n <textPath [attr.href]=\"'#edge-path-' + i\" startOffset=\"50%\" text-anchor=\"middle\">\r\n {{ e.labelBack }}\r\n </textPath>\r\n </text>\r\n -->\r\n\r\n <!-- text th\u1EB3ng n\u1EB1m ngang -->\r\n <text\r\n *ngIf=\"e.ActionText\"\r\n class=\"edge-label\"\r\n [attr.x]=\"getEdgeLabelPosition(e).x\"\r\n [attr.y]=\"getEdgeLabelPosition(e).y - 8\"\r\n [attr.text-anchor]=\"'middle'\"\r\n >\r\n {{ e.ActionText }}\r\n </text>\r\n\r\n <text\r\n *ngIf=\"e.allowBack && e.labelBack\"\r\n class=\"edge-label\"\r\n [attr.x]=\"getEdgeLabelPosition(e).x\"\r\n [attr.y]=\"getEdgeLabelPosition(e).y + 14\"\r\n [attr.text-anchor]=\"'middle'\"\r\n >\r\n {{ e.labelBack }}\r\n </text>\r\n </ng-container>\r\n\r\n <!-- EDGE \u0110ANG HOVER (LU\u00D4N TR\u00CAN C\u00D9NG) -->\r\n <ng-container *ngFor=\"let e of hoverEdges; let i = index\">\r\n <path\r\n class=\"edge red\"\r\n [attr.id]=\"'edge-path-hover-' + i\"\r\n [attr.d]=\"buildPath(e)\"\r\n marker-end=\"url(#arrow-red)\"\r\n [attr.marker-start]=\"e.allowBack ? 'url(#arrow-red-start)' : ''\"\r\n ></path>\r\n\r\n <path\r\n class=\"edge-hit\"\r\n [attr.d]=\"buildPath(e)\"\r\n (mouseleave)=\"onMouseLeaveEdge(e)\"\r\n (click)=\"onClickEdge(e, $event)\"\r\n ></path>\r\n\r\n <!-- LABEL -->\r\n <!-- <text *ngIf=\"e.ActionText\" class=\"edge-label\" dy=\"-6\">\r\n <textPath [attr.href]=\"'#edge-path-hover-' + i\" startOffset=\"50%\" text-anchor=\"middle\">\r\n {{ e.ActionText }}\r\n </textPath>\r\n </text>\r\n\r\n <text *ngIf=\"e.allowBack && e.labelBack\" class=\"edge-label\" dy=\"14\">\r\n <textPath [attr.href]=\"'#edge-path-hover-' + i\" startOffset=\"50%\" text-anchor=\"middle\">\r\n {{ e.labelBack }}\r\n </textPath>\r\n </text> -->\r\n\r\n <text\r\n *ngIf=\"e.ActionText\"\r\n class=\"edge-label\"\r\n [attr.x]=\"getEdgeLabelPosition(e).x\"\r\n [attr.y]=\"getEdgeLabelPosition(e).y - 8\"\r\n [attr.text-anchor]=\"'middle'\"\r\n >\r\n {{ e.ActionText }}\r\n </text>\r\n\r\n <text\r\n *ngIf=\"e.allowBack && e.labelBack\"\r\n class=\"edge-label\"\r\n [attr.x]=\"getEdgeLabelPosition(e).x\"\r\n [attr.y]=\"getEdgeLabelPosition(e).y + 14\"\r\n [attr.text-anchor]=\"'middle'\"\r\n >\r\n {{ e.labelBack }}\r\n </text>\r\n </ng-container>\r\n\r\n <!-- preview -->\r\n <path\r\n *ngIf=\"connectingFrom\"\r\n class=\"edge\"\r\n [attr.d]=\"buildPreviewPath()\"\r\n stroke-dasharray=\"5,5\"\r\n marker-end=\"url(#arrow-blue)\"\r\n ></path>\r\n </g>\r\n </svg>\r\n\r\n <div\r\n *ngIf=\"isSelecting && selectStart && selectEnd\"\r\n class=\"selection-box\"\r\n [style.left.px]=\"Math.min(selectStart.x, selectEnd.x)\"\r\n [style.top.px]=\"Math.min(selectStart.y, selectEnd.y)\"\r\n [style.width.px]=\"Math.abs(selectEnd.x - selectStart.x)\"\r\n [style.height.px]=\"Math.abs(selectEnd.y - selectStart.y)\"\r\n ></div>\r\n\r\n <!-- lstStage -->\r\n @for (n of lstStage; track $index) {\r\n <!-- START NODE -->\r\n @if (n.StageType === \"_start_\") {\r\n <nz-card\r\n class=\"workflow-node workflow-node-start\"\r\n [attr.data-id]=\"n.Code\"\r\n [class.selected]=\"n == selectedStage || n == hoverStage || lstSelectedStageId.has(n.WF_TemplateStage_Id)\"\r\n [style.left.px]=\"n.editorOption.x\"\r\n [style.top.px]=\"n.editorOption.y\"\r\n [class.connecting-source]=\"isConnectingFrom(n) || isDraggingFrom(n) || isSelectedNode(n)\"\r\n nzSize=\"small\"\r\n (mousedown)=\"onMouseDownNode($event, n)\"\r\n (click)=\"$event.stopPropagation(); onClickStage(n)\"\r\n >\r\n <nz-tag [nzColor]=\"'green'\"> START </nz-tag>\r\n\r\n @if (!n.editorOption.isReverse) {\r\n <!-- connector RIGHT: output -->\r\n <div class=\"connector connector-right connector-start\" (click)=\"onClickConnector($event, n, 'right')\"></div>\r\n } @else {\r\n <div\r\n class=\"connector connector-right connector-start reverse\"\r\n (click)=\"onClickConnector($event, n, 'right')\"\r\n ></div>\r\n }\r\n </nz-card>\r\n }\r\n <!-- END NODE -->\r\n @else if (n.StageType === \"_end_\") {\r\n <nz-card\r\n class=\"workflow-node workflow-node-end\"\r\n [attr.data-id]=\"n.Code\"\r\n [class.selected]=\"n == selectedStage || n == hoverStage || lstSelectedStageId.has(n.WF_TemplateStage_Id)\"\r\n [style.left.px]=\"n.editorOption.x\"\r\n [style.top.px]=\"n.editorOption.y\"\r\n [class.connecting-source]=\"isConnectingFrom(n) || isDraggingFrom(n) || isSelectedNode(n)\"\r\n nzSize=\"small\"\r\n (mousedown)=\"onMouseDownNode($event, n)\"\r\n (click)=\"$event.stopPropagation(); onClickStage(n)\"\r\n >\r\n <nz-tag [nzColor]=\"'red'\"> END </nz-tag>\r\n\r\n @if (!n.editorOption.isReverse) {\r\n <!-- connector LEFT: input -->\r\n <div class=\"connector connector-left connector-end\" (click)=\"onClickConnector($event, n, 'left')\"></div>\r\n } @else {\r\n <div\r\n class=\"connector connector-left connector-end reverse\"\r\n (click)=\"onClickConnector($event, n, 'left')\"\r\n ></div>\r\n }\r\n </nz-card>\r\n } @else {\r\n <nz-card\r\n class=\"workflow-node\"\r\n [attr.data-id]=\"n.Code\"\r\n [class.selected]=\"n == selectedStage || n == hoverStage || lstSelectedStageId.has(n.WF_TemplateStage_Id)\"\r\n [style.left.px]=\"n.editorOption.x\"\r\n [style.top.px]=\"n.editorOption.y\"\r\n [class.connecting-source]=\"isConnectingFrom(n) || isDraggingFrom(n) || isSelectedNode(n)\"\r\n nzSize=\"small\"\r\n (mousedown)=\"onMouseDownNode($event, n)\"\r\n (click)=\"$event.stopPropagation(); onClickStage(n)\"\r\n >\r\n <div class=\"title\">{{ n.Code }}</div>\r\n\r\n <div>{{ n.Name }}</div>\r\n\r\n @if (!n.editorOption.isReverse) {\r\n <!-- connector RIGHT: output -->\r\n <div class=\"connector connector-right\" (click)=\"onClickConnector($event, n, 'right')\"></div>\r\n\r\n <!-- connector LEFT: input -->\r\n <div class=\"connector connector-left\" (click)=\"onClickConnector($event, n, 'left')\"></div>\r\n } @else {\r\n <div class=\"connector connector-right reverse\" (click)=\"onClickConnector($event, n, 'right')\"></div>\r\n <div class=\"connector connector-left reverse\" (click)=\"onClickConnector($event, n, 'left')\"></div>\r\n }\r\n </nz-card>\r\n }\r\n }\r\n\r\n <!-- POINTS -->\r\n @for (p of connectingPoints; track $index) {\r\n @if (p != draggingPoint) {\r\n <div\r\n class=\"waypoint\"\r\n [style.left.px]=\"p.x\"\r\n [style.top.px]=\"p.y\"\r\n (mousedown)=\"onmousedownPoint($event, p)\"\r\n (contextmenu)=\"onRightClickPoint($event, hoverAction!, $index)\"\r\n ></div>\r\n } @else {\r\n <div\r\n class=\"waypoint dragging\"\r\n [style.left.px]=\"p.x\"\r\n [style.top.px]=\"p.y\"\r\n (mousedown)=\"onmousedownPoint($event, p)\"\r\n ></div>\r\n }\r\n }\r\n </div>\r\n</div>\r\n\r\n<!-- drawer TEMPLATE -->\r\n<nz-drawer\r\n [nzTitle]=\"drawTemplateTitle\"\r\n nzPlacement=\"right\"\r\n [nzWidth]=\"500\"\r\n [nzClosable]=\"false\"\r\n [nzVisible]=\"drawTemplateVisibel\"\r\n [nzFooter]=\"footerTplTemplate\"\r\n (nzOnClose)=\"drawTemplateVisibel = false\"\r\n>\r\n <ng-template #drawTemplateTitle> <nz-icon nzType=\"setting\"></nz-icon> &nbsp; Template </ng-template>\r\n <ng-container *nzDrawerContent>\r\n <extend-select\r\n [label]=\"'Org'\"\r\n [lstItem]=\"lstOrg\"\r\n [valueField]=\"'App_Org_Id'\"\r\n [displayFields]=\"['Name', 'Code']\"\r\n [(_ngModel)]=\"template.App_Org_Id\"\r\n ></extend-select>\r\n <extend-input [label]=\"'Code'\" [(_ngModel)]=\"template.Code\"></extend-input>\r\n <extend-input [label]=\"'Name'\" [(_ngModel)]=\"template.Name\"></extend-input>\r\n <extend-select\r\n [label]=\"'Type'\"\r\n [lstItem]=\"template.lstTemplateType\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"template.DocType\"\r\n ></extend-select>\r\n <extend-textarea [label]=\"'Desscription'\" [(_ngModel)]=\"template.Description\"></extend-textarea>\r\n <extend-select\r\n [label]=\"'Print template'\"\r\n [lstItem]=\"template.lstTemplatePrint\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"template.TemplatePrint\"\r\n ></extend-select>\r\n <extend-select\r\n [label]=\"'Apply to'\"\r\n [lstItem]=\"template.lstApplyTo\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"template.ApplyTo\"\r\n ></extend-select>\r\n\r\n <extend-checkbox [label]=\"'Active'\" [(_ngModel)]=\"template.IsActive\"></extend-checkbox>\r\n <extend-checkbox [label]=\"'Use Allow back'\" [(_ngModel)]=\"template.editorOption.AllowbackInUse\"></extend-checkbox>\r\n\r\n <h3 nz-col><nz-icon nzType=\"send\" nzTheme=\"outline\" />&nbsp;Stage</h3>\r\n\r\n <div nz-row [nzGutter]=\"[0, 5]\">\r\n @for (tag of getLstStage; track tag) {\r\n <div nz-col>\r\n <nz-tag (click)=\"hoverStage = tag\">\r\n {{ sliceTagName(tag.Code + (tag.Name ? \" - \" + tag.Name : \"\")) }}\r\n </nz-tag>\r\n </div>\r\n }\r\n </div>\r\n\r\n <box [height]=\"16\"></box>\r\n\r\n <h3 nz-col><nz-icon nzType=\"send\" nzTheme=\"outline\" />&nbsp;Stage status</h3>\r\n\r\n <div nz-row [nzGutter]=\"[0, 5]\">\r\n @for (tag of template.lstStageStatus; track tag) {\r\n <div nz-col>\r\n <nz-tag\r\n [nzMode]=\"checkRemoveableStageStatus(tag) ? 'closeable' : 'default'\"\r\n (nzOnClose)=\"handleCloseStageStatus(tag)\"\r\n >\r\n {{ sliceTagName(tag.Code + (tag.Name ? \" - \" + tag.Name : \"\")) }}\r\n </nz-tag>\r\n </div>\r\n }\r\n\r\n <div nz-col>\r\n @if (!inputStageStatusVisible) {\r\n <nz-tag class=\"editable-tag\" nzNoAnimation (click)=\"showInputStageStatus()\">\r\n <nz-icon nzType=\"plus\" />\r\n New Action type\r\n </nz-tag>\r\n } @else {\r\n <input\r\n #inputStageStatusElement\r\n nz-input\r\n nzSize=\"small\"\r\n type=\"text\"\r\n style=\"width: 150px\"\r\n placeholder=\"Code\"\r\n [(ngModel)]=\"inputStageStatusCode\"\r\n (keydown.enter)=\"inputStageStatusNameElement.select()\"\r\n />\r\n <input\r\n #inputStageStatusNameElement\r\n nz-input\r\n nzSize=\"small\"\r\n type=\"text\"\r\n style=\"width: 150px\"\r\n placeholder=\"Name\"\r\n [(ngModel)]=\"inputStageStatusName\"\r\n (blur)=\"handleInputStageStatusConfirm()\"\r\n (keydown.enter)=\"handleInputStageStatusConfirm()\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n\r\n <box [height]=\"16\"></box>\r\n\r\n <h3 nz-col><nz-icon nzType=\"send\" nzTheme=\"outline\" />&nbsp;Action type</h3>\r\n\r\n <div nz-row [nzGutter]=\"[0, 5]\">\r\n @for (tag of template.lstActionType; track tag) {\r\n <div nz-col>\r\n <nz-tag\r\n [nzMode]=\"checkRemoveableActionType(tag) ? 'closeable' : 'default'\"\r\n (nzOnClose)=\"handleCloseActionType(tag)\"\r\n >\r\n {{ sliceTagName(tag.Code + (tag.Name ? \" - \" + tag.Name : \"\")) }}\r\n </nz-tag>\r\n </div>\r\n }\r\n\r\n <div nz-col>\r\n @if (!inputActionTypeVisible) {\r\n <nz-tag class=\"editable-tag\" nzNoAnimation (click)=\"showInputActionType()\">\r\n <nz-icon nzType=\"plus\" />\r\n New Action type\r\n </nz-tag>\r\n } @else {\r\n <input\r\n #inputActionTypeElement\r\n nz-input\r\n nzSize=\"small\"\r\n type=\"text\"\r\n style=\"width: 150px\"\r\n placeholder=\"Code\"\r\n [(ngModel)]=\"inputActionTypeCode\"\r\n (keydown.enter)=\"inputActionTypeNameElement.select()\"\r\n />\r\n <input\r\n #inputActionTypeNameElement\r\n nz-input\r\n nzSize=\"small\"\r\n type=\"text\"\r\n style=\"width: 150px\"\r\n placeholder=\"Name\"\r\n [(ngModel)]=\"inputActionTypeName\"\r\n (blur)=\"handleInputActionTypeConfirm()\"\r\n (keydown.enter)=\"handleInputActionTypeConfirm()\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n\r\n <box [height]=\"16\"></box>\r\n\r\n <h3 nz-col><nz-icon nzType=\"send\" nzTheme=\"outline\" />&nbsp;Action status</h3>\r\n\r\n <div nz-row [nzGutter]=\"[0, 5]\">\r\n @for (tag of template.lstActionStatus; track tag) {\r\n <div nz-col>\r\n @if (template.editingActionStatus != tag) {\r\n <nz-tag\r\n [nzMode]=\"checkRemoveableActionStatus(tag.Code) ? 'closeable' : 'default'\"\r\n (nzOnClose)=\"handleClose(tag.Code)\"\r\n (click)=\"template.editingActionStatus = checkRemoveableActionStatus(tag.Code) ? tag : undefined\"\r\n >\r\n {{ sliceTagName(tag.Code + (tag.Name ? \" - \" + tag.Name : \"\")) }}\r\n </nz-tag>\r\n } @else {\r\n <input\r\n nz-input\r\n nzSize=\"small\"\r\n type=\"text\"\r\n style=\"width: 150px\"\r\n [appAutoFocus]=\"true\"\r\n [(ngModel)]=\"tag.Code\"\r\n (blur)=\"template.editingActionStatus = undefined\"\r\n (keydown.enter)=\"template.editingActionStatus = undefined\"\r\n />&nbsp;&nbsp;\r\n }\r\n </div>\r\n }\r\n\r\n <div nz-col>\r\n @if (!inputVisible) {\r\n <nz-tag class=\"editable-tag\" nzNoAnimation (click)=\"showInput()\">\r\n <nz-icon nzType=\"plus\" />\r\n New Action status\r\n </nz-tag>\r\n } @else {\r\n <input\r\n #inputElement\r\n nz-input\r\n nzSize=\"small\"\r\n type=\"text\"\r\n style=\"width: 150px\"\r\n placeholder=\"+ New Action status\"\r\n [(ngModel)]=\"inputValue\"\r\n (blur)=\"handleInputConfirm()\"\r\n (keydown.enter)=\"handleInputConfirm()\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #footerTplTemplate>\r\n <div nz-flex [nzGap]=\"6\" [nzJustify]=\"'end'\">\r\n <button nz-button nzDanger [nzLoading]=\"!ready\" (click)=\"save()\">Save</button>\r\n <button nz-button (click)=\"drawTemplateVisibel = false\">Close</button>\r\n </div>\r\n </ng-template>\r\n</nz-drawer>\r\n\r\n<!-- drawer STAGE -->\r\n<nz-drawer\r\n [nzTitle]=\"drawerTitleStage\"\r\n [nzPlacement]=\"selectedStage?.editorOption?.drawerPosition == 'left' ? 'left' : 'right'\"\r\n [nzVisible]=\"!!selectedStage\"\r\n [nzWidth]=\"'calc(50vw)'\"\r\n [nzClosable]=\"false\"\r\n [nzFooter]=\"footerTplNode\"\r\n (nzOnClose)=\"selectedStage = undefined\"\r\n>\r\n <ng-template #drawerTitleStage>\r\n <div nz-row nzJustify=\"space-between\">\r\n @if (selectedStage && selectedStage.editorOption) {\r\n @if (selectedStage.editorOption.drawerPosition == \"left\") {\r\n <button\r\n nz-button\r\n nzSize=\"small\"\r\n nz-tooltip=\"To the right\"\r\n (click)=\"selectedStage.editorOption.drawerPosition = 'right'\"\r\n >\r\n <nz-icon nzType=\"double-right\"></nz-icon>\r\n </button>\r\n STAGE\r\n } @else {\r\n STAGE\r\n <button\r\n nz-button\r\n nzSize=\"small\"\r\n nz-tooltip=\"To the left\"\r\n (click)=\"selectedStage.editorOption.drawerPosition = 'left'\"\r\n >\r\n <nz-icon nzType=\"double-left\"></nz-icon>\r\n </button>\r\n }\r\n }\r\n </div>\r\n </ng-template>\r\n <ng-container *nzDrawerContent>\r\n <ng-container *ngIf=\"selectedStage\">\r\n <nz-radio-group [(ngModel)]=\"selectedStage.StageType\">\r\n <label nz-radio nzValue=\"_start_\">UI start</label>\r\n <label nz-radio nzValue=\"_end_\">UI end</label>\r\n <label nz-radio nzValue=\"start\">START</label>\r\n <label nz-radio nzValue=\"node\">NODE</label>\r\n <label nz-radio nzValue=\"end\">END</label>\r\n </nz-radio-group>\r\n\r\n <box [height]=\"16\"></box>\r\n\r\n <div nz-row [nzGutter]=\"32\" class=\"form-item-no-bottom\">\r\n <extend-input\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Code'\"\r\n [floatingLabel]=\"true\"\r\n [required]=\"true\"\r\n [(_ngModel)]=\"selectedStage.Code\"\r\n ></extend-input>\r\n\r\n <extend-input\r\n nz-col\r\n [nzSpan]=\"16\"\r\n [label]=\"'Name'\"\r\n [floatingLabel]=\"true\"\r\n [required]=\"true\"\r\n [(_ngModel)]=\"selectedStage.Name\"\r\n ></extend-input>\r\n </div>\r\n\r\n <div nz-row [nzGutter]=\"32\" class=\"form-item-no-bottom\">\r\n <extend-input-number\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Sequence'\"\r\n [floatingLabel]=\"true\"\r\n [(_ngModel)]=\"selectedStage.SeqValue\"\r\n ></extend-input-number>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"16\"\r\n [label]=\"'Org implement'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"lstOrg\"\r\n [valueField]=\"'App_Org_Id'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"selectedStage.App_Org_Id\"\r\n ></extend-select>\r\n </div>\r\n\r\n <div nz-row [nzGutter]=\"32\" class=\"form-item-no-bottom\">\r\n <extend-input-number\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Number Day'\"\r\n [floatingLabel]=\"true\"\r\n [precision]=\"1\"\r\n [(_ngModel)]=\"selectedStage.NumberDay\"\r\n ></extend-input-number>\r\n </div>\r\n\r\n @if (selectedStage.editorOption) {\r\n @if ([\"start\", \"node\", \"end\"].includes(selectedStage.StageType.toLowerCase())) {\r\n <extend-checkbox\r\n [label]=\"'Reverse'\"\r\n [labelSpan]=\"0\"\r\n [(_ngModel)]=\"selectedStage.editorOption.isReverse\"\r\n ></extend-checkbox>\r\n }\r\n\r\n <extend-checkbox\r\n [label]=\"'Require user action'\"\r\n [labelSpan]=\"0\"\r\n [(_ngModel)]=\"selectedStage.IsRequireUser\"\r\n ></extend-checkbox>\r\n }\r\n\r\n <box [height]=\"16\"></box>\r\n\r\n <div nz-row [nzGutter]=\"16\">\r\n <h3 nz-col><nz-icon nzType=\"send\" nzTheme=\"outline\" />&nbsp;List Action</h3>\r\n <div nz-col>\r\n <button nz-button nzType=\"primary\" nzSize=\"small\" (click)=\"addAction()\">\r\n <nz-icon nzType=\"plus\"></nz-icon>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <nz-table nzSize=\"small\" [nzData]=\"lstActionOfCurrentStage\" [nzShowPagination]=\"false\" [nzNoResult]=\"'&nbsp;'\">\r\n <thead>\r\n <tr [hidden]=\"true\">\r\n <th nzWidth=\"40px\"></th>\r\n <th></th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (action of lstActionOfCurrentStage; track $index) {\r\n <tr [class.text-bold]=\"action == hoverAction\" (click)=\"onclickaction(action)\">\r\n <td style=\"border-bottom: solid 1px orange\">\r\n ({{ $index + 1 }})\r\n <nz-icon\r\n nzType=\"delete\"\r\n nzTheme=\"outline\"\r\n class=\"color-warn cursor-pointer icon-size-16\"\r\n (click)=\"$event.stopPropagation(); deleteAction(action)\"\r\n ></nz-icon>\r\n </td>\r\n <td style=\"border-bottom: solid 1px orange\">\r\n <div nz-row [nzGutter]=\"16\" class=\"form-item-no-bottom\">\r\n <div nz-col [nzSpan]=\"8\">\r\n <nz-form-item>\r\n <nz-form-label [nzSpan]=\"24\" style=\"height: 32px\">Action status</nz-form-label>\r\n <nz-form-control [nzSpan]=\"24\">\r\n <nz-input-group class=\"full-width\">\r\n <input\r\n nz-input\r\n [(ngModel)]=\"action.ActionStatus\"\r\n [nzAutocomplete]=\"auto\"\r\n (ngModelChange)=\"nzAutocompletechange($event, template.lstActionStatus)\"\r\n (click)=\"lstActionStatusFiltered = template.lstActionStatus\"\r\n (keyup.enter)=\"onenterAotu(action.ActionStatus)\"\r\n (blur)=\"onenterAotu(action.ActionStatus)\"\r\n />\r\n <nz-autocomplete #auto [compareWith]=\"compareFun\">\r\n @for (option of lstActionStatusFiltered; track $index) {\r\n <nz-auto-option [nzValue]=\"option.Code\" [nzLabel]=\"option.Code\">\r\n {{ option.Code }}\r\n <icon-delete\r\n *ngIf=\"checkRemoveableActionStatus(option.Code)\"\r\n style=\"float: right\"\r\n [size]=\"12\"\r\n (click)=\"handleClose(option.Code)\"\r\n ></icon-delete>\r\n </nz-auto-option>\r\n }\r\n </nz-autocomplete>\r\n </nz-input-group>\r\n </nz-form-control>\r\n </nz-form-item>\r\n </div>\r\n\r\n <extend-input\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Action text'\"\r\n [floatingLabel]=\"true\"\r\n [(_ngModel)]=\"action.ActionText\"\r\n (_ngModelChange)=\"onchangeActionText(action)\"\r\n ></extend-input>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Action type'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"template.lstActionType\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"action.ActionType\"\r\n ></extend-select>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Stage status'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"template.lstStageStatus\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"action.StageStatus\"\r\n ></extend-select>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Next stage'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"getlstStage\"\r\n [valueField]=\"'WF_TemplateStage_Id'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"action.To_WF_TemplateStage_Id\"\r\n (_ngModelChange)=\"onchangeNextStage(action)\"\r\n ></extend-select>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Next stage status'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"template.lstStageStatus\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"action.To_StageStatus\"\r\n ></extend-select>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Process status'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"template.lstProcessStatus\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"action.DocProcessStatus\"\r\n ></extend-select>\r\n </div>\r\n <box [height]=\"8\"></box>\r\n <div nz-row>Role</div>\r\n <div nz-row>\r\n <extend-select\r\n nz-col\r\n nzSpan=\"24\"\r\n [size]=\"'small'\"\r\n [lstItem]=\"lstRole\"\r\n [valueField]=\"'App_Role_Id'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [multiple]=\"true\"\r\n [(_ngModel)]=\"action._lstRoleId\"\r\n (_ngModelChange)=\"onselectedRoleEmail(action)\"\r\n ></extend-select>\r\n </div>\r\n <box [height]=\"8\"></box>\r\n <div nz-row>Email action</div>\r\n <div nz-row>\r\n <extend-select\r\n nz-col\r\n nzSpan=\"24\"\r\n [size]=\"'small'\"\r\n [lstItem]=\"lstEmailAction\"\r\n [valueField]=\"'ID'\"\r\n [displayField]=\"'Name'\"\r\n [multiple]=\"true\"\r\n [(_ngModel)]=\"action._lstEmailActionId\"\r\n (_ngModelChange)=\"onselectedRoleEmail(action)\"\r\n ></extend-select>\r\n </div>\r\n <box [height]=\"8\"></box>\r\n <div *ngIf=\"action._lstEmailActionId && action._lstEmailActionId.length\" nz-row>Email template</div>\r\n <div *ngIf=\"action._lstEmailActionId && action._lstEmailActionId.length\" nz-row>\r\n <div nz-col nzSpan=\"1\"></div>\r\n <div nz-col nzSpan=\"23\" class=\"form-item-no-bottom\" style=\"font-weight: normal\">\r\n @for (actionRef of lstActionRefOf(action); track $index) {\r\n <div nz-row>\r\n <extend-select\r\n nz-col\r\n nzSpan=\"24\"\r\n [labelSpan]=\"12\"\r\n [size]=\"'small'\"\r\n [label]=\"emailActionText(actionRef.To_WF_TemplateStageAction_Id)\"\r\n [lstItem]=\"lstEmailTemplate\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"actionRef.TemplateMail\"\r\n ></extend-select>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n <box [height]=\"8\"></box>\r\n <div nz-row [nzGutter]=\"8\">\r\n Action rule\r\n <button nz-button nzType=\"text\" nzSize=\"small\" (click)=\"actionRuleModalVisible = true\">\r\n <nz-icon nzType=\"export\" nzTheme=\"outline\" class=\"color-primary\" />\r\n </button>\r\n <button\r\n *ngIf=\"action.WF_TransitionsRule_Id\"\r\n nz-button\r\n nzType=\"text\"\r\n nzSize=\"small\"\r\n (click)=\"deleteActionRule(action)\"\r\n >\r\n <nz-icon nzType=\"delete\" nzTheme=\"outline\" class=\"color-warn\" />\r\n </button>\r\n </div>\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </nz-table>\r\n\r\n <box [height]=\"16\"></box>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #footerTplNode>\r\n <div\r\n nz-flex\r\n [nzGap]=\"6\"\r\n [nzJustify]=\"\r\n selectedStage && selectedStage.editorOption && selectedStage.editorOption.drawerPosition == 'left'\r\n ? 'start'\r\n : 'end'\r\n \"\r\n >\r\n <button nz-button nzDanger nzDanger [nzLoading]=\"!ready\" (click)=\"save()\">Save</button>\r\n <button nz-button (click)=\"selectedStage = undefined\">Close</button>\r\n <button\r\n *ngIf=\"selectedStage && ['START', 'END'].indexOf(selectedStage.StageType) < 0\"\r\n nz-button\r\n nzDanger\r\n (click)=\"deleteStage()\"\r\n >\r\n Delete\r\n </button>\r\n </div>\r\n </ng-template>\r\n</nz-drawer>\r\n\r\n<!-- drawer ACTION -->\r\n<nz-drawer\r\n [nzTitle]=\"drawerTitleAction\"\r\n nzTitle=\"ACTION\"\r\n [nzPlacement]=\"selectedAction?.editorOption?.drawerPosition == 'left' ? 'left' : 'right'\"\r\n [nzClosable]=\"false\"\r\n [nzWidth]=\"750\"\r\n [nzVisible]=\"!!selectedAction\"\r\n [nzFooter]=\"footerTplAction\"\r\n (nzOnClose)=\"selectedAction = undefined\"\r\n>\r\n <ng-template #drawerTitleAction>\r\n <div nz-row nzJustify=\"space-between\">\r\n @if (selectedAction && selectedAction.editorOption) {\r\n @if (selectedAction.editorOption.drawerPosition == \"left\") {\r\n <button\r\n nz-button\r\n nzSize=\"small\"\r\n nz-tooltip=\"To the right\"\r\n (click)=\"selectedAction.editorOption.drawerPosition = 'right'\"\r\n >\r\n <nz-icon nzType=\"double-right\"></nz-icon>\r\n </button>\r\n ACTION\r\n } @else {\r\n ACTION\r\n <button\r\n nz-button\r\n nzSize=\"small\"\r\n nz-tooltip=\"To the left\"\r\n (click)=\"selectedAction.editorOption.drawerPosition = 'left'\"\r\n >\r\n <nz-icon nzType=\"double-left\"></nz-icon>\r\n </button>\r\n }\r\n }\r\n </div>\r\n </ng-template>\r\n <ng-container *nzDrawerContent>\r\n <ng-container *ngIf=\"selectedAction\">\r\n <div>\r\n <strong\r\n >{{ selectedAction.getFromStageCode(lstStage) }} -> {{ selectedAction.getToStageCode(lstStage) }}</strong\r\n >\r\n </div>\r\n <div>{{ selectedAction.getFromStageName(lstStage) }} -> {{ selectedAction.getToStageName(lstStage) }}</div>\r\n\r\n <box [height]=\"16\"></box>\r\n\r\n <div nz-row [nzGutter]=\"16\" class=\"form-item-no-bottom\">\r\n <div nz-col [nzSpan]=\"8\">\r\n <nz-form-item>\r\n <nz-form-label [nzSpan]=\"24\" style=\"height: 32px\">Action status</nz-form-label>\r\n <nz-form-control [nzSpan]=\"24\">\r\n <nz-input-group class=\"full-width\">\r\n <input\r\n nz-input\r\n [(ngModel)]=\"selectedAction.ActionStatus\"\r\n [nzAutocomplete]=\"auto\"\r\n (ngModelChange)=\"nzAutocompletechange($event, template.lstActionStatus)\"\r\n (click)=\"lstActionStatusFiltered = template.lstActionStatus\"\r\n (keyup.enter)=\"onenterAotu(selectedAction.ActionStatus)\"\r\n (blur)=\"onenterAotu(selectedAction.ActionStatus)\"\r\n />\r\n <nz-autocomplete #auto [compareWith]=\"compareFun\">\r\n @for (option of lstActionStatusFiltered; track $index) {\r\n <nz-auto-option [nzValue]=\"option.Code\" [nzLabel]=\"option.Code\">\r\n {{ option.Code }}\r\n <icon-delete\r\n *ngIf=\"checkRemoveableActionStatus(option.Code)\"\r\n style=\"float: right\"\r\n [size]=\"12\"\r\n (click)=\"handleClose(option.Code)\"\r\n ></icon-delete>\r\n </nz-auto-option>\r\n }\r\n </nz-autocomplete>\r\n </nz-input-group>\r\n </nz-form-control>\r\n </nz-form-item>\r\n </div>\r\n\r\n <extend-input\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Action text'\"\r\n [floatingLabel]=\"true\"\r\n [(_ngModel)]=\"selectedAction.ActionText\"\r\n (_ngModelChange)=\"onchangeActionText(selectedAction)\"\r\n ></extend-input>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Action type'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"template.lstActionType\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"selectedAction.ActionType\"\r\n ></extend-select>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Stage status'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"template.lstStageStatus\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"selectedAction.StageStatus\"\r\n ></extend-select>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Next stage'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"lstStage\"\r\n [valueField]=\"'WF_TemplateStage_Id'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"selectedAction.To_WF_TemplateStage_Id\"\r\n (_ngModelChange)=\"onchangeNextStage(selectedAction)\"\r\n ></extend-select>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Next stage status'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"template.lstStageStatus\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"selectedAction.To_StageStatus\"\r\n ></extend-select>\r\n </div>\r\n\r\n <!-- <box [height]=\"16\"></box> -->\r\n <nz-divider></nz-divider>\r\n\r\n @if (template.editorOption.AllowbackInUse) {\r\n <extend-checkbox\r\n [label]=\"'Allow back'\"\r\n [labelSpan]=\"0\"\r\n [(_ngModel)]=\"selectedAction.allowBack\"\r\n (_ngModelChange)=\"onchangeAllowBack(selectedAction)\"\r\n ></extend-checkbox>\r\n }\r\n\r\n <box [height]=\"16\"></box>\r\n\r\n @if (selectedAction.allowBack) {\r\n <div>\r\n <strong\r\n >{{ selectedAction.getToStageCode(lstStage) }} -> {{ selectedAction.getFromStageCode(lstStage) }}</strong\r\n >\r\n </div>\r\n <div>{{ selectedAction.getToStageName(lstStage) }} -> {{ selectedAction.getFromStageName(lstStage) }}</div>\r\n\r\n @if (selectedBackAction) {\r\n <div nz-row [nzGutter]=\"16\" class=\"form-item-no-bottom\">\r\n <div nz-col [nzSpan]=\"8\">\r\n <nz-form-item>\r\n <nz-form-label [nzSpan]=\"24\" style=\"height: 32px\">Action status</nz-form-label>\r\n <nz-form-control [nzSpan]=\"24\">\r\n <nz-input-group class=\"full-width\">\r\n <input\r\n nz-input\r\n [(ngModel)]=\"selectedBackAction.ActionStatus\"\r\n [nzAutocomplete]=\"auto\"\r\n (ngModelChange)=\"nzAutocompletechange($event, template.lstActionStatus)\"\r\n (click)=\"lstActionStatusFiltered = template.lstActionStatus\"\r\n (keyup.enter)=\"onenterAotu(selectedBackAction.ActionStatus)\"\r\n (blur)=\"onenterAotu(selectedBackAction.ActionStatus)\"\r\n />\r\n <nz-autocomplete #auto [compareWith]=\"compareFun\">\r\n @for (option of lstActionStatusFiltered; track $index) {\r\n <nz-auto-option [nzValue]=\"option.Code\" [nzLabel]=\"option.Code\">\r\n {{ option.Code }}\r\n <icon-delete\r\n *ngIf=\"checkRemoveableActionStatus(option.Code)\"\r\n style=\"float: right\"\r\n [size]=\"12\"\r\n (click)=\"handleClose(option.Code)\"\r\n ></icon-delete>\r\n </nz-auto-option>\r\n }\r\n </nz-autocomplete>\r\n </nz-input-group>\r\n </nz-form-control>\r\n </nz-form-item>\r\n </div>\r\n\r\n <extend-input\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Action text'\"\r\n [floatingLabel]=\"true\"\r\n [(_ngModel)]=\"selectedBackAction.ActionText\"\r\n (_ngModelChange)=\"onchangeActionText(selectedBackAction)\"\r\n ></extend-input>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Action type'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"template.lstActionType\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"selectedBackAction.ActionType\"\r\n ></extend-select>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Stage status'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"template.lstStageStatus\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"selectedBackAction.StageStatus\"\r\n ></extend-select>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Next stage'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"lstStage\"\r\n [valueField]=\"'WF_TemplateStage_Id'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"selectedBackAction.To_WF_TemplateStage_Id\"\r\n (_ngModelChange)=\"onchangeNextStage(selectedBackAction)\"\r\n ></extend-select>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Next stage status'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"template.lstStageStatus\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"selectedBackAction.To_StageStatus\"\r\n ></extend-select>\r\n </div>\r\n }\r\n }\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #footerTplAction>\r\n <div\r\n nz-flex\r\n [nzGap]=\"6\"\r\n [nzJustify]=\"selectedAction && selectedAction.editorOption.drawerPosition == 'left' ? 'start' : 'end'\"\r\n >\r\n <button nz-button nzDanger nzDanger [nzLoading]=\"!ready\" (click)=\"save()\">Save</button>\r\n <button nz-button nzDanger (click)=\"deleteAction(selectedAction!)\">Delete</button>\r\n <button nz-button (click)=\"selectedAction = undefined\">Close</button>\r\n </div>\r\n </ng-template>\r\n</nz-drawer>\r\n\r\n<!-- setting editor -->\r\n<nz-drawer\r\n [nzTitle]=\"drawSettingTitle\"\r\n nzPlacement=\"right\"\r\n [nzClosable]=\"false\"\r\n [nzVisible]=\"settingVisible\"\r\n (nzOnClose)=\"settingVisible = false\"\r\n>\r\n <ng-template #drawSettingTitle> <nz-icon nzType=\"setting\"></nz-icon> &nbsp; Editor </ng-template>\r\n <ng-container *nzDrawerContent>\r\n <div class=\"form-item-no-bottom\">\r\n <extend-checkbox [label]=\"'Show grid'\" [labelSpan]=\"0\" [(_ngModel)]=\"wfcSetting.ShowGrid\"></extend-checkbox>\r\n\r\n <box [height]=\"16\"></box>\r\n </div>\r\n </ng-container>\r\n</nz-drawer>\r\n\r\n<!-- editor infomation -->\r\n<nz-drawer\r\n [nzTitle]=\"drawInfoTitle\"\r\n nzPlacement=\"right\"\r\n [nzClosable]=\"false\"\r\n [nzVisible]=\"infoVisible\"\r\n (nzOnClose)=\"infoVisible = false\"\r\n>\r\n <ng-template #drawInfoTitle> <nz-icon nzType=\"info-circle\"></nz-icon> &nbsp; Infomation </ng-template>\r\n <ng-container *nzDrawerContent>\r\n <p>1. C\u00E1c th\u00E0nh ph\u1EA7n: Stage or Node (stag, node quy tr\u00ECnh), Action or Connector (\u0111\u01B0\u1EDDng n\u1ED1i gi\u1EEFa c\u00E1c stage)</p>\r\n <p>2. Save \u0111\u1EC3 load c\u00E1c th\u00F4ng tin: Stage status, Action type</p>\r\n <p>\r\n 3. N\u1ED1i 2 node (t\u1EA1o connector t\u01B0\u01A1ng \u0111\u01B0\u01A1ng t\u1EA1o action):\r\n <br />- Click ch\u1EA5m cam t\u1EEB Node ngu\u1ED3n \u0111\u1EBFn ch\u1EA5m xanh c\u1EE7a Node \u0111\u00EDch (ho\u1EB7c click v\u00E0o Node \u0111\u00EDch), c\u00F3 th\u1EC3 click th\u00E0nh\r\n nhi\u1EC1u \u0111i\u1EC3m \u0111\u1EC3 t\u1EA1o \u0111\u01B0\u1EDDng n\u1ED1i cong<br />- Khi hover connector chuy\u1EC3n sang m\u1EA7u \u0111\u1ECF c\u00F3 th\u1EC3 click \u0111\u00FAp \u0111\u1EC3 th\u00EAm m\u1ED9t \u0111i\u1EC3m\r\n c\u1EE7a connector<br />- Khi hover l\u00EAn \u0111i\u1EC3m c\u1EE7a connector c\u00F3 th\u1EC3 di chuy\u1EC3n \u0111i\u1EC3m \u0111\u00F3 b\u1EB1ng c\u00E1ch nh\u1EA5n gi\u1EEF chu\u1ED9t v\u00E0 k\u00E9o th\u1EA3\r\n \u0111\u1EBFn v\u1ECB tr\u00ED m\u1EDBi<br />- Chu\u1ED9t ph\u1EA3i v\u00E0o \u0111i\u1EC3m n\u1ED1i connector \u0111\u1EC3 xo\u00E1 \u0111i\u1EC3m \u0111\u00F3\r\n </p>\r\n </ng-container>\r\n</nz-drawer>\r\n\r\n<!-- action rule modal -->\r\n<nz-modal\r\n [(nzVisible)]=\"actionRuleModalVisible\"\r\n [nzMaskClosable]=\"false\"\r\n [nzClosable]=\"false\"\r\n [nzKeyboard]=\"true\"\r\n [nzWidth]=\"'50vw'\"\r\n>\r\n <ng-container *nzModalTitle>\r\n ACTION RULE: [{{ selectedStage?.Code }}] {{ selectedStage?.Name }} > [{{ hoverAction?.ActionStatus }}]\r\n {{ hoverAction?.ActionText }}\r\n </ng-container>\r\n <ng-container *nzModalContent>\r\n @if (hoverAction && hoverAction.actionRule) {\r\n <div nz-row [nzGutter]=\"32\">\r\n <extend-input nz-col nzSpan=\"12\" [label]=\"'Code'\" [(_ngModel)]=\"hoverAction.actionRule.Code\"></extend-input>\r\n <extend-input nz-col nzSpan=\"12\" [label]=\"'Name'\" [(_ngModel)]=\"hoverAction.actionRule.Name\"></extend-input>\r\n <extend-input nz-col nzSpan=\"12\" [label]=\"'Note'\" [(_ngModel)]=\"hoverAction.actionRule.Note\"></extend-input>\r\n <extend-checkbox\r\n nz-col\r\n nzSpan=\"12\"\r\n [label]=\"'IsActive'\"\r\n [(_ngModel)]=\"hoverAction.actionRule.IsActive\"\r\n ></extend-checkbox>\r\n </div>\r\n <div nz-row [nzGutter]=\"16\">\r\n <div nz-col nzSpan=\"24\">\r\n <nz-table nzSize=\"small\" [nzData]=\"hoverAction.actionRule.lstLine\" [nzShowPagination]=\"false\">\r\n <thead>\r\n <tr>\r\n <th [nzWidth]=\"'50px'\"><icon-add (click)=\"addActionRuleLine()\"></icon-add></th>\r\n <th [nzWidth]=\"'25%'\">Template</th>\r\n <th [nzWidth]=\"'25%'\">Template stage</th>\r\n <th [nzWidth]=\"'25%'\">Template action</th>\r\n <th [nzWidth]=\"'50px'\">IsActive</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (item of hoverAction.actionRule.lstLine; track $index) {\r\n <tr>\r\n <td><icon-delete (click)=\"deleteActionRuleLine(hoverAction.actionRule, item)\"></icon-delete></td>\r\n <td>\r\n <extend-select\r\n #xxx\r\n [size]=\"'small'\"\r\n [lstItem]=\"lstTemplateForRule(item)\"\r\n [valueField]=\"'WF_Template_Id'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"item.WF_Template_Id\"\r\n (_ngModelChange)=\"item.WF_TemplateStage_Id = 0; item.WF_TemplateStageAction_Id = 0\"\r\n ></extend-select>\r\n </td>\r\n <td>\r\n <extend-select\r\n #yyy\r\n [size]=\"'small'\"\r\n [lstItem]=\"lstStageForRule(xxx._ngModel)\"\r\n [valueField]=\"'WF_TemplateStage_Id'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"item.WF_TemplateStage_Id\"\r\n (_ngModelChange)=\"item.WF_TemplateStageAction_Id = 0\"\r\n ></extend-select>\r\n </td>\r\n <td>\r\n <extend-select\r\n [size]=\"'small'\"\r\n [lstItem]=\"lstActionForRule(yyy._ngModel)\"\r\n [valueField]=\"'WF_TemplateStageAction_Id'\"\r\n [displayFields]=\"['ActionStatus', 'ActionText']\"\r\n [(_ngModel)]=\"item.WF_TemplateStageAction_Id\"\r\n ></extend-select>\r\n </td>\r\n <td class=\"text-center\">\r\n <extend-checkbox [(_ngModel)]=\"item.IsActive\"></extend-checkbox>\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </nz-table>\r\n </div>\r\n </div>\r\n }\r\n </ng-container>\r\n <ng-container *nzModalFooter>\r\n <button nz-button nzType=\"primary\" (click)=\"actionRuleModalVisible = false\">OK</button>\r\n </ng-container>\r\n</nz-modal>\r\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%}.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}.zoom-toolbar{position:absolute;top:8px;left:8px;z-index:10;display:flex;align-items:center;gap:6px;background:#fff;padding:4px 6px;border-radius:6px;box-shadow:0 2px 6px #00000026}.zoom-toolbar span{min-width:40px;text-align:center;font-size:12px}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{position:fixed;width:180px;height:125px;top:60px;right:15px;background-color:#eee;border:1px solid #aaa;opacity:.9;z-index:1}::ng-deep .minimap-node{position:absolute;background-color:#607a86}::ng-deep .minimap-node-round{position:absolute;background-color:#607a86;border-radius:10px}::ng-deep .minimap-node-round-start{background-color:green}::ng-deep .minimap-node-round-end{background-color:#000}::ng-deep .minimap-viewport{position:absolute;box-sizing:border-box;background-color:#4f6f7e66;z-index:1;cursor:move}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: NzCardModule }, { kind: "component", type: i3$2.NzCardComponent, selector: "nz-card", inputs: ["nzBordered", "nzLoading", "nzHoverable", "nzBodyStyle", "nzCover", "nzActions", "nzType", "nzSize", "nzTitle", "nzExtra"], exportAs: ["nzCard"] }, { kind: "ngmodule", type: NzDrawerModule }, { kind: "component", type: i4$1.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: i4$1.NzDrawerContentDirective, selector: "[nzDrawerContent]", exportAs: ["nzDrawerContent"] }, { kind: "ngmodule", type: NzTagModule }, { kind: "component", type: i5$2.NzTagComponent, selector: "nz-tag", inputs: ["nzMode", "nzColor", "nzChecked", "nzBordered"], outputs: ["nzOnClose", "nzCheckedChange"], exportAs: ["nzTag"] }, { kind: "ngmodule", type: NzRadioModule }, { kind: "component", type: i6$4.NzRadioComponent, selector: "[nz-radio],[nz-radio-button]", inputs: ["nzValue", "nzDisabled", "nzAutoFocus", "nz-radio-button"], exportAs: ["nzRadio"] }, { kind: "component", type: i6$4.NzRadioGroupComponent, selector: "nz-radio-group", inputs: ["nzDisabled", "nzButtonStyle", "nzSize", "nzName"], exportAs: ["nzRadioGroup"] }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.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: i5$3.NzButtonComponent, selector: "button[nz-button], a[nz-button]", inputs: ["nzBlock", "nzGhost", "nzSearch", "nzLoading", "nzDanger", "disabled", "tabIndex", "nzType", "nzShape", "nzSize"], exportAs: ["nzButton"] }, { kind: "directive", type: i6$3.ɵ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: i7.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "ngmodule", type: NzToolTipModule }, { kind: "directive", type: i11.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", "allowClear", "disabled", "readOnly", "required", "noBottom", "selectModeType", "autocomplete", "autofocus", "inputWidth", "inputHeight", "borderBottomOnly", "displayInline", "size", "lstItem", "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", "valueField", "formData", "controlName", "_ngModel", "isSubmited"], outputs: ["_ngModelChange", "itemChange", "onFocus"] }, { kind: "component", type: ExtendCheckbox, selector: "extend-checkbox", inputs: ["label", "labelSpan", "labelFlex", "disabled", "formData", "controlName", "valueType", "_ngModel"], outputs: ["_ngModelChange"] }, { kind: "component", type: ExtendTextArea, selector: "extend-textarea", inputs: ["label", "placeHolder", "labelAlign", "floatingLabel", "displayInline", "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: "directive", type: i6$1.NzInputDirective, selector: "input[nz-input],textarea[nz-input]", inputs: ["nzBorderless", "nzSize", "nzStepperless", "nzStatus", "disabled"], exportAs: ["nzInput"] }, { kind: "component", type: i6$1.NzInputGroupComponent, selector: "nz-input-group", inputs: ["nzAddOnBeforeIcon", "nzAddOnAfterIcon", "nzPrefixIcon", "nzSuffixIcon", "nzAddOnBefore", "nzAddOnAfter", "nzPrefix", "nzStatus", "nzSuffix", "nzSize", "nzSearch", "nzCompact"], exportAs: ["nzInputGroup"] }, { kind: "ngmodule", type: NzGridModule }, { kind: "directive", type: i4.NzColDirective, selector: "[nz-col],nz-col,nz-form-control,nz-form-label", inputs: ["nzFlex", "nzSpan", "nzOrder", "nzOffset", "nzPush", "nzPull", "nzXs", "nzSm", "nzMd", "nzLg", "nzXl", "nzXXl"], exportAs: ["nzCol"] }, { kind: "directive", type: i4.NzRowDirective, selector: "[nz-row],nz-row,nz-form-item", inputs: ["nzAlign", "nzJustify", "nzGutter"], exportAs: ["nzRow"] }, { kind: "ngmodule", type: NzFlexModule }, { kind: "directive", type: i9.NzFlexDirective, selector: "[nz-flex],nz-flex", inputs: ["nzVertical", "nzJustify", "nzAlign", "nzGap", "nzWrap", "nzFlex"], exportAs: ["nzFlex"] }, { kind: "component", type: ExtendInputNumber, selector: "extend-input-number", inputs: ["label", "placeHolder", "labelAlign", "floatingLabel", "hiddenUpDown", "labelSpan", "labelFlex", "inputFlex", "disabled", "required", "noBottom", "size", "min", "max", "precision", "inputWidth", "inputHeight", "borderBottomOnly", "displayInline", "isSubmited", "separatorType", "formData", "controlName", "_ngModel"], outputs: ["_ngModelChange"] }, { kind: "ngmodule", type: NzTableModule }, { kind: "component", type: i1$5.NzTableComponent, selector: "nz-table", inputs: ["nzTableLayout", "nzShowTotal", "nzItemRender", "nzTitle", "nzFooter", "nzNoResult", "nzPageSizeOptions", "nzVirtualItemSize", "nzVirtualMaxBufferPx", "nzVirtualMinBufferPx", "nzVirtualForTrackBy", "nzLoadingDelay", "nzPageIndex", "nzPageSize", "nzTotal", "nzWidthConfig", "nzData", "nzCustomColumn", "nzPaginationPosition", "nzScroll", "noDataVirtualHeight", "nzPaginationType", "nzFrontPagination", "nzTemplateMode", "nzShowPagination", "nzLoading", "nzOuterBordered", "nzLoadingIndicator", "nzBordered", "nzSize", "nzShowSizeChanger", "nzHideOnSinglePage", "nzShowQuickJumper", "nzSimple"], outputs: ["nzPageSizeChange", "nzPageIndexChange", "nzQueryParams", "nzCurrentPageDataChange", "nzCustomColumnChange"], exportAs: ["nzTable"] }, { kind: "directive", type: i1$5.NzTableCellDirective, selector: "th:not(.nz-disable-th):not([mat-cell]), td:not(.nz-disable-td):not([mat-cell])" }, { kind: "directive", type: i1$5.NzThMeasureDirective, selector: "th", inputs: ["nzWidth", "colspan", "colSpan", "rowspan", "rowSpan"] }, { kind: "component", type: i1$5.NzTheadComponent, selector: "thead:not(.ant-table-thead)", outputs: ["nzSortOrderChange"] }, { kind: "component", type: i1$5.NzTbodyComponent, selector: "tbody" }, { kind: "directive", type: i1$5.NzTrDirective, selector: "tr:not([mat-row]):not([mat-header-row]):not([nz-table-measure-row]):not([nzExpand]):not([nz-table-fixed-row])" }, { kind: "ngmodule", type: NzDividerModule }, { kind: "component", type: i8.NzDividerComponent, selector: "nz-divider", inputs: ["nzText", "nzType", "nzOrientation", "nzVariant", "nzDashed", "nzPlain"], exportAs: ["nzDivider"] }, { kind: "directive", type: AutoFocusDirective, selector: "[appAutoFocus]", inputs: ["appAutoFocus"] }, { kind: "ngmodule", type: NzAutocompleteModule }, { kind: "component", type: i17.NzAutocompleteComponent, selector: "nz-autocomplete", inputs: ["nzWidth", "nzOverlayClassName", "nzOverlayStyle", "nzDefaultActiveFirstOption", "nzBackfill", "compareWith", "nzDataSource"], outputs: ["selectionChange"], exportAs: ["nzAutocomplete"] }, { kind: "component", type: i17.NzAutocompleteOptionComponent, selector: "nz-auto-option", inputs: ["nzValue", "nzLabel", "nzDisabled"], outputs: ["selectionChange", "mouseEntered"], exportAs: ["nzAutoOption"] }, { kind: "directive", type: i17.NzAutocompleteTriggerDirective, selector: "input[nzAutocomplete], textarea[nzAutocomplete]", inputs: ["nzAutocomplete"], exportAs: ["nzAutocompleteTrigger"] }, { kind: "component", type: IconDelete, selector: "icon-delete", inputs: ["size"], outputs: ["click"] }, { 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: "directive", type: NzModalTitleDirective, selector: "[nzModalTitle]", exportAs: ["nzModalTitle"] }, { kind: "component", type: IconAdd, selector: "icon-add", inputs: ["size"], outputs: ["click"] }, { kind: "directive", type: NzModalFooterDirective, selector: "[nzModalFooter]", exportAs: ["nzModalFooter"] }] });
6348
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.7", type: WorkflowEditorComponent, isStandalone: true, selector: "app-workflow-editor", inputs: { lstOrg: "lstOrg", lstRole: "lstRole", lstEmailTemplate: "lstEmailTemplate" }, outputs: { onSave: "onSave", onDeleteStage: "onDeleteStage", onDeleteAction: "onDeleteAction", onDeleteRule: "onDeleteRule", onDeleteRuleLine: "onDeleteRuleLine" }, 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: "inputStageStatusElement", first: true, predicate: ["inputStageStatusElement"], descendants: true }, { propertyName: "inputActionTypeElement", first: true, predicate: ["inputActionTypeElement"], descendants: true }, { propertyName: "inputElement", first: true, predicate: ["inputElement"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div\r\n #canvasRef\r\n class=\"workflow-canvas\"\r\n [class.connecting]=\"!!connectingFrom\"\r\n [class.dragging-point]=\"!!draggingPoint\"\r\n [style.width.px]=\"getCanvasWidth()\"\r\n [style.height.px]=\"getCanvasHeight()\"\r\n (mousedown)=\"onMouseDownCanvas($event)\"\r\n (mousemove)=\"onMouseMoveCanvas($event)\"\r\n (mouseup)=\"onMouseUpCanvas($event)\"\r\n (click)=\"onClickCanvas($event)\"\r\n>\r\n <!-- \r\n\r\n [style.width.px]=\"getCanvasWidth()\"\r\n [style.height.px]=\"getCanvasHeight()\" \r\n\r\n [style.width.px]=\"CANVAS_WIDTH\"\r\n [style.height.px]=\"CANVAS_HEIGHT\"\r\n\r\n style=\"width: 100%; height: calc(100vh - 120px)\"\r\n \r\n -->\r\n\r\n <div class=\"toolbar\" (mousedown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\">\r\n <button nz-button nzSize=\"small\" nz-tooltip=\"Editor setting\" (click)=\"settingVisible = true\">\r\n <nz-icon nzType=\"setting\"></nz-icon>\r\n </button>\r\n\r\n <button nz-button nzSize=\"small\" nz-tooltip=\"Infomation\" (click)=\"infoVisible = true\">\r\n <nz-icon nzType=\"info-circle\"></nz-icon>\r\n </button>\r\n\r\n <box [width]=\"1\"></box>\r\n <span class=\"divider\"></span>\r\n <box [width]=\"1\"></box>\r\n\r\n <button nz-button nzSize=\"small\" nz-tooltip=\"Template setting\" (click)=\"drawTemplateVisibel = true\">\r\n <nz-icon nzType=\"setting\"></nz-icon> T\r\n </button>\r\n\r\n <box [width]=\"1\"></box>\r\n <span class=\"divider\"></span>\r\n <box [width]=\"1\"></box>\r\n\r\n <button nz-button nzSize=\"small\" nzDanger [nzLoading]=\"!ready\" nz-tooltip=\"Save (Ctrl + S)\" (click)=\"save()\">\r\n <nz-icon nzType=\"save\"></nz-icon>\r\n </button>\r\n <button nz-button nzSize=\"small\" nz-tooltip=\"Add stage\" (click)=\"addStage()\">\r\n <nz-icon nzType=\"plus\" class=\"color-primary\"></nz-icon>\r\n </button>\r\n\r\n <box [width]=\"1\"></box>\r\n <span class=\"divider\"></span>\r\n <box [width]=\"1\"></box>\r\n\r\n <button\r\n nz-button\r\n nzSize=\"small\"\r\n [nzType]=\"isMoveMode ? 'primary' : 'default'\"\r\n nz-tooltip=\"Move mode\"\r\n (click)=\"isMoveMode = true\"\r\n >\r\n <nz-icon><img src=\"/assets/icon/hand-palm.png\" width=\"19\" height=\"19\" /></nz-icon>\r\n </button>\r\n <button\r\n nz-button\r\n nzSize=\"small\"\r\n [nzType]=\"!isMoveMode ? 'primary' : 'default'\"\r\n nz-tooltip=\"Select mode\"\r\n (click)=\"isMoveMode = false\"\r\n >\r\n <nz-icon><img src=\"/assets/icon/cursor.png\" width=\"19\" height=\"19\" /></nz-icon>\r\n </button>\r\n\r\n <box [width]=\"1\"></box>\r\n <span class=\"divider\"></span>\r\n <box [width]=\"1\"></box>\r\n\r\n <!-- UNDO / REDO -->\r\n <button\r\n nz-button\r\n nzSize=\"small\"\r\n nzType=\"default\"\r\n [disabled]=\"undoStack.length === 0\"\r\n nz-tooltip=\"Undo\"\r\n (click)=\"undo()\"\r\n >\r\n <nz-icon nzType=\"undo\"></nz-icon>\r\n </button>\r\n\r\n <button\r\n nz-button\r\n nzSize=\"small\"\r\n nzType=\"default\"\r\n [disabled]=\"redoStack.length === 0\"\r\n nz-tooltip=\"Redo\"\r\n (click)=\"redo()\"\r\n >\r\n <nz-icon nzType=\"redo\"></nz-icon>\r\n </button>\r\n\r\n <box [width]=\"1\"></box>\r\n <span class=\"divider\"></span>\r\n <box [width]=\"1\"></box>\r\n\r\n <!-- ALIGN -->\r\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedStageId.size < 2\" (click)=\"alignLeft()\">\u27F8</button>\r\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedStageId.size < 2\" (click)=\"alignCenter()\">\u2261</button>\r\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedStageId.size < 2\" (click)=\"alignRight()\">\u27F9</button>\r\n\r\n <span class=\"divider\"></span>\r\n\r\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedStageId.size < 2\" (click)=\"alignTop()\">\u21D1</button>\r\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedStageId.size < 2\" (click)=\"alignMiddle()\">\u2550</button>\r\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedStageId.size < 2\" (click)=\"alignBottom()\">\u21D3</button>\r\n\r\n <span class=\"divider\"></span>\r\n\r\n <!-- DISTRIBUTE -->\r\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedStageId.size < 3\" (click)=\"distributeHorizontal()\">\r\n \u21C4\r\n </button>\r\n <button nz-button nzSize=\"small\" [disabled]=\"lstSelectedStageId.size < 3\" (click)=\"distributeVertical()\">\u21C5</button>\r\n </div>\r\n\r\n <div\r\n class=\"canvas-content\"\r\n [class.panning]=\"isMoveMode\"\r\n [style.transform]=\"'translate(' + template.editorOption.panX + 'px,' + template.editorOption.panY + 'px)'\"\r\n >\r\n <!-- GRID -->\r\n <div *ngIf=\"wfcSetting.ShowGrid\" class=\"grid-layer\"></div>\r\n\r\n <!-- <div class=\"zoom-toolbar\">\r\n <button nz-button nzSize=\"small\" (click)=\"zoomOut()\">\u2212</button>\r\n <span>{{ zoom * 100 | number: \"1.0-0\" }}%</span>\r\n <button nz-button nzSize=\"small\" (click)=\"zoomIn()\">+</button>\r\n </div> -->\r\n\r\n <!-- SVG EDGES -->\r\n <svg #svg class=\"edges-layer\" width=\"100%\" height=\"100%\" preserveAspectRatio=\"none\">\r\n <g [attr.transform]=\"svgTransform\">\r\n <!-- DEFS -->\r\n <defs>\r\n <!-- glow effect -->\r\n <filter id=\"edge-glow\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\r\n <feGaussianBlur stdDeviation=\"2\" result=\"blur\" />\r\n <feMerge>\r\n <feMergeNode in=\"blur\" />\r\n <feMergeNode in=\"SourceGraphic\" />\r\n </feMerge>\r\n </filter>\r\n\r\n <!-- arrow markers -->\r\n <marker\r\n id=\"arrow-blue\"\r\n markerWidth=\"10\"\r\n markerHeight=\"10\"\r\n refX=\"10\"\r\n refY=\"5\"\r\n orient=\"auto\"\r\n markerUnits=\"strokeWidth\"\r\n >\r\n <path class=\"blue\" d=\"M0,0 L10,5 L0,10\"></path>\r\n </marker>\r\n\r\n <marker\r\n id=\"arrow-red\"\r\n markerWidth=\"10\"\r\n markerHeight=\"10\"\r\n refX=\"10\"\r\n refY=\"5\"\r\n orient=\"auto\"\r\n markerUnits=\"strokeWidth\"\r\n >\r\n <path class=\"red\" d=\"M0,0 L10,5 L0,10\"></path>\r\n </marker>\r\n\r\n <marker\r\n id=\"arrow-blue-start\"\r\n markerWidth=\"10\"\r\n markerHeight=\"10\"\r\n viewBox=\"0 0 10 10\"\r\n refX=\"0\"\r\n refY=\"5\"\r\n orient=\"auto\"\r\n markerUnits=\"strokeWidth\"\r\n >\r\n <path class=\"blue\" d=\"M10,0 L0,5 L10,10\"></path>\r\n </marker>\r\n\r\n <marker\r\n id=\"arrow-red-start\"\r\n markerWidth=\"10\"\r\n markerHeight=\"10\"\r\n viewBox=\"0 0 10 10\"\r\n refX=\"0\"\r\n refY=\"5\"\r\n orient=\"auto\"\r\n markerUnits=\"strokeWidth\"\r\n >\r\n <path class=\"red\" d=\"M10,0 L0,5 L10,10\"></path>\r\n </marker>\r\n </defs>\r\n\r\n <!-- EDGES B\u00CCNH TH\u01AF\u1EDCNG -->\r\n <ng-container *ngFor=\"let e of normalEdges; let i = index\">\r\n <path\r\n class=\"edge\"\r\n [attr.id]=\"'edge-path-' + i\"\r\n [attr.d]=\"buildPath(e)\"\r\n marker-end=\"url(#arrow-blue)\"\r\n [attr.marker-start]=\"e.allowBack ? 'url(#arrow-blue-start)' : ''\"\r\n ></path>\r\n\r\n <path\r\n class=\"edge-hit\"\r\n [attr.d]=\"buildPath(e)\"\r\n (mouseenter)=\"onMouseEnterEdge(e)\"\r\n (mouseleave)=\"onMouseLeaveEdge(e)\"\r\n (click)=\"onClickEdge(e, $event)\"\r\n ></path>\r\n\r\n <!-- LABEL -->\r\n <!-- text b\u00E1m theo line -->\r\n <!-- \r\n <text *ngIf=\"e.ActionText\" class=\"edge-label\" dy=\"-6\">\r\n <textPath [attr.href]=\"'#edge-path-' + i\" startOffset=\"50%\" text-anchor=\"middle\">\r\n {{ e.ActionText }}\r\n </textPath>\r\n </text> \r\n \r\n <text *ngIf=\"e.allowBack && e.labelBack\" class=\"edge-label\" dy=\"14\">\r\n <textPath [attr.href]=\"'#edge-path-' + i\" startOffset=\"50%\" text-anchor=\"middle\">\r\n {{ e.labelBack }}\r\n </textPath>\r\n </text>\r\n -->\r\n\r\n <!-- text th\u1EB3ng n\u1EB1m ngang -->\r\n <text\r\n *ngIf=\"e.ActionText\"\r\n class=\"edge-label\"\r\n [attr.x]=\"getEdgeLabelPosition(e).x\"\r\n [attr.y]=\"getEdgeLabelPosition(e).y - 8\"\r\n [attr.text-anchor]=\"'middle'\"\r\n >\r\n {{ e.ActionText }}\r\n </text>\r\n\r\n <text\r\n *ngIf=\"e.allowBack && e.labelBack\"\r\n class=\"edge-label\"\r\n [attr.x]=\"getEdgeLabelPosition(e).x\"\r\n [attr.y]=\"getEdgeLabelPosition(e).y + 14\"\r\n [attr.text-anchor]=\"'middle'\"\r\n >\r\n {{ e.labelBack }}\r\n </text>\r\n </ng-container>\r\n\r\n <!-- EDGE \u0110ANG HOVER (LU\u00D4N TR\u00CAN C\u00D9NG) -->\r\n <ng-container *ngFor=\"let e of hoverEdges; let i = index\">\r\n <path\r\n class=\"edge red\"\r\n [attr.id]=\"'edge-path-hover-' + i\"\r\n [attr.d]=\"buildPath(e)\"\r\n marker-end=\"url(#arrow-red)\"\r\n [attr.marker-start]=\"e.allowBack ? 'url(#arrow-red-start)' : ''\"\r\n ></path>\r\n\r\n <path\r\n class=\"edge-hit\"\r\n [attr.d]=\"buildPath(e)\"\r\n (mouseleave)=\"onMouseLeaveEdge(e)\"\r\n (click)=\"onClickEdge(e, $event)\"\r\n ></path>\r\n\r\n <!-- LABEL -->\r\n <!-- <text *ngIf=\"e.ActionText\" class=\"edge-label\" dy=\"-6\">\r\n <textPath [attr.href]=\"'#edge-path-hover-' + i\" startOffset=\"50%\" text-anchor=\"middle\">\r\n {{ e.ActionText }}\r\n </textPath>\r\n </text>\r\n\r\n <text *ngIf=\"e.allowBack && e.labelBack\" class=\"edge-label\" dy=\"14\">\r\n <textPath [attr.href]=\"'#edge-path-hover-' + i\" startOffset=\"50%\" text-anchor=\"middle\">\r\n {{ e.labelBack }}\r\n </textPath>\r\n </text> -->\r\n\r\n <text\r\n *ngIf=\"e.ActionText\"\r\n class=\"edge-label\"\r\n [attr.x]=\"getEdgeLabelPosition(e).x\"\r\n [attr.y]=\"getEdgeLabelPosition(e).y - 8\"\r\n [attr.text-anchor]=\"'middle'\"\r\n >\r\n {{ e.ActionText }}\r\n </text>\r\n\r\n <text\r\n *ngIf=\"e.allowBack && e.labelBack\"\r\n class=\"edge-label\"\r\n [attr.x]=\"getEdgeLabelPosition(e).x\"\r\n [attr.y]=\"getEdgeLabelPosition(e).y + 14\"\r\n [attr.text-anchor]=\"'middle'\"\r\n >\r\n {{ e.labelBack }}\r\n </text>\r\n </ng-container>\r\n\r\n <!-- preview -->\r\n <path\r\n *ngIf=\"connectingFrom\"\r\n class=\"edge\"\r\n [attr.d]=\"buildPreviewPath()\"\r\n stroke-dasharray=\"5,5\"\r\n marker-end=\"url(#arrow-blue)\"\r\n ></path>\r\n </g>\r\n </svg>\r\n\r\n <div\r\n *ngIf=\"isSelecting && selectStart && selectEnd\"\r\n class=\"selection-box\"\r\n [style.left.px]=\"Math.min(selectStart.x, selectEnd.x)\"\r\n [style.top.px]=\"Math.min(selectStart.y, selectEnd.y)\"\r\n [style.width.px]=\"Math.abs(selectEnd.x - selectStart.x)\"\r\n [style.height.px]=\"Math.abs(selectEnd.y - selectStart.y)\"\r\n ></div>\r\n\r\n <!-- lstStage -->\r\n @for (n of lstStage; track $index) {\r\n <!-- START NODE -->\r\n @if (n.StageType === \"_start_\") {\r\n <nz-card\r\n class=\"workflow-node workflow-node-start\"\r\n [attr.data-id]=\"n.Code\"\r\n [class.selected]=\"n == selectedStage || n == hoverStage || lstSelectedStageId.has(n.WF_TemplateStage_Id)\"\r\n [style.left.px]=\"n.editorOption.x\"\r\n [style.top.px]=\"n.editorOption.y\"\r\n [class.connecting-source]=\"isConnectingFrom(n) || isDraggingFrom(n) || isSelectedNode(n)\"\r\n nzSize=\"small\"\r\n (mousedown)=\"onMouseDownNode($event, n)\"\r\n (click)=\"$event.stopPropagation(); onClickStage(n)\"\r\n >\r\n <nz-tag [nzColor]=\"'green'\"> START </nz-tag>\r\n\r\n @if (!n.editorOption.isReverse) {\r\n <!-- connector RIGHT: output -->\r\n <div class=\"connector connector-right connector-start\" (click)=\"onClickConnector($event, n, 'right')\"></div>\r\n } @else {\r\n <div\r\n class=\"connector connector-right connector-start reverse\"\r\n (click)=\"onClickConnector($event, n, 'right')\"\r\n ></div>\r\n }\r\n </nz-card>\r\n }\r\n <!-- END NODE -->\r\n @else if (n.StageType === \"_end_\") {\r\n <nz-card\r\n class=\"workflow-node workflow-node-end\"\r\n [attr.data-id]=\"n.Code\"\r\n [class.selected]=\"n == selectedStage || n == hoverStage || lstSelectedStageId.has(n.WF_TemplateStage_Id)\"\r\n [style.left.px]=\"n.editorOption.x\"\r\n [style.top.px]=\"n.editorOption.y\"\r\n [class.connecting-source]=\"isConnectingFrom(n) || isDraggingFrom(n) || isSelectedNode(n)\"\r\n nzSize=\"small\"\r\n (mousedown)=\"onMouseDownNode($event, n)\"\r\n (click)=\"$event.stopPropagation(); onClickStage(n)\"\r\n >\r\n <nz-tag [nzColor]=\"'red'\"> END </nz-tag>\r\n\r\n @if (!n.editorOption.isReverse) {\r\n <!-- connector LEFT: input -->\r\n <div class=\"connector connector-left connector-end\" (click)=\"onClickConnector($event, n, 'left')\"></div>\r\n } @else {\r\n <div\r\n class=\"connector connector-left connector-end reverse\"\r\n (click)=\"onClickConnector($event, n, 'left')\"\r\n ></div>\r\n }\r\n </nz-card>\r\n } @else {\r\n <nz-card\r\n class=\"workflow-node\"\r\n [attr.data-id]=\"n.Code\"\r\n [class.selected]=\"n == selectedStage || n == hoverStage || lstSelectedStageId.has(n.WF_TemplateStage_Id)\"\r\n [style.left.px]=\"n.editorOption.x\"\r\n [style.top.px]=\"n.editorOption.y\"\r\n [class.connecting-source]=\"isConnectingFrom(n) || isDraggingFrom(n) || isSelectedNode(n)\"\r\n nzSize=\"small\"\r\n (mousedown)=\"onMouseDownNode($event, n)\"\r\n (click)=\"$event.stopPropagation(); onClickStage(n)\"\r\n >\r\n <div class=\"title\">{{ n.Code }}</div>\r\n\r\n <div>{{ n.Name }}</div>\r\n\r\n @if (!n.editorOption.isReverse) {\r\n <!-- connector RIGHT: output -->\r\n <div class=\"connector connector-right\" (click)=\"onClickConnector($event, n, 'right')\"></div>\r\n\r\n <!-- connector LEFT: input -->\r\n <div class=\"connector connector-left\" (click)=\"onClickConnector($event, n, 'left')\"></div>\r\n } @else {\r\n <div class=\"connector connector-right reverse\" (click)=\"onClickConnector($event, n, 'right')\"></div>\r\n <div class=\"connector connector-left reverse\" (click)=\"onClickConnector($event, n, 'left')\"></div>\r\n }\r\n </nz-card>\r\n }\r\n }\r\n\r\n <!-- POINTS -->\r\n @for (p of connectingPoints; track $index) {\r\n @if (p != draggingPoint) {\r\n <div\r\n class=\"waypoint\"\r\n [style.left.px]=\"p.x\"\r\n [style.top.px]=\"p.y\"\r\n (mousedown)=\"onmousedownPoint($event, p)\"\r\n (contextmenu)=\"onRightClickPoint($event, hoverAction!, $index)\"\r\n ></div>\r\n } @else {\r\n <div\r\n class=\"waypoint dragging\"\r\n [style.left.px]=\"p.x\"\r\n [style.top.px]=\"p.y\"\r\n (mousedown)=\"onmousedownPoint($event, p)\"\r\n ></div>\r\n }\r\n }\r\n </div>\r\n</div>\r\n\r\n<!-- drawer TEMPLATE -->\r\n<nz-drawer\r\n [nzTitle]=\"drawTemplateTitle\"\r\n nzPlacement=\"right\"\r\n [nzWidth]=\"500\"\r\n [nzClosable]=\"false\"\r\n [nzVisible]=\"drawTemplateVisibel\"\r\n [nzFooter]=\"footerTplTemplate\"\r\n (nzOnClose)=\"drawTemplateVisibel = false\"\r\n>\r\n <ng-template #drawTemplateTitle> <nz-icon nzType=\"setting\"></nz-icon> &nbsp; Template </ng-template>\r\n <ng-container *nzDrawerContent>\r\n <extend-select\r\n [label]=\"'Org'\"\r\n [lstItem]=\"lstOrg\"\r\n [valueField]=\"'App_Org_Id'\"\r\n [displayFields]=\"['Name', 'Code']\"\r\n [(_ngModel)]=\"template.App_Org_Id\"\r\n ></extend-select>\r\n <extend-input [label]=\"'Code'\" [(_ngModel)]=\"template.Code\"></extend-input>\r\n <extend-input [label]=\"'Name'\" [(_ngModel)]=\"template.Name\"></extend-input>\r\n <extend-select\r\n [label]=\"'Type'\"\r\n [lstItem]=\"template.lstTemplateType\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"template.DocType\"\r\n ></extend-select>\r\n <extend-textarea [label]=\"'Desscription'\" [(_ngModel)]=\"template.Description\"></extend-textarea>\r\n <extend-select\r\n [label]=\"'Print template'\"\r\n [lstItem]=\"template.lstTemplatePrint\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"template.TemplatePrint\"\r\n ></extend-select>\r\n <extend-select\r\n [label]=\"'Apply to'\"\r\n [lstItem]=\"template.lstApplyTo\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"template.ApplyTo\"\r\n ></extend-select>\r\n\r\n <extend-checkbox [label]=\"'Active'\" [(_ngModel)]=\"template.IsActive\"></extend-checkbox>\r\n <extend-checkbox [label]=\"'Use Allow back'\" [(_ngModel)]=\"template.editorOption.AllowbackInUse\"></extend-checkbox>\r\n\r\n <h3 nz-col><nz-icon nzType=\"send\" nzTheme=\"outline\" />&nbsp;Stage</h3>\r\n\r\n <div nz-row [nzGutter]=\"[0, 5]\">\r\n @for (tag of getLstStage; track tag) {\r\n <div nz-col>\r\n <nz-tag (click)=\"hoverStage = tag\">\r\n {{ sliceTagName(tag.Code + (tag.Name ? \" - \" + tag.Name : \"\")) }}\r\n </nz-tag>\r\n </div>\r\n }\r\n </div>\r\n\r\n <box [height]=\"16\"></box>\r\n\r\n <h3 nz-col><nz-icon nzType=\"send\" nzTheme=\"outline\" />&nbsp;Stage status</h3>\r\n\r\n <div nz-row [nzGutter]=\"[0, 5]\">\r\n @for (tag of template.lstStageStatus; track tag) {\r\n <div nz-col>\r\n <nz-tag\r\n [nzMode]=\"checkRemoveableStageStatus(tag) ? 'closeable' : 'default'\"\r\n (nzOnClose)=\"handleCloseStageStatus(tag)\"\r\n >\r\n {{ sliceTagName(tag.Code + (tag.Name ? \" - \" + tag.Name : \"\")) }}\r\n </nz-tag>\r\n </div>\r\n }\r\n\r\n <div nz-col>\r\n @if (!inputStageStatusVisible) {\r\n <nz-tag class=\"editable-tag\" nzNoAnimation (click)=\"showInputStageStatus()\">\r\n <nz-icon nzType=\"plus\" />\r\n New Action type\r\n </nz-tag>\r\n } @else {\r\n <input\r\n #inputStageStatusElement\r\n nz-input\r\n nzSize=\"small\"\r\n type=\"text\"\r\n style=\"width: 150px\"\r\n placeholder=\"Code\"\r\n [(ngModel)]=\"inputStageStatusCode\"\r\n (keydown.enter)=\"inputStageStatusNameElement.select()\"\r\n />\r\n <input\r\n #inputStageStatusNameElement\r\n nz-input\r\n nzSize=\"small\"\r\n type=\"text\"\r\n style=\"width: 150px\"\r\n placeholder=\"Name\"\r\n [(ngModel)]=\"inputStageStatusName\"\r\n (blur)=\"handleInputStageStatusConfirm()\"\r\n (keydown.enter)=\"handleInputStageStatusConfirm()\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n\r\n <box [height]=\"16\"></box>\r\n\r\n <h3 nz-col><nz-icon nzType=\"send\" nzTheme=\"outline\" />&nbsp;Action type</h3>\r\n\r\n <div nz-row [nzGutter]=\"[0, 5]\">\r\n @for (tag of template.lstActionType; track tag) {\r\n <div nz-col>\r\n <nz-tag\r\n [nzMode]=\"checkRemoveableActionType(tag) ? 'closeable' : 'default'\"\r\n (nzOnClose)=\"handleCloseActionType(tag)\"\r\n >\r\n {{ sliceTagName(tag.Code + (tag.Name ? \" - \" + tag.Name : \"\")) }}\r\n </nz-tag>\r\n </div>\r\n }\r\n\r\n <div nz-col>\r\n @if (!inputActionTypeVisible) {\r\n <nz-tag class=\"editable-tag\" nzNoAnimation (click)=\"showInputActionType()\">\r\n <nz-icon nzType=\"plus\" />\r\n New Action type\r\n </nz-tag>\r\n } @else {\r\n <input\r\n #inputActionTypeElement\r\n nz-input\r\n nzSize=\"small\"\r\n type=\"text\"\r\n style=\"width: 150px\"\r\n placeholder=\"Code\"\r\n [(ngModel)]=\"inputActionTypeCode\"\r\n (keydown.enter)=\"inputActionTypeNameElement.select()\"\r\n />\r\n <input\r\n #inputActionTypeNameElement\r\n nz-input\r\n nzSize=\"small\"\r\n type=\"text\"\r\n style=\"width: 150px\"\r\n placeholder=\"Name\"\r\n [(ngModel)]=\"inputActionTypeName\"\r\n (blur)=\"handleInputActionTypeConfirm()\"\r\n (keydown.enter)=\"handleInputActionTypeConfirm()\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n\r\n <box [height]=\"16\"></box>\r\n\r\n <h3 nz-col><nz-icon nzType=\"send\" nzTheme=\"outline\" />&nbsp;Action status</h3>\r\n\r\n <div nz-row [nzGutter]=\"[0, 5]\">\r\n @for (tag of template.lstActionStatus; track tag) {\r\n <div nz-col>\r\n @if (template.editingActionStatus != tag) {\r\n <nz-tag\r\n [nzMode]=\"checkRemoveableActionStatus(tag.Code) ? 'closeable' : 'default'\"\r\n (nzOnClose)=\"handleClose(tag.Code)\"\r\n (click)=\"template.editingActionStatus = checkRemoveableActionStatus(tag.Code) ? tag : undefined\"\r\n >\r\n {{ sliceTagName(tag.Code + (tag.Name ? \" - \" + tag.Name : \"\")) }}\r\n </nz-tag>\r\n } @else {\r\n <input\r\n nz-input\r\n nzSize=\"small\"\r\n type=\"text\"\r\n style=\"width: 150px\"\r\n [appAutoFocus]=\"true\"\r\n [(ngModel)]=\"tag.Code\"\r\n (blur)=\"template.editingActionStatus = undefined\"\r\n (keydown.enter)=\"template.editingActionStatus = undefined\"\r\n />&nbsp;&nbsp;\r\n }\r\n </div>\r\n }\r\n\r\n <div nz-col>\r\n @if (!inputVisible) {\r\n <nz-tag class=\"editable-tag\" nzNoAnimation (click)=\"showInput()\">\r\n <nz-icon nzType=\"plus\" />\r\n New Action status\r\n </nz-tag>\r\n } @else {\r\n <input\r\n #inputElement\r\n nz-input\r\n nzSize=\"small\"\r\n type=\"text\"\r\n style=\"width: 150px\"\r\n placeholder=\"+ New Action status\"\r\n [(ngModel)]=\"inputValue\"\r\n (blur)=\"handleInputConfirm()\"\r\n (keydown.enter)=\"handleInputConfirm()\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #footerTplTemplate>\r\n <div nz-flex [nzGap]=\"6\" [nzJustify]=\"'end'\">\r\n <button nz-button nzDanger [nzLoading]=\"!ready\" (click)=\"save()\">Save</button>\r\n <button nz-button (click)=\"drawTemplateVisibel = false\">Close</button>\r\n </div>\r\n </ng-template>\r\n</nz-drawer>\r\n\r\n<!-- drawer STAGE -->\r\n<nz-drawer\r\n [nzTitle]=\"drawerTitleStage\"\r\n [nzPlacement]=\"selectedStage?.editorOption?.drawerPosition == 'left' ? 'left' : 'right'\"\r\n [nzVisible]=\"!!selectedStage\"\r\n [nzWidth]=\"'calc(50vw)'\"\r\n [nzClosable]=\"false\"\r\n [nzFooter]=\"footerTplNode\"\r\n (nzOnClose)=\"selectedStage = undefined\"\r\n>\r\n <ng-template #drawerTitleStage>\r\n <div nz-row nzJustify=\"space-between\">\r\n @if (selectedStage && selectedStage.editorOption) {\r\n @if (selectedStage.editorOption.drawerPosition == \"left\") {\r\n <button\r\n nz-button\r\n nzSize=\"small\"\r\n nz-tooltip=\"To the right\"\r\n (click)=\"selectedStage.editorOption.drawerPosition = 'right'\"\r\n >\r\n <nz-icon nzType=\"double-right\"></nz-icon>\r\n </button>\r\n STAGE\r\n } @else {\r\n STAGE\r\n <button\r\n nz-button\r\n nzSize=\"small\"\r\n nz-tooltip=\"To the left\"\r\n (click)=\"selectedStage.editorOption.drawerPosition = 'left'\"\r\n >\r\n <nz-icon nzType=\"double-left\"></nz-icon>\r\n </button>\r\n }\r\n }\r\n </div>\r\n </ng-template>\r\n <ng-container *nzDrawerContent>\r\n <ng-container *ngIf=\"selectedStage\">\r\n <nz-radio-group [(ngModel)]=\"selectedStage.StageType\">\r\n <label nz-radio nzValue=\"_start_\">UI start</label>\r\n <label nz-radio nzValue=\"_end_\">UI end</label>\r\n <label nz-radio nzValue=\"start\">START</label>\r\n <label nz-radio nzValue=\"node\">NODE</label>\r\n <label nz-radio nzValue=\"end\">END</label>\r\n </nz-radio-group>\r\n\r\n <box [height]=\"16\"></box>\r\n\r\n <div nz-row [nzGutter]=\"32\" class=\"form-item-no-bottom\">\r\n <extend-input\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Code'\"\r\n [floatingLabel]=\"true\"\r\n [required]=\"true\"\r\n [(_ngModel)]=\"selectedStage.Code\"\r\n ></extend-input>\r\n\r\n <extend-input\r\n nz-col\r\n [nzSpan]=\"16\"\r\n [label]=\"'Name'\"\r\n [floatingLabel]=\"true\"\r\n [required]=\"true\"\r\n [(_ngModel)]=\"selectedStage.Name\"\r\n ></extend-input>\r\n </div>\r\n\r\n <div nz-row [nzGutter]=\"32\" class=\"form-item-no-bottom\">\r\n <extend-input-number\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Sequence'\"\r\n [floatingLabel]=\"true\"\r\n [(_ngModel)]=\"selectedStage.SeqValue\"\r\n ></extend-input-number>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"16\"\r\n [label]=\"'Org implement'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"lstOrg\"\r\n [valueField]=\"'App_Org_Id'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"selectedStage.App_Org_Id\"\r\n ></extend-select>\r\n </div>\r\n\r\n <div nz-row [nzGutter]=\"32\" class=\"form-item-no-bottom\">\r\n <extend-input-number\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Number Day'\"\r\n [floatingLabel]=\"true\"\r\n [precision]=\"1\"\r\n [(_ngModel)]=\"selectedStage.NumberDay\"\r\n ></extend-input-number>\r\n </div>\r\n\r\n @if (selectedStage.editorOption) {\r\n @if ([\"start\", \"node\", \"end\"].includes(selectedStage.StageType.toLowerCase())) {\r\n <extend-checkbox\r\n [label]=\"'Reverse'\"\r\n [labelSpan]=\"0\"\r\n [(_ngModel)]=\"selectedStage.editorOption.isReverse\"\r\n ></extend-checkbox>\r\n }\r\n\r\n <extend-checkbox\r\n [label]=\"'Require user action'\"\r\n [labelSpan]=\"0\"\r\n [(_ngModel)]=\"selectedStage.IsRequireUser\"\r\n ></extend-checkbox>\r\n }\r\n\r\n <box [height]=\"16\"></box>\r\n\r\n <div nz-row [nzGutter]=\"16\">\r\n <h3 nz-col><nz-icon nzType=\"send\" nzTheme=\"outline\" />&nbsp;List Action</h3>\r\n <div nz-col>\r\n <button nz-button nzType=\"primary\" nzSize=\"small\" (click)=\"addAction()\">\r\n <nz-icon nzType=\"plus\"></nz-icon>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <nz-table nzSize=\"small\" [nzData]=\"lstActionOfCurrentStage\" [nzShowPagination]=\"false\" [nzNoResult]=\"'&nbsp;'\">\r\n <thead>\r\n <tr [hidden]=\"true\">\r\n <th nzWidth=\"40px\"></th>\r\n <th></th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (action of lstActionOfCurrentStage; track $index) {\r\n <tr [class.text-bold]=\"action == hoverAction\" (click)=\"onclickaction(action)\">\r\n <td style=\"border-bottom: solid 1px orange\">\r\n ({{ $index + 1 }})\r\n <nz-icon\r\n nzType=\"delete\"\r\n nzTheme=\"outline\"\r\n class=\"color-warn cursor-pointer icon-size-16\"\r\n (click)=\"$event.stopPropagation(); deleteAction(action)\"\r\n ></nz-icon>\r\n </td>\r\n <td style=\"border-bottom: solid 1px orange\">\r\n <div nz-row [nzGutter]=\"16\" class=\"form-item-no-bottom\">\r\n <div nz-col [nzSpan]=\"8\">\r\n <nz-form-item>\r\n <nz-form-label [nzSpan]=\"24\" style=\"height: 32px\">Action status</nz-form-label>\r\n <nz-form-control [nzSpan]=\"24\">\r\n <nz-input-group class=\"full-width\">\r\n <input\r\n nz-input\r\n [(ngModel)]=\"action.ActionStatus\"\r\n [nzAutocomplete]=\"auto\"\r\n (ngModelChange)=\"nzAutocompletechange($event, template.lstActionStatus)\"\r\n (click)=\"lstActionStatusFiltered = template.lstActionStatus\"\r\n (keyup.enter)=\"onenterAotu(action.ActionStatus)\"\r\n (blur)=\"onenterAotu(action.ActionStatus)\"\r\n />\r\n <nz-autocomplete #auto [compareWith]=\"compareFun\">\r\n @for (option of lstActionStatusFiltered; track $index) {\r\n <nz-auto-option [nzValue]=\"option.Code\" [nzLabel]=\"option.Code\">\r\n {{ option.Code }}\r\n <icon-delete\r\n *ngIf=\"checkRemoveableActionStatus(option.Code)\"\r\n style=\"float: right\"\r\n [size]=\"12\"\r\n (click)=\"handleClose(option.Code)\"\r\n ></icon-delete>\r\n </nz-auto-option>\r\n }\r\n </nz-autocomplete>\r\n </nz-input-group>\r\n </nz-form-control>\r\n </nz-form-item>\r\n </div>\r\n\r\n <extend-input\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Action text'\"\r\n [floatingLabel]=\"true\"\r\n [(_ngModel)]=\"action.ActionText\"\r\n (_ngModelChange)=\"onchangeActionText(action)\"\r\n ></extend-input>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Action type'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"template.lstActionType\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"action.ActionType\"\r\n ></extend-select>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Stage status'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"template.lstStageStatus\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"action.StageStatus\"\r\n ></extend-select>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Next stage'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"getlstStage\"\r\n [valueField]=\"'WF_TemplateStage_Id'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"action.To_WF_TemplateStage_Id\"\r\n (_ngModelChange)=\"onchangeNextStage(action)\"\r\n ></extend-select>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Next stage status'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"template.lstStageStatus\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"action.To_StageStatus\"\r\n ></extend-select>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Process status'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"template.lstProcessStatus\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"action.DocProcessStatus\"\r\n ></extend-select>\r\n </div>\r\n <box [height]=\"8\"></box>\r\n <div nz-row>Role</div>\r\n <div nz-row>\r\n <extend-select\r\n nz-col\r\n nzSpan=\"24\"\r\n [size]=\"'small'\"\r\n [lstItem]=\"lstRole\"\r\n [valueField]=\"'App_Role_Id'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [multiple]=\"true\"\r\n [(_ngModel)]=\"action._lstRoleId\"\r\n (_ngModelChange)=\"onselectedRoleEmail(action)\"\r\n ></extend-select>\r\n </div>\r\n <box [height]=\"8\"></box>\r\n <div nz-row>Email action</div>\r\n <div nz-row>\r\n <extend-select\r\n nz-col\r\n nzSpan=\"24\"\r\n [size]=\"'small'\"\r\n [lstItem]=\"lstEmailAction\"\r\n [valueField]=\"'ID'\"\r\n [displayField]=\"'Name'\"\r\n [multiple]=\"true\"\r\n [(_ngModel)]=\"action._lstEmailActionId\"\r\n (_ngModelChange)=\"onselectedRoleEmail(action)\"\r\n ></extend-select>\r\n </div>\r\n <box [height]=\"8\"></box>\r\n <div *ngIf=\"action._lstEmailActionId && action._lstEmailActionId.length\" nz-row>Email template</div>\r\n <div *ngIf=\"action._lstEmailActionId && action._lstEmailActionId.length\" nz-row>\r\n <div nz-col nzSpan=\"1\"></div>\r\n <div nz-col nzSpan=\"23\" class=\"form-item-no-bottom\" style=\"font-weight: normal\">\r\n @for (actionRef of lstActionRefOf(action); track $index) {\r\n <div nz-row>\r\n <extend-select\r\n nz-col\r\n nzSpan=\"24\"\r\n [labelSpan]=\"12\"\r\n [size]=\"'small'\"\r\n [label]=\"emailActionText(actionRef.To_WF_TemplateStageAction_Id)\"\r\n [lstItem]=\"lstEmailTemplate\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"actionRef.TemplateMail\"\r\n ></extend-select>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n <box [height]=\"8\"></box>\r\n <div nz-row [nzGutter]=\"8\">\r\n Action rule\r\n <button nz-button nzType=\"text\" nzSize=\"small\" (click)=\"actionRuleModalVisible = true\">\r\n <nz-icon nzType=\"export\" nzTheme=\"outline\" class=\"color-primary\" />\r\n </button>\r\n <button\r\n *ngIf=\"action.WF_TransitionsRule_Id\"\r\n nz-button\r\n nzType=\"text\"\r\n nzSize=\"small\"\r\n (click)=\"deleteActionRule(action)\"\r\n >\r\n <nz-icon nzType=\"delete\" nzTheme=\"outline\" class=\"color-warn\" />\r\n </button>\r\n </div>\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </nz-table>\r\n\r\n <box [height]=\"16\"></box>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #footerTplNode>\r\n <div\r\n nz-flex\r\n [nzGap]=\"6\"\r\n [nzJustify]=\"\r\n selectedStage && selectedStage.editorOption && selectedStage.editorOption.drawerPosition == 'left'\r\n ? 'start'\r\n : 'end'\r\n \"\r\n >\r\n <button nz-button nzDanger nzDanger [nzLoading]=\"!ready\" (click)=\"save()\">Save</button>\r\n <button nz-button (click)=\"selectedStage = undefined\">Close</button>\r\n <button\r\n *ngIf=\"selectedStage && ['START', 'END'].indexOf(selectedStage.StageType) < 0\"\r\n nz-button\r\n nzDanger\r\n (click)=\"deleteStage()\"\r\n >\r\n Delete\r\n </button>\r\n </div>\r\n </ng-template>\r\n</nz-drawer>\r\n\r\n<!-- drawer ACTION -->\r\n<nz-drawer\r\n [nzTitle]=\"drawerTitleAction\"\r\n nzTitle=\"ACTION\"\r\n [nzPlacement]=\"selectedAction?.editorOption?.drawerPosition == 'left' ? 'left' : 'right'\"\r\n [nzClosable]=\"false\"\r\n [nzWidth]=\"750\"\r\n [nzVisible]=\"!!selectedAction\"\r\n [nzFooter]=\"footerTplAction\"\r\n (nzOnClose)=\"selectedAction = undefined\"\r\n>\r\n <ng-template #drawerTitleAction>\r\n <div nz-row nzJustify=\"space-between\">\r\n @if (selectedAction && selectedAction.editorOption) {\r\n @if (selectedAction.editorOption.drawerPosition == \"left\") {\r\n <button\r\n nz-button\r\n nzSize=\"small\"\r\n nz-tooltip=\"To the right\"\r\n (click)=\"selectedAction.editorOption.drawerPosition = 'right'\"\r\n >\r\n <nz-icon nzType=\"double-right\"></nz-icon>\r\n </button>\r\n ACTION\r\n } @else {\r\n ACTION\r\n <button\r\n nz-button\r\n nzSize=\"small\"\r\n nz-tooltip=\"To the left\"\r\n (click)=\"selectedAction.editorOption.drawerPosition = 'left'\"\r\n >\r\n <nz-icon nzType=\"double-left\"></nz-icon>\r\n </button>\r\n }\r\n }\r\n </div>\r\n </ng-template>\r\n <ng-container *nzDrawerContent>\r\n <ng-container *ngIf=\"selectedAction\">\r\n <div>\r\n <strong\r\n >{{ selectedAction.getFromStageCode(lstStage) }} -> {{ selectedAction.getToStageCode(lstStage) }}</strong\r\n >\r\n </div>\r\n <div>{{ selectedAction.getFromStageName(lstStage) }} -> {{ selectedAction.getToStageName(lstStage) }}</div>\r\n\r\n <box [height]=\"16\"></box>\r\n\r\n <div nz-row [nzGutter]=\"16\" class=\"form-item-no-bottom\">\r\n <div nz-col [nzSpan]=\"8\">\r\n <nz-form-item>\r\n <nz-form-label [nzSpan]=\"24\" style=\"height: 32px\">Action status</nz-form-label>\r\n <nz-form-control [nzSpan]=\"24\">\r\n <nz-input-group class=\"full-width\">\r\n <input\r\n nz-input\r\n [(ngModel)]=\"selectedAction.ActionStatus\"\r\n [nzAutocomplete]=\"auto\"\r\n (ngModelChange)=\"nzAutocompletechange($event, template.lstActionStatus)\"\r\n (click)=\"lstActionStatusFiltered = template.lstActionStatus\"\r\n (keyup.enter)=\"onenterAotu(selectedAction.ActionStatus)\"\r\n (blur)=\"onenterAotu(selectedAction.ActionStatus)\"\r\n />\r\n <nz-autocomplete #auto [compareWith]=\"compareFun\">\r\n @for (option of lstActionStatusFiltered; track $index) {\r\n <nz-auto-option [nzValue]=\"option.Code\" [nzLabel]=\"option.Code\">\r\n {{ option.Code }}\r\n <icon-delete\r\n *ngIf=\"checkRemoveableActionStatus(option.Code)\"\r\n style=\"float: right\"\r\n [size]=\"12\"\r\n (click)=\"handleClose(option.Code)\"\r\n ></icon-delete>\r\n </nz-auto-option>\r\n }\r\n </nz-autocomplete>\r\n </nz-input-group>\r\n </nz-form-control>\r\n </nz-form-item>\r\n </div>\r\n\r\n <extend-input\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Action text'\"\r\n [floatingLabel]=\"true\"\r\n [(_ngModel)]=\"selectedAction.ActionText\"\r\n (_ngModelChange)=\"onchangeActionText(selectedAction)\"\r\n ></extend-input>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Action type'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"template.lstActionType\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"selectedAction.ActionType\"\r\n ></extend-select>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Stage status'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"template.lstStageStatus\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"selectedAction.StageStatus\"\r\n ></extend-select>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Next stage'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"lstStage\"\r\n [valueField]=\"'WF_TemplateStage_Id'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"selectedAction.To_WF_TemplateStage_Id\"\r\n (_ngModelChange)=\"onchangeNextStage(selectedAction)\"\r\n ></extend-select>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Next stage status'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"template.lstStageStatus\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"selectedAction.To_StageStatus\"\r\n ></extend-select>\r\n </div>\r\n\r\n <!-- <box [height]=\"16\"></box> -->\r\n <nz-divider></nz-divider>\r\n\r\n @if (template.editorOption.AllowbackInUse) {\r\n <extend-checkbox\r\n [label]=\"'Allow back'\"\r\n [labelSpan]=\"0\"\r\n [(_ngModel)]=\"selectedAction.allowBack\"\r\n (_ngModelChange)=\"onchangeAllowBack(selectedAction)\"\r\n ></extend-checkbox>\r\n }\r\n\r\n <box [height]=\"16\"></box>\r\n\r\n @if (selectedAction.allowBack) {\r\n <div>\r\n <strong\r\n >{{ selectedAction.getToStageCode(lstStage) }} -> {{ selectedAction.getFromStageCode(lstStage) }}</strong\r\n >\r\n </div>\r\n <div>{{ selectedAction.getToStageName(lstStage) }} -> {{ selectedAction.getFromStageName(lstStage) }}</div>\r\n\r\n @if (selectedBackAction) {\r\n <div nz-row [nzGutter]=\"16\" class=\"form-item-no-bottom\">\r\n <div nz-col [nzSpan]=\"8\">\r\n <nz-form-item>\r\n <nz-form-label [nzSpan]=\"24\" style=\"height: 32px\">Action status</nz-form-label>\r\n <nz-form-control [nzSpan]=\"24\">\r\n <nz-input-group class=\"full-width\">\r\n <input\r\n nz-input\r\n [(ngModel)]=\"selectedBackAction.ActionStatus\"\r\n [nzAutocomplete]=\"auto\"\r\n (ngModelChange)=\"nzAutocompletechange($event, template.lstActionStatus)\"\r\n (click)=\"lstActionStatusFiltered = template.lstActionStatus\"\r\n (keyup.enter)=\"onenterAotu(selectedBackAction.ActionStatus)\"\r\n (blur)=\"onenterAotu(selectedBackAction.ActionStatus)\"\r\n />\r\n <nz-autocomplete #auto [compareWith]=\"compareFun\">\r\n @for (option of lstActionStatusFiltered; track $index) {\r\n <nz-auto-option [nzValue]=\"option.Code\" [nzLabel]=\"option.Code\">\r\n {{ option.Code }}\r\n <icon-delete\r\n *ngIf=\"checkRemoveableActionStatus(option.Code)\"\r\n style=\"float: right\"\r\n [size]=\"12\"\r\n (click)=\"handleClose(option.Code)\"\r\n ></icon-delete>\r\n </nz-auto-option>\r\n }\r\n </nz-autocomplete>\r\n </nz-input-group>\r\n </nz-form-control>\r\n </nz-form-item>\r\n </div>\r\n\r\n <extend-input\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Action text'\"\r\n [floatingLabel]=\"true\"\r\n [(_ngModel)]=\"selectedBackAction.ActionText\"\r\n (_ngModelChange)=\"onchangeActionText(selectedBackAction)\"\r\n ></extend-input>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Action type'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"template.lstActionType\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"selectedBackAction.ActionType\"\r\n ></extend-select>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Stage status'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"template.lstStageStatus\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"selectedBackAction.StageStatus\"\r\n ></extend-select>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Next stage'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"lstStage\"\r\n [valueField]=\"'WF_TemplateStage_Id'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"selectedBackAction.To_WF_TemplateStage_Id\"\r\n (_ngModelChange)=\"onchangeNextStage(selectedBackAction)\"\r\n ></extend-select>\r\n\r\n <extend-select\r\n nz-col\r\n [nzSpan]=\"8\"\r\n [label]=\"'Next stage status'\"\r\n [floatingLabel]=\"true\"\r\n [lstItem]=\"template.lstStageStatus\"\r\n [valueField]=\"'Code'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"selectedBackAction.To_StageStatus\"\r\n ></extend-select>\r\n </div>\r\n }\r\n }\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #footerTplAction>\r\n <div\r\n nz-flex\r\n [nzGap]=\"6\"\r\n [nzJustify]=\"selectedAction && selectedAction.editorOption.drawerPosition == 'left' ? 'start' : 'end'\"\r\n >\r\n <button nz-button nzDanger nzDanger [nzLoading]=\"!ready\" (click)=\"save()\">Save</button>\r\n <button nz-button nzDanger (click)=\"deleteAction(selectedAction!)\">Delete</button>\r\n <button nz-button (click)=\"selectedAction = undefined\">Close</button>\r\n </div>\r\n </ng-template>\r\n</nz-drawer>\r\n\r\n<!-- setting editor -->\r\n<nz-drawer\r\n [nzTitle]=\"drawSettingTitle\"\r\n nzPlacement=\"right\"\r\n [nzClosable]=\"false\"\r\n [nzVisible]=\"settingVisible\"\r\n (nzOnClose)=\"settingVisible = false\"\r\n>\r\n <ng-template #drawSettingTitle> <nz-icon nzType=\"setting\"></nz-icon> &nbsp; Editor </ng-template>\r\n <ng-container *nzDrawerContent>\r\n <div class=\"form-item-no-bottom\">\r\n <extend-checkbox [label]=\"'Show grid'\" [labelSpan]=\"0\" [(_ngModel)]=\"wfcSetting.ShowGrid\"></extend-checkbox>\r\n\r\n <box [height]=\"16\"></box>\r\n </div>\r\n </ng-container>\r\n</nz-drawer>\r\n\r\n<!-- editor infomation -->\r\n<nz-drawer\r\n [nzTitle]=\"drawInfoTitle\"\r\n nzPlacement=\"right\"\r\n [nzClosable]=\"false\"\r\n [nzVisible]=\"infoVisible\"\r\n (nzOnClose)=\"infoVisible = false\"\r\n>\r\n <ng-template #drawInfoTitle> <nz-icon nzType=\"info-circle\"></nz-icon> &nbsp; Infomation </ng-template>\r\n <ng-container *nzDrawerContent>\r\n <p>1. C\u00E1c th\u00E0nh ph\u1EA7n: Stage or Node (stag, node quy tr\u00ECnh), Action or Connector (\u0111\u01B0\u1EDDng n\u1ED1i gi\u1EEFa c\u00E1c stage)</p>\r\n <p>2. Save \u0111\u1EC3 load c\u00E1c th\u00F4ng tin: Stage status, Action type</p>\r\n <p>\r\n 3. N\u1ED1i 2 node (t\u1EA1o connector t\u01B0\u01A1ng \u0111\u01B0\u01A1ng t\u1EA1o action):\r\n <br />- Click ch\u1EA5m cam t\u1EEB Node ngu\u1ED3n \u0111\u1EBFn ch\u1EA5m xanh c\u1EE7a Node \u0111\u00EDch (ho\u1EB7c click v\u00E0o Node \u0111\u00EDch), c\u00F3 th\u1EC3 click th\u00E0nh\r\n nhi\u1EC1u \u0111i\u1EC3m \u0111\u1EC3 t\u1EA1o \u0111\u01B0\u1EDDng n\u1ED1i cong<br />- Khi hover connector chuy\u1EC3n sang m\u1EA7u \u0111\u1ECF c\u00F3 th\u1EC3 click \u0111\u00FAp \u0111\u1EC3 th\u00EAm m\u1ED9t \u0111i\u1EC3m\r\n c\u1EE7a connector<br />- Khi hover l\u00EAn \u0111i\u1EC3m c\u1EE7a connector c\u00F3 th\u1EC3 di chuy\u1EC3n \u0111i\u1EC3m \u0111\u00F3 b\u1EB1ng c\u00E1ch nh\u1EA5n gi\u1EEF chu\u1ED9t v\u00E0 k\u00E9o th\u1EA3\r\n \u0111\u1EBFn v\u1ECB tr\u00ED m\u1EDBi<br />- Chu\u1ED9t ph\u1EA3i v\u00E0o \u0111i\u1EC3m n\u1ED1i connector \u0111\u1EC3 xo\u00E1 \u0111i\u1EC3m \u0111\u00F3\r\n </p>\r\n </ng-container>\r\n</nz-drawer>\r\n\r\n<!-- action rule modal -->\r\n<nz-modal\r\n [(nzVisible)]=\"actionRuleModalVisible\"\r\n [nzMaskClosable]=\"false\"\r\n [nzClosable]=\"false\"\r\n [nzKeyboard]=\"true\"\r\n [nzWidth]=\"'50vw'\"\r\n>\r\n <ng-container *nzModalTitle>\r\n ACTION RULE: [{{ selectedStage?.Code }}] {{ selectedStage?.Name }} > [{{ hoverAction?.ActionStatus }}]\r\n {{ hoverAction?.ActionText }}\r\n </ng-container>\r\n <ng-container *nzModalContent>\r\n @if (hoverAction && hoverAction.actionRule) {\r\n <div nz-row [nzGutter]=\"32\">\r\n <extend-input nz-col nzSpan=\"12\" [label]=\"'Code'\" [(_ngModel)]=\"hoverAction.actionRule.Code\"></extend-input>\r\n <extend-input nz-col nzSpan=\"12\" [label]=\"'Name'\" [(_ngModel)]=\"hoverAction.actionRule.Name\"></extend-input>\r\n <extend-input nz-col nzSpan=\"12\" [label]=\"'Note'\" [(_ngModel)]=\"hoverAction.actionRule.Note\"></extend-input>\r\n <extend-checkbox\r\n nz-col\r\n nzSpan=\"12\"\r\n [label]=\"'IsActive'\"\r\n [(_ngModel)]=\"hoverAction.actionRule.IsActive\"\r\n ></extend-checkbox>\r\n </div>\r\n <div nz-row [nzGutter]=\"16\">\r\n <div nz-col nzSpan=\"24\">\r\n <nz-table nzSize=\"small\" [nzData]=\"hoverAction.actionRule.lstLine\" [nzShowPagination]=\"false\">\r\n <thead>\r\n <tr>\r\n <th [nzWidth]=\"'50px'\"><icon-add (click)=\"addActionRuleLine()\"></icon-add></th>\r\n <th [nzWidth]=\"'25%'\">Template</th>\r\n <th [nzWidth]=\"'25%'\">Template stage</th>\r\n <th [nzWidth]=\"'25%'\">Template action</th>\r\n <th [nzWidth]=\"'50px'\">IsActive</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (item of hoverAction.actionRule.lstLine; track $index) {\r\n <tr>\r\n <td><icon-delete (click)=\"deleteActionRuleLine(hoverAction.actionRule, item)\"></icon-delete></td>\r\n <td>\r\n <extend-select\r\n #xxx\r\n [size]=\"'small'\"\r\n [lstItem]=\"lstTemplateForRule(item)\"\r\n [valueField]=\"'WF_Template_Id'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"item.WF_Template_Id\"\r\n (_ngModelChange)=\"item.WF_TemplateStage_Id = 0; item.WF_TemplateStageAction_Id = 0\"\r\n ></extend-select>\r\n </td>\r\n <td>\r\n <extend-select\r\n #yyy\r\n [size]=\"'small'\"\r\n [lstItem]=\"lstStageForRule(xxx._ngModel)\"\r\n [valueField]=\"'WF_TemplateStage_Id'\"\r\n [displayFields]=\"['Code', 'Name']\"\r\n [(_ngModel)]=\"item.WF_TemplateStage_Id\"\r\n (_ngModelChange)=\"item.WF_TemplateStageAction_Id = 0\"\r\n ></extend-select>\r\n </td>\r\n <td>\r\n <extend-select\r\n [size]=\"'small'\"\r\n [lstItem]=\"lstActionForRule(yyy._ngModel)\"\r\n [valueField]=\"'WF_TemplateStageAction_Id'\"\r\n [displayFields]=\"['ActionStatus', 'ActionText']\"\r\n [(_ngModel)]=\"item.WF_TemplateStageAction_Id\"\r\n ></extend-select>\r\n </td>\r\n <td class=\"text-center\">\r\n <extend-checkbox [(_ngModel)]=\"item.IsActive\"></extend-checkbox>\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </nz-table>\r\n </div>\r\n </div>\r\n }\r\n </ng-container>\r\n <ng-container *nzModalFooter>\r\n <button nz-button nzType=\"primary\" (click)=\"actionRuleModalVisible = false\">OK</button>\r\n </ng-container>\r\n</nz-modal>\r\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%}.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}.zoom-toolbar{position:absolute;top:8px;left:8px;z-index:10;display:flex;align-items:center;gap:6px;background:#fff;padding:4px 6px;border-radius:6px;box-shadow:0 2px 6px #00000026}.zoom-toolbar span{min-width:40px;text-align:center;font-size:12px}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{position:fixed;width:180px;height:125px;top:60px;right:15px;background-color:#eee;border:1px solid #aaa;opacity:.9;z-index:1}::ng-deep .minimap-node{position:absolute;background-color:#607a86}::ng-deep .minimap-node-round{position:absolute;background-color:#607a86;border-radius:10px}::ng-deep .minimap-node-round-start{background-color:green}::ng-deep .minimap-node-round-end{background-color:#000}::ng-deep .minimap-viewport{position:absolute;box-sizing:border-box;background-color:#4f6f7e66;z-index:1;cursor:move}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: NzCardModule }, { kind: "component", type: i3$3.NzCardComponent, selector: "nz-card", inputs: ["nzBordered", "nzLoading", "nzHoverable", "nzBodyStyle", "nzCover", "nzActions", "nzType", "nzSize", "nzTitle", "nzExtra"], exportAs: ["nzCard"] }, { kind: "ngmodule", type: NzDrawerModule }, { kind: "component", type: i4$1.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: i4$1.NzDrawerContentDirective, selector: "[nzDrawerContent]", exportAs: ["nzDrawerContent"] }, { kind: "ngmodule", type: NzTagModule }, { kind: "component", type: i5$2.NzTagComponent, selector: "nz-tag", inputs: ["nzMode", "nzColor", "nzChecked", "nzBordered"], outputs: ["nzOnClose", "nzCheckedChange"], exportAs: ["nzTag"] }, { kind: "ngmodule", type: NzRadioModule }, { kind: "component", type: i6$3.NzRadioComponent, selector: "[nz-radio],[nz-radio-button]", inputs: ["nzValue", "nzDisabled", "nzAutoFocus", "nz-radio-button"], exportAs: ["nzRadio"] }, { kind: "component", type: i6$3.NzRadioGroupComponent, selector: "nz-radio-group", inputs: ["nzDisabled", "nzButtonStyle", "nzSize", "nzName"], exportAs: ["nzRadioGroup"] }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.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$2.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "ngmodule", type: NzToolTipModule }, { kind: "directive", type: i11.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", "lstItem", "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", "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", "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: "directive", type: i6$1.NzInputDirective, selector: "input[nz-input],textarea[nz-input]", inputs: ["nzBorderless", "nzSize", "nzStepperless", "nzStatus", "disabled"], exportAs: ["nzInput"] }, { kind: "component", type: i6$1.NzInputGroupComponent, selector: "nz-input-group", inputs: ["nzAddOnBeforeIcon", "nzAddOnAfterIcon", "nzPrefixIcon", "nzSuffixIcon", "nzAddOnBefore", "nzAddOnAfter", "nzPrefix", "nzStatus", "nzSuffix", "nzSize", "nzSearch", "nzCompact"], exportAs: ["nzInputGroup"] }, { kind: "ngmodule", type: NzGridModule }, { kind: "directive", type: i4.NzColDirective, selector: "[nz-col],nz-col,nz-form-control,nz-form-label", inputs: ["nzFlex", "nzSpan", "nzOrder", "nzOffset", "nzPush", "nzPull", "nzXs", "nzSm", "nzMd", "nzLg", "nzXl", "nzXXl"], exportAs: ["nzCol"] }, { kind: "directive", type: i4.NzRowDirective, selector: "[nz-row],nz-row,nz-form-item", inputs: ["nzAlign", "nzJustify", "nzGutter"], exportAs: ["nzRow"] }, { kind: "ngmodule", type: NzFlexModule }, { kind: "directive", type: i5$3.NzFlexDirective, selector: "[nz-flex],nz-flex", inputs: ["nzVertical", "nzJustify", "nzAlign", "nzGap", "nzWrap", "nzFlex"], exportAs: ["nzFlex"] }, { kind: "component", type: ExtendInputNumber, selector: "extend-input-number", inputs: ["label", "placeHolder", "labelAlign", "floatingLabel", "hiddenUpDown", "labelSpan", "labelFlex", "inputFlex", "disabled", "required", "noBottom", "size", "min", "max", "precision", "inputWidth", "inputHeight", "borderBottomOnly", "displayInline", "isSubmited", "separatorType", "formData", "controlName", "_ngModel"], outputs: ["_ngModelChange"] }, { kind: "ngmodule", type: NzTableModule }, { kind: "component", type: i1$5.NzTableComponent, selector: "nz-table", inputs: ["nzTableLayout", "nzShowTotal", "nzItemRender", "nzTitle", "nzFooter", "nzNoResult", "nzPageSizeOptions", "nzVirtualItemSize", "nzVirtualMaxBufferPx", "nzVirtualMinBufferPx", "nzVirtualForTrackBy", "nzLoadingDelay", "nzPageIndex", "nzPageSize", "nzTotal", "nzWidthConfig", "nzData", "nzCustomColumn", "nzPaginationPosition", "nzScroll", "noDataVirtualHeight", "nzPaginationType", "nzFrontPagination", "nzTemplateMode", "nzShowPagination", "nzLoading", "nzOuterBordered", "nzLoadingIndicator", "nzBordered", "nzSize", "nzShowSizeChanger", "nzHideOnSinglePage", "nzShowQuickJumper", "nzSimple"], outputs: ["nzPageSizeChange", "nzPageIndexChange", "nzQueryParams", "nzCurrentPageDataChange", "nzCustomColumnChange"], exportAs: ["nzTable"] }, { kind: "directive", type: i1$5.NzTableCellDirective, selector: "th:not(.nz-disable-th):not([mat-cell]), td:not(.nz-disable-td):not([mat-cell])" }, { kind: "directive", type: i1$5.NzThMeasureDirective, selector: "th", inputs: ["nzWidth", "colspan", "colSpan", "rowspan", "rowSpan"] }, { kind: "component", type: i1$5.NzTheadComponent, selector: "thead:not(.ant-table-thead)", outputs: ["nzSortOrderChange"] }, { kind: "component", type: i1$5.NzTbodyComponent, selector: "tbody" }, { kind: "directive", type: i1$5.NzTrDirective, selector: "tr:not([mat-row]):not([mat-header-row]):not([nz-table-measure-row]):not([nzExpand]):not([nz-table-fixed-row])" }, { kind: "ngmodule", type: NzDividerModule }, { kind: "component", type: i8.NzDividerComponent, selector: "nz-divider", inputs: ["nzText", "nzType", "nzOrientation", "nzVariant", "nzDashed", "nzPlain"], exportAs: ["nzDivider"] }, { kind: "directive", type: AutoFocusDirective, selector: "[appAutoFocus]", inputs: ["appAutoFocus"] }, { kind: "ngmodule", type: NzAutocompleteModule }, { kind: "component", type: i17.NzAutocompleteComponent, selector: "nz-autocomplete", inputs: ["nzWidth", "nzOverlayClassName", "nzOverlayStyle", "nzDefaultActiveFirstOption", "nzBackfill", "compareWith", "nzDataSource"], outputs: ["selectionChange"], exportAs: ["nzAutocomplete"] }, { kind: "component", type: i17.NzAutocompleteOptionComponent, selector: "nz-auto-option", inputs: ["nzValue", "nzLabel", "nzDisabled"], outputs: ["selectionChange", "mouseEntered"], exportAs: ["nzAutoOption"] }, { kind: "directive", type: i17.NzAutocompleteTriggerDirective, selector: "input[nzAutocomplete], textarea[nzAutocomplete]", inputs: ["nzAutocomplete"], exportAs: ["nzAutocompleteTrigger"] }, { kind: "component", type: IconDelete, selector: "icon-delete", inputs: ["size"], outputs: ["click"] }, { 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: "directive", type: NzModalTitleDirective, selector: "[nzModalTitle]", exportAs: ["nzModalTitle"] }, { kind: "component", type: IconAdd, selector: "icon-add", inputs: ["size"], outputs: ["click"] }, { kind: "directive", type: NzModalFooterDirective, selector: "[nzModalFooter]", exportAs: ["nzModalFooter"] }] });
6308
6349
  }
6309
6350
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: WorkflowEditorComponent, decorators: [{
6310
6351
  type: Component,
@@ -6428,11 +6469,11 @@ class ExpandableSearchComponent {
6428
6469
  this.onSearch.emit(this.searchValue);
6429
6470
  }
6430
6471
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: ExpandableSearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6431
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.7", type: ExpandableSearchComponent, isStandalone: true, selector: "expandable-search", inputs: { searchValue: "searchValue" }, outputs: { searchValueChange: "searchValueChange", onSearch: "onSearch" }, viewQueries: [{ propertyName: "searchInputRef", first: true, predicate: ["searchInput"], descendants: true }], ngImport: i0, template: "<div class=\"nz-search-wrapper\" [class.expanded]=\"isExpanded\">\r\n <input\r\n #searchInput\r\n type=\"text\"\r\n class=\"custom-search-input\"\r\n [(ngModel)]=\"searchValue\"\r\n placeholder=\"Nh\u1EADp \u0111i\u1EC1u ki\u1EC7n t\u00ECm ki\u1EBFm...\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n (keyup.enter)=\"performSearch()\"\r\n />\r\n\r\n <span class=\"suffix-wrap\" (mousedown)=\"$event.preventDefault()\" (click)=\"toggleSearch()\">\r\n <i\r\n nz-icon\r\n nzType=\"close-circle\"\r\n nzTheme=\"fill\"\r\n class=\"suffix-icon delete\"\r\n [class.show]=\"isExpanded && searchValue\"\r\n (click)=\"clearSearch($event)\"\r\n ></i>\r\n\r\n <i\r\n nz-icon\r\n nzType=\"search\"\r\n nzTheme=\"outline\"\r\n class=\"suffix-icon search\"\r\n [class.show]=\"!isExpanded || !searchValue\"\r\n ></i>\r\n </span>\r\n</div>\r\n", styles: ["@charset \"UTF-8\";.nz-search-wrapper{position:relative;display:inline-flex;align-items:center;height:32px;width:32px;background-color:transparent;border:1px solid transparent;border-radius:6px;transition:all .3s cubic-bezier(.645,.045,.355,1);overflow:hidden}.nz-search-wrapper:hover:not(.expanded){background-color:#0000000a;cursor:pointer}.nz-search-wrapper.expanded{width:250px;background-color:#fff;border-color:#1890ff;box-shadow:0 0 0 2px #1890ff33}.nz-search-wrapper.expanded .custom-search-input{width:100%;padding:4px 32px 4px 11px;opacity:1}.custom-search-input{width:0;opacity:0;border:none;outline:none;background:transparent;padding:0;font-size:14px;color:#000000d9;transition:all .3s cubic-bezier(.645,.045,.355,1)}.custom-search-input::placeholder{color:#bfbfbf}.suffix-wrap{position:absolute;right:0;top:0;width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;cursor:pointer}.suffix-icon{position:absolute;display:flex;align-items:center;justify-content:center;font-size:16px;opacity:0;pointer-events:none;transition:opacity .2s ease}.suffix-icon.show{opacity:1;pointer-events:auto}.search{color:var(--primary-color)}.delete{color:#bfbfbf}.delete:hover{color:#ff4d4f}.delete.show{animation:popIn .18s ease}@keyframes popIn{0%{transform:scale(.5)}70%{transform:scale(1.15)}to{transform:scale(1)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }] });
6472
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.7", type: ExpandableSearchComponent, isStandalone: true, selector: "expandable-search", inputs: { searchValue: "searchValue" }, outputs: { searchValueChange: "searchValueChange", onSearch: "onSearch" }, viewQueries: [{ propertyName: "searchInputRef", first: true, predicate: ["searchInput"], descendants: true }], ngImport: i0, template: "<div class=\"nz-search-wrapper\" [class.expanded]=\"isExpanded\">\r\n <input\r\n #searchInput\r\n type=\"text\"\r\n class=\"custom-search-input\"\r\n [(ngModel)]=\"searchValue\"\r\n placeholder=\"Nh\u1EADp \u0111i\u1EC1u ki\u1EC7n t\u00ECm ki\u1EBFm...\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n (keyup.enter)=\"performSearch()\"\r\n />\r\n\r\n <span class=\"suffix-wrap\" (mousedown)=\"$event.preventDefault()\" (click)=\"toggleSearch()\">\r\n <i\r\n nz-icon\r\n nzType=\"close-circle\"\r\n nzTheme=\"fill\"\r\n class=\"suffix-icon delete\"\r\n [class.show]=\"isExpanded && searchValue\"\r\n (click)=\"clearSearch($event)\"\r\n ></i>\r\n\r\n <i\r\n nz-icon\r\n nzType=\"search\"\r\n nzTheme=\"outline\"\r\n class=\"suffix-icon search\"\r\n [class.show]=\"!isExpanded || !searchValue\"\r\n ></i>\r\n </span>\r\n</div>\r\n", styles: ["@charset \"UTF-8\";.nz-search-wrapper{position:relative;display:inline-flex;align-items:center;height:32px;width:32px;background-color:transparent;border:1px solid transparent;border-radius:6px;transition:all .3s cubic-bezier(.645,.045,.355,1);overflow:hidden}.nz-search-wrapper:hover:not(.expanded){background-color:#0000000a;cursor:pointer}.nz-search-wrapper.expanded{width:250px;background-color:#fff;border-color:#1890ff;box-shadow:0 0 0 2px #1890ff33}.nz-search-wrapper.expanded .custom-search-input{width:100%;padding:4px 32px 4px 11px;opacity:1}.custom-search-input{width:0;opacity:0;border:none;outline:none;background:transparent;padding:0;font-size:14px;color:#000000d9;transition:all .3s cubic-bezier(.645,.045,.355,1)}.custom-search-input::placeholder{color:#bfbfbf}.suffix-wrap{position:absolute;right:0;top:0;width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;cursor:pointer}.suffix-icon{position:absolute;top:-1px;left:4px;width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-size:16px;opacity:0;pointer-events:none;transition:opacity .2s ease}.suffix-icon.show{opacity:1;pointer-events:auto}.search{color:var(--primary-color)}.search.white{color:#fff}.delete{color:#bfbfbf}.delete:hover{color:#ff4d4f}.delete.show{animation:popIn .18s ease}.nz-search-wrapper{position:relative;display:inline-flex;align-items:center;height:36px;width:36px;background-color:transparent;border:1px solid transparent;border-radius:50%;transition:all .3s cubic-bezier(.645,.045,.355,1);overflow:hidden}.nz-search-wrapper:hover:not(.expanded){background-color:#ffffff26;cursor:pointer}.nz-search-wrapper.expanded{width:250px;background-color:#fff;border-color:#1890ff;box-shadow:0 0 0 2px #1890ff33;border-radius:6px}.nz-search-wrapper.expanded .custom-search-input{width:100%;padding:4px 40px 4px 11px;opacity:1}.suffix-wrap{position:absolute;right:0;top:0;width:40px;height:40px;display:inline-flex;align-items:center;justify-content:center;cursor:pointer}@keyframes popIn{0%{transform:scale(.5)}70%{transform:scale(1.15)}to{transform:scale(1)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }] });
6432
6473
  }
6433
6474
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: ExpandableSearchComponent, decorators: [{
6434
6475
  type: Component,
6435
- args: [{ selector: 'expandable-search', imports: [CommonModule, FormsModule, NzIconModule], template: "<div class=\"nz-search-wrapper\" [class.expanded]=\"isExpanded\">\r\n <input\r\n #searchInput\r\n type=\"text\"\r\n class=\"custom-search-input\"\r\n [(ngModel)]=\"searchValue\"\r\n placeholder=\"Nh\u1EADp \u0111i\u1EC1u ki\u1EC7n t\u00ECm ki\u1EBFm...\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n (keyup.enter)=\"performSearch()\"\r\n />\r\n\r\n <span class=\"suffix-wrap\" (mousedown)=\"$event.preventDefault()\" (click)=\"toggleSearch()\">\r\n <i\r\n nz-icon\r\n nzType=\"close-circle\"\r\n nzTheme=\"fill\"\r\n class=\"suffix-icon delete\"\r\n [class.show]=\"isExpanded && searchValue\"\r\n (click)=\"clearSearch($event)\"\r\n ></i>\r\n\r\n <i\r\n nz-icon\r\n nzType=\"search\"\r\n nzTheme=\"outline\"\r\n class=\"suffix-icon search\"\r\n [class.show]=\"!isExpanded || !searchValue\"\r\n ></i>\r\n </span>\r\n</div>\r\n", styles: ["@charset \"UTF-8\";.nz-search-wrapper{position:relative;display:inline-flex;align-items:center;height:32px;width:32px;background-color:transparent;border:1px solid transparent;border-radius:6px;transition:all .3s cubic-bezier(.645,.045,.355,1);overflow:hidden}.nz-search-wrapper:hover:not(.expanded){background-color:#0000000a;cursor:pointer}.nz-search-wrapper.expanded{width:250px;background-color:#fff;border-color:#1890ff;box-shadow:0 0 0 2px #1890ff33}.nz-search-wrapper.expanded .custom-search-input{width:100%;padding:4px 32px 4px 11px;opacity:1}.custom-search-input{width:0;opacity:0;border:none;outline:none;background:transparent;padding:0;font-size:14px;color:#000000d9;transition:all .3s cubic-bezier(.645,.045,.355,1)}.custom-search-input::placeholder{color:#bfbfbf}.suffix-wrap{position:absolute;right:0;top:0;width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;cursor:pointer}.suffix-icon{position:absolute;display:flex;align-items:center;justify-content:center;font-size:16px;opacity:0;pointer-events:none;transition:opacity .2s ease}.suffix-icon.show{opacity:1;pointer-events:auto}.search{color:var(--primary-color)}.delete{color:#bfbfbf}.delete:hover{color:#ff4d4f}.delete.show{animation:popIn .18s ease}@keyframes popIn{0%{transform:scale(.5)}70%{transform:scale(1.15)}to{transform:scale(1)}}\n"] }]
6476
+ args: [{ selector: 'expandable-search', imports: [CommonModule, FormsModule, NzIconModule], template: "<div class=\"nz-search-wrapper\" [class.expanded]=\"isExpanded\">\r\n <input\r\n #searchInput\r\n type=\"text\"\r\n class=\"custom-search-input\"\r\n [(ngModel)]=\"searchValue\"\r\n placeholder=\"Nh\u1EADp \u0111i\u1EC1u ki\u1EC7n t\u00ECm ki\u1EBFm...\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n (keyup.enter)=\"performSearch()\"\r\n />\r\n\r\n <span class=\"suffix-wrap\" (mousedown)=\"$event.preventDefault()\" (click)=\"toggleSearch()\">\r\n <i\r\n nz-icon\r\n nzType=\"close-circle\"\r\n nzTheme=\"fill\"\r\n class=\"suffix-icon delete\"\r\n [class.show]=\"isExpanded && searchValue\"\r\n (click)=\"clearSearch($event)\"\r\n ></i>\r\n\r\n <i\r\n nz-icon\r\n nzType=\"search\"\r\n nzTheme=\"outline\"\r\n class=\"suffix-icon search\"\r\n [class.show]=\"!isExpanded || !searchValue\"\r\n ></i>\r\n </span>\r\n</div>\r\n", styles: ["@charset \"UTF-8\";.nz-search-wrapper{position:relative;display:inline-flex;align-items:center;height:32px;width:32px;background-color:transparent;border:1px solid transparent;border-radius:6px;transition:all .3s cubic-bezier(.645,.045,.355,1);overflow:hidden}.nz-search-wrapper:hover:not(.expanded){background-color:#0000000a;cursor:pointer}.nz-search-wrapper.expanded{width:250px;background-color:#fff;border-color:#1890ff;box-shadow:0 0 0 2px #1890ff33}.nz-search-wrapper.expanded .custom-search-input{width:100%;padding:4px 32px 4px 11px;opacity:1}.custom-search-input{width:0;opacity:0;border:none;outline:none;background:transparent;padding:0;font-size:14px;color:#000000d9;transition:all .3s cubic-bezier(.645,.045,.355,1)}.custom-search-input::placeholder{color:#bfbfbf}.suffix-wrap{position:absolute;right:0;top:0;width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;cursor:pointer}.suffix-icon{position:absolute;top:-1px;left:4px;width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-size:16px;opacity:0;pointer-events:none;transition:opacity .2s ease}.suffix-icon.show{opacity:1;pointer-events:auto}.search{color:var(--primary-color)}.search.white{color:#fff}.delete{color:#bfbfbf}.delete:hover{color:#ff4d4f}.delete.show{animation:popIn .18s ease}.nz-search-wrapper{position:relative;display:inline-flex;align-items:center;height:36px;width:36px;background-color:transparent;border:1px solid transparent;border-radius:50%;transition:all .3s cubic-bezier(.645,.045,.355,1);overflow:hidden}.nz-search-wrapper:hover:not(.expanded){background-color:#ffffff26;cursor:pointer}.nz-search-wrapper.expanded{width:250px;background-color:#fff;border-color:#1890ff;box-shadow:0 0 0 2px #1890ff33;border-radius:6px}.nz-search-wrapper.expanded .custom-search-input{width:100%;padding:4px 40px 4px 11px;opacity:1}.suffix-wrap{position:absolute;right:0;top:0;width:40px;height:40px;display:inline-flex;align-items:center;justify-content:center;cursor:pointer}@keyframes popIn{0%{transform:scale(.5)}70%{transform:scale(1.15)}to{transform:scale(1)}}\n"] }]
6436
6477
  }], propDecorators: { searchInputRef: [{
6437
6478
  type: ViewChild,
6438
6479
  args: ['searchInput']
@@ -6514,75 +6555,45 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImpor
6514
6555
  class PermissionService extends HTTPService {
6515
6556
  cms = inject(CommonService);
6516
6557
  updateUserRoleRef(data) {
6517
- return this.cms.ESP({
6518
- SPN: 'Permission_updateUserRoleRef',
6519
- Params: [data],
6520
- });
6558
+ return this.postData(AppGlobals.apiEndpoint + '/api/permission/updateUserRoleRef', data);
6521
6559
  }
6522
- getUserRoleRef() {
6523
- return this.cms.ESP({
6524
- SPN: 'Permission_getUserRoleRef',
6525
- });
6560
+ getUserRoleRef(RoleId = '', SearchRole = '', SearchUser = '') {
6561
+ const pr = new HttpParams()
6562
+ .append('RoleId', RoleId)
6563
+ .append('SearchRole', SearchRole)
6564
+ .append('SearchUser', SearchUser);
6565
+ return this.getParams(AppGlobals.apiEndpoint + '/api/permission/getUserRoleRef', pr);
6526
6566
  }
6527
6567
  updateRoleMenuRef(data) {
6528
- return this.cms.ESP({
6529
- SPN: 'Permission_updateRoleMenuRef',
6530
- Params: [data],
6531
- });
6532
- }
6533
- getRoleMenuRef() {
6534
- return this.cms.ESP({
6535
- SPN: 'Permission_getRoleMenuRef',
6536
- });
6537
- }
6538
- getRoleMenuRefStr(RoleId) {
6539
- return this.cms.ESP({
6540
- SPN: 'Permission_getRoleMenuRefStr',
6541
- Params: [RoleId],
6542
- });
6568
+ return this.postData(AppGlobals.apiEndpoint + '/api/permission/updateRoleMenuRef', data);
6543
6569
  }
6544
- getUserRoleRefStr(RoleId) {
6545
- return this.cms.ESP({
6546
- SPN: 'Permission_getUserRoleRefStr',
6547
- Params: [RoleId],
6548
- });
6549
- }
6550
- getUserForRole(RoleId) {
6551
- return this.cms.ESP({
6552
- SPN: 'Permission_getUserForRole',
6553
- Params: [RoleId],
6554
- });
6570
+ getRoleMenuRef(RoleId) {
6571
+ const pr = new HttpParams().append('RoleId', RoleId);
6572
+ return this.getParams(AppGlobals.apiEndpoint + '/api/permission/getRoleMenuRef', pr);
6555
6573
  }
6556
6574
  createPermission(obj) {
6557
- return this.postData(AppGlobals.apiEndpoint + '/api/App_Permission/AddOrEdit', obj);
6575
+ return this.postData(AppGlobals.apiEndpoint + '/api/permission/AddOrEdit', obj);
6558
6576
  }
6559
6577
  createLstPermission(bulkPayload) {
6560
- return this.postData(AppGlobals.apiEndpoint + '/api/App_Permission/AddOrEditLst', bulkPayload);
6578
+ return this.postData(AppGlobals.apiEndpoint + '/api/permission/createLstPermission', bulkPayload);
6561
6579
  }
6562
6580
  deletePermission(id) {
6563
6581
  const p = new HttpParams().append('id', id);
6564
- return this.postParams(AppGlobals.apiEndpoint + '/api/App_Permission/delete', p);
6582
+ return this.postParams(AppGlobals.apiEndpoint + '/api/permission/delete', p);
6565
6583
  }
6566
6584
  getResourcePermission(searchText) {
6567
- return this.cms.ESP({
6568
- SPN: 'Permission_getResourcePermission',
6569
- Params: [searchText],
6570
- });
6585
+ const pr = new HttpParams().append('searchText', searchText);
6586
+ return this.getParams(AppGlobals.apiEndpoint + '/api/permission/getResourcePermission', pr);
6571
6587
  }
6572
6588
  getPermissionGroupByCode() {
6573
- return this.cms.ESP({
6574
- SPN: 'Permission_getPermissionGroupByCode',
6575
- });
6589
+ return this.get(AppGlobals.apiEndpoint + '/api/permission/getPermissionGroupByCode');
6576
6590
  }
6577
- addRoleResourcePermissionRef(roleId, permissionCodes) {
6578
- let pr = new HttpParams().append('roleId', roleId).append('permissionCodes', permissionCodes);
6579
- return this.postParams(AppGlobals.apiEndpoint + '/api/App_Permission/addRoleResourcePermissionRef', pr);
6591
+ addRoleResourcePermissionRef(obj) {
6592
+ return this.postData(AppGlobals.apiEndpoint + '/api/permission/addRoleResourcePermissionRef', obj);
6580
6593
  }
6581
6594
  getRolePermissions(roleId) {
6582
- return this.cms.ESP({
6583
- SPN: 'Permission_getRolePermissions',
6584
- Params: [roleId],
6585
- });
6595
+ let pr = new HttpParams().append('roleId', roleId);
6596
+ return this.getParams(AppGlobals.apiEndpoint + '/api/permission/getRolePermissions', pr);
6586
6597
  }
6587
6598
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: PermissionService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
6588
6599
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: PermissionService, providedIn: 'root' });
@@ -6605,30 +6616,20 @@ const URLs$5 = {
6605
6616
  class RoleService extends HTTPService {
6606
6617
  commonService = inject(CommonService);
6607
6618
  getById(id) {
6608
- return this.commonService.ESP({
6609
- SPN: 'App_Role_getById',
6610
- Params: [id],
6611
- });
6619
+ let pr = new HttpParams().append('id', id);
6620
+ return this.postParams(AppGlobals.apiEndpoint + URLs$5.getById, pr);
6612
6621
  }
6613
6622
  getAll() {
6614
- return this.commonService.ESP({
6615
- SPN: 'App_Role_getAll',
6616
- });
6623
+ return this.post(AppGlobals.apiEndpoint + URLs$5.getAll);
6617
6624
  }
6618
6625
  getList(filter) {
6619
6626
  return this.postData(AppGlobals.apiEndpoint + URLs$5.getList, filter);
6620
6627
  }
6621
6628
  getPaging(filter) {
6622
- return this.commonService.ESP({
6623
- SPN: 'App_Role_getPaging',
6624
- Params: [filter],
6625
- });
6629
+ return this.postData(AppGlobals.apiEndpoint + URLs$5.getPaging, filter);
6626
6630
  }
6627
6631
  addOrEdit(obj) {
6628
- return this.commonService.ESP({
6629
- SPN: 'App_Role_addOrEdit',
6630
- Params: [obj],
6631
- });
6632
+ return this.postData(AppGlobals.apiEndpoint + URLs$5.addOrEdit, obj);
6632
6633
  }
6633
6634
  delete(id) {
6634
6635
  const params = new HttpParams().append('id', id);
@@ -6649,72 +6650,38 @@ const URLs$4 = {
6649
6650
  getAll: '/api/App_Menu/GetAll',
6650
6651
  getList: '/api/App_Menu/GetList',
6651
6652
  getPaging: '/api/App_Menu/GetPaging',
6653
+ getTree: '/api/App_Menu/getTree',
6652
6654
  addOrEdit: '/api/App_Menu/AddOrEdit',
6653
6655
  delete: '/api/App_Menu/Delete',
6654
6656
  };
6655
6657
  class MenuService extends HTTPService {
6656
6658
  commonService = inject(CommonService);
6657
6659
  getById(id) {
6658
- return this.commonService.ESP({
6659
- SPN: 'App_Menu_getById',
6660
- Params: [id],
6661
- });
6660
+ let pr = new HttpParams().append('id', id);
6661
+ return this.postParams(AppGlobals.apiEndpoint + URLs$4.getById, pr);
6662
6662
  }
6663
6663
  getAll() {
6664
- return this.commonService.ESP({
6665
- SPN: 'App_Menu_getAll',
6666
- });
6664
+ return this.post(AppGlobals.apiEndpoint + URLs$4.getAll);
6667
6665
  }
6668
6666
  getList(filter) {
6669
6667
  return this.postData(AppGlobals.apiEndpoint + URLs$4.getList, filter);
6670
6668
  }
6671
6669
  getPaging(filter) {
6672
- return this.commonService.ESP({
6673
- SPN: 'App_Menu_getPaging',
6674
- Params: [filter],
6675
- });
6670
+ return this.postData(AppGlobals.apiEndpoint + URLs$4.getPaging, filter);
6676
6671
  }
6677
6672
  addOrEdit(obj) {
6678
- return this.commonService.ESP({
6679
- SPN: 'App_Menu_addOrEdit',
6680
- Params: [obj],
6681
- });
6673
+ return this.postData(AppGlobals.apiEndpoint + URLs$4.addOrEdit, obj);
6682
6674
  }
6683
6675
  delete(id) {
6684
6676
  const params = new HttpParams().append('id', id);
6685
6677
  return this.postParams(AppGlobals.apiEndpoint + URLs$4.delete, params);
6686
6678
  }
6687
6679
  getTree() {
6688
- return this.commonService.ESP({
6689
- SPN: 'App_Menu_getTree',
6690
- });
6691
- }
6692
- getRolesByMenuId(menuId) {
6693
- return this.commonService.ESP({
6694
- SPN: 'App_Role_Menu_Ref_getByMenuId',
6695
- Params: [menuId],
6696
- });
6680
+ return this.post(AppGlobals.apiEndpoint + URLs$4.getTree);
6697
6681
  }
6698
- addRolesToMenu(menuId, roleIds) {
6699
- if (!menuId) {
6700
- return Promise.reject('Menu ID is required');
6701
- }
6702
- return this.commonService.ESP({
6703
- SPN: 'App_Menu_addRolesToMenu',
6704
- Params: [menuId, roleIds.join(',')],
6705
- });
6706
- }
6707
- updateRoleMenuPermission(obj) {
6708
- return this.commonService.ESP({
6709
- SPN: 'App_Menu_updateRoleMenuPermission',
6710
- Params: [obj.App_Role_Menu_Ref_Id, obj.HasViewPermission, obj.HasEditPermission],
6711
- });
6712
- }
6713
- deleteRoleFromMenu(refId) {
6714
- return this.commonService.ESP({
6715
- SPN: 'App_Menu_deleteRoleFromMenu',
6716
- Params: [refId],
6717
- });
6682
+ getRoleMenuRefByMenuId(menuId) {
6683
+ let pr = new HttpParams().append('menuId', menuId);
6684
+ return this.postParams(AppGlobals.apiEndpoint + '/api/App_Menu/getRoleMenuRefByMenuId', pr);
6718
6685
  }
6719
6686
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: MenuService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
6720
6687
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: MenuService, providedIn: 'root' });
@@ -6726,99 +6693,360 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImpor
6726
6693
  }]
6727
6694
  }] });
6728
6695
 
6729
- class RoleMenuPermission extends BaseComponent {
6730
- roleService = inject(RoleService);
6731
- menuService = inject(MenuService);
6732
- permissionService = inject(PermissionService);
6733
- lstRole = [];
6734
- lstMenu = [];
6735
- lstRoleMenuRef = [];
6736
- // Mapping quyền: RoleId -> MenuId -> boolean
6737
- roleMenuMap = {};
6738
- // Quản lý trạng thái Checkbox của từng cột (Role) trên Thead
6739
- roleColumnState = {};
6740
- ngOnInit() {
6741
- this.getData();
6742
- }
6743
- getData() {
6744
- Promise.all([this.roleService.getAll(), this.menuService.getAll(), this.permissionService.getRoleMenuRef()])
6745
- .then(([roleRes, menuRes, roleMenuRefRes]) => {
6746
- this.lstRole = roleRes.Data || [];
6747
- this.lstMenu = menuRes.Data || [];
6748
- this.lstRoleMenuRef = roleMenuRefRes.Data || [];
6749
- this.initializeRoleMenuMap();
6750
- })
6751
- .catch((err) => this.handleError(err));
6752
- }
6753
- initializeRoleMenuMap() {
6754
- this.roleMenuMap = {};
6755
- // 1. Dùng Set để tra cứu O(1) thay vì dùng Array.find()
6756
- const roleMenuSet = new Set(this.lstRoleMenuRef.map((x) => `${x.App_Role_Id}_${x.App_Menu_Id}`));
6757
- this.lstRole.forEach((role) => {
6758
- const roleId = role.App_Role_Id;
6759
- this.roleMenuMap[roleId] = {};
6760
- this.lstMenu.forEach((menu) => {
6761
- const menuId = menu.App_Menu_Id;
6762
- // 2. Lookup siêu tốc bằng Set.has()
6763
- this.roleMenuMap[roleId][menuId] = roleMenuSet.has(`${roleId}_${menuId}`);
6764
- });
6765
- // 3. Tính toán sẵn trạng thái Select All cho cột Role hiện tại
6766
- this.updateRoleColumnState(roleId);
6767
- });
6768
- }
6769
- // Cập nhật trạng thái Checked / Indeterminate cho cột Role
6770
- updateRoleColumnState(roleId) {
6771
- if (!this.lstMenu.length) {
6772
- this.roleColumnState[roleId] = { checked: false, indeterminate: false };
6773
- return;
6774
- }
6775
- let checkedCount = 0;
6776
- this.lstMenu.forEach((menu) => {
6777
- if (this.roleMenuMap[roleId][menu.App_Menu_Id]) {
6778
- checkedCount++;
6779
- }
6780
- });
6781
- this.roleColumnState[roleId] = {
6782
- checked: checkedCount === this.lstMenu.length,
6783
- indeterminate: checkedCount > 0 && checkedCount < this.lstMenu.length,
6784
- };
6785
- }
6786
- // Khi click vào Checkbox All trên Thead
6787
- toggleRolePermissions(roleId, checked) {
6788
- this.lstMenu.forEach((menu) => {
6789
- this.roleMenuMap[roleId][menu.App_Menu_Id] = checked;
6790
- });
6791
- // Tính lại trạng thái của cột này
6792
- this.updateRoleColumnState(roleId);
6793
- }
6794
- // Khi click vào từng Checkbox lẻ trong Tbody
6795
- onSinglePermissionChange(roleId) {
6796
- this.updateRoleColumnState(roleId);
6797
- }
6798
- convertRoleMenuMapToArray() {
6799
- const result = [];
6800
- Object.keys(this.roleMenuMap).forEach((roleId) => {
6801
- Object.keys(this.roleMenuMap[roleId]).forEach((menuId) => {
6802
- result.push({
6803
- RoleId: roleId,
6804
- MenuId: menuId,
6805
- IsChecked: this.roleMenuMap[roleId][menuId],
6806
- });
6807
- });
6808
- });
6809
- return result;
6810
- }
6811
- saveRoleMenuMap() {
6812
- const payload = this.convertRoleMenuMapToArray();
6813
- this.permissionService.updateRoleMenuRef(payload).then(() => this.notiService.success(this.translate.instant(this.TranslateKey.SAVE_SUCCESS)), (err) => this.handleError(err));
6814
- }
6815
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: RoleMenuPermission, deps: null, target: i0.ɵɵFactoryTarget.Component });
6816
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.7", type: RoleMenuPermission, isStandalone: true, selector: "app-role-menu-permission", usesInheritance: true, ngImport: i0, template: "<div nz-row [nzGutter]=\"[0, 8]\">\r\n <div nz-col nzSpan=\"24\" nz-flex nzGap=\"small\">\r\n <button nz-button nzType=\"primary\" (click)=\"saveRoleMenuMap()\">{{ TranslateKey.SAVE | translate }}</button>\r\n <button nz-button nzType=\"primary\" (click)=\"getData()\">{{ TranslateKey.REFEESH | translate }}</button>\r\n </div>\r\n <div nz-col nzSpan=\"24\">\r\n <nz-table [nzData]=\"lstMenu\" nzShowPagination=\"false\" [nzBordered]=\"true\" [nzSize]=\"'small'\">\r\n <thead>\r\n <tr>\r\n <th nzWidth=\"200px\"></th>\r\n @for (role of lstRole; track role.App_Role_Id) {\r\n <th style=\"text-align: center\">{{ role.Name }}</th>\r\n }\r\n </tr>\r\n <tr>\r\n <th nzWidth=\"200px\"></th>\r\n @for (role of lstRole; track role.App_Role_Id) {\r\n <th style=\"text-align: center\">\r\n <label\r\n nz-checkbox\r\n [nzChecked]=\"roleColumnState[role.App_Role_Id!].checked\"\r\n [nzIndeterminate]=\"roleColumnState[role.App_Role_Id!].indeterminate\"\r\n (nzCheckedChange)=\"toggleRolePermissions(role.App_Role_Id!, $event)\"\r\n ></label>\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (menu of lstMenu; track menu.App_Menu_Id) {\r\n <tr>\r\n <td>{{ menu.TreeNodeName }}</td>\r\n @for (role of lstRole; track role.App_Role_Id) {\r\n <td class=\"text-center\">\r\n <label\r\n nz-checkbox\r\n [(ngModel)]=\"roleMenuMap[role.App_Role_Id!][menu.App_Menu_Id]\"\r\n (ngModelChange)=\"onSinglePermissionChange(role.App_Role_Id!)\"\r\n ></label>\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </nz-table>\r\n </div>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: NzSpinModule }, { kind: "ngmodule", type: NzTableModule }, { kind: "component", type: i1$5.NzTableComponent, selector: "nz-table", inputs: ["nzTableLayout", "nzShowTotal", "nzItemRender", "nzTitle", "nzFooter", "nzNoResult", "nzPageSizeOptions", "nzVirtualItemSize", "nzVirtualMaxBufferPx", "nzVirtualMinBufferPx", "nzVirtualForTrackBy", "nzLoadingDelay", "nzPageIndex", "nzPageSize", "nzTotal", "nzWidthConfig", "nzData", "nzCustomColumn", "nzPaginationPosition", "nzScroll", "noDataVirtualHeight", "nzPaginationType", "nzFrontPagination", "nzTemplateMode", "nzShowPagination", "nzLoading", "nzOuterBordered", "nzLoadingIndicator", "nzBordered", "nzSize", "nzShowSizeChanger", "nzHideOnSinglePage", "nzShowQuickJumper", "nzSimple"], outputs: ["nzPageSizeChange", "nzPageIndexChange", "nzQueryParams", "nzCurrentPageDataChange", "nzCustomColumnChange"], exportAs: ["nzTable"] }, { kind: "directive", type: i1$5.NzTableCellDirective, selector: "th:not(.nz-disable-th):not([mat-cell]), td:not(.nz-disable-td):not([mat-cell])" }, { kind: "directive", type: i1$5.NzThMeasureDirective, selector: "th", inputs: ["nzWidth", "colspan", "colSpan", "rowspan", "rowSpan"] }, { kind: "component", type: i1$5.NzTheadComponent, selector: "thead:not(.ant-table-thead)", outputs: ["nzSortOrderChange"] }, { kind: "component", type: i1$5.NzTbodyComponent, selector: "tbody" }, { kind: "directive", type: i1$5.NzTrDirective, selector: "tr:not([mat-row]):not([mat-header-row]):not([nz-table-measure-row]):not([nzExpand]):not([nz-table-fixed-row])" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: NzCheckboxModule }, { kind: "component", type: i3.NzCheckboxComponent, selector: "[nz-checkbox]", inputs: ["nzValue", "nzAutoFocus", "nzDisabled", "nzIndeterminate", "nzChecked", "nzId", "nzName"], outputs: ["nzCheckedChange"], exportAs: ["nzCheckbox"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3$1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: NzButtonModule }, { kind: "component", type: i5$3.NzButtonComponent, selector: "button[nz-button], a[nz-button]", inputs: ["nzBlock", "nzGhost", "nzSearch", "nzLoading", "nzDanger", "disabled", "tabIndex", "nzType", "nzShape", "nzSize"], exportAs: ["nzButton"] }, { kind: "directive", type: i6$3.ɵ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: i7.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "ngmodule", type: NzGridModule }, { kind: "directive", type: i4.NzColDirective, selector: "[nz-col],nz-col,nz-form-control,nz-form-label", inputs: ["nzFlex", "nzSpan", "nzOrder", "nzOffset", "nzPush", "nzPull", "nzXs", "nzSm", "nzMd", "nzLg", "nzXl", "nzXXl"], exportAs: ["nzCol"] }, { kind: "directive", type: i4.NzRowDirective, selector: "[nz-row],nz-row,nz-form-item", inputs: ["nzAlign", "nzJustify", "nzGutter"], exportAs: ["nzRow"] }, { kind: "ngmodule", type: NzFlexModule }, { kind: "directive", type: i9.NzFlexDirective, selector: "[nz-flex],nz-flex", inputs: ["nzVertical", "nzJustify", "nzAlign", "nzGap", "nzWrap", "nzFlex"], exportAs: ["nzFlex"] }] });
6696
+ class App_Role {
6697
+ // #region properties
6698
+ App_Role_Id;
6699
+ CreatedDate;
6700
+ CreatedUser;
6701
+ UpdatedDate;
6702
+ UpdatedUser;
6703
+ IsActive;
6704
+ Code;
6705
+ Name;
6706
+ Description;
6707
+ LstMenuId;
6708
+ LstUserId;
6817
6709
  }
6818
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: RoleMenuPermission, decorators: [{
6819
- type: Component,
6820
- args: [{ selector: 'app-role-menu-permission', imports: [
6821
- NzSpinModule,
6710
+ class RoleFilter extends GridFilter {
6711
+ Code;
6712
+ Name;
6713
+ }
6714
+
6715
+ let App_Menu$1 = class App_Menu {
6716
+ // #region properties
6717
+ App_Menu_Id;
6718
+ App_Org_Id;
6719
+ IsActive;
6720
+ Name;
6721
+ TranslateKey;
6722
+ Url;
6723
+ Icon;
6724
+ OrderValue;
6725
+ ParentId;
6726
+ IsHidden;
6727
+ TreeNodeName;
6728
+ TreeNodeOrder;
6729
+ IsHeaderMenu;
6730
+ // #endregion properties
6731
+ Level;
6732
+ Open;
6733
+ SubMenu;
6734
+ ParentName;
6735
+ HasEditMenu; // for role menu ref
6736
+ AllSubHasEditMenu;
6737
+ SomeSubHasEditMenu;
6738
+ HasViewMenu; // for role menu ref
6739
+ AllSubHasViewMenu;
6740
+ SomeSubHasViewMenu;
6741
+ constructor(obj) {
6742
+ obj = obj || {};
6743
+ this.App_Menu_Id = obj.App_Menu_Id || '';
6744
+ this.App_Org_Id = obj.App_Org_Id || '';
6745
+ this.IsActive = obj.IsActive || null;
6746
+ this.Name = obj.Name || '';
6747
+ this.TranslateKey = obj.TranslateKey || '';
6748
+ this.ParentId = obj.ParentId || '';
6749
+ this.Url = obj.Url || '';
6750
+ this.Icon = obj.Icon || '';
6751
+ this.OrderValue = obj.OrderValue || null;
6752
+ this.IsHidden = obj.IsHidden || false;
6753
+ this.TreeNodeOrder = obj.TreeNodeOrder || '';
6754
+ this.IsHeaderMenu = obj.IsHeaderMenu || false;
6755
+ this.TreeNodeName = obj.TreeNodeName;
6756
+ this.Level = obj.Level;
6757
+ this.Open = obj.Open;
6758
+ this.SubMenu = obj.SubMenu;
6759
+ this.ParentName = obj.ParentName;
6760
+ this.HasEditMenu = obj.HasEditMenu;
6761
+ this.AllSubHasEditMenu = obj.AllSubHasEditMenu;
6762
+ this.SomeSubHasEditMenu = obj.SomeSubHasEditMenu;
6763
+ this.HasViewMenu = obj.HasViewMenu;
6764
+ this.AllSubHasViewMenu = obj.AllSubHasViewMenu;
6765
+ this.SomeSubHasViewMenu = obj.SomeSubHasViewMenu;
6766
+ }
6767
+ };
6768
+ class MenuFilter extends GridFilter {
6769
+ Name = '';
6770
+ ParentName = '';
6771
+ }
6772
+ // Model cho bảng trung gian Role-Menu
6773
+ class App_Role_Menu_Ref {
6774
+ App_Role_Menu_Ref_Id;
6775
+ App_Org_Id;
6776
+ CreatedDate;
6777
+ CreatedUser;
6778
+ App_Role_Id;
6779
+ App_Menu_Id;
6780
+ HasViewPermission;
6781
+ HasEditPermission;
6782
+ // For display - join với App_Role
6783
+ RoleCode;
6784
+ RoleName;
6785
+ RoleDescription;
6786
+ constructor(obj) {
6787
+ obj = obj || {};
6788
+ this.App_Role_Menu_Ref_Id = obj.App_Role_Menu_Ref_Id || '';
6789
+ this.App_Org_Id = obj.App_Org_Id || '';
6790
+ this.CreatedDate = obj.CreatedDate || null;
6791
+ this.CreatedUser = obj.CreatedUser || '';
6792
+ this.App_Role_Id = obj.App_Role_Id || '';
6793
+ this.App_Menu_Id = obj.App_Menu_Id || '';
6794
+ this.HasViewPermission = obj.HasViewPermission !== undefined ? obj.HasViewPermission : false;
6795
+ this.HasEditPermission = obj.HasEditPermission !== undefined ? obj.HasEditPermission : false;
6796
+ this.RoleCode = obj.RoleCode || '';
6797
+ this.RoleName = obj.RoleName || '';
6798
+ this.RoleDescription = obj.RoleDescription || '';
6799
+ }
6800
+ }
6801
+
6802
+ class ButtonBack {
6803
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: ButtonBack, deps: [], target: i0.ɵɵFactoryTarget.Component });
6804
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.7", type: ButtonBack, isStandalone: true, selector: "button-back", ngImport: i0, template: `
6805
+ <button type="button" nz-button nzType="default" nzSize="default">
6806
+ <nz-icon nzType="arrow-left" nzTheme="outline"></nz-icon>{{ 'BACK' | translate }}
6807
+ </button>
6808
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { 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$2.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
6809
+ }
6810
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: ButtonBack, decorators: [{
6811
+ type: Component,
6812
+ args: [{
6813
+ selector: 'button-back',
6814
+ template: `
6815
+ <button type="button" nz-button nzType="default" nzSize="default">
6816
+ <nz-icon nzType="arrow-left" nzTheme="outline"></nz-icon>{{ 'BACK' | translate }}
6817
+ </button>
6818
+ `,
6819
+ imports: [NzIconModule, NzButtonModule, TranslatePipe],
6820
+ }]
6821
+ }] });
6822
+ class ButtonSave {
6823
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: ButtonSave, deps: [], target: i0.ɵɵFactoryTarget.Component });
6824
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.7", type: ButtonSave, isStandalone: true, selector: "button-save", ngImport: i0, template: `
6825
+ <button type="button" nz-button nzType="primary" nzSize="default">
6826
+ <nz-icon nzType="save" nzTheme="outline"></nz-icon>{{ 'SAVE' | translate }}
6827
+ </button>
6828
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { 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$2.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
6829
+ }
6830
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: ButtonSave, decorators: [{
6831
+ type: Component,
6832
+ args: [{
6833
+ selector: 'button-save',
6834
+ template: `
6835
+ <button type="button" nz-button nzType="primary" nzSize="default">
6836
+ <nz-icon nzType="save" nzTheme="outline"></nz-icon>{{ 'SAVE' | translate }}
6837
+ </button>
6838
+ `,
6839
+ imports: [NzIconModule, NzButtonModule, TranslatePipe],
6840
+ }]
6841
+ }] });
6842
+ class ButtonAdd {
6843
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: ButtonAdd, deps: [], target: i0.ɵɵFactoryTarget.Component });
6844
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.7", type: ButtonAdd, isStandalone: true, selector: "button-add", ngImport: i0, template: `
6845
+ <button type="button" nz-button nzType="primary" nzSize="default">
6846
+ <nz-icon nzType="plus" nzTheme="outline"></nz-icon>{{ 'ADD' | translate }}
6847
+ </button>
6848
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { 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$2.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
6849
+ }
6850
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: ButtonAdd, decorators: [{
6851
+ type: Component,
6852
+ args: [{
6853
+ selector: 'button-add',
6854
+ template: `
6855
+ <button type="button" nz-button nzType="primary" nzSize="default">
6856
+ <nz-icon nzType="plus" nzTheme="outline"></nz-icon>{{ 'ADD' | translate }}
6857
+ </button>
6858
+ `,
6859
+ imports: [NzIconModule, NzButtonModule, TranslatePipe],
6860
+ }]
6861
+ }] });
6862
+ class ButtonDelete {
6863
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: ButtonDelete, deps: [], target: i0.ɵɵFactoryTarget.Component });
6864
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.7", type: ButtonDelete, isStandalone: true, selector: "button-delete", ngImport: i0, template: `
6865
+ <button type="button" nz-button nzType="primary" nzSize="default" nzDanger>
6866
+ <nz-icon nzType="delete" nzTheme="outline" />{{ 'DELETE' | translate }}
6867
+ </button>
6868
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { 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$2.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
6869
+ }
6870
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: ButtonDelete, decorators: [{
6871
+ type: Component,
6872
+ args: [{
6873
+ selector: 'button-delete',
6874
+ template: `
6875
+ <button type="button" nz-button nzType="primary" nzSize="default" nzDanger>
6876
+ <nz-icon nzType="delete" nzTheme="outline" />{{ 'DELETE' | translate }}
6877
+ </button>
6878
+ `,
6879
+ imports: [NzIconModule, NzButtonModule, TranslatePipe],
6880
+ }]
6881
+ }] });
6882
+ class ButtonSearch {
6883
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: ButtonSearch, deps: [], target: i0.ɵɵFactoryTarget.Component });
6884
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.7", type: ButtonSearch, isStandalone: true, selector: "button-search", ngImport: i0, template: `
6885
+ <button type="button" nz-button nzType="default" nzSize="default">
6886
+ <nz-icon nzType="search" nzTheme="outline" />{{ 'SEARCH' | translate }}
6887
+ </button>
6888
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { 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$2.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
6889
+ }
6890
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: ButtonSearch, decorators: [{
6891
+ type: Component,
6892
+ args: [{
6893
+ selector: 'button-search',
6894
+ template: `
6895
+ <button type="button" nz-button nzType="default" nzSize="default">
6896
+ <nz-icon nzType="search" nzTheme="outline" />{{ 'SEARCH' | translate }}
6897
+ </button>
6898
+ `,
6899
+ imports: [NzIconModule, NzButtonModule, TranslatePipe],
6900
+ }]
6901
+ }] });
6902
+ class ButtonEdit {
6903
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: ButtonEdit, deps: [], target: i0.ɵɵFactoryTarget.Component });
6904
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.7", type: ButtonEdit, isStandalone: true, selector: "button-edit", ngImport: i0, template: `
6905
+ <button type="button" nz-button nzType="default" nzSize="default">
6906
+ <nz-icon nzType="edit" nzTheme="outline" />{{ 'SEARCH' | translate }}
6907
+ </button>
6908
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { 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$2.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
6909
+ }
6910
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: ButtonEdit, decorators: [{
6911
+ type: Component,
6912
+ args: [{
6913
+ selector: 'button-edit',
6914
+ template: `
6915
+ <button type="button" nz-button nzType="default" nzSize="default">
6916
+ <nz-icon nzType="edit" nzTheme="outline" />{{ 'SEARCH' | translate }}
6917
+ </button>
6918
+ `,
6919
+ imports: [NzIconModule, NzButtonModule, TranslatePipe],
6920
+ }]
6921
+ }] });
6922
+ class ButtonReload {
6923
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: ButtonReload, deps: [], target: i0.ɵɵFactoryTarget.Component });
6924
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.7", type: ButtonReload, isStandalone: true, selector: "button-reload", ngImport: i0, template: `
6925
+ <button type="button" nz-button nzType="default" nzSize="default">
6926
+ <nz-icon nzType="reload" nzTheme="outline" />{{ 'REFEESH' | translate }}
6927
+ </button>
6928
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { 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$2.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
6929
+ }
6930
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: ButtonReload, decorators: [{
6931
+ type: Component,
6932
+ args: [{
6933
+ selector: 'button-reload',
6934
+ template: `
6935
+ <button type="button" nz-button nzType="default" nzSize="default">
6936
+ <nz-icon nzType="reload" nzTheme="outline" />{{ 'REFEESH' | translate }}
6937
+ </button>
6938
+ `,
6939
+ imports: [NzIconModule, NzButtonModule, TranslatePipe],
6940
+ }]
6941
+ }] });
6942
+
6943
+ class RoleMenuPermission extends BaseComponent {
6944
+ roleService = inject(RoleService);
6945
+ menuService = inject(MenuService);
6946
+ permissionService = inject(PermissionService);
6947
+ lstRole = [];
6948
+ lstMenu = [];
6949
+ lstRoleMenuRef = [];
6950
+ roleFilter = new RoleFilter();
6951
+ menuFilter = new MenuFilter();
6952
+ // Mapping quyền: RoleId -> MenuId -> boolean
6953
+ roleMenuMap = {};
6954
+ // Quản lý trạng thái Checkbox của từng cột (Role) trên Thead
6955
+ roleColumnState = {};
6956
+ ngOnInit() {
6957
+ this.getData();
6958
+ }
6959
+ getData() {
6960
+ Promise.all([
6961
+ this.roleService.getList(this.roleFilter),
6962
+ this.menuService.getList(this.menuFilter),
6963
+ this.permissionService.getRoleMenuRef(''),
6964
+ ])
6965
+ .then(([roleRes, menuRes, roleMenuRefRes]) => {
6966
+ this.lstRole = roleRes.Data || [];
6967
+ this.lstMenu = menuRes.Data || [];
6968
+ this.lstRoleMenuRef = roleMenuRefRes.Data || [];
6969
+ this.initializeRoleMenuMap();
6970
+ })
6971
+ .catch((err) => this.handleError(err));
6972
+ }
6973
+ initializeRoleMenuMap() {
6974
+ this.roleMenuMap = {};
6975
+ // 1. Dùng Set để tra cứu O(1) thay vì dùng Array.find()
6976
+ const roleMenuSet = new Set(this.lstRoleMenuRef.map((x) => `${x.App_Role_Id}_${x.App_Menu_Id}`));
6977
+ this.lstRole.forEach((role) => {
6978
+ const roleId = role.App_Role_Id;
6979
+ this.roleMenuMap[roleId] = {};
6980
+ this.lstMenu.forEach((menu) => {
6981
+ const menuId = menu.App_Menu_Id;
6982
+ // 2. Lookup siêu tốc bằng Set.has()
6983
+ this.roleMenuMap[roleId][menuId] = roleMenuSet.has(`${roleId}_${menuId}`);
6984
+ });
6985
+ // 3. Tính toán sẵn trạng thái Select All cho cột Role hiện tại
6986
+ this.updateRoleColumnState(roleId);
6987
+ });
6988
+ }
6989
+ // Cập nhật trạng thái Checked / Indeterminate cho cột Role
6990
+ updateRoleColumnState(roleId) {
6991
+ if (!this.lstMenu.length) {
6992
+ this.roleColumnState[roleId] = { checked: false, indeterminate: false };
6993
+ return;
6994
+ }
6995
+ let checkedCount = 0;
6996
+ this.lstMenu.forEach((menu) => {
6997
+ if (this.roleMenuMap[roleId][menu.App_Menu_Id]) {
6998
+ checkedCount++;
6999
+ }
7000
+ });
7001
+ this.roleColumnState[roleId] = {
7002
+ checked: checkedCount === this.lstMenu.length,
7003
+ indeterminate: checkedCount > 0 && checkedCount < this.lstMenu.length,
7004
+ };
7005
+ }
7006
+ // Khi click vào Checkbox All trên Thead
7007
+ toggleRolePermissions(roleId, checked) {
7008
+ this.lstMenu.forEach((menu) => {
7009
+ this.roleMenuMap[roleId][menu.App_Menu_Id] = checked;
7010
+ });
7011
+ // Tính lại trạng thái của cột này
7012
+ this.updateRoleColumnState(roleId);
7013
+ }
7014
+ // Khi click vào từng Checkbox lẻ trong Tbody
7015
+ onSinglePermissionChange(roleId) {
7016
+ this.updateRoleColumnState(roleId);
7017
+ }
7018
+ convertRoleMenuMapToArray() {
7019
+ const result = [];
7020
+ Object.keys(this.roleMenuMap).forEach((roleId) => {
7021
+ Object.keys(this.roleMenuMap[roleId]).forEach((menuId) => {
7022
+ result.push({
7023
+ RoleId: roleId,
7024
+ MenuId: menuId,
7025
+ IsChecked: this.roleMenuMap[roleId][menuId],
7026
+ });
7027
+ });
7028
+ });
7029
+ return result;
7030
+ }
7031
+ saveRoleMenuMap() {
7032
+ const map = this.convertRoleMenuMapToArray();
7033
+ const payload = map
7034
+ .filter((x) => x.IsChecked)
7035
+ .map((x) => {
7036
+ return {
7037
+ App_Role_Id: x.RoleId,
7038
+ App_Menu_Id: x.MenuId,
7039
+ };
7040
+ });
7041
+ this.permissionService.updateRoleMenuRef(payload).then(() => this.success(), (err) => this.handleError(err));
7042
+ }
7043
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: RoleMenuPermission, deps: null, target: i0.ɵɵFactoryTarget.Component });
7044
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.7", type: RoleMenuPermission, isStandalone: true, selector: "app-role-menu-permission", usesInheritance: true, ngImport: i0, template: "<div nz-row [nzGutter]=\"[0, 8]\">\r\n <div nz-col nzSpan=\"24\">\r\n <div nz-flex nzGap=\"small\" nzJustify=\"end\">\r\n <button-save (click)=\"saveRoleMenuMap()\"></button-save>\r\n <button-reload (click)=\"getData()\"></button-reload>\r\n </div>\r\n </div>\r\n <div nz-col nzSpan=\"24\">\r\n <nz-table [nzData]=\"lstMenu\" nzShowPagination=\"false\" [nzBordered]=\"true\" [nzSize]=\"'small'\">\r\n <thead>\r\n <tr>\r\n <th nzWidth=\"200px\">\r\n <extend-input\r\n [size]=\"'small'\"\r\n [placeHolder]=\"'Search Role ...'\"\r\n [(_ngModel)]=\"roleFilter.Name\"\r\n (keyup.enter)=\"getData()\"\r\n (onclickClearIcon)=\"getData()\"\r\n ></extend-input>\r\n <extend-input\r\n [size]=\"'small'\"\r\n [placeHolder]=\"'Search Menu ...'\"\r\n [(_ngModel)]=\"menuFilter.Name\"\r\n (keyup.enter)=\"getData()\"\r\n (onclickClearIcon)=\"getData()\"\r\n ></extend-input>\r\n </th>\r\n @for (role of lstRole; track role.App_Role_Id) {\r\n <th style=\"text-align: center\">{{ role.Name }}</th>\r\n }\r\n </tr>\r\n <tr>\r\n <th nzWidth=\"200px\"></th>\r\n @for (role of lstRole; track role.App_Role_Id) {\r\n <th style=\"text-align: center\">\r\n <label\r\n nz-checkbox\r\n [nzChecked]=\"roleColumnState[role.App_Role_Id!].checked\"\r\n [nzIndeterminate]=\"roleColumnState[role.App_Role_Id!].indeterminate\"\r\n (nzCheckedChange)=\"toggleRolePermissions(role.App_Role_Id!, $event)\"\r\n ></label>\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (menu of lstMenu; track menu.App_Menu_Id) {\r\n <tr>\r\n <td>{{ menu.TreeNodeName }}</td>\r\n @for (role of lstRole; track role.App_Role_Id) {\r\n <td class=\"text-center\">\r\n <label\r\n nz-checkbox\r\n [(ngModel)]=\"roleMenuMap[role.App_Role_Id!][menu.App_Menu_Id]\"\r\n (ngModelChange)=\"onSinglePermissionChange(role.App_Role_Id!)\"\r\n ></label>\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </nz-table>\r\n </div>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: NzSpinModule }, { kind: "ngmodule", type: NzTableModule }, { kind: "component", type: i1$5.NzTableComponent, selector: "nz-table", inputs: ["nzTableLayout", "nzShowTotal", "nzItemRender", "nzTitle", "nzFooter", "nzNoResult", "nzPageSizeOptions", "nzVirtualItemSize", "nzVirtualMaxBufferPx", "nzVirtualMinBufferPx", "nzVirtualForTrackBy", "nzLoadingDelay", "nzPageIndex", "nzPageSize", "nzTotal", "nzWidthConfig", "nzData", "nzCustomColumn", "nzPaginationPosition", "nzScroll", "noDataVirtualHeight", "nzPaginationType", "nzFrontPagination", "nzTemplateMode", "nzShowPagination", "nzLoading", "nzOuterBordered", "nzLoadingIndicator", "nzBordered", "nzSize", "nzShowSizeChanger", "nzHideOnSinglePage", "nzShowQuickJumper", "nzSimple"], outputs: ["nzPageSizeChange", "nzPageIndexChange", "nzQueryParams", "nzCurrentPageDataChange", "nzCustomColumnChange"], exportAs: ["nzTable"] }, { kind: "directive", type: i1$5.NzTableCellDirective, selector: "th:not(.nz-disable-th):not([mat-cell]), td:not(.nz-disable-td):not([mat-cell])" }, { kind: "directive", type: i1$5.NzThMeasureDirective, selector: "th", inputs: ["nzWidth", "colspan", "colSpan", "rowspan", "rowSpan"] }, { kind: "component", type: i1$5.NzTheadComponent, selector: "thead:not(.ant-table-thead)", outputs: ["nzSortOrderChange"] }, { kind: "component", type: i1$5.NzTbodyComponent, selector: "tbody" }, { kind: "directive", type: i1$5.NzTrDirective, selector: "tr:not([mat-row]):not([mat-header-row]):not([nz-table-measure-row]):not([nzExpand]):not([nz-table-fixed-row])" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: NzCheckboxModule }, { kind: "component", type: i3.NzCheckboxComponent, selector: "[nz-checkbox]", inputs: ["nzValue", "nzAutoFocus", "nzDisabled", "nzIndeterminate", "nzChecked", "nzId", "nzName"], outputs: ["nzCheckedChange"], exportAs: ["nzCheckbox"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: NzButtonModule }, { kind: "ngmodule", type: NzGridModule }, { kind: "directive", type: i4.NzColDirective, selector: "[nz-col],nz-col,nz-form-control,nz-form-label", inputs: ["nzFlex", "nzSpan", "nzOrder", "nzOffset", "nzPush", "nzPull", "nzXs", "nzSm", "nzMd", "nzLg", "nzXl", "nzXXl"], exportAs: ["nzCol"] }, { kind: "directive", type: i4.NzRowDirective, selector: "[nz-row],nz-row,nz-form-item", inputs: ["nzAlign", "nzJustify", "nzGutter"], exportAs: ["nzRow"] }, { kind: "ngmodule", type: NzFlexModule }, { kind: "directive", type: i5$3.NzFlexDirective, selector: "[nz-flex],nz-flex", inputs: ["nzVertical", "nzJustify", "nzAlign", "nzGap", "nzWrap", "nzFlex"], exportAs: ["nzFlex"] }, { kind: "component", type: ButtonSave, selector: "button-save" }, { kind: "component", type: ButtonReload, selector: "button-reload" }, { 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", "lstItem", "displayField", "valueField", "formData", "controlName", "_ngModel", "isSubmited"], outputs: ["_ngModelChange", "onclickClearIcon", "onenter"] }] });
7045
+ }
7046
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: RoleMenuPermission, decorators: [{
7047
+ type: Component,
7048
+ args: [{ selector: 'app-role-menu-permission', imports: [
7049
+ NzSpinModule,
6822
7050
  NzTableModule,
6823
7051
  FormsModule,
6824
7052
  NzCheckboxModule,
@@ -6826,7 +7054,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImpor
6826
7054
  NzButtonModule,
6827
7055
  NzGridModule,
6828
7056
  NzFlexModule,
6829
- ], template: "<div nz-row [nzGutter]=\"[0, 8]\">\r\n <div nz-col nzSpan=\"24\" nz-flex nzGap=\"small\">\r\n <button nz-button nzType=\"primary\" (click)=\"saveRoleMenuMap()\">{{ TranslateKey.SAVE | translate }}</button>\r\n <button nz-button nzType=\"primary\" (click)=\"getData()\">{{ TranslateKey.REFEESH | translate }}</button>\r\n </div>\r\n <div nz-col nzSpan=\"24\">\r\n <nz-table [nzData]=\"lstMenu\" nzShowPagination=\"false\" [nzBordered]=\"true\" [nzSize]=\"'small'\">\r\n <thead>\r\n <tr>\r\n <th nzWidth=\"200px\"></th>\r\n @for (role of lstRole; track role.App_Role_Id) {\r\n <th style=\"text-align: center\">{{ role.Name }}</th>\r\n }\r\n </tr>\r\n <tr>\r\n <th nzWidth=\"200px\"></th>\r\n @for (role of lstRole; track role.App_Role_Id) {\r\n <th style=\"text-align: center\">\r\n <label\r\n nz-checkbox\r\n [nzChecked]=\"roleColumnState[role.App_Role_Id!].checked\"\r\n [nzIndeterminate]=\"roleColumnState[role.App_Role_Id!].indeterminate\"\r\n (nzCheckedChange)=\"toggleRolePermissions(role.App_Role_Id!, $event)\"\r\n ></label>\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (menu of lstMenu; track menu.App_Menu_Id) {\r\n <tr>\r\n <td>{{ menu.TreeNodeName }}</td>\r\n @for (role of lstRole; track role.App_Role_Id) {\r\n <td class=\"text-center\">\r\n <label\r\n nz-checkbox\r\n [(ngModel)]=\"roleMenuMap[role.App_Role_Id!][menu.App_Menu_Id]\"\r\n (ngModelChange)=\"onSinglePermissionChange(role.App_Role_Id!)\"\r\n ></label>\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </nz-table>\r\n </div>\r\n</div>\r\n" }]
7057
+ ButtonSave,
7058
+ ButtonReload,
7059
+ ExtendInput,
7060
+ ], template: "<div nz-row [nzGutter]=\"[0, 8]\">\r\n <div nz-col nzSpan=\"24\">\r\n <div nz-flex nzGap=\"small\" nzJustify=\"end\">\r\n <button-save (click)=\"saveRoleMenuMap()\"></button-save>\r\n <button-reload (click)=\"getData()\"></button-reload>\r\n </div>\r\n </div>\r\n <div nz-col nzSpan=\"24\">\r\n <nz-table [nzData]=\"lstMenu\" nzShowPagination=\"false\" [nzBordered]=\"true\" [nzSize]=\"'small'\">\r\n <thead>\r\n <tr>\r\n <th nzWidth=\"200px\">\r\n <extend-input\r\n [size]=\"'small'\"\r\n [placeHolder]=\"'Search Role ...'\"\r\n [(_ngModel)]=\"roleFilter.Name\"\r\n (keyup.enter)=\"getData()\"\r\n (onclickClearIcon)=\"getData()\"\r\n ></extend-input>\r\n <extend-input\r\n [size]=\"'small'\"\r\n [placeHolder]=\"'Search Menu ...'\"\r\n [(_ngModel)]=\"menuFilter.Name\"\r\n (keyup.enter)=\"getData()\"\r\n (onclickClearIcon)=\"getData()\"\r\n ></extend-input>\r\n </th>\r\n @for (role of lstRole; track role.App_Role_Id) {\r\n <th style=\"text-align: center\">{{ role.Name }}</th>\r\n }\r\n </tr>\r\n <tr>\r\n <th nzWidth=\"200px\"></th>\r\n @for (role of lstRole; track role.App_Role_Id) {\r\n <th style=\"text-align: center\">\r\n <label\r\n nz-checkbox\r\n [nzChecked]=\"roleColumnState[role.App_Role_Id!].checked\"\r\n [nzIndeterminate]=\"roleColumnState[role.App_Role_Id!].indeterminate\"\r\n (nzCheckedChange)=\"toggleRolePermissions(role.App_Role_Id!, $event)\"\r\n ></label>\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (menu of lstMenu; track menu.App_Menu_Id) {\r\n <tr>\r\n <td>{{ menu.TreeNodeName }}</td>\r\n @for (role of lstRole; track role.App_Role_Id) {\r\n <td class=\"text-center\">\r\n <label\r\n nz-checkbox\r\n [(ngModel)]=\"roleMenuMap[role.App_Role_Id!][menu.App_Menu_Id]\"\r\n (ngModelChange)=\"onSinglePermissionChange(role.App_Role_Id!)\"\r\n ></label>\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </nz-table>\r\n </div>\r\n</div>\r\n" }]
6830
7061
  }] });
6831
7062
 
6832
7063
  const URLs$3 = {
@@ -6845,30 +7076,20 @@ class UserService extends HTTPService {
6845
7076
  return this.postParams(AppGlobals.apiEndpoint + URLs$3.getById, params);
6846
7077
  }
6847
7078
  getByIdEx(id) {
6848
- return this.cms.ESP({
6849
- SPN: 'App_User_getByIdEx',
6850
- Params: [id],
6851
- });
7079
+ const params = new HttpParams().append('id', id);
7080
+ return this.postParams(AppGlobals.apiEndpoint + URLs$3.getByIdEx, params);
6852
7081
  }
6853
7082
  getAll() {
6854
- return this.cms.ESP({
6855
- SPN: 'App_User_getAll',
6856
- });
7083
+ return this.post(AppGlobals.apiEndpoint + URLs$3.getAll);
6857
7084
  }
6858
7085
  getList(filter) {
6859
7086
  return this.postData(AppGlobals.apiEndpoint + URLs$3.getList, filter);
6860
7087
  }
6861
7088
  getPaging(filter) {
6862
- return this.cms.ESP({
6863
- SPN: 'App_User_getPaging',
6864
- Params: [filter],
6865
- });
7089
+ return this.postData(AppGlobals.apiEndpoint + URLs$3.getPaging, filter);
6866
7090
  }
6867
7091
  addOrEdit(obj) {
6868
- return this.cms.ESP({
6869
- SPN: 'App_User_addOrEdit',
6870
- Params: [obj],
6871
- });
7092
+ return this.postData(AppGlobals.apiEndpoint + URLs$3.addOrEdit, obj);
6872
7093
  }
6873
7094
  delete(id) {
6874
7095
  const params = new HttpParams().append('id', id);
@@ -6877,12 +7098,6 @@ class UserService extends HTTPService {
6877
7098
  importUser(data) {
6878
7099
  return this.postData(`${AppGlobals.apiEndpoint}/api/App_User/ImportUser`, data);
6879
7100
  }
6880
- checkImportUser(data) {
6881
- return this.cms.ESP({
6882
- SPN: 'App_User_checkImportUser',
6883
- Params: [data],
6884
- });
6885
- }
6886
7101
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: UserService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
6887
7102
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: UserService, providedIn: 'root' });
6888
7103
  }
@@ -6893,6 +7108,45 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImpor
6893
7108
  }]
6894
7109
  }] });
6895
7110
 
7111
+ class App_User {
7112
+ // #region properties
7113
+ App_User_Id;
7114
+ App_Org_Id;
7115
+ IsActive;
7116
+ CreateUser;
7117
+ CreateDate;
7118
+ UpdateUser;
7119
+ UpdateDate;
7120
+ UserName;
7121
+ FullName;
7122
+ Email;
7123
+ EmailConfirmed;
7124
+ PhoneNumber;
7125
+ PhoneNumberConfirmed;
7126
+ AccessFailedCount;
7127
+ IsAdmin;
7128
+ PasswordHash;
7129
+ SecurityStamp;
7130
+ LastLogin;
7131
+ IsLocked;
7132
+ // #endregion properties
7133
+ Password = '';
7134
+ ChangePassword = false;
7135
+ OrgName = '';
7136
+ LstOrgName = '';
7137
+ DepartmentId = 0;
7138
+ LoginStatus = false;
7139
+ lstOrg;
7140
+ lstRole;
7141
+ }
7142
+ class UserFilter extends GridFilter {
7143
+ UserName;
7144
+ FullName;
7145
+ OrgName;
7146
+ isUserNameSearch = false;
7147
+ isOrgNameSearch = false;
7148
+ }
7149
+
6896
7150
  class UserRolePermission extends BaseComponent {
6897
7151
  roleService = inject(RoleService);
6898
7152
  userService = inject(UserService);
@@ -6900,6 +7154,8 @@ class UserRolePermission extends BaseComponent {
6900
7154
  lstRole = [];
6901
7155
  lstUser = [];
6902
7156
  lstUserRoleRef = [];
7157
+ roleFilter = new RoleFilter();
7158
+ userFilter = new UserFilter();
6903
7159
  // Lưu trữ mapping quyền
6904
7160
  userRoleMap = {};
6905
7161
  // Lưu trữ trạng thái Checkbox của cột "Chọn tất cả" cho từng User để tránh gọi hàm trong HTML
@@ -6908,7 +7164,11 @@ class UserRolePermission extends BaseComponent {
6908
7164
  this.getData();
6909
7165
  }
6910
7166
  getData() {
6911
- Promise.all([this.roleService.getAll(), this.userService.getAll(), this.permissionService.getUserRoleRef()])
7167
+ Promise.all([
7168
+ this.roleService.getList(this.roleFilter),
7169
+ this.userService.getList(this.userFilter),
7170
+ this.permissionService.getUserRoleRef('', this.roleFilter.Name || '', this.userFilter.FullName || ''),
7171
+ ])
6912
7172
  .then(([roleRes, userRes, roleMenuRefRes]) => {
6913
7173
  this.lstRole = roleRes.Data || [];
6914
7174
  this.lstUser = userRes.Data || [];
@@ -6976,11 +7236,19 @@ class UserRolePermission extends BaseComponent {
6976
7236
  return result;
6977
7237
  }
6978
7238
  saveUserRoleMap() {
6979
- const payload = this.convertUserRoleMapToArray();
6980
- this.permissionService.updateUserRoleRef(payload).then(() => this.notiService.success(this.translate.instant(this.TranslateKey.SAVE_SUCCESS)), (err) => this.handleError(err));
7239
+ const userRoleMap = this.convertUserRoleMapToArray();
7240
+ const payload = userRoleMap
7241
+ .filter((x) => x.IsChecked)
7242
+ .map((x) => {
7243
+ return {
7244
+ App_User_Id: x.UserId,
7245
+ App_Role_Id: x.RoleId,
7246
+ };
7247
+ });
7248
+ this.permissionService.updateUserRoleRef(payload).then(() => this.success(), (err) => this.handleError(err));
6981
7249
  }
6982
7250
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: UserRolePermission, deps: null, target: i0.ɵɵFactoryTarget.Component });
6983
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.7", type: UserRolePermission, isStandalone: true, selector: "app-user-role-permission", usesInheritance: true, ngImport: i0, template: "<div nz-row [nzGutter]=\"[0, 8]\">\r\n <div nz-col nzSpan=\"24\" nz-flex nzGap=\"small\">\r\n <button nz-button nzType=\"primary\" (click)=\"saveUserRoleMap()\">{{ TranslateKey.SAVE | translate }}</button>\r\n <button nz-button nzType=\"primary\" (click)=\"getData()\">{{ TranslateKey.REFEESH | translate }}</button>\r\n </div>\r\n <div nz-col nzSpan=\"24\">\r\n <nz-table [nzData]=\"lstUser\" nzShowPagination=\"false\" [nzBordered]=\"true\" [nzSize]=\"'small'\">\r\n <thead>\r\n <tr>\r\n <th nzWidth=\"200px\"></th>\r\n <th nzWidth=\"40px\"></th>\r\n @for (role of lstRole; track role.App_Role_Id) {\r\n <th style=\"text-align: center\">{{ role.Name }}</th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (user of lstUser; track user.App_User_Id) {\r\n <tr>\r\n <td>{{ user.FullName }}</td>\r\n <td>\r\n <label\r\n nz-checkbox\r\n [nzChecked]=\"userRowState[user.App_User_Id!].checked\"\r\n [nzIndeterminate]=\"userRowState[user.App_User_Id!].indeterminate\"\r\n (nzCheckedChange)=\"toggleUserPermissions(user.App_User_Id!, $event)\"\r\n ></label>\r\n </td>\r\n @for (role of lstRole; track role.App_Role_Id) {\r\n <td class=\"text-center\">\r\n <label\r\n nz-checkbox\r\n [(ngModel)]=\"userRoleMap[user.App_User_Id!][role.App_Role_Id!]\"\r\n (ngModelChange)=\"onSinglePermissionChange(user.App_User_Id!)\"\r\n ></label>\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </nz-table>\r\n </div>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: NzSpinModule }, { kind: "ngmodule", type: NzTableModule }, { kind: "component", type: i1$5.NzTableComponent, selector: "nz-table", inputs: ["nzTableLayout", "nzShowTotal", "nzItemRender", "nzTitle", "nzFooter", "nzNoResult", "nzPageSizeOptions", "nzVirtualItemSize", "nzVirtualMaxBufferPx", "nzVirtualMinBufferPx", "nzVirtualForTrackBy", "nzLoadingDelay", "nzPageIndex", "nzPageSize", "nzTotal", "nzWidthConfig", "nzData", "nzCustomColumn", "nzPaginationPosition", "nzScroll", "noDataVirtualHeight", "nzPaginationType", "nzFrontPagination", "nzTemplateMode", "nzShowPagination", "nzLoading", "nzOuterBordered", "nzLoadingIndicator", "nzBordered", "nzSize", "nzShowSizeChanger", "nzHideOnSinglePage", "nzShowQuickJumper", "nzSimple"], outputs: ["nzPageSizeChange", "nzPageIndexChange", "nzQueryParams", "nzCurrentPageDataChange", "nzCustomColumnChange"], exportAs: ["nzTable"] }, { kind: "directive", type: i1$5.NzTableCellDirective, selector: "th:not(.nz-disable-th):not([mat-cell]), td:not(.nz-disable-td):not([mat-cell])" }, { kind: "directive", type: i1$5.NzThMeasureDirective, selector: "th", inputs: ["nzWidth", "colspan", "colSpan", "rowspan", "rowSpan"] }, { kind: "component", type: i1$5.NzTheadComponent, selector: "thead:not(.ant-table-thead)", outputs: ["nzSortOrderChange"] }, { kind: "component", type: i1$5.NzTbodyComponent, selector: "tbody" }, { kind: "directive", type: i1$5.NzTrDirective, selector: "tr:not([mat-row]):not([mat-header-row]):not([nz-table-measure-row]):not([nzExpand]):not([nz-table-fixed-row])" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: NzCheckboxModule }, { kind: "component", type: i3.NzCheckboxComponent, selector: "[nz-checkbox]", inputs: ["nzValue", "nzAutoFocus", "nzDisabled", "nzIndeterminate", "nzChecked", "nzId", "nzName"], outputs: ["nzCheckedChange"], exportAs: ["nzCheckbox"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3$1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: NzButtonModule }, { kind: "component", type: i5$3.NzButtonComponent, selector: "button[nz-button], a[nz-button]", inputs: ["nzBlock", "nzGhost", "nzSearch", "nzLoading", "nzDanger", "disabled", "tabIndex", "nzType", "nzShape", "nzSize"], exportAs: ["nzButton"] }, { kind: "directive", type: i6$3.ɵ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: i7.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "ngmodule", type: NzGridModule }, { kind: "directive", type: i4.NzColDirective, selector: "[nz-col],nz-col,nz-form-control,nz-form-label", inputs: ["nzFlex", "nzSpan", "nzOrder", "nzOffset", "nzPush", "nzPull", "nzXs", "nzSm", "nzMd", "nzLg", "nzXl", "nzXXl"], exportAs: ["nzCol"] }, { kind: "directive", type: i4.NzRowDirective, selector: "[nz-row],nz-row,nz-form-item", inputs: ["nzAlign", "nzJustify", "nzGutter"], exportAs: ["nzRow"] }, { kind: "ngmodule", type: NzFlexModule }, { kind: "directive", type: i9.NzFlexDirective, selector: "[nz-flex],nz-flex", inputs: ["nzVertical", "nzJustify", "nzAlign", "nzGap", "nzWrap", "nzFlex"], exportAs: ["nzFlex"] }] });
7251
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.7", type: UserRolePermission, isStandalone: true, selector: "app-user-role-permission", usesInheritance: true, ngImport: i0, template: "<div nz-row [nzGutter]=\"[0, 8]\">\r\n <div nz-col nzSpan=\"24\">\r\n <div nz-flex nzGap=\"small\" nzJustify=\"end\">\r\n <button-save (click)=\"saveUserRoleMap()\"></button-save>\r\n <button-reload (click)=\"getData()\"></button-reload>\r\n </div>\r\n </div>\r\n <div nz-col nzSpan=\"24\">\r\n <nz-table\r\n [nzData]=\"lstUser\"\r\n nzShowPagination=\"false\"\r\n [nzBordered]=\"true\"\r\n [nzSize]=\"'small'\"\r\n [nzScroll]=\"{ x: 'auto' }\"\r\n >\r\n <thead>\r\n <tr>\r\n <th nzWidth=\"200px\">\r\n <extend-input\r\n [size]=\"'small'\"\r\n [placeHolder]=\"'Search Role ...'\"\r\n [(_ngModel)]=\"roleFilter.Name\"\r\n (keyup.enter)=\"getData()\"\r\n (onclickClearIcon)=\"getData()\"\r\n ></extend-input>\r\n <extend-input\r\n [size]=\"'small'\"\r\n [placeHolder]=\"'Search User ...'\"\r\n [(_ngModel)]=\"userFilter.FullName\"\r\n (keyup.enter)=\"getData()\"\r\n (onclickClearIcon)=\"getData()\"\r\n ></extend-input>\r\n </th>\r\n <th nzWidth=\"40px\"></th>\r\n @for (role of lstRole; track role.App_Role_Id) {\r\n <th style=\"text-align: center\">{{ role.Name }}</th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (user of lstUser; track user.App_User_Id) {\r\n <tr>\r\n <td>{{ user.FullName }}</td>\r\n <td>\r\n <label\r\n nz-checkbox\r\n [nzChecked]=\"userRowState[user.App_User_Id!].checked\"\r\n [nzIndeterminate]=\"userRowState[user.App_User_Id!].indeterminate\"\r\n (nzCheckedChange)=\"toggleUserPermissions(user.App_User_Id!, $event)\"\r\n ></label>\r\n </td>\r\n @for (role of lstRole; track role.App_Role_Id) {\r\n <td class=\"text-center\">\r\n <label\r\n nz-checkbox\r\n [(ngModel)]=\"userRoleMap[user.App_User_Id!][role.App_Role_Id!]\"\r\n (ngModelChange)=\"onSinglePermissionChange(user.App_User_Id!)\"\r\n ></label>\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </nz-table>\r\n </div>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: NzSpinModule }, { kind: "ngmodule", type: NzTableModule }, { kind: "component", type: i1$5.NzTableComponent, selector: "nz-table", inputs: ["nzTableLayout", "nzShowTotal", "nzItemRender", "nzTitle", "nzFooter", "nzNoResult", "nzPageSizeOptions", "nzVirtualItemSize", "nzVirtualMaxBufferPx", "nzVirtualMinBufferPx", "nzVirtualForTrackBy", "nzLoadingDelay", "nzPageIndex", "nzPageSize", "nzTotal", "nzWidthConfig", "nzData", "nzCustomColumn", "nzPaginationPosition", "nzScroll", "noDataVirtualHeight", "nzPaginationType", "nzFrontPagination", "nzTemplateMode", "nzShowPagination", "nzLoading", "nzOuterBordered", "nzLoadingIndicator", "nzBordered", "nzSize", "nzShowSizeChanger", "nzHideOnSinglePage", "nzShowQuickJumper", "nzSimple"], outputs: ["nzPageSizeChange", "nzPageIndexChange", "nzQueryParams", "nzCurrentPageDataChange", "nzCustomColumnChange"], exportAs: ["nzTable"] }, { kind: "directive", type: i1$5.NzTableCellDirective, selector: "th:not(.nz-disable-th):not([mat-cell]), td:not(.nz-disable-td):not([mat-cell])" }, { kind: "directive", type: i1$5.NzThMeasureDirective, selector: "th", inputs: ["nzWidth", "colspan", "colSpan", "rowspan", "rowSpan"] }, { kind: "component", type: i1$5.NzTheadComponent, selector: "thead:not(.ant-table-thead)", outputs: ["nzSortOrderChange"] }, { kind: "component", type: i1$5.NzTbodyComponent, selector: "tbody" }, { kind: "directive", type: i1$5.NzTrDirective, selector: "tr:not([mat-row]):not([mat-header-row]):not([nz-table-measure-row]):not([nzExpand]):not([nz-table-fixed-row])" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: NzCheckboxModule }, { kind: "component", type: i3.NzCheckboxComponent, selector: "[nz-checkbox]", inputs: ["nzValue", "nzAutoFocus", "nzDisabled", "nzIndeterminate", "nzChecked", "nzId", "nzName"], outputs: ["nzCheckedChange"], exportAs: ["nzCheckbox"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: NzButtonModule }, { kind: "ngmodule", type: NzGridModule }, { kind: "directive", type: i4.NzColDirective, selector: "[nz-col],nz-col,nz-form-control,nz-form-label", inputs: ["nzFlex", "nzSpan", "nzOrder", "nzOffset", "nzPush", "nzPull", "nzXs", "nzSm", "nzMd", "nzLg", "nzXl", "nzXXl"], exportAs: ["nzCol"] }, { kind: "directive", type: i4.NzRowDirective, selector: "[nz-row],nz-row,nz-form-item", inputs: ["nzAlign", "nzJustify", "nzGutter"], exportAs: ["nzRow"] }, { kind: "ngmodule", type: NzFlexModule }, { kind: "directive", type: i5$3.NzFlexDirective, selector: "[nz-flex],nz-flex", inputs: ["nzVertical", "nzJustify", "nzAlign", "nzGap", "nzWrap", "nzFlex"], exportAs: ["nzFlex"] }, { kind: "component", type: ButtonSave, selector: "button-save" }, { kind: "component", type: ButtonReload, selector: "button-reload" }, { 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", "lstItem", "displayField", "valueField", "formData", "controlName", "_ngModel", "isSubmited"], outputs: ["_ngModelChange", "onclickClearIcon", "onenter"] }] });
6984
7252
  }
6985
7253
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: UserRolePermission, decorators: [{
6986
7254
  type: Component,
@@ -6993,7 +7261,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImpor
6993
7261
  NzButtonModule,
6994
7262
  NzGridModule,
6995
7263
  NzFlexModule,
6996
- ], template: "<div nz-row [nzGutter]=\"[0, 8]\">\r\n <div nz-col nzSpan=\"24\" nz-flex nzGap=\"small\">\r\n <button nz-button nzType=\"primary\" (click)=\"saveUserRoleMap()\">{{ TranslateKey.SAVE | translate }}</button>\r\n <button nz-button nzType=\"primary\" (click)=\"getData()\">{{ TranslateKey.REFEESH | translate }}</button>\r\n </div>\r\n <div nz-col nzSpan=\"24\">\r\n <nz-table [nzData]=\"lstUser\" nzShowPagination=\"false\" [nzBordered]=\"true\" [nzSize]=\"'small'\">\r\n <thead>\r\n <tr>\r\n <th nzWidth=\"200px\"></th>\r\n <th nzWidth=\"40px\"></th>\r\n @for (role of lstRole; track role.App_Role_Id) {\r\n <th style=\"text-align: center\">{{ role.Name }}</th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (user of lstUser; track user.App_User_Id) {\r\n <tr>\r\n <td>{{ user.FullName }}</td>\r\n <td>\r\n <label\r\n nz-checkbox\r\n [nzChecked]=\"userRowState[user.App_User_Id!].checked\"\r\n [nzIndeterminate]=\"userRowState[user.App_User_Id!].indeterminate\"\r\n (nzCheckedChange)=\"toggleUserPermissions(user.App_User_Id!, $event)\"\r\n ></label>\r\n </td>\r\n @for (role of lstRole; track role.App_Role_Id) {\r\n <td class=\"text-center\">\r\n <label\r\n nz-checkbox\r\n [(ngModel)]=\"userRoleMap[user.App_User_Id!][role.App_Role_Id!]\"\r\n (ngModelChange)=\"onSinglePermissionChange(user.App_User_Id!)\"\r\n ></label>\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </nz-table>\r\n </div>\r\n</div>\r\n" }]
7264
+ ButtonSave,
7265
+ ButtonReload,
7266
+ ExtendInput,
7267
+ ], template: "<div nz-row [nzGutter]=\"[0, 8]\">\r\n <div nz-col nzSpan=\"24\">\r\n <div nz-flex nzGap=\"small\" nzJustify=\"end\">\r\n <button-save (click)=\"saveUserRoleMap()\"></button-save>\r\n <button-reload (click)=\"getData()\"></button-reload>\r\n </div>\r\n </div>\r\n <div nz-col nzSpan=\"24\">\r\n <nz-table\r\n [nzData]=\"lstUser\"\r\n nzShowPagination=\"false\"\r\n [nzBordered]=\"true\"\r\n [nzSize]=\"'small'\"\r\n [nzScroll]=\"{ x: 'auto' }\"\r\n >\r\n <thead>\r\n <tr>\r\n <th nzWidth=\"200px\">\r\n <extend-input\r\n [size]=\"'small'\"\r\n [placeHolder]=\"'Search Role ...'\"\r\n [(_ngModel)]=\"roleFilter.Name\"\r\n (keyup.enter)=\"getData()\"\r\n (onclickClearIcon)=\"getData()\"\r\n ></extend-input>\r\n <extend-input\r\n [size]=\"'small'\"\r\n [placeHolder]=\"'Search User ...'\"\r\n [(_ngModel)]=\"userFilter.FullName\"\r\n (keyup.enter)=\"getData()\"\r\n (onclickClearIcon)=\"getData()\"\r\n ></extend-input>\r\n </th>\r\n <th nzWidth=\"40px\"></th>\r\n @for (role of lstRole; track role.App_Role_Id) {\r\n <th style=\"text-align: center\">{{ role.Name }}</th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (user of lstUser; track user.App_User_Id) {\r\n <tr>\r\n <td>{{ user.FullName }}</td>\r\n <td>\r\n <label\r\n nz-checkbox\r\n [nzChecked]=\"userRowState[user.App_User_Id!].checked\"\r\n [nzIndeterminate]=\"userRowState[user.App_User_Id!].indeterminate\"\r\n (nzCheckedChange)=\"toggleUserPermissions(user.App_User_Id!, $event)\"\r\n ></label>\r\n </td>\r\n @for (role of lstRole; track role.App_Role_Id) {\r\n <td class=\"text-center\">\r\n <label\r\n nz-checkbox\r\n [(ngModel)]=\"userRoleMap[user.App_User_Id!][role.App_Role_Id!]\"\r\n (ngModelChange)=\"onSinglePermissionChange(user.App_User_Id!)\"\r\n ></label>\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </nz-table>\r\n </div>\r\n</div>\r\n" }]
6997
7268
  }] });
6998
7269
 
6999
7270
  class RolePermissionComponent extends BaseComponent {
@@ -7001,11 +7272,8 @@ class RolePermissionComponent extends BaseComponent {
7001
7272
  permissionService = inject(PermissionService);
7002
7273
  lstRole = [];
7003
7274
  resourceGroups = [];
7004
- selectedRoleId = null;
7005
7275
  // Lưu trữ danh sách PermissionCode đang được tích chọn cho Role hiện tại
7006
- selectedPermissionCodes = new Set();
7007
- isLoading = false;
7008
- isSaving = false;
7276
+ selectedPermissionIds = new Set();
7009
7277
  ngOnInit() {
7010
7278
  this.loadRoles();
7011
7279
  // this.loadAllResources(); // Load khung Matrix (danh mục Module & Actions)
@@ -7024,46 +7292,46 @@ class RolePermissionComponent extends BaseComponent {
7024
7292
  return;
7025
7293
  this.isLoading = true;
7026
7294
  // Xóa state cũ
7027
- this.selectedPermissionCodes.clear();
7295
+ this.selectedPermissionIds.clear();
7028
7296
  let activePermsFromDb = [];
7029
7297
  this.permissionService
7030
7298
  .getRolePermissions(roleId)
7031
7299
  .then((res) => {
7032
- activePermsFromDb = res.Data?.split(';') || [];
7033
- this.selectedPermissionCodes = new Set(activePermsFromDb);
7300
+ activePermsFromDb = res.Data || [];
7301
+ this.selectedPermissionIds = new Set(activePermsFromDb);
7034
7302
  }, (err) => this.handleError(err))
7035
7303
  .finally(() => (this.isLoading = false));
7036
7304
  this.loadAllResources();
7037
7305
  }
7038
7306
  // --- 4. Logic UI: Thao tác Check/Uncheck ---
7039
- isPermissionChecked(code) {
7040
- return this.selectedPermissionCodes.has(code);
7307
+ isPermissionChecked(id) {
7308
+ return this.selectedPermissionIds.has(id);
7041
7309
  }
7042
- onCheckChange(code, isChecked) {
7310
+ onCheckChange(id, isChecked) {
7043
7311
  if (isChecked) {
7044
- this.selectedPermissionCodes.add(code);
7312
+ this.selectedPermissionIds.add(id);
7045
7313
  }
7046
7314
  else {
7047
- this.selectedPermissionCodes.delete(code);
7315
+ this.selectedPermissionIds.delete(id);
7048
7316
  }
7049
7317
  }
7050
7318
  // --- 5. Lưu xuống DB ---
7051
7319
  savePermissions() {
7052
- if (!this.selectedRoleId)
7320
+ if (!this.selectedId)
7053
7321
  return;
7054
7322
  this.isSaving = true;
7055
7323
  const payload = {
7056
- roleId: this.selectedRoleId,
7324
+ roleId: this.selectedId + '',
7057
7325
  // Chuyển Set về lại Array để gửi API
7058
- permissionCodes: Array.from(this.selectedPermissionCodes),
7326
+ permissionIds: Array.from(this.selectedPermissionIds),
7059
7327
  };
7060
7328
  this.permissionService
7061
- .addRoleResourcePermissionRef(payload.roleId, payload.permissionCodes.join(';'))
7329
+ .addRoleResourcePermissionRef({ roleId: payload.roleId, lstPermissionId: payload.permissionIds })
7062
7330
  .then((res) => this.notiService.success('Đã lưu cấu hình phân quyền thành công!'), (err) => this.handleError(err))
7063
7331
  .finally(() => (this.isSaving = false));
7064
7332
  }
7065
7333
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: RolePermissionComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
7066
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.7", type: RolePermissionComponent, isStandalone: true, selector: "role-resource-permission", usesInheritance: true, ngImport: i0, template: "<nz-card [nzBordered]=\"false\" nzTitle=\"C\u1EA5u h\u00ECnh Ph\u00E2n quy\u1EC1n H\u1EC7 th\u1ED1ng\">\r\n <div class=\"header-action\" nz-row nzJustify=\"space-between\" nzAlign=\"middle\" style=\"margin-bottom: 24px\">\r\n <div nz-col>\r\n <span style=\"margin-right: 16px; font-weight: bold\">Ch\u1ECDn Nh\u00F3m quy\u1EC1n (Role):</span>\r\n <nz-select\r\n [(ngModel)]=\"selectedRoleId\"\r\n (ngModelChange)=\"onRoleChange($event)\"\r\n nzPlaceHolder=\"-- Vui l\u00F2ng ch\u1ECDn Role --\"\r\n style=\"width: 300px\"\r\n >\r\n <nz-option *ngFor=\"let role of lstRole\" [nzValue]=\"role.App_Role_Id\" [nzLabel]=\"role.Name || ''\"></nz-option>\r\n </nz-select>\r\n </div>\r\n <div nz-col>\r\n <button\r\n nz-button\r\n nzType=\"primary\"\r\n (click)=\"savePermissions()\"\r\n [nzLoading]=\"isSaving\"\r\n [disabled]=\"!selectedRoleId\"\r\n >\r\n <i nz-icon nzType=\"save\"></i> L\u01B0u c\u1EA5u h\u00ECnh\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <nz-divider></nz-divider>\r\n\r\n <nz-spin [nzSpinning]=\"isLoading\">\r\n <div *ngIf=\"!selectedRoleId\" style=\"text-align: center; color: #999; padding: 40px 0\">\r\n Vui l\u00F2ng ch\u1ECDn m\u1ED9t Nh\u00F3m quy\u1EC1n \u0111\u1EC3 xem v\u00E0 c\u1EA5u h\u00ECnh.\r\n </div>\r\n\r\n <div *ngIf=\"selectedRoleId\">\r\n <div *ngFor=\"let group of resourceGroups\" style=\"margin-bottom: 24px\">\r\n <h4 style=\"border-left: 4px solid #1890ff; padding-left: 8px; margin-bottom: 16px\">\r\n {{ group.ResourceName }}\r\n </h4>\r\n\r\n <nz-card [nzBordered]=\"true\" nzSize=\"small\">\r\n <nz-row [nzGutter]=\"[16, 16]\">\r\n <nz-col [nzSpan]=\"6\" *ngFor=\"let perm of group.permissions\">\r\n <label\r\n nz-checkbox\r\n [nzChecked]=\"isPermissionChecked(perm.PermissionCode)\"\r\n (nzCheckedChange)=\"onCheckChange(perm.PermissionCode, $event)\"\r\n >\r\n {{ perm.PermissionName }} <br />\r\n <small style=\"color: #888\">({{ perm.PermissionCode }})</small>\r\n </label>\r\n </nz-col>\r\n </nz-row>\r\n </nz-card>\r\n </div>\r\n </div>\r\n </nz-spin>\r\n</nz-card>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: NzCardModule }, { kind: "component", type: i3$2.NzCardComponent, selector: "nz-card", inputs: ["nzBordered", "nzLoading", "nzHoverable", "nzBodyStyle", "nzCover", "nzActions", "nzType", "nzSize", "nzTitle", "nzExtra"], exportAs: ["nzCard"] }, { kind: "ngmodule", type: NzSelectModule }, { kind: "component", type: i6$2.NzOptionComponent, selector: "nz-option", inputs: ["nzTitle", "nzLabel", "nzValue", "nzKey", "nzDisabled", "nzHide", "nzCustomContent"], exportAs: ["nzOption"] }, { kind: "component", type: i6$2.NzSelectComponent, selector: "nz-select", inputs: ["nzId", "nzSize", "nzStatus", "nzOptionHeightPx", "nzOptionOverflowSize", "nzDropdownClassName", "nzDropdownMatchSelectWidth", "nzDropdownStyle", "nzNotFoundContent", "nzPlaceHolder", "nzPlacement", "nzMaxTagCount", "nzDropdownRender", "nzCustomTemplate", "nzSuffixIcon", "nzClearIcon", "nzRemoveIcon", "nzMenuItemSelectedIcon", "nzTokenSeparators", "nzMaxTagPlaceholder", "nzMaxMultipleCount", "nzMode", "nzFilterOption", "compareWith", "nzAllowClear", "nzBorderless", "nzShowSearch", "nzLoading", "nzAutoFocus", "nzAutoClearSearchValue", "nzServerSearch", "nzDisabled", "nzOpen", "nzSelectOnTab", "nzBackdrop", "nzOptions", "nzShowArrow"], outputs: ["nzOnSearch", "nzScrollToBottom", "nzOpenChange", "nzBlur", "nzFocus"], exportAs: ["nzSelect"] }, { kind: "ngmodule", type: NzButtonModule }, { kind: "component", type: i5$3.NzButtonComponent, selector: "button[nz-button], a[nz-button]", inputs: ["nzBlock", "nzGhost", "nzSearch", "nzLoading", "nzDanger", "disabled", "tabIndex", "nzType", "nzShape", "nzSize"], exportAs: ["nzButton"] }, { kind: "directive", type: i6$3.ɵ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: i7.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "ngmodule", type: NzDividerModule }, { kind: "component", type: i8.NzDividerComponent, selector: "nz-divider", inputs: ["nzText", "nzType", "nzOrientation", "nzVariant", "nzDashed", "nzPlain"], exportAs: ["nzDivider"] }, { kind: "ngmodule", type: NzSpinModule }, { kind: "component", type: i2$1.NzSpinComponent, selector: "nz-spin", inputs: ["nzIndicator", "nzSize", "nzTip", "nzDelay", "nzSimple", "nzSpinning"], exportAs: ["nzSpin"] }, { kind: "ngmodule", type: NzGridModule }, { kind: "directive", type: i4.NzColDirective, selector: "[nz-col],nz-col,nz-form-control,nz-form-label", inputs: ["nzFlex", "nzSpan", "nzOrder", "nzOffset", "nzPush", "nzPull", "nzXs", "nzSm", "nzMd", "nzLg", "nzXl", "nzXXl"], exportAs: ["nzCol"] }, { kind: "directive", type: i4.NzRowDirective, selector: "[nz-row],nz-row,nz-form-item", inputs: ["nzAlign", "nzJustify", "nzGutter"], exportAs: ["nzRow"] }, { kind: "ngmodule", type: NzCheckboxModule }, { kind: "component", type: i3.NzCheckboxComponent, selector: "[nz-checkbox]", inputs: ["nzValue", "nzAutoFocus", "nzDisabled", "nzIndeterminate", "nzChecked", "nzId", "nzName"], outputs: ["nzCheckedChange"], exportAs: ["nzCheckbox"] }] });
7334
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.7", type: RolePermissionComponent, isStandalone: true, selector: "role-resource-permission", usesInheritance: true, ngImport: i0, template: "<nz-card [nzBordered]=\"false\" nzTitle=\"C\u1EA5u h\u00ECnh Ph\u00E2n quy\u1EC1n H\u1EC7 th\u1ED1ng\">\r\n <div class=\"header-action\" nz-row nzJustify=\"space-between\" nzAlign=\"middle\" style=\"margin-bottom: 24px\">\r\n <div nz-col>\r\n <span style=\"margin-right: 16px; font-weight: bold\">Ch\u1ECDn Nh\u00F3m quy\u1EC1n (Role):</span>\r\n <nz-select\r\n [(ngModel)]=\"selectedId\"\r\n (ngModelChange)=\"onRoleChange($event)\"\r\n nzPlaceHolder=\"-- Vui l\u00F2ng ch\u1ECDn Role --\"\r\n style=\"width: 300px\"\r\n >\r\n <nz-option *ngFor=\"let role of lstRole\" [nzValue]=\"role.App_Role_Id\" [nzLabel]=\"role.Name || ''\"></nz-option>\r\n </nz-select>\r\n </div>\r\n <div nz-col>\r\n <button nz-button nzType=\"primary\" (click)=\"savePermissions()\" [nzLoading]=\"isSaving\" [disabled]=\"!selectedId\">\r\n <i nz-icon nzType=\"save\"></i> L\u01B0u c\u1EA5u h\u00ECnh\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <nz-divider></nz-divider>\r\n\r\n <nz-spin [nzSpinning]=\"isLoading\">\r\n <div *ngIf=\"!selectedId\" style=\"text-align: center; color: #999; padding: 40px 0\">\r\n Vui l\u00F2ng ch\u1ECDn m\u1ED9t Nh\u00F3m quy\u1EC1n \u0111\u1EC3 xem v\u00E0 c\u1EA5u h\u00ECnh.\r\n </div>\r\n\r\n <div *ngIf=\"selectedId\">\r\n <div *ngFor=\"let group of resourceGroups\" style=\"margin-bottom: 24px\">\r\n <h4 style=\"border-left: 4px solid #1890ff; padding-left: 8px; margin-bottom: 16px\">\r\n {{ group.ResourceName }}\r\n </h4>\r\n\r\n <nz-card [nzBordered]=\"true\" nzSize=\"small\">\r\n <nz-row [nzGutter]=\"[16, 16]\">\r\n <nz-col [nzSpan]=\"6\" *ngFor=\"let perm of group.permissions\">\r\n <label\r\n nz-checkbox\r\n [nzChecked]=\"isPermissionChecked(perm.App_Permission_Id)\"\r\n (nzCheckedChange)=\"onCheckChange(perm.App_Permission_Id, $event)\"\r\n >\r\n {{ perm.PermissionName }} <br />\r\n <small style=\"color: #888\">({{ perm.PermissionCode }})</small>\r\n </label>\r\n </nz-col>\r\n </nz-row>\r\n </nz-card>\r\n </div>\r\n </div>\r\n </nz-spin>\r\n</nz-card>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: NzCardModule }, { kind: "component", type: i3$3.NzCardComponent, selector: "nz-card", inputs: ["nzBordered", "nzLoading", "nzHoverable", "nzBodyStyle", "nzCover", "nzActions", "nzType", "nzSize", "nzTitle", "nzExtra"], exportAs: ["nzCard"] }, { kind: "ngmodule", type: NzSelectModule }, { kind: "component", type: i6$2.NzOptionComponent, selector: "nz-option", inputs: ["nzTitle", "nzLabel", "nzValue", "nzKey", "nzDisabled", "nzHide", "nzCustomContent"], exportAs: ["nzOption"] }, { kind: "component", type: i6$2.NzSelectComponent, selector: "nz-select", inputs: ["nzId", "nzSize", "nzStatus", "nzOptionHeightPx", "nzOptionOverflowSize", "nzDropdownClassName", "nzDropdownMatchSelectWidth", "nzDropdownStyle", "nzNotFoundContent", "nzPlaceHolder", "nzPlacement", "nzMaxTagCount", "nzDropdownRender", "nzCustomTemplate", "nzSuffixIcon", "nzClearIcon", "nzRemoveIcon", "nzMenuItemSelectedIcon", "nzTokenSeparators", "nzMaxTagPlaceholder", "nzMaxMultipleCount", "nzMode", "nzFilterOption", "compareWith", "nzAllowClear", "nzBorderless", "nzShowSearch", "nzLoading", "nzAutoFocus", "nzAutoClearSearchValue", "nzServerSearch", "nzDisabled", "nzOpen", "nzSelectOnTab", "nzBackdrop", "nzOptions", "nzShowArrow"], outputs: ["nzOnSearch", "nzScrollToBottom", "nzOpenChange", "nzBlur", "nzFocus"], exportAs: ["nzSelect"] }, { 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$2.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "ngmodule", type: NzDividerModule }, { kind: "component", type: i8.NzDividerComponent, selector: "nz-divider", inputs: ["nzText", "nzType", "nzOrientation", "nzVariant", "nzDashed", "nzPlain"], exportAs: ["nzDivider"] }, { kind: "ngmodule", type: NzSpinModule }, { kind: "component", type: i2$1.NzSpinComponent, selector: "nz-spin", inputs: ["nzIndicator", "nzSize", "nzTip", "nzDelay", "nzSimple", "nzSpinning"], exportAs: ["nzSpin"] }, { kind: "ngmodule", type: NzGridModule }, { kind: "directive", type: i4.NzColDirective, selector: "[nz-col],nz-col,nz-form-control,nz-form-label", inputs: ["nzFlex", "nzSpan", "nzOrder", "nzOffset", "nzPush", "nzPull", "nzXs", "nzSm", "nzMd", "nzLg", "nzXl", "nzXXl"], exportAs: ["nzCol"] }, { kind: "directive", type: i4.NzRowDirective, selector: "[nz-row],nz-row,nz-form-item", inputs: ["nzAlign", "nzJustify", "nzGutter"], exportAs: ["nzRow"] }, { kind: "ngmodule", type: NzCheckboxModule }, { kind: "component", type: i3.NzCheckboxComponent, selector: "[nz-checkbox]", inputs: ["nzValue", "nzAutoFocus", "nzDisabled", "nzIndeterminate", "nzChecked", "nzId", "nzName"], outputs: ["nzCheckedChange"], exportAs: ["nzCheckbox"] }] });
7067
7335
  }
7068
7336
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: RolePermissionComponent, decorators: [{
7069
7337
  type: Component,
@@ -7077,7 +7345,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImpor
7077
7345
  NzSpinModule,
7078
7346
  NzGridModule,
7079
7347
  NzCheckboxModule,
7080
- ], template: "<nz-card [nzBordered]=\"false\" nzTitle=\"C\u1EA5u h\u00ECnh Ph\u00E2n quy\u1EC1n H\u1EC7 th\u1ED1ng\">\r\n <div class=\"header-action\" nz-row nzJustify=\"space-between\" nzAlign=\"middle\" style=\"margin-bottom: 24px\">\r\n <div nz-col>\r\n <span style=\"margin-right: 16px; font-weight: bold\">Ch\u1ECDn Nh\u00F3m quy\u1EC1n (Role):</span>\r\n <nz-select\r\n [(ngModel)]=\"selectedRoleId\"\r\n (ngModelChange)=\"onRoleChange($event)\"\r\n nzPlaceHolder=\"-- Vui l\u00F2ng ch\u1ECDn Role --\"\r\n style=\"width: 300px\"\r\n >\r\n <nz-option *ngFor=\"let role of lstRole\" [nzValue]=\"role.App_Role_Id\" [nzLabel]=\"role.Name || ''\"></nz-option>\r\n </nz-select>\r\n </div>\r\n <div nz-col>\r\n <button\r\n nz-button\r\n nzType=\"primary\"\r\n (click)=\"savePermissions()\"\r\n [nzLoading]=\"isSaving\"\r\n [disabled]=\"!selectedRoleId\"\r\n >\r\n <i nz-icon nzType=\"save\"></i> L\u01B0u c\u1EA5u h\u00ECnh\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <nz-divider></nz-divider>\r\n\r\n <nz-spin [nzSpinning]=\"isLoading\">\r\n <div *ngIf=\"!selectedRoleId\" style=\"text-align: center; color: #999; padding: 40px 0\">\r\n Vui l\u00F2ng ch\u1ECDn m\u1ED9t Nh\u00F3m quy\u1EC1n \u0111\u1EC3 xem v\u00E0 c\u1EA5u h\u00ECnh.\r\n </div>\r\n\r\n <div *ngIf=\"selectedRoleId\">\r\n <div *ngFor=\"let group of resourceGroups\" style=\"margin-bottom: 24px\">\r\n <h4 style=\"border-left: 4px solid #1890ff; padding-left: 8px; margin-bottom: 16px\">\r\n {{ group.ResourceName }}\r\n </h4>\r\n\r\n <nz-card [nzBordered]=\"true\" nzSize=\"small\">\r\n <nz-row [nzGutter]=\"[16, 16]\">\r\n <nz-col [nzSpan]=\"6\" *ngFor=\"let perm of group.permissions\">\r\n <label\r\n nz-checkbox\r\n [nzChecked]=\"isPermissionChecked(perm.PermissionCode)\"\r\n (nzCheckedChange)=\"onCheckChange(perm.PermissionCode, $event)\"\r\n >\r\n {{ perm.PermissionName }} <br />\r\n <small style=\"color: #888\">({{ perm.PermissionCode }})</small>\r\n </label>\r\n </nz-col>\r\n </nz-row>\r\n </nz-card>\r\n </div>\r\n </div>\r\n </nz-spin>\r\n</nz-card>\r\n" }]
7348
+ ], template: "<nz-card [nzBordered]=\"false\" nzTitle=\"C\u1EA5u h\u00ECnh Ph\u00E2n quy\u1EC1n H\u1EC7 th\u1ED1ng\">\r\n <div class=\"header-action\" nz-row nzJustify=\"space-between\" nzAlign=\"middle\" style=\"margin-bottom: 24px\">\r\n <div nz-col>\r\n <span style=\"margin-right: 16px; font-weight: bold\">Ch\u1ECDn Nh\u00F3m quy\u1EC1n (Role):</span>\r\n <nz-select\r\n [(ngModel)]=\"selectedId\"\r\n (ngModelChange)=\"onRoleChange($event)\"\r\n nzPlaceHolder=\"-- Vui l\u00F2ng ch\u1ECDn Role --\"\r\n style=\"width: 300px\"\r\n >\r\n <nz-option *ngFor=\"let role of lstRole\" [nzValue]=\"role.App_Role_Id\" [nzLabel]=\"role.Name || ''\"></nz-option>\r\n </nz-select>\r\n </div>\r\n <div nz-col>\r\n <button nz-button nzType=\"primary\" (click)=\"savePermissions()\" [nzLoading]=\"isSaving\" [disabled]=\"!selectedId\">\r\n <i nz-icon nzType=\"save\"></i> L\u01B0u c\u1EA5u h\u00ECnh\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <nz-divider></nz-divider>\r\n\r\n <nz-spin [nzSpinning]=\"isLoading\">\r\n <div *ngIf=\"!selectedId\" style=\"text-align: center; color: #999; padding: 40px 0\">\r\n Vui l\u00F2ng ch\u1ECDn m\u1ED9t Nh\u00F3m quy\u1EC1n \u0111\u1EC3 xem v\u00E0 c\u1EA5u h\u00ECnh.\r\n </div>\r\n\r\n <div *ngIf=\"selectedId\">\r\n <div *ngFor=\"let group of resourceGroups\" style=\"margin-bottom: 24px\">\r\n <h4 style=\"border-left: 4px solid #1890ff; padding-left: 8px; margin-bottom: 16px\">\r\n {{ group.ResourceName }}\r\n </h4>\r\n\r\n <nz-card [nzBordered]=\"true\" nzSize=\"small\">\r\n <nz-row [nzGutter]=\"[16, 16]\">\r\n <nz-col [nzSpan]=\"6\" *ngFor=\"let perm of group.permissions\">\r\n <label\r\n nz-checkbox\r\n [nzChecked]=\"isPermissionChecked(perm.App_Permission_Id)\"\r\n (nzCheckedChange)=\"onCheckChange(perm.App_Permission_Id, $event)\"\r\n >\r\n {{ perm.PermissionName }} <br />\r\n <small style=\"color: #888\">({{ perm.PermissionCode }})</small>\r\n </label>\r\n </nz-col>\r\n </nz-row>\r\n </nz-card>\r\n </div>\r\n </div>\r\n </nz-spin>\r\n</nz-card>\r\n" }]
7081
7349
  }] });
7082
7350
 
7083
7351
  class PermissionManagerComponent extends BaseComponent {
@@ -7086,7 +7354,6 @@ class PermissionManagerComponent extends BaseComponent {
7086
7354
  permissions = [];
7087
7355
  searchText = '';
7088
7356
  isModalVisible = false;
7089
- isSaving = false;
7090
7357
  isEditMode = false;
7091
7358
  currentEditingId = null;
7092
7359
  permissionForm;
@@ -7244,7 +7511,7 @@ class PermissionManagerComponent extends BaseComponent {
7244
7511
  this.loadData();
7245
7512
  }
7246
7513
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: PermissionManagerComponent, deps: [{ token: i2.FormBuilder }, { token: PermissionService }], target: i0.ɵɵFactoryTarget.Component });
7247
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.7", type: PermissionManagerComponent, isStandalone: true, selector: "resource-permission", usesInheritance: true, ngImport: i0, template: "<nz-card nzTitle=\"Qu\u1EA3n l\u00FD Danh m\u1EE5c M\u00E3 quy\u1EC1n (App_Permission)\" [nzBordered]=\"false\">\r\n <div class=\"table-operations\" nz-row nzJustify=\"space-between\" style=\"margin-bottom: 16px\">\r\n <div nz-col>\r\n <expandable-search [(searchValue)]=\"searchText\" (onSearch)=\"loadData()\"></expandable-search>\r\n <button nz-button nzType=\"primary\" (click)=\"loadData()\" style=\"margin-right: 8px\">T\u1EA3i l\u1EA1i</button>\r\n </div>\r\n <div nz-col>\r\n <button nz-button nzType=\"primary\" (click)=\"openBulkModal()\" style=\"margin-right: 8px\">\r\n <i nz-icon nzType=\"bolt\"></i> T\u1EA1o m\u1EDBi (default)\r\n </button>\r\n <button nz-button nzType=\"primary\" (click)=\"openModal()\"><i nz-icon nzType=\"plus\"></i> Th\u00EAm m\u1EDBi</button>\r\n </div>\r\n </div>\r\n\r\n <nz-table\r\n #basicTable\r\n [nzData]=\"permissions\"\r\n nzBordered\r\n nzSize=\"small\"\r\n nzShowPagination=\"true\"\r\n nzShowSizeChanger=\"true\"\r\n >\r\n <thead>\r\n <tr>\r\n <th>Resource</th>\r\n <th>Permission code</th>\r\n <th>Permission name</th>\r\n <th>Description</th>\r\n <th nzAlign=\"center\">H\u00E0nh \u0111\u1ED9ng</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let data of basicTable.data\">\r\n <td>\r\n <div nz-flex nzGap=\"small\">\r\n <span>{{ data.ResourceName }}</span\r\n ><nz-tag [nzColor]=\"'blue'\">{{ data.ResourceCode }}</nz-tag>\r\n </div>\r\n </td>\r\n <td>\r\n <strong>{{ data.PermissionCode }}</strong>\r\n </td>\r\n <td>{{ data.PermissionName }}</td>\r\n <td>{{ data.Description }}</td>\r\n <td nzAlign=\"center\">\r\n <a (click)=\"openModal(data)\"><i nz-icon nzType=\"edit\" nzTheme=\"outline\"></i></a>\r\n <nz-divider nzType=\"vertical\"></nz-divider>\r\n <a\r\n nz-popconfirm\r\n nzPopconfirmTitle=\"X\u00E1c nh\u1EADn x\u00F3a?\"\r\n nzPopconfirmPlacement=\"left\"\r\n (nzOnConfirm)=\"deletePermission(data.App_Permission_Id)\"\r\n style=\"color: red\"\r\n >\r\n <i nz-icon nzType=\"delete\" nzTheme=\"outline\"></i>\r\n </a>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </nz-table>\r\n</nz-card>\r\n\r\n<nz-modal\r\n [(nzVisible)]=\"isBulkModalVisible\"\r\n nzTitle=\"Create Resource permission\"\r\n (nzOnCancel)=\"closeBulkModal()\"\r\n (nzOnOk)=\"saveBulkPermissions()\"\r\n [nzMaskClosable]=\"false\"\r\n nzWidth=\"750px\"\r\n>\r\n <ng-container *nzModalContent>\r\n <!-- <div style=\"margin-bottom: 16px; color: #666\">\r\n <i nz-icon nzType=\"info-circle\"></i> H\u1EC7 th\u1ED1ng s\u1EBD t\u1EF1 \u0111\u1ED9ng sinh m\u00E3 quy\u1EC1n v\u00E0 t\u00EAn thao t\u00E1c d\u1EF1a tr\u00EAn Module b\u1EA1n nh\u1EADp.\r\n B\u1EA1n c\u00F3 th\u1EC3 b\u1ECF t\u00EDch c\u00E1c thao t\u00E1c kh\u00F4ng c\u1EA7n thi\u1EBFt.\r\n </div> -->\r\n\r\n <form nz-form [formGroup]=\"bulkForm\" nzLayout=\"vertical\">\r\n <nz-row [nzGutter]=\"16\">\r\n <nz-col [nzSpan]=\"12\">\r\n <nz-form-item>\r\n <nz-form-label nzRequired>Resource Code</nz-form-label>\r\n <nz-form-control nzErrorTip=\"Vui l\u00F2ng nh\u1EADp m\u00E3 Module vi\u1EBFt li\u1EC1n!\">\r\n <input nz-input formControlName=\"ResourceCode\" placeholder=\"VD: Invoices, Products...\" />\r\n </nz-form-control>\r\n </nz-form-item>\r\n </nz-col>\r\n\r\n <nz-col [nzSpan]=\"12\">\r\n <nz-form-item>\r\n <nz-form-label nzRequired>Resource Name</nz-form-label>\r\n <nz-form-control nzErrorTip=\"Vui l\u00F2ng nh\u1EADp t\u00EAn Module!\">\r\n <input nz-input formControlName=\"ResourceName\" placeholder=\"VD: H\u00F3a \u0111\u01A1n, S\u1EA3n ph\u1EA9m...\" />\r\n </nz-form-control>\r\n </nz-form-item>\r\n </nz-col>\r\n </nz-row>\r\n </form>\r\n\r\n <nz-divider nzText=\"Danh s\u00E1ch Thao t\u00E1c\" nzOrientation=\"left\"></nz-divider>\r\n\r\n <nz-row [nzGutter]=\"[16, 16]\">\r\n @for (item of bulkActionCheckboxes; track $index) {\r\n <nz-col [nzSpan]=\"$index == 0 ? 24 : 8\">\r\n <label nz-checkbox [(ngModel)]=\"item.checked\" [ngModelOptions]=\"{ standalone: true }\">\r\n {{ item.label }}\r\n </label>\r\n </nz-col>\r\n }\r\n </nz-row>\r\n </ng-container>\r\n</nz-modal>\r\n\r\n<nz-modal\r\n [(nzVisible)]=\"isModalVisible\"\r\n [nzTitle]=\"isEditMode ? 'Update Resource permission' : 'Create Resource permission'\"\r\n (nzOnCancel)=\"closeModal()\"\r\n (nzOnOk)=\"savePermission()\"\r\n [nzOkLoading]=\"isSaving\"\r\n [nzMaskClosable]=\"false\"\r\n>\r\n <ng-container *nzModalContent>\r\n <form nz-form [formGroup]=\"permissionForm\" nzLayout=\"vertical\">\r\n <nz-row [nzGutter]=\"16\">\r\n <nz-col [nzSpan]=\"24\">\r\n <nz-form-item>\r\n <nz-form-label nzRequired>Resource name</nz-form-label>\r\n <nz-form-control nzErrorTip=\"Vui l\u00F2ng nh\u1EADp nh\u00F3m Resource name!\">\r\n <input nz-input formControlName=\"ResourceName\" placeholder=\"VD: Todos\" />\r\n </nz-form-control>\r\n </nz-form-item>\r\n </nz-col>\r\n\r\n <nz-col [nzSpan]=\"12\">\r\n <nz-form-item>\r\n <nz-form-label nzRequired>Resource code</nz-form-label>\r\n <nz-form-control nzErrorTip=\"Vui l\u00F2ng nh\u1EADp nh\u00F3m Resource Code!\">\r\n <input nz-input formControlName=\"ResourceCode\" placeholder=\"VD: todo\" />\r\n </nz-form-control>\r\n </nz-form-item>\r\n </nz-col>\r\n\r\n <nz-col [nzSpan]=\"12\">\r\n <nz-form-item>\r\n <nz-form-label nzRequired>Permission code</nz-form-label>\r\n <nz-form-control nzErrorTip=\"Vui l\u00F2ng nh\u1EADp Permission code!\">\r\n <input\r\n nz-input\r\n formControlName=\"actionSuffix\"\r\n placeholder=\"-- Ch\u1ECDn ho\u1EB7c t\u1EF1 nh\u1EADp --\"\r\n [nzAutocomplete]=\"auto\"\r\n />\r\n\r\n <nz-autocomplete #auto>\r\n <nz-auto-option *ngFor=\"let option of filteredActionOptions\" [nzValue]=\"option.value\">\r\n {{ option.label }}\r\n </nz-auto-option>\r\n </nz-autocomplete>\r\n </nz-form-control>\r\n </nz-form-item>\r\n </nz-col>\r\n </nz-row>\r\n\r\n <nz-form-item>\r\n <nz-form-label>M\u00E3 quy\u1EC1n h\u1EC7 th\u1ED1ng (T\u1EF1 \u0111\u1ED9ng sinh)</nz-form-label>\r\n <nz-form-control>\r\n <input\r\n nz-input\r\n formControlName=\"PermissionCode\"\r\n style=\"background-color: #f5f5f5; color: #1890ff; font-weight: bold; font-family: monospace\"\r\n />\r\n </nz-form-control>\r\n </nz-form-item>\r\n\r\n <nz-form-item>\r\n <nz-form-label nzRequired>T\u00EAn thao t\u00E1c hi\u1EC3n th\u1ECB</nz-form-label>\r\n <nz-form-control nzErrorTip=\"Vui l\u00F2ng nh\u1EADp t\u00EAn thao t\u00E1c!\">\r\n <input nz-input formControlName=\"PermissionName\" placeholder=\"VD: Xem c\u00F4ng vi\u1EC7c c\u1EE7a m\u00ECnh\" />\r\n </nz-form-control>\r\n </nz-form-item>\r\n </form>\r\n </ng-container>\r\n</nz-modal>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: NzCardModule }, { kind: "component", type: i3$2.NzCardComponent, selector: "nz-card", inputs: ["nzBordered", "nzLoading", "nzHoverable", "nzBodyStyle", "nzCover", "nzActions", "nzType", "nzSize", "nzTitle", "nzExtra"], exportAs: ["nzCard"] }, { kind: "ngmodule", type: NzInputModule }, { kind: "directive", type: i6$1.NzInputDirective, selector: "input[nz-input],textarea[nz-input]", inputs: ["nzBorderless", "nzSize", "nzStepperless", "nzStatus", "disabled"], exportAs: ["nzInput"] }, { kind: "ngmodule", type: NzTableModule }, { kind: "component", type: i1$5.NzTableComponent, selector: "nz-table", inputs: ["nzTableLayout", "nzShowTotal", "nzItemRender", "nzTitle", "nzFooter", "nzNoResult", "nzPageSizeOptions", "nzVirtualItemSize", "nzVirtualMaxBufferPx", "nzVirtualMinBufferPx", "nzVirtualForTrackBy", "nzLoadingDelay", "nzPageIndex", "nzPageSize", "nzTotal", "nzWidthConfig", "nzData", "nzCustomColumn", "nzPaginationPosition", "nzScroll", "noDataVirtualHeight", "nzPaginationType", "nzFrontPagination", "nzTemplateMode", "nzShowPagination", "nzLoading", "nzOuterBordered", "nzLoadingIndicator", "nzBordered", "nzSize", "nzShowSizeChanger", "nzHideOnSinglePage", "nzShowQuickJumper", "nzSimple"], outputs: ["nzPageSizeChange", "nzPageIndexChange", "nzQueryParams", "nzCurrentPageDataChange", "nzCustomColumnChange"], exportAs: ["nzTable"] }, { kind: "directive", type: i1$5.NzTableCellDirective, selector: "th:not(.nz-disable-th):not([mat-cell]), td:not(.nz-disable-td):not([mat-cell])" }, { kind: "directive", type: i1$5.NzThMeasureDirective, selector: "th", inputs: ["nzWidth", "colspan", "colSpan", "rowspan", "rowSpan"] }, { kind: "component", type: i1$5.NzTheadComponent, selector: "thead:not(.ant-table-thead)", outputs: ["nzSortOrderChange"] }, { kind: "component", type: i1$5.NzTbodyComponent, selector: "tbody" }, { kind: "directive", type: i1$5.NzTrDirective, selector: "tr:not([mat-row]):not([mat-header-row]):not([nz-table-measure-row]):not([nzExpand]):not([nz-table-fixed-row])" }, { kind: "directive", type: i1$5.NzCellAlignDirective, selector: "th[nzAlign],td[nzAlign]", inputs: ["nzAlign"] }, { kind: "ngmodule", type: NzTagModule }, { kind: "component", type: i5$2.NzTagComponent, selector: "nz-tag", inputs: ["nzMode", "nzColor", "nzChecked", "nzBordered"], outputs: ["nzOnClose", "nzCheckedChange"], exportAs: ["nzTag"] }, { kind: "ngmodule", type: NzDividerModule }, { kind: "component", type: i8.NzDividerComponent, selector: "nz-divider", inputs: ["nzText", "nzType", "nzOrientation", "nzVariant", "nzDashed", "nzPlain"], exportAs: ["nzDivider"] }, { kind: "ngmodule", type: NzModalModule }, { kind: "component", type: i1$1.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: i1$1.NzModalContentDirective, selector: "[nzModalContent]", exportAs: ["nzModalContent"] }, { kind: "ngmodule", type: NzFormModule }, { kind: "directive", type: i4.NzColDirective, selector: "[nz-col],nz-col,nz-form-control,nz-form-label", inputs: ["nzFlex", "nzSpan", "nzOrder", "nzOffset", "nzPush", "nzPull", "nzXs", "nzSm", "nzMd", "nzLg", "nzXl", "nzXXl"], exportAs: ["nzCol"] }, { kind: "directive", type: i4.NzRowDirective, selector: "[nz-row],nz-row,nz-form-item", inputs: ["nzAlign", "nzJustify", "nzGutter"], exportAs: ["nzRow"] }, { kind: "directive", type: i5.NzFormDirective, selector: "[nz-form]", inputs: ["nzLayout", "nzNoColon", "nzAutoTips", "nzDisableAutoTips", "nzTooltipIcon", "nzLabelAlign", "nzLabelWrap"], exportAs: ["nzForm"] }, { kind: "component", type: i5.NzFormItemComponent, selector: "nz-form-item", exportAs: ["nzFormItem"] }, { kind: "component", type: i5.NzFormLabelComponent, selector: "nz-form-label", inputs: ["nzFor", "nzRequired", "nzNoColon", "nzTooltipTitle", "nzTooltipIcon", "nzLabelAlign", "nzLabelWrap"], exportAs: ["nzFormLabel"] }, { kind: "component", type: i5.NzFormControlComponent, selector: "nz-form-control", inputs: ["nzSuccessTip", "nzWarningTip", "nzErrorTip", "nzValidatingTip", "nzExtra", "nzAutoTips", "nzDisableAutoTips", "nzHasFeedback", "nzValidateStatus"], exportAs: ["nzFormControl"] }, { kind: "ngmodule", type: NzButtonModule }, { kind: "component", type: i5$3.NzButtonComponent, selector: "button[nz-button], a[nz-button]", inputs: ["nzBlock", "nzGhost", "nzSearch", "nzLoading", "nzDanger", "disabled", "tabIndex", "nzType", "nzShape", "nzSize"], exportAs: ["nzButton"] }, { kind: "directive", type: i6$3.ɵ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: i7.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "ngmodule", type: NzSelectModule }, { kind: "ngmodule", type: NzCheckboxModule }, { kind: "component", type: i3.NzCheckboxComponent, selector: "[nz-checkbox]", inputs: ["nzValue", "nzAutoFocus", "nzDisabled", "nzIndeterminate", "nzChecked", "nzId", "nzName"], outputs: ["nzCheckedChange"], exportAs: ["nzCheckbox"] }, { kind: "ngmodule", type: NzAutocompleteModule }, { kind: "component", type: i17.NzAutocompleteComponent, selector: "nz-autocomplete", inputs: ["nzWidth", "nzOverlayClassName", "nzOverlayStyle", "nzDefaultActiveFirstOption", "nzBackfill", "compareWith", "nzDataSource"], outputs: ["selectionChange"], exportAs: ["nzAutocomplete"] }, { kind: "component", type: i17.NzAutocompleteOptionComponent, selector: "nz-auto-option", inputs: ["nzValue", "nzLabel", "nzDisabled"], outputs: ["selectionChange", "mouseEntered"], exportAs: ["nzAutoOption"] }, { kind: "directive", type: i17.NzAutocompleteTriggerDirective, selector: "input[nzAutocomplete], textarea[nzAutocomplete]", inputs: ["nzAutocomplete"], exportAs: ["nzAutocompleteTrigger"] }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "component", type: ExpandableSearchComponent, selector: "expandable-search", inputs: ["searchValue"], outputs: ["searchValueChange", "onSearch"] }, { kind: "ngmodule", type: NzPopconfirmModule }, { kind: "directive", type: i18.NzPopconfirmDirective, selector: "[nz-popconfirm]", inputs: ["nzPopconfirmArrowPointAtCenter", "nzPopconfirmTitle", "nzPopconfirmTitleContext", "nz-popconfirm", "nzPopconfirmTrigger", "nzPopconfirmPlacement", "nzPopconfirmOrigin", "nzPopconfirmMouseEnterDelay", "nzPopconfirmMouseLeaveDelay", "nzPopconfirmOverlayClassName", "nzPopconfirmOverlayStyle", "nzPopconfirmVisible", "nzOkText", "nzOkType", "nzOkDisabled", "nzOkDanger", "nzCancelText", "nzBeforeConfirm", "nzIcon", "nzCondition", "nzPopconfirmShowArrow", "nzPopconfirmBackdrop", "nzAutofocus"], outputs: ["nzPopconfirmVisibleChange", "nzOnCancel", "nzOnConfirm"], exportAs: ["nzPopconfirm"] }, { kind: "directive", type: NzFlexDirective, selector: "[nz-flex],nz-flex", inputs: ["nzVertical", "nzJustify", "nzAlign", "nzGap", "nzWrap", "nzFlex"], exportAs: ["nzFlex"] }] });
7514
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.7", type: PermissionManagerComponent, isStandalone: true, selector: "resource-permission", usesInheritance: true, ngImport: i0, template: "<nz-card nzTitle=\"Qu\u1EA3n l\u00FD Danh m\u1EE5c M\u00E3 quy\u1EC1n (App_Permission)\" [nzBordered]=\"false\">\r\n <div class=\"table-operations\" nz-row nzJustify=\"space-between\" style=\"margin-bottom: 16px\">\r\n <div nz-col nz-flex nzGap=\"small\">\r\n <expandable-search [(searchValue)]=\"searchText\" (onSearch)=\"loadData()\"></expandable-search>\r\n <button-reload (click)=\"loadData()\"></button-reload>\r\n </div>\r\n <div nz-col>\r\n <button nz-button nzType=\"primary\" (click)=\"openBulkModal()\" style=\"margin-right: 8px\">\r\n <i nz-icon nzType=\"plus\"></i> T\u1EA1o m\u1EDBi (default)\r\n </button>\r\n <button nz-button nzType=\"primary\" (click)=\"openModal()\"><i nz-icon nzType=\"plus\"></i> Th\u00EAm m\u1EDBi</button>\r\n </div>\r\n </div>\r\n\r\n <nz-table\r\n #basicTable\r\n [nzData]=\"permissions\"\r\n nzBordered\r\n nzSize=\"small\"\r\n nzShowPagination=\"true\"\r\n nzShowSizeChanger=\"true\"\r\n >\r\n <thead>\r\n <tr>\r\n <th>Resource</th>\r\n <th>Permission code</th>\r\n <th>Permission name</th>\r\n <th>Description</th>\r\n <th nzAlign=\"center\">H\u00E0nh \u0111\u1ED9ng</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let data of basicTable.data\">\r\n <td>\r\n <div nz-flex nzGap=\"small\">\r\n <span>{{ data.ResourceName }}</span\r\n ><nz-tag [nzColor]=\"'blue'\">{{ data.ResourceCode }}</nz-tag>\r\n </div>\r\n </td>\r\n <td>\r\n <strong>{{ data.PermissionCode }}</strong>\r\n </td>\r\n <td>{{ data.PermissionName }}</td>\r\n <td>{{ data.Description }}</td>\r\n <td nzAlign=\"center\">\r\n <a (click)=\"openModal(data)\"><i nz-icon nzType=\"edit\" nzTheme=\"outline\"></i></a>\r\n <nz-divider nzType=\"vertical\"></nz-divider>\r\n <a\r\n nz-popconfirm\r\n nzPopconfirmTitle=\"X\u00E1c nh\u1EADn x\u00F3a?\"\r\n nzPopconfirmPlacement=\"left\"\r\n (nzOnConfirm)=\"deletePermission(data.App_Permission_Id)\"\r\n style=\"color: red\"\r\n >\r\n <i nz-icon nzType=\"delete\" nzTheme=\"outline\"></i>\r\n </a>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </nz-table>\r\n</nz-card>\r\n\r\n<nz-modal\r\n [(nzVisible)]=\"isBulkModalVisible\"\r\n nzTitle=\"Create Resource permission\"\r\n (nzOnCancel)=\"closeBulkModal()\"\r\n (nzOnOk)=\"saveBulkPermissions()\"\r\n [nzMaskClosable]=\"false\"\r\n nzWidth=\"750px\"\r\n>\r\n <ng-container *nzModalContent>\r\n <!-- <div style=\"margin-bottom: 16px; color: #666\">\r\n <i nz-icon nzType=\"info-circle\"></i> H\u1EC7 th\u1ED1ng s\u1EBD t\u1EF1 \u0111\u1ED9ng sinh m\u00E3 quy\u1EC1n v\u00E0 t\u00EAn thao t\u00E1c d\u1EF1a tr\u00EAn Module b\u1EA1n nh\u1EADp.\r\n B\u1EA1n c\u00F3 th\u1EC3 b\u1ECF t\u00EDch c\u00E1c thao t\u00E1c kh\u00F4ng c\u1EA7n thi\u1EBFt.\r\n </div> -->\r\n\r\n <form nz-form [formGroup]=\"bulkForm\" nzLayout=\"vertical\">\r\n <nz-row [nzGutter]=\"16\">\r\n <nz-col [nzSpan]=\"12\">\r\n <nz-form-item>\r\n <nz-form-label nzRequired>Resource Code</nz-form-label>\r\n <nz-form-control nzErrorTip=\"Vui l\u00F2ng nh\u1EADp m\u00E3 Module vi\u1EBFt li\u1EC1n!\">\r\n <input nz-input formControlName=\"ResourceCode\" placeholder=\"VD: Invoices, Products...\" />\r\n </nz-form-control>\r\n </nz-form-item>\r\n </nz-col>\r\n\r\n <nz-col [nzSpan]=\"12\">\r\n <nz-form-item>\r\n <nz-form-label nzRequired>Resource Name</nz-form-label>\r\n <nz-form-control nzErrorTip=\"Vui l\u00F2ng nh\u1EADp t\u00EAn Module!\">\r\n <input nz-input formControlName=\"ResourceName\" placeholder=\"VD: H\u00F3a \u0111\u01A1n, S\u1EA3n ph\u1EA9m...\" />\r\n </nz-form-control>\r\n </nz-form-item>\r\n </nz-col>\r\n </nz-row>\r\n </form>\r\n\r\n <nz-divider nzText=\"Danh s\u00E1ch Thao t\u00E1c\" nzOrientation=\"left\"></nz-divider>\r\n\r\n <nz-row [nzGutter]=\"[16, 16]\">\r\n @for (item of bulkActionCheckboxes; track $index) {\r\n <nz-col [nzSpan]=\"$index == 0 ? 24 : 8\">\r\n <label nz-checkbox [(ngModel)]=\"item.checked\" [ngModelOptions]=\"{ standalone: true }\">\r\n {{ item.label }}\r\n </label>\r\n </nz-col>\r\n }\r\n </nz-row>\r\n </ng-container>\r\n</nz-modal>\r\n\r\n<nz-modal\r\n [(nzVisible)]=\"isModalVisible\"\r\n [nzTitle]=\"isEditMode ? 'Update Resource permission' : 'Create Resource permission'\"\r\n (nzOnCancel)=\"closeModal()\"\r\n (nzOnOk)=\"savePermission()\"\r\n [nzOkLoading]=\"isSaving\"\r\n [nzMaskClosable]=\"false\"\r\n>\r\n <ng-container *nzModalContent>\r\n <form nz-form [formGroup]=\"permissionForm\" nzLayout=\"vertical\">\r\n <nz-row [nzGutter]=\"16\">\r\n <nz-col [nzSpan]=\"24\">\r\n <nz-form-item>\r\n <nz-form-label nzRequired>Resource name</nz-form-label>\r\n <nz-form-control nzErrorTip=\"Vui l\u00F2ng nh\u1EADp nh\u00F3m Resource name!\">\r\n <input nz-input formControlName=\"ResourceName\" placeholder=\"VD: Todos\" />\r\n </nz-form-control>\r\n </nz-form-item>\r\n </nz-col>\r\n\r\n <nz-col [nzSpan]=\"12\">\r\n <nz-form-item>\r\n <nz-form-label nzRequired>Resource code</nz-form-label>\r\n <nz-form-control nzErrorTip=\"Vui l\u00F2ng nh\u1EADp nh\u00F3m Resource Code!\">\r\n <input nz-input formControlName=\"ResourceCode\" placeholder=\"VD: todo\" />\r\n </nz-form-control>\r\n </nz-form-item>\r\n </nz-col>\r\n\r\n <nz-col [nzSpan]=\"12\">\r\n <nz-form-item>\r\n <nz-form-label nzRequired>Permission code</nz-form-label>\r\n <nz-form-control nzErrorTip=\"Vui l\u00F2ng nh\u1EADp Permission code!\">\r\n <input\r\n nz-input\r\n formControlName=\"actionSuffix\"\r\n placeholder=\"-- Ch\u1ECDn ho\u1EB7c t\u1EF1 nh\u1EADp --\"\r\n [nzAutocomplete]=\"auto\"\r\n />\r\n\r\n <nz-autocomplete #auto>\r\n <nz-auto-option *ngFor=\"let option of filteredActionOptions\" [nzValue]=\"option.value\">\r\n {{ option.label }}\r\n </nz-auto-option>\r\n </nz-autocomplete>\r\n </nz-form-control>\r\n </nz-form-item>\r\n </nz-col>\r\n </nz-row>\r\n\r\n <nz-form-item>\r\n <nz-form-label>M\u00E3 quy\u1EC1n h\u1EC7 th\u1ED1ng (T\u1EF1 \u0111\u1ED9ng sinh)</nz-form-label>\r\n <nz-form-control>\r\n <input\r\n nz-input\r\n formControlName=\"PermissionCode\"\r\n style=\"background-color: #f5f5f5; color: #1890ff; font-weight: bold; font-family: monospace\"\r\n />\r\n </nz-form-control>\r\n </nz-form-item>\r\n\r\n <nz-form-item>\r\n <nz-form-label nzRequired>T\u00EAn thao t\u00E1c hi\u1EC3n th\u1ECB</nz-form-label>\r\n <nz-form-control nzErrorTip=\"Vui l\u00F2ng nh\u1EADp t\u00EAn thao t\u00E1c!\">\r\n <input nz-input formControlName=\"PermissionName\" placeholder=\"VD: Xem c\u00F4ng vi\u1EC7c c\u1EE7a m\u00ECnh\" />\r\n </nz-form-control>\r\n </nz-form-item>\r\n </form>\r\n </ng-container>\r\n</nz-modal>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: NzCardModule }, { kind: "component", type: i3$3.NzCardComponent, selector: "nz-card", inputs: ["nzBordered", "nzLoading", "nzHoverable", "nzBodyStyle", "nzCover", "nzActions", "nzType", "nzSize", "nzTitle", "nzExtra"], exportAs: ["nzCard"] }, { kind: "ngmodule", type: NzInputModule }, { kind: "directive", type: i6$1.NzInputDirective, selector: "input[nz-input],textarea[nz-input]", inputs: ["nzBorderless", "nzSize", "nzStepperless", "nzStatus", "disabled"], exportAs: ["nzInput"] }, { kind: "ngmodule", type: NzTableModule }, { kind: "component", type: i1$5.NzTableComponent, selector: "nz-table", inputs: ["nzTableLayout", "nzShowTotal", "nzItemRender", "nzTitle", "nzFooter", "nzNoResult", "nzPageSizeOptions", "nzVirtualItemSize", "nzVirtualMaxBufferPx", "nzVirtualMinBufferPx", "nzVirtualForTrackBy", "nzLoadingDelay", "nzPageIndex", "nzPageSize", "nzTotal", "nzWidthConfig", "nzData", "nzCustomColumn", "nzPaginationPosition", "nzScroll", "noDataVirtualHeight", "nzPaginationType", "nzFrontPagination", "nzTemplateMode", "nzShowPagination", "nzLoading", "nzOuterBordered", "nzLoadingIndicator", "nzBordered", "nzSize", "nzShowSizeChanger", "nzHideOnSinglePage", "nzShowQuickJumper", "nzSimple"], outputs: ["nzPageSizeChange", "nzPageIndexChange", "nzQueryParams", "nzCurrentPageDataChange", "nzCustomColumnChange"], exportAs: ["nzTable"] }, { kind: "directive", type: i1$5.NzTableCellDirective, selector: "th:not(.nz-disable-th):not([mat-cell]), td:not(.nz-disable-td):not([mat-cell])" }, { kind: "directive", type: i1$5.NzThMeasureDirective, selector: "th", inputs: ["nzWidth", "colspan", "colSpan", "rowspan", "rowSpan"] }, { kind: "component", type: i1$5.NzTheadComponent, selector: "thead:not(.ant-table-thead)", outputs: ["nzSortOrderChange"] }, { kind: "component", type: i1$5.NzTbodyComponent, selector: "tbody" }, { kind: "directive", type: i1$5.NzTrDirective, selector: "tr:not([mat-row]):not([mat-header-row]):not([nz-table-measure-row]):not([nzExpand]):not([nz-table-fixed-row])" }, { kind: "directive", type: i1$5.NzCellAlignDirective, selector: "th[nzAlign],td[nzAlign]", inputs: ["nzAlign"] }, { kind: "ngmodule", type: NzTagModule }, { kind: "component", type: i5$2.NzTagComponent, selector: "nz-tag", inputs: ["nzMode", "nzColor", "nzChecked", "nzBordered"], outputs: ["nzOnClose", "nzCheckedChange"], exportAs: ["nzTag"] }, { kind: "ngmodule", type: NzDividerModule }, { kind: "component", type: i8.NzDividerComponent, selector: "nz-divider", inputs: ["nzText", "nzType", "nzOrientation", "nzVariant", "nzDashed", "nzPlain"], exportAs: ["nzDivider"] }, { kind: "ngmodule", type: NzModalModule }, { kind: "component", type: i1$1.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: i1$1.NzModalContentDirective, selector: "[nzModalContent]", exportAs: ["nzModalContent"] }, { kind: "ngmodule", type: NzFormModule }, { kind: "directive", type: i4.NzColDirective, selector: "[nz-col],nz-col,nz-form-control,nz-form-label", inputs: ["nzFlex", "nzSpan", "nzOrder", "nzOffset", "nzPush", "nzPull", "nzXs", "nzSm", "nzMd", "nzLg", "nzXl", "nzXXl"], exportAs: ["nzCol"] }, { kind: "directive", type: i4.NzRowDirective, selector: "[nz-row],nz-row,nz-form-item", inputs: ["nzAlign", "nzJustify", "nzGutter"], exportAs: ["nzRow"] }, { kind: "directive", type: i5.NzFormDirective, selector: "[nz-form]", inputs: ["nzLayout", "nzNoColon", "nzAutoTips", "nzDisableAutoTips", "nzTooltipIcon", "nzLabelAlign", "nzLabelWrap"], exportAs: ["nzForm"] }, { kind: "component", type: i5.NzFormItemComponent, selector: "nz-form-item", exportAs: ["nzFormItem"] }, { kind: "component", type: i5.NzFormLabelComponent, selector: "nz-form-label", inputs: ["nzFor", "nzRequired", "nzNoColon", "nzTooltipTitle", "nzTooltipIcon", "nzLabelAlign", "nzLabelWrap"], exportAs: ["nzFormLabel"] }, { kind: "component", type: i5.NzFormControlComponent, selector: "nz-form-control", inputs: ["nzSuccessTip", "nzWarningTip", "nzErrorTip", "nzValidatingTip", "nzExtra", "nzAutoTips", "nzDisableAutoTips", "nzHasFeedback", "nzValidateStatus"], exportAs: ["nzFormControl"] }, { 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$2.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "ngmodule", type: NzSelectModule }, { kind: "ngmodule", type: NzCheckboxModule }, { kind: "component", type: i3.NzCheckboxComponent, selector: "[nz-checkbox]", inputs: ["nzValue", "nzAutoFocus", "nzDisabled", "nzIndeterminate", "nzChecked", "nzId", "nzName"], outputs: ["nzCheckedChange"], exportAs: ["nzCheckbox"] }, { kind: "ngmodule", type: NzAutocompleteModule }, { kind: "component", type: i17.NzAutocompleteComponent, selector: "nz-autocomplete", inputs: ["nzWidth", "nzOverlayClassName", "nzOverlayStyle", "nzDefaultActiveFirstOption", "nzBackfill", "compareWith", "nzDataSource"], outputs: ["selectionChange"], exportAs: ["nzAutocomplete"] }, { kind: "component", type: i17.NzAutocompleteOptionComponent, selector: "nz-auto-option", inputs: ["nzValue", "nzLabel", "nzDisabled"], outputs: ["selectionChange", "mouseEntered"], exportAs: ["nzAutoOption"] }, { kind: "directive", type: i17.NzAutocompleteTriggerDirective, selector: "input[nzAutocomplete], textarea[nzAutocomplete]", inputs: ["nzAutocomplete"], exportAs: ["nzAutocompleteTrigger"] }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "component", type: ExpandableSearchComponent, selector: "expandable-search", inputs: ["searchValue"], outputs: ["searchValueChange", "onSearch"] }, { kind: "ngmodule", type: NzPopconfirmModule }, { kind: "directive", type: i18.NzPopconfirmDirective, selector: "[nz-popconfirm]", inputs: ["nzPopconfirmArrowPointAtCenter", "nzPopconfirmTitle", "nzPopconfirmTitleContext", "nz-popconfirm", "nzPopconfirmTrigger", "nzPopconfirmPlacement", "nzPopconfirmOrigin", "nzPopconfirmMouseEnterDelay", "nzPopconfirmMouseLeaveDelay", "nzPopconfirmOverlayClassName", "nzPopconfirmOverlayStyle", "nzPopconfirmVisible", "nzOkText", "nzOkType", "nzOkDisabled", "nzOkDanger", "nzCancelText", "nzBeforeConfirm", "nzIcon", "nzCondition", "nzPopconfirmShowArrow", "nzPopconfirmBackdrop", "nzAutofocus"], outputs: ["nzPopconfirmVisibleChange", "nzOnCancel", "nzOnConfirm"], exportAs: ["nzPopconfirm"] }, { kind: "directive", type: NzFlexDirective, selector: "[nz-flex],nz-flex", inputs: ["nzVertical", "nzJustify", "nzAlign", "nzGap", "nzWrap", "nzFlex"], exportAs: ["nzFlex"] }, { kind: "component", type: ButtonReload, selector: "button-reload" }] });
7248
7515
  }
7249
7516
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: PermissionManagerComponent, decorators: [{
7250
7517
  type: Component,
@@ -7267,20 +7534,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImpor
7267
7534
  ExpandableSearchComponent,
7268
7535
  NzPopconfirmModule,
7269
7536
  NzFlexDirective,
7270
- ], template: "<nz-card nzTitle=\"Qu\u1EA3n l\u00FD Danh m\u1EE5c M\u00E3 quy\u1EC1n (App_Permission)\" [nzBordered]=\"false\">\r\n <div class=\"table-operations\" nz-row nzJustify=\"space-between\" style=\"margin-bottom: 16px\">\r\n <div nz-col>\r\n <expandable-search [(searchValue)]=\"searchText\" (onSearch)=\"loadData()\"></expandable-search>\r\n <button nz-button nzType=\"primary\" (click)=\"loadData()\" style=\"margin-right: 8px\">T\u1EA3i l\u1EA1i</button>\r\n </div>\r\n <div nz-col>\r\n <button nz-button nzType=\"primary\" (click)=\"openBulkModal()\" style=\"margin-right: 8px\">\r\n <i nz-icon nzType=\"bolt\"></i> T\u1EA1o m\u1EDBi (default)\r\n </button>\r\n <button nz-button nzType=\"primary\" (click)=\"openModal()\"><i nz-icon nzType=\"plus\"></i> Th\u00EAm m\u1EDBi</button>\r\n </div>\r\n </div>\r\n\r\n <nz-table\r\n #basicTable\r\n [nzData]=\"permissions\"\r\n nzBordered\r\n nzSize=\"small\"\r\n nzShowPagination=\"true\"\r\n nzShowSizeChanger=\"true\"\r\n >\r\n <thead>\r\n <tr>\r\n <th>Resource</th>\r\n <th>Permission code</th>\r\n <th>Permission name</th>\r\n <th>Description</th>\r\n <th nzAlign=\"center\">H\u00E0nh \u0111\u1ED9ng</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let data of basicTable.data\">\r\n <td>\r\n <div nz-flex nzGap=\"small\">\r\n <span>{{ data.ResourceName }}</span\r\n ><nz-tag [nzColor]=\"'blue'\">{{ data.ResourceCode }}</nz-tag>\r\n </div>\r\n </td>\r\n <td>\r\n <strong>{{ data.PermissionCode }}</strong>\r\n </td>\r\n <td>{{ data.PermissionName }}</td>\r\n <td>{{ data.Description }}</td>\r\n <td nzAlign=\"center\">\r\n <a (click)=\"openModal(data)\"><i nz-icon nzType=\"edit\" nzTheme=\"outline\"></i></a>\r\n <nz-divider nzType=\"vertical\"></nz-divider>\r\n <a\r\n nz-popconfirm\r\n nzPopconfirmTitle=\"X\u00E1c nh\u1EADn x\u00F3a?\"\r\n nzPopconfirmPlacement=\"left\"\r\n (nzOnConfirm)=\"deletePermission(data.App_Permission_Id)\"\r\n style=\"color: red\"\r\n >\r\n <i nz-icon nzType=\"delete\" nzTheme=\"outline\"></i>\r\n </a>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </nz-table>\r\n</nz-card>\r\n\r\n<nz-modal\r\n [(nzVisible)]=\"isBulkModalVisible\"\r\n nzTitle=\"Create Resource permission\"\r\n (nzOnCancel)=\"closeBulkModal()\"\r\n (nzOnOk)=\"saveBulkPermissions()\"\r\n [nzMaskClosable]=\"false\"\r\n nzWidth=\"750px\"\r\n>\r\n <ng-container *nzModalContent>\r\n <!-- <div style=\"margin-bottom: 16px; color: #666\">\r\n <i nz-icon nzType=\"info-circle\"></i> H\u1EC7 th\u1ED1ng s\u1EBD t\u1EF1 \u0111\u1ED9ng sinh m\u00E3 quy\u1EC1n v\u00E0 t\u00EAn thao t\u00E1c d\u1EF1a tr\u00EAn Module b\u1EA1n nh\u1EADp.\r\n B\u1EA1n c\u00F3 th\u1EC3 b\u1ECF t\u00EDch c\u00E1c thao t\u00E1c kh\u00F4ng c\u1EA7n thi\u1EBFt.\r\n </div> -->\r\n\r\n <form nz-form [formGroup]=\"bulkForm\" nzLayout=\"vertical\">\r\n <nz-row [nzGutter]=\"16\">\r\n <nz-col [nzSpan]=\"12\">\r\n <nz-form-item>\r\n <nz-form-label nzRequired>Resource Code</nz-form-label>\r\n <nz-form-control nzErrorTip=\"Vui l\u00F2ng nh\u1EADp m\u00E3 Module vi\u1EBFt li\u1EC1n!\">\r\n <input nz-input formControlName=\"ResourceCode\" placeholder=\"VD: Invoices, Products...\" />\r\n </nz-form-control>\r\n </nz-form-item>\r\n </nz-col>\r\n\r\n <nz-col [nzSpan]=\"12\">\r\n <nz-form-item>\r\n <nz-form-label nzRequired>Resource Name</nz-form-label>\r\n <nz-form-control nzErrorTip=\"Vui l\u00F2ng nh\u1EADp t\u00EAn Module!\">\r\n <input nz-input formControlName=\"ResourceName\" placeholder=\"VD: H\u00F3a \u0111\u01A1n, S\u1EA3n ph\u1EA9m...\" />\r\n </nz-form-control>\r\n </nz-form-item>\r\n </nz-col>\r\n </nz-row>\r\n </form>\r\n\r\n <nz-divider nzText=\"Danh s\u00E1ch Thao t\u00E1c\" nzOrientation=\"left\"></nz-divider>\r\n\r\n <nz-row [nzGutter]=\"[16, 16]\">\r\n @for (item of bulkActionCheckboxes; track $index) {\r\n <nz-col [nzSpan]=\"$index == 0 ? 24 : 8\">\r\n <label nz-checkbox [(ngModel)]=\"item.checked\" [ngModelOptions]=\"{ standalone: true }\">\r\n {{ item.label }}\r\n </label>\r\n </nz-col>\r\n }\r\n </nz-row>\r\n </ng-container>\r\n</nz-modal>\r\n\r\n<nz-modal\r\n [(nzVisible)]=\"isModalVisible\"\r\n [nzTitle]=\"isEditMode ? 'Update Resource permission' : 'Create Resource permission'\"\r\n (nzOnCancel)=\"closeModal()\"\r\n (nzOnOk)=\"savePermission()\"\r\n [nzOkLoading]=\"isSaving\"\r\n [nzMaskClosable]=\"false\"\r\n>\r\n <ng-container *nzModalContent>\r\n <form nz-form [formGroup]=\"permissionForm\" nzLayout=\"vertical\">\r\n <nz-row [nzGutter]=\"16\">\r\n <nz-col [nzSpan]=\"24\">\r\n <nz-form-item>\r\n <nz-form-label nzRequired>Resource name</nz-form-label>\r\n <nz-form-control nzErrorTip=\"Vui l\u00F2ng nh\u1EADp nh\u00F3m Resource name!\">\r\n <input nz-input formControlName=\"ResourceName\" placeholder=\"VD: Todos\" />\r\n </nz-form-control>\r\n </nz-form-item>\r\n </nz-col>\r\n\r\n <nz-col [nzSpan]=\"12\">\r\n <nz-form-item>\r\n <nz-form-label nzRequired>Resource code</nz-form-label>\r\n <nz-form-control nzErrorTip=\"Vui l\u00F2ng nh\u1EADp nh\u00F3m Resource Code!\">\r\n <input nz-input formControlName=\"ResourceCode\" placeholder=\"VD: todo\" />\r\n </nz-form-control>\r\n </nz-form-item>\r\n </nz-col>\r\n\r\n <nz-col [nzSpan]=\"12\">\r\n <nz-form-item>\r\n <nz-form-label nzRequired>Permission code</nz-form-label>\r\n <nz-form-control nzErrorTip=\"Vui l\u00F2ng nh\u1EADp Permission code!\">\r\n <input\r\n nz-input\r\n formControlName=\"actionSuffix\"\r\n placeholder=\"-- Ch\u1ECDn ho\u1EB7c t\u1EF1 nh\u1EADp --\"\r\n [nzAutocomplete]=\"auto\"\r\n />\r\n\r\n <nz-autocomplete #auto>\r\n <nz-auto-option *ngFor=\"let option of filteredActionOptions\" [nzValue]=\"option.value\">\r\n {{ option.label }}\r\n </nz-auto-option>\r\n </nz-autocomplete>\r\n </nz-form-control>\r\n </nz-form-item>\r\n </nz-col>\r\n </nz-row>\r\n\r\n <nz-form-item>\r\n <nz-form-label>M\u00E3 quy\u1EC1n h\u1EC7 th\u1ED1ng (T\u1EF1 \u0111\u1ED9ng sinh)</nz-form-label>\r\n <nz-form-control>\r\n <input\r\n nz-input\r\n formControlName=\"PermissionCode\"\r\n style=\"background-color: #f5f5f5; color: #1890ff; font-weight: bold; font-family: monospace\"\r\n />\r\n </nz-form-control>\r\n </nz-form-item>\r\n\r\n <nz-form-item>\r\n <nz-form-label nzRequired>T\u00EAn thao t\u00E1c hi\u1EC3n th\u1ECB</nz-form-label>\r\n <nz-form-control nzErrorTip=\"Vui l\u00F2ng nh\u1EADp t\u00EAn thao t\u00E1c!\">\r\n <input nz-input formControlName=\"PermissionName\" placeholder=\"VD: Xem c\u00F4ng vi\u1EC7c c\u1EE7a m\u00ECnh\" />\r\n </nz-form-control>\r\n </nz-form-item>\r\n </form>\r\n </ng-container>\r\n</nz-modal>\r\n" }]
7537
+ ButtonReload,
7538
+ ], template: "<nz-card nzTitle=\"Qu\u1EA3n l\u00FD Danh m\u1EE5c M\u00E3 quy\u1EC1n (App_Permission)\" [nzBordered]=\"false\">\r\n <div class=\"table-operations\" nz-row nzJustify=\"space-between\" style=\"margin-bottom: 16px\">\r\n <div nz-col nz-flex nzGap=\"small\">\r\n <expandable-search [(searchValue)]=\"searchText\" (onSearch)=\"loadData()\"></expandable-search>\r\n <button-reload (click)=\"loadData()\"></button-reload>\r\n </div>\r\n <div nz-col>\r\n <button nz-button nzType=\"primary\" (click)=\"openBulkModal()\" style=\"margin-right: 8px\">\r\n <i nz-icon nzType=\"plus\"></i> T\u1EA1o m\u1EDBi (default)\r\n </button>\r\n <button nz-button nzType=\"primary\" (click)=\"openModal()\"><i nz-icon nzType=\"plus\"></i> Th\u00EAm m\u1EDBi</button>\r\n </div>\r\n </div>\r\n\r\n <nz-table\r\n #basicTable\r\n [nzData]=\"permissions\"\r\n nzBordered\r\n nzSize=\"small\"\r\n nzShowPagination=\"true\"\r\n nzShowSizeChanger=\"true\"\r\n >\r\n <thead>\r\n <tr>\r\n <th>Resource</th>\r\n <th>Permission code</th>\r\n <th>Permission name</th>\r\n <th>Description</th>\r\n <th nzAlign=\"center\">H\u00E0nh \u0111\u1ED9ng</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let data of basicTable.data\">\r\n <td>\r\n <div nz-flex nzGap=\"small\">\r\n <span>{{ data.ResourceName }}</span\r\n ><nz-tag [nzColor]=\"'blue'\">{{ data.ResourceCode }}</nz-tag>\r\n </div>\r\n </td>\r\n <td>\r\n <strong>{{ data.PermissionCode }}</strong>\r\n </td>\r\n <td>{{ data.PermissionName }}</td>\r\n <td>{{ data.Description }}</td>\r\n <td nzAlign=\"center\">\r\n <a (click)=\"openModal(data)\"><i nz-icon nzType=\"edit\" nzTheme=\"outline\"></i></a>\r\n <nz-divider nzType=\"vertical\"></nz-divider>\r\n <a\r\n nz-popconfirm\r\n nzPopconfirmTitle=\"X\u00E1c nh\u1EADn x\u00F3a?\"\r\n nzPopconfirmPlacement=\"left\"\r\n (nzOnConfirm)=\"deletePermission(data.App_Permission_Id)\"\r\n style=\"color: red\"\r\n >\r\n <i nz-icon nzType=\"delete\" nzTheme=\"outline\"></i>\r\n </a>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </nz-table>\r\n</nz-card>\r\n\r\n<nz-modal\r\n [(nzVisible)]=\"isBulkModalVisible\"\r\n nzTitle=\"Create Resource permission\"\r\n (nzOnCancel)=\"closeBulkModal()\"\r\n (nzOnOk)=\"saveBulkPermissions()\"\r\n [nzMaskClosable]=\"false\"\r\n nzWidth=\"750px\"\r\n>\r\n <ng-container *nzModalContent>\r\n <!-- <div style=\"margin-bottom: 16px; color: #666\">\r\n <i nz-icon nzType=\"info-circle\"></i> H\u1EC7 th\u1ED1ng s\u1EBD t\u1EF1 \u0111\u1ED9ng sinh m\u00E3 quy\u1EC1n v\u00E0 t\u00EAn thao t\u00E1c d\u1EF1a tr\u00EAn Module b\u1EA1n nh\u1EADp.\r\n B\u1EA1n c\u00F3 th\u1EC3 b\u1ECF t\u00EDch c\u00E1c thao t\u00E1c kh\u00F4ng c\u1EA7n thi\u1EBFt.\r\n </div> -->\r\n\r\n <form nz-form [formGroup]=\"bulkForm\" nzLayout=\"vertical\">\r\n <nz-row [nzGutter]=\"16\">\r\n <nz-col [nzSpan]=\"12\">\r\n <nz-form-item>\r\n <nz-form-label nzRequired>Resource Code</nz-form-label>\r\n <nz-form-control nzErrorTip=\"Vui l\u00F2ng nh\u1EADp m\u00E3 Module vi\u1EBFt li\u1EC1n!\">\r\n <input nz-input formControlName=\"ResourceCode\" placeholder=\"VD: Invoices, Products...\" />\r\n </nz-form-control>\r\n </nz-form-item>\r\n </nz-col>\r\n\r\n <nz-col [nzSpan]=\"12\">\r\n <nz-form-item>\r\n <nz-form-label nzRequired>Resource Name</nz-form-label>\r\n <nz-form-control nzErrorTip=\"Vui l\u00F2ng nh\u1EADp t\u00EAn Module!\">\r\n <input nz-input formControlName=\"ResourceName\" placeholder=\"VD: H\u00F3a \u0111\u01A1n, S\u1EA3n ph\u1EA9m...\" />\r\n </nz-form-control>\r\n </nz-form-item>\r\n </nz-col>\r\n </nz-row>\r\n </form>\r\n\r\n <nz-divider nzText=\"Danh s\u00E1ch Thao t\u00E1c\" nzOrientation=\"left\"></nz-divider>\r\n\r\n <nz-row [nzGutter]=\"[16, 16]\">\r\n @for (item of bulkActionCheckboxes; track $index) {\r\n <nz-col [nzSpan]=\"$index == 0 ? 24 : 8\">\r\n <label nz-checkbox [(ngModel)]=\"item.checked\" [ngModelOptions]=\"{ standalone: true }\">\r\n {{ item.label }}\r\n </label>\r\n </nz-col>\r\n }\r\n </nz-row>\r\n </ng-container>\r\n</nz-modal>\r\n\r\n<nz-modal\r\n [(nzVisible)]=\"isModalVisible\"\r\n [nzTitle]=\"isEditMode ? 'Update Resource permission' : 'Create Resource permission'\"\r\n (nzOnCancel)=\"closeModal()\"\r\n (nzOnOk)=\"savePermission()\"\r\n [nzOkLoading]=\"isSaving\"\r\n [nzMaskClosable]=\"false\"\r\n>\r\n <ng-container *nzModalContent>\r\n <form nz-form [formGroup]=\"permissionForm\" nzLayout=\"vertical\">\r\n <nz-row [nzGutter]=\"16\">\r\n <nz-col [nzSpan]=\"24\">\r\n <nz-form-item>\r\n <nz-form-label nzRequired>Resource name</nz-form-label>\r\n <nz-form-control nzErrorTip=\"Vui l\u00F2ng nh\u1EADp nh\u00F3m Resource name!\">\r\n <input nz-input formControlName=\"ResourceName\" placeholder=\"VD: Todos\" />\r\n </nz-form-control>\r\n </nz-form-item>\r\n </nz-col>\r\n\r\n <nz-col [nzSpan]=\"12\">\r\n <nz-form-item>\r\n <nz-form-label nzRequired>Resource code</nz-form-label>\r\n <nz-form-control nzErrorTip=\"Vui l\u00F2ng nh\u1EADp nh\u00F3m Resource Code!\">\r\n <input nz-input formControlName=\"ResourceCode\" placeholder=\"VD: todo\" />\r\n </nz-form-control>\r\n </nz-form-item>\r\n </nz-col>\r\n\r\n <nz-col [nzSpan]=\"12\">\r\n <nz-form-item>\r\n <nz-form-label nzRequired>Permission code</nz-form-label>\r\n <nz-form-control nzErrorTip=\"Vui l\u00F2ng nh\u1EADp Permission code!\">\r\n <input\r\n nz-input\r\n formControlName=\"actionSuffix\"\r\n placeholder=\"-- Ch\u1ECDn ho\u1EB7c t\u1EF1 nh\u1EADp --\"\r\n [nzAutocomplete]=\"auto\"\r\n />\r\n\r\n <nz-autocomplete #auto>\r\n <nz-auto-option *ngFor=\"let option of filteredActionOptions\" [nzValue]=\"option.value\">\r\n {{ option.label }}\r\n </nz-auto-option>\r\n </nz-autocomplete>\r\n </nz-form-control>\r\n </nz-form-item>\r\n </nz-col>\r\n </nz-row>\r\n\r\n <nz-form-item>\r\n <nz-form-label>M\u00E3 quy\u1EC1n h\u1EC7 th\u1ED1ng (T\u1EF1 \u0111\u1ED9ng sinh)</nz-form-label>\r\n <nz-form-control>\r\n <input\r\n nz-input\r\n formControlName=\"PermissionCode\"\r\n style=\"background-color: #f5f5f5; color: #1890ff; font-weight: bold; font-family: monospace\"\r\n />\r\n </nz-form-control>\r\n </nz-form-item>\r\n\r\n <nz-form-item>\r\n <nz-form-label nzRequired>T\u00EAn thao t\u00E1c hi\u1EC3n th\u1ECB</nz-form-label>\r\n <nz-form-control nzErrorTip=\"Vui l\u00F2ng nh\u1EADp t\u00EAn thao t\u00E1c!\">\r\n <input nz-input formControlName=\"PermissionName\" placeholder=\"VD: Xem c\u00F4ng vi\u1EC7c c\u1EE7a m\u00ECnh\" />\r\n </nz-form-control>\r\n </nz-form-item>\r\n </form>\r\n </ng-container>\r\n</nz-modal>\r\n" }]
7271
7539
  }], ctorParameters: () => [{ type: i2.FormBuilder }, { type: PermissionService }] });
7272
7540
 
7273
7541
  class PermissionComponent extends BaseComponent {
7274
7542
  ngOnInit() {
7275
7543
  this.tab = +(this.getUrlQueryParam('tab') || 0);
7276
- Breadcrumb.lstBreadcrumb = [
7277
- {
7278
- Name: 'Permission',
7279
- },
7280
- {
7281
- Name: 'User - Role',
7282
- },
7283
- ];
7544
+ this.onSelectedIndexChange(this.tab);
7284
7545
  }
7285
7546
  ngOnDestroy() {
7286
7547
  Breadcrumb.lstBreadcrumb = [];
@@ -7288,48 +7549,46 @@ class PermissionComponent extends BaseComponent {
7288
7549
  tab = 0;
7289
7550
  onSelectedIndexChange(tabIndex) {
7290
7551
  this.setQueryParam('tab', tabIndex + '');
7291
- setTimeout(() => {
7292
- if (tabIndex == 0) {
7293
- Breadcrumb.lstBreadcrumb = [
7294
- {
7295
- Name: 'Permission',
7296
- },
7297
- {
7298
- Name: 'User - Role',
7299
- },
7300
- ];
7301
- }
7302
- else if (tabIndex == 1) {
7303
- Breadcrumb.lstBreadcrumb = [
7304
- {
7305
- Name: 'Permission',
7306
- },
7307
- {
7308
- Name: 'Role - Menu',
7309
- },
7310
- ];
7311
- }
7312
- else if (tabIndex == 2) {
7313
- Breadcrumb.lstBreadcrumb = [
7314
- {
7315
- Name: 'Permission',
7316
- },
7317
- {
7318
- Name: 'Resource permission',
7319
- },
7320
- ];
7321
- }
7322
- else if (tabIndex == 3) {
7323
- Breadcrumb.lstBreadcrumb = [
7324
- {
7325
- Name: 'Permission',
7326
- },
7327
- {
7328
- Name: 'Role - Resource permission',
7329
- },
7330
- ];
7331
- }
7332
- }, 0);
7552
+ if (tabIndex == 0) {
7553
+ Breadcrumb.lstBreadcrumb = [
7554
+ {
7555
+ Name: 'Permission',
7556
+ },
7557
+ {
7558
+ Name: 'User - Role',
7559
+ },
7560
+ ];
7561
+ }
7562
+ else if (tabIndex == 1) {
7563
+ Breadcrumb.lstBreadcrumb = [
7564
+ {
7565
+ Name: 'Permission',
7566
+ },
7567
+ {
7568
+ Name: 'Role - Menu',
7569
+ },
7570
+ ];
7571
+ }
7572
+ else if (tabIndex == 2) {
7573
+ Breadcrumb.lstBreadcrumb = [
7574
+ {
7575
+ Name: 'Permission',
7576
+ },
7577
+ {
7578
+ Name: 'Resource permission',
7579
+ },
7580
+ ];
7581
+ }
7582
+ else if (tabIndex == 3) {
7583
+ Breadcrumb.lstBreadcrumb = [
7584
+ {
7585
+ Name: 'Permission',
7586
+ },
7587
+ {
7588
+ Name: 'Role - Resource permission',
7589
+ },
7590
+ ];
7591
+ }
7333
7592
  }
7334
7593
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: PermissionComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
7335
7594
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.7", type: PermissionComponent, isStandalone: true, selector: "app-permision", usesInheritance: true, ngImport: i0, template: "<div class=\"panel\">\r\n <nz-tabset\r\n nzType=\"card\"\r\n [nzSize]=\"'small'\"\r\n [nzSelectedIndex]=\"tab\"\r\n (nzSelectedIndexChange)=\"onSelectedIndexChange($event)\"\r\n >\r\n <nz-tab nzTitle=\"User - Role\">\r\n <app-user-role-permission></app-user-role-permission>\r\n </nz-tab>\r\n <nz-tab nzTitle=\"Role - Menu\">\r\n <app-role-menu-permission></app-role-menu-permission>\r\n </nz-tab>\r\n <nz-tab nzTitle=\"Resource permission\">\r\n <resource-permission></resource-permission>\r\n </nz-tab>\r\n <nz-tab nzTitle=\"Role - Resource permission\">\r\n <role-resource-permission></role-resource-permission>\r\n </nz-tab>\r\n </nz-tabset>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: NzTabsModule }, { kind: "component", type: i1$9.NzTabSetComponent, selector: "nz-tabset", inputs: ["nzSelectedIndex", "nzTabPosition", "nzTabBarExtraContent", "nzCanDeactivate", "nzAddIcon", "nzTabBarStyle", "nzType", "nzSize", "nzAnimated", "nzTabBarGutter", "nzHideAdd", "nzCentered", "nzHideAll", "nzLinkRouter", "nzLinkExact", "nzDestroyInactiveTabPane"], outputs: ["nzSelectChange", "nzSelectedIndexChange", "nzTabListScroll", "nzClose", "nzAdd"], exportAs: ["nzTabset"] }, { kind: "component", type: i1$9.NzTabComponent, selector: "nz-tab", inputs: ["nzTitle", "nzClosable", "nzCloseIcon", "nzDisabled", "nzForceRender"], outputs: ["nzSelect", "nzDeselect", "nzClick", "nzContextmenu"], exportAs: ["nzTab"] }, { kind: "component", type: UserRolePermission, selector: "app-user-role-permission" }, { kind: "component", type: RoleMenuPermission, selector: "app-role-menu-permission" }, { kind: "component", type: RolePermissionComponent, selector: "role-resource-permission" }, { kind: "component", type: PermissionManagerComponent, selector: "resource-permission" }] });
@@ -8018,42 +8277,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImpor
8018
8277
  args: ['error', ['$event']]
8019
8278
  }] } });
8020
8279
 
8021
- const fadeInOut = trigger('fadeInOut', [
8022
- transition(':enter', [
8023
- style({ opacity: 0, transform: 'translateY(-5px)' }),
8024
- animate('150ms ease-out', style({ opacity: 1, transform: 'translateY(0)' })),
8025
- ]),
8026
- transition(':leave', [animate('150ms ease-in', style({ opacity: 0, transform: 'translateY(-5px)' }))]),
8027
- ]);
8028
- const fadeSlide = trigger('fadeSlide', [
8029
- transition(':enter', [
8030
- style({
8031
- height: 0,
8032
- opacity: 0,
8033
- overflow: 'hidden',
8034
- transform: 'translateY(-5px)',
8035
- }),
8036
- animate('250ms ease-out', style({
8037
- height: '*',
8038
- opacity: 1,
8039
- transform: 'translateY(0)',
8040
- })),
8041
- ]),
8042
- transition(':leave', [
8043
- style({
8044
- height: '*',
8045
- opacity: 1,
8046
- overflow: 'hidden',
8047
- transform: 'translateY(0)',
8048
- }),
8049
- animate('200ms ease-in', style({
8050
- height: 0,
8051
- opacity: 0,
8052
- transform: 'translateY(-5px)',
8053
- })),
8054
- ]),
8055
- ]);
8056
-
8057
8280
  const URLs$2 = {
8058
8281
  getById: '/api/App_Setting/GetById',
8059
8282
  getAll: '/api/App_Setting/GetAll',
@@ -8067,9 +8290,9 @@ const URLs$2 = {
8067
8290
  GetDbInfo: '/api/App_Setting/GetDbInfo',
8068
8291
  };
8069
8292
  class SettingService extends HTTPService {
8070
- commonService = inject(CommonService);
8293
+ cms = inject(CommonService);
8071
8294
  getById(id) {
8072
- return this.commonService.ESP({
8295
+ return this.cms.ESP({
8073
8296
  SPN: 'App_Setting_getById',
8074
8297
  Params: [id],
8075
8298
  });
@@ -8081,13 +8304,13 @@ class SettingService extends HTTPService {
8081
8304
  return this.postData(AppGlobals.apiEndpoint + URLs$2.getList, filter);
8082
8305
  }
8083
8306
  getPaging(filter) {
8084
- return this.commonService.ESP({
8307
+ return this.cms.ESP({
8085
8308
  SPN: 'App_Setting_getPaging',
8086
8309
  Params: [filter],
8087
8310
  });
8088
8311
  }
8089
8312
  addOrEdit(obj) {
8090
- return this.commonService.ESP({
8313
+ return this.cms.ESP({
8091
8314
  SPN: 'App_Setting_addOrEdit',
8092
8315
  Params: [obj],
8093
8316
  });
@@ -8101,97 +8324,31 @@ class SettingService extends HTTPService {
8101
8324
  return this.getParams(AppGlobals.apiEndpoint + URLs$2.getByCodeAnonymous, params);
8102
8325
  }
8103
8326
  // getGroupByCodeAnonymous(code: string) {
8104
- // const params = new HttpParams().append('Code', code);
8105
- // return this.getParams(AppGlobals.apiEndpoint + URLs.getByCodeAnonymous, params);
8106
- // }
8107
- getAllConfig() {
8108
- return this.post(AppGlobals.apiEndpoint + URLs$2.GetAllConfig);
8109
- }
8110
- applyConfig(config) {
8111
- return this.postData(AppGlobals.apiEndpoint + URLs$2.ApplyConfig, config);
8112
- }
8113
- getDbInfo() {
8114
- return this.post(AppGlobals.apiEndpoint + URLs$2.GetDbInfo);
8115
- }
8116
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: SettingService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
8117
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: SettingService, providedIn: 'root' });
8118
- }
8119
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: SettingService, decorators: [{
8120
- type: Injectable,
8121
- args: [{
8122
- providedIn: 'root',
8123
- }]
8124
- }] });
8125
-
8126
- class LayoutUser extends BaseComponent {
8127
- cms = inject(CommonService);
8128
- authService = inject(AuthService);
8129
- sessionManager = inject(SessionManagerService);
8130
- breakpointObserver = inject(BreakpointObserver);
8131
- settingService = inject(SettingService);
8132
- TokenStorage = TokenStorage;
8133
- isXSmall = false;
8134
- lstOrg = [];
8135
- isOneUserMultiOrgs = false;
8136
- ngOnInit() {
8137
- this.breakpointObserver.observe([Breakpoints.XSmall, Breakpoints.Small]).subscribe((result) => {
8138
- this.isXSmall = result.matches;
8139
- });
8140
- this.settingService.getByCodeAnonymous('ONE_USER_MULTI_ORGS').then((res) => {
8141
- if (res?.Data) {
8142
- if (res.Data == '1') {
8143
- this.isOneUserMultiOrgs = true;
8144
- this.getLstOrg();
8145
- }
8146
- }
8147
- }, (err) => this.handleError(err));
8148
- }
8149
- getLstOrg() {
8150
- this.cms
8151
- .ESP({
8152
- SPN: 'App_User_getLstOrg',
8153
- })
8154
- .then((res) => (this.lstOrg = res.Data), (err) => this.handleError(err));
8155
- }
8156
- async changeOrg(org) {
8157
- if (await this.confirm(`Chuyển sang đơn vị: ${org.Name}`)) {
8158
- this.authService.changeOrg(org).then(async (res) => {
8159
- if (res) {
8160
- await this.notiService.success(`Đã chuyển sang đơn vị: ${org.Name}`, '', true);
8161
- window.location.reload();
8162
- }
8163
- }, (err) => this.handleError(err));
8164
- }
8327
+ // const params = new HttpParams().append('Code', code);
8328
+ // return this.getParams(AppGlobals.apiEndpoint + URLs.getByCodeAnonymous, params);
8329
+ // }
8330
+ getAllConfig() {
8331
+ return this.post(AppGlobals.apiEndpoint + URLs$2.GetAllConfig);
8165
8332
  }
8166
- gotoSetting() {
8167
- this.goto('/admin/user_profile');
8333
+ applyConfig(config) {
8334
+ return this.postData(AppGlobals.apiEndpoint + URLs$2.ApplyConfig, config);
8168
8335
  }
8169
- logout() {
8170
- this.sessionManager.logout();
8336
+ getDbInfo() {
8337
+ return this.post(AppGlobals.apiEndpoint + URLs$2.GetDbInfo);
8171
8338
  }
8172
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: LayoutUser, deps: null, target: i0.ɵɵFactoryTarget.Component });
8173
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.7", type: LayoutUser, isStandalone: true, selector: "layout-user", usesInheritance: true, ngImport: i0, template: "<nz-badge [nzSize]=\"'small'\" [nzCount]=\"0\">\r\n <button nz-button nzType=\"text\" nzSize=\"small\">\r\n <nz-icon nzType=\"bell\" nzTheme=\"outline\" style=\"color: #ffffff\" />\r\n </button>\r\n</nz-badge>\r\n\r\n<button\r\n *ngIf=\"!isXSmall && TokenStorage.getOrgName()\"\r\n [@fadeInOut]\r\n nz-button\r\n nzType=\"text\"\r\n nz-dropdown\r\n [nzDropdownMenu]=\"isOneUserMultiOrgs ? menuOrg : null\"\r\n [nzTrigger]=\"'click'\"\r\n style=\"height: var(--app-header-height); color: #ffffff\"\r\n>\r\n <nz-icon nzType=\"cluster\" nzTheme=\"outline\" />\r\n {{ TokenStorage.getOrgName() }}\r\n</button>\r\n\r\n<nz-dropdown-menu #menuOrg=\"nzDropdownMenu\">\r\n <ul nz-menu>\r\n @for (org of lstOrg; track $index) {\r\n <li *ngIf=\"$index > 0\" nz-menu-divider></li>\r\n <li nz-menu-item (click)=\"changeOrg(org)\">\r\n <nz-icon nzType=\"swap\" nzTheme=\"outline\" />&nbsp;&nbsp; {{ org.Name }}\r\n </li>\r\n }\r\n </ul>\r\n</nz-dropdown-menu>\r\n\r\n<button\r\n nz-button\r\n nzType=\"text\"\r\n nz-dropdown\r\n [nzDropdownMenu]=\"menuUser\"\r\n [nzTrigger]=\"'click'\"\r\n style=\"height: var(--app-header-height); color: #ffffff\"\r\n>\r\n <nz-icon nzType=\"user\" nzTheme=\"outline\" />\r\n {{ TokenStorage.getUserFullname() }}\r\n</button>\r\n\r\n<nz-dropdown-menu #menuUser=\"nzDropdownMenu\">\r\n <ul nz-menu>\r\n <li *ngIf=\"!(!isXSmall && TokenStorage.getOrgName())\" nz-menu-item>\r\n <nz-icon nzType=\"cluster\" nzTheme=\"outline\" />&nbsp;&nbsp; {{ TokenStorage.getOrgName() }}\r\n </li>\r\n <li *ngIf=\"!(!isXSmall && TokenStorage.getOrgName())\" nz-menu-divider></li>\r\n <li nz-menu-item (click)=\"gotoSetting()\">\r\n <nz-icon nzType=\"setting\" nzTheme=\"outline\" />&nbsp;&nbsp; {{ TranslateKey.SETTING | translate }}\r\n </li>\r\n <li nz-menu-divider></li>\r\n <li nz-menu-item (click)=\"logout()\">\r\n <nz-icon nzType=\"logout\" nzTheme=\"outline\" />&nbsp;&nbsp; {{ TranslateKey.LOGOUT | translate }}\r\n </li>\r\n </ul>\r\n</nz-dropdown-menu>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3$1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: NzLayoutModule }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "ngmodule", type: NzDropDownModule }, { kind: "directive", type: i4$2.NzMenuDirective, selector: "[nz-menu]", inputs: ["nzInlineIndent", "nzTheme", "nzMode", "nzInlineCollapsed", "nzSelectable"], outputs: ["nzClick"], exportAs: ["nzMenu"] }, { kind: "component", type: i4$2.NzMenuItemComponent, selector: "[nz-menu-item]", inputs: ["nzPaddingLeft", "nzDisabled", "nzSelected", "nzDanger", "nzMatchRouterExact", "nzMatchRouter"], exportAs: ["nzMenuItem"] }, { kind: "directive", type: i4$2.NzMenuDividerDirective, selector: "[nz-menu-divider]", exportAs: ["nzMenuDivider"] }, { kind: "directive", type: i5$4.NzDropDownDirective, selector: "[nz-dropdown]", inputs: ["nzDropdownMenu", "nzTrigger", "nzMatchWidthElement", "nzBackdrop", "nzClickHide", "nzDisabled", "nzVisible", "nzOverlayClassName", "nzOverlayStyle", "nzPlacement"], outputs: ["nzVisibleChange"], exportAs: ["nzDropdown"] }, { kind: "component", type: i5$4.NzDropdownMenuComponent, selector: "nz-dropdown-menu", exportAs: ["nzDropdownMenu"] }, { kind: "directive", type: i5$4.NzDropdownButtonDirective, selector: "[nz-button][nz-dropdown]" }, { kind: "ngmodule", type: NzGridModule }, { kind: "ngmodule", type: NzFlexModule }, { kind: "ngmodule", type: NzButtonModule }, { kind: "component", type: i5$3.NzButtonComponent, selector: "button[nz-button], a[nz-button]", inputs: ["nzBlock", "nzGhost", "nzSearch", "nzLoading", "nzDanger", "disabled", "tabIndex", "nzType", "nzShape", "nzSize"], exportAs: ["nzButton"] }, { kind: "directive", type: i6$3.ɵ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: "ngmodule", type: NzTreeModule }, { kind: "ngmodule", type: NzBackTopModule }, { kind: "ngmodule", type: NzDrawerModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: NzInputModule }, { kind: "ngmodule", type: NzSegmentedModule }, { kind: "ngmodule", type: NzBadgeModule }, { kind: "component", type: i8$1.NzBadgeComponent, selector: "nz-badge", inputs: ["nzShowZero", "nzShowDot", "nzStandalone", "nzDot", "nzOverflowCount", "nzColor", "nzStyle", "nzText", "nzTitle", "nzStatus", "nzCount", "nzOffset", "nzSize"], exportAs: ["nzBadge"] }], animations: [fadeInOut] });
8339
+ loadConfigTheme() {
8340
+ return this.cms.ESP({
8341
+ SPN: 'App_Setting_getConfigTheme',
8342
+ });
8343
+ }
8344
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: SettingService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
8345
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: SettingService, providedIn: 'root' });
8174
8346
  }
8175
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: LayoutUser, decorators: [{
8176
- type: Component,
8177
- args: [{ selector: 'layout-user', imports: [
8178
- CommonModule,
8179
- TranslateModule,
8180
- NzLayoutModule,
8181
- NzIconModule,
8182
- NzDropDownModule,
8183
- NzGridModule,
8184
- NzFlexModule,
8185
- NzButtonModule,
8186
- NzTreeModule,
8187
- NzBackTopModule,
8188
- NzDrawerModule,
8189
- FormsModule,
8190
- NzInputModule,
8191
- NzTreeModule,
8192
- NzSegmentedModule,
8193
- NzBadgeModule,
8194
- ], animations: [fadeInOut], template: "<nz-badge [nzSize]=\"'small'\" [nzCount]=\"0\">\r\n <button nz-button nzType=\"text\" nzSize=\"small\">\r\n <nz-icon nzType=\"bell\" nzTheme=\"outline\" style=\"color: #ffffff\" />\r\n </button>\r\n</nz-badge>\r\n\r\n<button\r\n *ngIf=\"!isXSmall && TokenStorage.getOrgName()\"\r\n [@fadeInOut]\r\n nz-button\r\n nzType=\"text\"\r\n nz-dropdown\r\n [nzDropdownMenu]=\"isOneUserMultiOrgs ? menuOrg : null\"\r\n [nzTrigger]=\"'click'\"\r\n style=\"height: var(--app-header-height); color: #ffffff\"\r\n>\r\n <nz-icon nzType=\"cluster\" nzTheme=\"outline\" />\r\n {{ TokenStorage.getOrgName() }}\r\n</button>\r\n\r\n<nz-dropdown-menu #menuOrg=\"nzDropdownMenu\">\r\n <ul nz-menu>\r\n @for (org of lstOrg; track $index) {\r\n <li *ngIf=\"$index > 0\" nz-menu-divider></li>\r\n <li nz-menu-item (click)=\"changeOrg(org)\">\r\n <nz-icon nzType=\"swap\" nzTheme=\"outline\" />&nbsp;&nbsp; {{ org.Name }}\r\n </li>\r\n }\r\n </ul>\r\n</nz-dropdown-menu>\r\n\r\n<button\r\n nz-button\r\n nzType=\"text\"\r\n nz-dropdown\r\n [nzDropdownMenu]=\"menuUser\"\r\n [nzTrigger]=\"'click'\"\r\n style=\"height: var(--app-header-height); color: #ffffff\"\r\n>\r\n <nz-icon nzType=\"user\" nzTheme=\"outline\" />\r\n {{ TokenStorage.getUserFullname() }}\r\n</button>\r\n\r\n<nz-dropdown-menu #menuUser=\"nzDropdownMenu\">\r\n <ul nz-menu>\r\n <li *ngIf=\"!(!isXSmall && TokenStorage.getOrgName())\" nz-menu-item>\r\n <nz-icon nzType=\"cluster\" nzTheme=\"outline\" />&nbsp;&nbsp; {{ TokenStorage.getOrgName() }}\r\n </li>\r\n <li *ngIf=\"!(!isXSmall && TokenStorage.getOrgName())\" nz-menu-divider></li>\r\n <li nz-menu-item (click)=\"gotoSetting()\">\r\n <nz-icon nzType=\"setting\" nzTheme=\"outline\" />&nbsp;&nbsp; {{ TranslateKey.SETTING | translate }}\r\n </li>\r\n <li nz-menu-divider></li>\r\n <li nz-menu-item (click)=\"logout()\">\r\n <nz-icon nzType=\"logout\" nzTheme=\"outline\" />&nbsp;&nbsp; {{ TranslateKey.LOGOUT | translate }}\r\n </li>\r\n </ul>\r\n</nz-dropdown-menu>\r\n" }]
8347
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: SettingService, decorators: [{
8348
+ type: Injectable,
8349
+ args: [{
8350
+ providedIn: 'root',
8351
+ }]
8195
8352
  }] });
8196
8353
 
8197
8354
  const URLs$1 = {
@@ -8292,11 +8449,47 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImpor
8292
8449
  }]
8293
8450
  }] });
8294
8451
 
8452
+ const fadeInOut = trigger('fadeInOut', [
8453
+ transition(':enter', [
8454
+ style({ opacity: 0, transform: 'translateY(-5px)' }),
8455
+ animate('150ms ease-out', style({ opacity: 1, transform: 'translateY(0)' })),
8456
+ ]),
8457
+ transition(':leave', [animate('150ms ease-in', style({ opacity: 0, transform: 'translateY(-5px)' }))]),
8458
+ ]);
8459
+ const fadeSlide = trigger('fadeSlide', [
8460
+ transition(':enter', [
8461
+ style({
8462
+ height: 0,
8463
+ opacity: 0,
8464
+ overflow: 'hidden',
8465
+ transform: 'translateY(-5px)',
8466
+ }),
8467
+ animate('250ms ease-out', style({
8468
+ height: '*',
8469
+ opacity: 1,
8470
+ transform: 'translateY(0)',
8471
+ })),
8472
+ ]),
8473
+ transition(':leave', [
8474
+ style({
8475
+ height: '*',
8476
+ opacity: 1,
8477
+ overflow: 'hidden',
8478
+ transform: 'translateY(0)',
8479
+ }),
8480
+ animate('200ms ease-in', style({
8481
+ height: 0,
8482
+ opacity: 0,
8483
+ transform: 'translateY(-5px)',
8484
+ })),
8485
+ ]),
8486
+ ]);
8487
+
8295
8488
  class SignalRService {
8296
8489
  static connection;
8297
8490
  static sendRequestLoginStatus() {
8298
- if (this.connection.state == signalR.HubConnectionState.Connected) {
8299
- // console.log('Send RequestLoginStatus');
8491
+ if (this.connection?.state == signalR.HubConnectionState.Connected) {
8492
+ console.log('Send RequestLoginStatus');
8300
8493
  this.connection
8301
8494
  .send('RequestLoginStatus')
8302
8495
  .then()
@@ -8304,17 +8497,18 @@ class SignalRService {
8304
8497
  }
8305
8498
  }
8306
8499
  static initNoti() {
8500
+ console.log('SignalRService.initNoti');
8307
8501
  this.connection = SignalRService.getConnection();
8308
8502
  this.registerAction();
8309
8503
  }
8310
8504
  static registerAction() {
8311
- this.connection.on('BroadcastMessage', (msg) => {
8312
- // console.log('SignalR on BroadcastMessage: ' + msg);
8505
+ this.connection?.on('BroadcastMessage', (msg) => {
8506
+ console.log('SignalR on BroadcastMessage: ' + msg);
8313
8507
  });
8314
- this.connection.on('RequestLoginStatus', (ConnectionId) => {
8315
- // console.log('Received RequestLoginStatus ConnectionId: ' + ConnectionId);
8508
+ this.connection?.on('RequestLoginStatus', (ConnectionId) => {
8509
+ console.log('Received RequestLoginStatus ConnectionId: ' + ConnectionId);
8316
8510
  this.connection
8317
- .send('ResponseLoginStatus', ConnectionId)
8511
+ ?.send('ResponseLoginStatus', ConnectionId)
8318
8512
  .then()
8319
8513
  .catch((err) => console.log(err));
8320
8514
  });
@@ -8363,6 +8557,237 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImpor
8363
8557
  }]
8364
8558
  }] });
8365
8559
 
8560
+ // notification.service.ts
8561
+ class NotificationService {
8562
+ http;
8563
+ // Quản lý state bằng BehaviorSubject
8564
+ notificationsSubject = new BehaviorSubject([]);
8565
+ unreadCountSubject = new BehaviorSubject(0);
8566
+ isLoadingSubject = new BehaviorSubject(false);
8567
+ // Expose ra cho Component subscribe bằng async pipe
8568
+ notifications$ = this.notificationsSubject.asObservable();
8569
+ unreadCount$ = this.unreadCountSubject.asObservable();
8570
+ isLoading$ = this.isLoadingSubject.asObservable();
8571
+ constructor(http) {
8572
+ this.http = http;
8573
+ }
8574
+ // Gọi API lấy thông báo lần đầu / phân trang
8575
+ loadNotifications(page = 1) {
8576
+ this.isLoadingSubject.next(true);
8577
+ // Giả lập gọi API HTTP
8578
+ this.http.get(`/api/notifications?page=${page}`).subscribe({
8579
+ next: (res) => {
8580
+ const currentData = this.notificationsSubject.getValue();
8581
+ // Append dữ liệu mới vào dữ liệu cũ (cho Infinite Scroll)
8582
+ this.notificationsSubject.next([...currentData, ...res.data]);
8583
+ this.unreadCountSubject.next(res.unreadCount);
8584
+ this.isLoadingSubject.next(false);
8585
+ },
8586
+ error: () => this.isLoadingSubject.next(false),
8587
+ });
8588
+ }
8589
+ // Optimistic Update: Đánh dấu đã đọc trước khi API trả về để UX mượt
8590
+ markAsRead(id) {
8591
+ const currentNotis = this.notificationsSubject.getValue();
8592
+ const updatedNotis = currentNotis.map((noti) => (noti.id === id ? { ...noti, isRead: true } : noti));
8593
+ this.notificationsSubject.next(updatedNotis);
8594
+ this.unreadCountSubject.next(Math.max(0, this.unreadCountSubject.getValue() - 1));
8595
+ // Gọi API update background
8596
+ this.http.post(`/api/notifications/${id}/read`, {}).subscribe();
8597
+ }
8598
+ markAllAsRead() {
8599
+ // Tương tự markAsRead nhưng áp dụng cho toàn bộ danh sách
8600
+ }
8601
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: NotificationService, deps: [{ token: i1$a.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
8602
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: NotificationService, providedIn: 'root' });
8603
+ }
8604
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: NotificationService, decorators: [{
8605
+ type: Injectable,
8606
+ args: [{
8607
+ providedIn: 'root',
8608
+ }]
8609
+ }], ctorParameters: () => [{ type: i1$a.HttpClient }] });
8610
+
8611
+ // notification-center.component.ts
8612
+ class NotificationCenterComponent {
8613
+ notificationService;
8614
+ hasNoti = false;
8615
+ constructor(notificationService) {
8616
+ this.notificationService = notificationService;
8617
+ }
8618
+ ngOnInit() {
8619
+ // Load trang đầu tiên khi khởi tạo
8620
+ this.notificationService.loadNotifications(1);
8621
+ }
8622
+ onNotificationClick(item) {
8623
+ if (!item.isRead) {
8624
+ this.notificationService.markAsRead(item.id);
8625
+ }
8626
+ // Logic điều hướng (Router.navigate) dựa vào loại thông báo...
8627
+ }
8628
+ onScrollDown() {
8629
+ // Logic gọi thêm dữ liệu khi cuộn xuống đáy (Infinite Scroll)
8630
+ // Có thể dùng thư viện ngx-infinite-scroll kết hợp với div danh sách
8631
+ }
8632
+ // Giúp Angular render lại DOM hiệu quả hơn thay vì render lại toàn bộ list
8633
+ trackById(index, item) {
8634
+ return item.id;
8635
+ }
8636
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: NotificationCenterComponent, deps: [{ token: NotificationService }], target: i0.ɵɵFactoryTarget.Component });
8637
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.7", type: NotificationCenterComponent, isStandalone: true, selector: "app-notification-center", ngImport: i0, template: "<div\r\n class=\"bell-trigger\"\r\n nz-popover\r\n [nzPopoverTitle]=\"notiTitle\"\r\n [nzPopoverContent]=\"notiContent\"\r\n nzPopoverTrigger=\"click\"\r\n nzPopoverPlacement=\"bottomCenter\"\r\n nzPopoverOverlayClassName=\"enterprise-noti-popover\"\r\n>\r\n <nz-badge [nzCount]=\"0\" [nzOverflowCount]=\"99\" nzSize=\"small\">\r\n <span nz-icon nzType=\"bell\" nzTheme=\"outline\" class=\"bell-icon\"></span>\r\n </nz-badge>\r\n</div>\r\n\r\n<ng-template #notiTitle>\r\n <div class=\"noti-header\">\r\n <span class=\"noti-title-text\">Th\u00F4ng b\u00E1o</span>\r\n <a *ngIf=\"hasNoti\" class=\"noti-mark-read\">\u0110\u00E1nh d\u1EA5u \u0111\u00E3 \u0111\u1ECDc</a>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #notiContent>\r\n <div class=\"noti-body\">\r\n @if (!hasNoti) {\r\n <box [height]=\"8\"></box>\r\n <nz-empty nzNotFoundContent=\"Kh\u00F4ng c\u00F3 Th\u00F4ng b\u00E1o\"></nz-empty>\r\n } @else {\r\n <nz-list nzItemLayout=\"horizontal\" [nzSplit]=\"false\">\r\n <nz-list-item class=\"noti-item unread\">\r\n <nz-list-item-meta\r\n [nzAvatar]=\"avatarTemplate\"\r\n nzTitle=\"H\u1EC7 th\u1ED1ng b\u1EA3o tr\u00EC\"\r\n nzDescription=\"H\u1EC7 th\u1ED1ng s\u1EBD b\u1EA3o tr\u00EC v\u00E0o 12:00 \u0111\u00EAm nay.\"\r\n ></nz-list-item-meta>\r\n </nz-list-item>\r\n\r\n <nz-list-item class=\"noti-item\">\r\n <nz-list-item-meta\r\n [nzAvatar]=\"avatarTemplate\"\r\n nzTitle=\"B\u00E1o c\u00E1o tu\u1EA7n \u0111\u00E3 s\u1EB5n s\u00E0ng\"\r\n nzDescription=\"Nh\u1EA5n v\u00E0o \u0111\u1EC3 xem chi ti\u1EBFt b\u00E1o c\u00E1o. Nh\u1EA5n v\u00E0o \u0111\u1EC3 xem chi ti\u1EBFt b\u00E1o c\u00E1o.\"\r\n ></nz-list-item-meta>\r\n </nz-list-item>\r\n </nz-list>\r\n\r\n <ng-template #avatarTemplate>\r\n <nz-avatar nzIcon=\"info\" class=\"noti-avatar\"></nz-avatar>\r\n </ng-template>\r\n }\r\n </div>\r\n</ng-template>\r\n", styles: ["@charset \"UTF-8\";::ng-deep .enterprise-noti-popover .ant-popover-inner-content{padding:0!important}::ng-deep .enterprise-noti-popover .ant-popover-title{padding:0!important;border-bottom:1px solid #f0f0f0}.bell-trigger{cursor:pointer;display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:50%;transition:background-color .3s;margin-top:4px}.bell-trigger .bell-icon{color:#fff}.bell-trigger:hover{background-color:#ffffff26}.bell-trigger ::ng-deep .ant-badge-count{box-shadow:0 0 0 2px #1f2937}.bell-trigger ::ng-deep .ant-badge-multiple-words{padding:0 3px}.noti-header{display:flex;justify-content:space-between;align-items:center;width:340px;padding:6px 8px}.noti-header .noti-title-text{font-size:16px;font-weight:600;color:#262626}.noti-header .noti-mark-read{font-size:13px;color:#1890ff;cursor:pointer;transition:opacity .3s}.noti-header .noti-mark-read:hover{opacity:.8}.noti-body{width:340px;max-height:400px;overflow-y:auto;overflow-x:hidden}.noti-body .noti-item{padding:14px 16px;cursor:pointer;border-bottom:1px solid #f0f0f0;transition:all .3s ease}.noti-body .noti-item:last-child{border-bottom:none}.noti-body .noti-item:hover{background-color:#f5f5f5}.noti-body .noti-item.unread{background-color:#e6f7ff;position:relative}.noti-body .noti-item.unread:after{content:\"\";position:absolute;top:50%;right:16px;transform:translateY(-50%);width:8px;height:8px;background-color:#1890ff;border-radius:50%}.noti-body .noti-item.unread:hover{background-color:#dcf4ff}.noti-body .noti-avatar{background-color:#1890ff;color:#fff}.noti-body ::ng-deep .ant-list-item-meta-title{margin-bottom:6px;font-size:14px;font-weight:500;line-height:1.4;color:#1f1f1f;word-break:break-word;padding-right:12px}.noti-body ::ng-deep .ant-list-item-meta-description{font-size:13px;line-height:1.4;color:#8c8c8c;word-break:break-word;padding-right:12px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: NzPopoverModule }, { kind: "directive", type: i3$4.NzPopoverDirective, selector: "[nz-popover]", inputs: ["nzPopoverArrowPointAtCenter", "nzPopoverTitle", "nzPopoverContent", "nz-popover", "nzPopoverTrigger", "nzPopoverPlacement", "nzPopoverOrigin", "nzPopoverVisible", "nzPopoverMouseEnterDelay", "nzPopoverMouseLeaveDelay", "nzPopoverOverlayClassName", "nzPopoverOverlayStyle", "nzPopoverOverlayClickable", "nzPopoverBackdrop"], outputs: ["nzPopoverVisibleChange"], exportAs: ["nzPopover"] }, { kind: "ngmodule", type: NzBadgeModule }, { kind: "component", type: i4$3.NzBadgeComponent, selector: "nz-badge", inputs: ["nzShowZero", "nzShowDot", "nzStandalone", "nzDot", "nzOverflowCount", "nzColor", "nzStyle", "nzText", "nzTitle", "nzStatus", "nzCount", "nzOffset", "nzSize"], exportAs: ["nzBadge"] }, { kind: "ngmodule", type: NzSkeletonModule }, { kind: "ngmodule", type: NzEmptyModule }, { kind: "component", type: i5$4.NzEmptyComponent, selector: "nz-empty", inputs: ["nzNotFoundImage", "nzNotFoundContent", "nzNotFoundFooter"], exportAs: ["nzEmpty"] }, { kind: "ngmodule", type: NzListModule }, { kind: "component", type: i6$4.NzListComponent, selector: "nz-list, [nz-list]", inputs: ["nzDataSource", "nzBordered", "nzGrid", "nzHeader", "nzFooter", "nzItemLayout", "nzRenderItem", "nzLoading", "nzLoadMore", "nzPagination", "nzSize", "nzSplit", "nzNoResult"], exportAs: ["nzList"] }, { kind: "component", type: i6$4.NzListItemComponent, selector: "nz-list-item, [nz-list-item]", inputs: ["nzActions", "nzContent", "nzExtra", "nzNoFlex"], exportAs: ["nzListItem"] }, { kind: "component", type: i6$4.NzListItemMetaComponent, selector: "nz-list-item-meta, [nz-list-item-meta]", inputs: ["nzAvatar", "nzTitle", "nzDescription"], exportAs: ["nzListItemMeta"] }, { kind: "ngmodule", type: NzAvatarModule }, { kind: "component", type: i7.NzAvatarComponent, selector: "nz-avatar", inputs: ["nzShape", "nzSize", "nzGap", "nzText", "nzSrc", "nzSrcSet", "nzAlt", "nzIcon"], outputs: ["nzError"], exportAs: ["nzAvatar"] }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "ngmodule", type: NzButtonModule }, { 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: "component", type: Box, selector: "box", inputs: ["display", "width", "height"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
8638
+ }
8639
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: NotificationCenterComponent, decorators: [{
8640
+ type: Component,
8641
+ args: [{ selector: 'app-notification-center', imports: [
8642
+ CommonModule,
8643
+ NzPopoverModule,
8644
+ NzBadgeModule,
8645
+ NzSkeletonModule,
8646
+ NzEmptyModule,
8647
+ NzListModule,
8648
+ NzAvatarModule,
8649
+ NzIconModule,
8650
+ NzButtonModule,
8651
+ Box,
8652
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\r\n class=\"bell-trigger\"\r\n nz-popover\r\n [nzPopoverTitle]=\"notiTitle\"\r\n [nzPopoverContent]=\"notiContent\"\r\n nzPopoverTrigger=\"click\"\r\n nzPopoverPlacement=\"bottomCenter\"\r\n nzPopoverOverlayClassName=\"enterprise-noti-popover\"\r\n>\r\n <nz-badge [nzCount]=\"0\" [nzOverflowCount]=\"99\" nzSize=\"small\">\r\n <span nz-icon nzType=\"bell\" nzTheme=\"outline\" class=\"bell-icon\"></span>\r\n </nz-badge>\r\n</div>\r\n\r\n<ng-template #notiTitle>\r\n <div class=\"noti-header\">\r\n <span class=\"noti-title-text\">Th\u00F4ng b\u00E1o</span>\r\n <a *ngIf=\"hasNoti\" class=\"noti-mark-read\">\u0110\u00E1nh d\u1EA5u \u0111\u00E3 \u0111\u1ECDc</a>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #notiContent>\r\n <div class=\"noti-body\">\r\n @if (!hasNoti) {\r\n <box [height]=\"8\"></box>\r\n <nz-empty nzNotFoundContent=\"Kh\u00F4ng c\u00F3 Th\u00F4ng b\u00E1o\"></nz-empty>\r\n } @else {\r\n <nz-list nzItemLayout=\"horizontal\" [nzSplit]=\"false\">\r\n <nz-list-item class=\"noti-item unread\">\r\n <nz-list-item-meta\r\n [nzAvatar]=\"avatarTemplate\"\r\n nzTitle=\"H\u1EC7 th\u1ED1ng b\u1EA3o tr\u00EC\"\r\n nzDescription=\"H\u1EC7 th\u1ED1ng s\u1EBD b\u1EA3o tr\u00EC v\u00E0o 12:00 \u0111\u00EAm nay.\"\r\n ></nz-list-item-meta>\r\n </nz-list-item>\r\n\r\n <nz-list-item class=\"noti-item\">\r\n <nz-list-item-meta\r\n [nzAvatar]=\"avatarTemplate\"\r\n nzTitle=\"B\u00E1o c\u00E1o tu\u1EA7n \u0111\u00E3 s\u1EB5n s\u00E0ng\"\r\n nzDescription=\"Nh\u1EA5n v\u00E0o \u0111\u1EC3 xem chi ti\u1EBFt b\u00E1o c\u00E1o. Nh\u1EA5n v\u00E0o \u0111\u1EC3 xem chi ti\u1EBFt b\u00E1o c\u00E1o.\"\r\n ></nz-list-item-meta>\r\n </nz-list-item>\r\n </nz-list>\r\n\r\n <ng-template #avatarTemplate>\r\n <nz-avatar nzIcon=\"info\" class=\"noti-avatar\"></nz-avatar>\r\n </ng-template>\r\n }\r\n </div>\r\n</ng-template>\r\n", styles: ["@charset \"UTF-8\";::ng-deep .enterprise-noti-popover .ant-popover-inner-content{padding:0!important}::ng-deep .enterprise-noti-popover .ant-popover-title{padding:0!important;border-bottom:1px solid #f0f0f0}.bell-trigger{cursor:pointer;display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:50%;transition:background-color .3s;margin-top:4px}.bell-trigger .bell-icon{color:#fff}.bell-trigger:hover{background-color:#ffffff26}.bell-trigger ::ng-deep .ant-badge-count{box-shadow:0 0 0 2px #1f2937}.bell-trigger ::ng-deep .ant-badge-multiple-words{padding:0 3px}.noti-header{display:flex;justify-content:space-between;align-items:center;width:340px;padding:6px 8px}.noti-header .noti-title-text{font-size:16px;font-weight:600;color:#262626}.noti-header .noti-mark-read{font-size:13px;color:#1890ff;cursor:pointer;transition:opacity .3s}.noti-header .noti-mark-read:hover{opacity:.8}.noti-body{width:340px;max-height:400px;overflow-y:auto;overflow-x:hidden}.noti-body .noti-item{padding:14px 16px;cursor:pointer;border-bottom:1px solid #f0f0f0;transition:all .3s ease}.noti-body .noti-item:last-child{border-bottom:none}.noti-body .noti-item:hover{background-color:#f5f5f5}.noti-body .noti-item.unread{background-color:#e6f7ff;position:relative}.noti-body .noti-item.unread:after{content:\"\";position:absolute;top:50%;right:16px;transform:translateY(-50%);width:8px;height:8px;background-color:#1890ff;border-radius:50%}.noti-body .noti-item.unread:hover{background-color:#dcf4ff}.noti-body .noti-avatar{background-color:#1890ff;color:#fff}.noti-body ::ng-deep .ant-list-item-meta-title{margin-bottom:6px;font-size:14px;font-weight:500;line-height:1.4;color:#1f1f1f;word-break:break-word;padding-right:12px}.noti-body ::ng-deep .ant-list-item-meta-description{font-size:13px;line-height:1.4;color:#8c8c8c;word-break:break-word;padding-right:12px}\n"] }]
8653
+ }], ctorParameters: () => [{ type: NotificationService }] });
8654
+
8655
+ class LayoutUser extends BaseComponent {
8656
+ cms = inject(CommonService);
8657
+ authService = inject(AuthService);
8658
+ sessionManager = inject(SessionManagerService);
8659
+ breakpointObserver = inject(BreakpointObserver);
8660
+ settingService = inject(SettingService);
8661
+ TokenStorage = TokenStorage;
8662
+ isXSmall = false;
8663
+ lstOrg = [];
8664
+ isOneUserMultiOrgs = false;
8665
+ ngOnInit() {
8666
+ this.breakpointObserver.observe([Breakpoints.XSmall, Breakpoints.Small]).subscribe((result) => {
8667
+ this.isXSmall = result.matches;
8668
+ });
8669
+ this.settingService.getByCodeAnonymous('ONE_USER_MULTI_ORGS').then((res) => {
8670
+ if (res?.Data) {
8671
+ if (res.Data == '1') {
8672
+ this.isOneUserMultiOrgs = true;
8673
+ this.getLstOrg();
8674
+ }
8675
+ }
8676
+ }, (err) => this.handleError(err));
8677
+ }
8678
+ getLstOrg() {
8679
+ this.cms
8680
+ .ESP({
8681
+ SPN: 'App_User_getLstOrg',
8682
+ })
8683
+ .then((res) => (this.lstOrg = res.Data), (err) => this.handleError(err));
8684
+ }
8685
+ async changeOrg(org) {
8686
+ if (await this.confirm(`Chuyển sang đơn vị: ${org.Name}`)) {
8687
+ this.authService.changeOrg(org).then(async (res) => {
8688
+ if (res) {
8689
+ await this.notiService.success(`Đã chuyển sang đơn vị: ${org.Name}`, '', true);
8690
+ window.location.reload();
8691
+ }
8692
+ }, (err) => this.handleError(err));
8693
+ }
8694
+ }
8695
+ gotoSetting() {
8696
+ this.goto('/admin/user_profile');
8697
+ }
8698
+ logout() {
8699
+ this.sessionManager.logout();
8700
+ }
8701
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: LayoutUser, deps: null, target: i0.ɵɵFactoryTarget.Component });
8702
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.7", type: LayoutUser, isStandalone: true, selector: "header-user", usesInheritance: true, ngImport: i0, template: "<button\r\n *ngIf=\"!isXSmall && TokenStorage.getOrgName()\"\r\n class=\"org-info\"\r\n [@fadeInOut]\r\n nz-button\r\n nzType=\"text\"\r\n nz-dropdown\r\n [nzDropdownMenu]=\"isOneUserMultiOrgs ? menuOrg : null\"\r\n [nzTrigger]=\"'click'\"\r\n style=\"height: var(--app-header-height); color: #ffffff\"\r\n>\r\n <nz-icon nzType=\"cluster\" nzTheme=\"outline\" />\r\n {{ TokenStorage.getOrgName() }}\r\n</button>\r\n\r\n<nz-dropdown-menu #menuOrg=\"nzDropdownMenu\">\r\n <ul nz-menu>\r\n @for (org of lstOrg; track $index) {\r\n <li *ngIf=\"$index > 0\" nz-menu-divider></li>\r\n <li nz-menu-item (click)=\"changeOrg(org)\">\r\n <nz-icon nzType=\"swap\" nzTheme=\"outline\" />&nbsp;&nbsp; {{ org.Name }}\r\n </li>\r\n }\r\n </ul>\r\n</nz-dropdown-menu>\r\n\r\n<button\r\n class=\"user-info\"\r\n nz-button\r\n nzType=\"text\"\r\n nz-dropdown\r\n [nzDropdownMenu]=\"menuUser\"\r\n [nzTrigger]=\"'click'\"\r\n style=\"height: var(--app-header-height); color: #ffffff\"\r\n>\r\n <nz-icon nzType=\"user\" nzTheme=\"outline\" />\r\n {{ TokenStorage.getUserFullname() }}\r\n</button>\r\n\r\n<nz-dropdown-menu #menuUser=\"nzDropdownMenu\">\r\n <ul nz-menu>\r\n <li *ngIf=\"!(!isXSmall && TokenStorage.getOrgName())\" nz-menu-item>\r\n <nz-icon nzType=\"cluster\" nzTheme=\"outline\" />&nbsp;&nbsp; {{ TokenStorage.getOrgName() }}\r\n </li>\r\n <li *ngIf=\"!(!isXSmall && TokenStorage.getOrgName())\" nz-menu-divider></li>\r\n <li nz-menu-item (click)=\"gotoSetting()\">\r\n <nz-icon nzType=\"setting\" nzTheme=\"outline\" />&nbsp;&nbsp; {{ TranslateKey.SETTING | translate }}\r\n </li>\r\n <li nz-menu-divider></li>\r\n <li nz-menu-item (click)=\"logout()\">\r\n <nz-icon nzType=\"logout\" nzTheme=\"outline\" />&nbsp;&nbsp; {{ TranslateKey.LOGOUT | translate }}\r\n </li>\r\n </ul>\r\n</nz-dropdown-menu>\r\n", styles: [".user-info:hover,.org-info:hover{background-color:#ffffff26}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3$1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: NzLayoutModule }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "ngmodule", type: NzDropDownModule }, { kind: "directive", type: i4$4.NzMenuDirective, selector: "[nz-menu]", inputs: ["nzInlineIndent", "nzTheme", "nzMode", "nzInlineCollapsed", "nzSelectable"], outputs: ["nzClick"], exportAs: ["nzMenu"] }, { kind: "component", type: i4$4.NzMenuItemComponent, selector: "[nz-menu-item]", inputs: ["nzPaddingLeft", "nzDisabled", "nzSelected", "nzDanger", "nzMatchRouterExact", "nzMatchRouter"], exportAs: ["nzMenuItem"] }, { kind: "directive", type: i4$4.NzMenuDividerDirective, selector: "[nz-menu-divider]", exportAs: ["nzMenuDivider"] }, { kind: "directive", type: i5$5.NzDropDownDirective, selector: "[nz-dropdown]", inputs: ["nzDropdownMenu", "nzTrigger", "nzMatchWidthElement", "nzBackdrop", "nzClickHide", "nzDisabled", "nzVisible", "nzOverlayClassName", "nzOverlayStyle", "nzPlacement"], outputs: ["nzVisibleChange"], exportAs: ["nzDropdown"] }, { kind: "component", type: i5$5.NzDropdownMenuComponent, selector: "nz-dropdown-menu", exportAs: ["nzDropdownMenu"] }, { kind: "directive", type: i5$5.NzDropdownButtonDirective, selector: "[nz-button][nz-dropdown]" }, { kind: "ngmodule", type: NzGridModule }, { kind: "ngmodule", type: NzFlexModule }, { 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: "ngmodule", type: NzTreeModule }, { kind: "ngmodule", type: NzBackTopModule }, { kind: "ngmodule", type: NzDrawerModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: NzInputModule }, { kind: "ngmodule", type: NzSegmentedModule }, { kind: "ngmodule", type: NzBadgeModule }], animations: [fadeInOut] });
8703
+ }
8704
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: LayoutUser, decorators: [{
8705
+ type: Component,
8706
+ args: [{ selector: 'header-user', imports: [
8707
+ CommonModule,
8708
+ TranslateModule,
8709
+ NzLayoutModule,
8710
+ NzIconModule,
8711
+ NzDropDownModule,
8712
+ NzGridModule,
8713
+ NzFlexModule,
8714
+ NzButtonModule,
8715
+ NzTreeModule,
8716
+ NzBackTopModule,
8717
+ NzDrawerModule,
8718
+ FormsModule,
8719
+ NzInputModule,
8720
+ NzTreeModule,
8721
+ NzSegmentedModule,
8722
+ NzBadgeModule,
8723
+ ], animations: [fadeInOut], template: "<button\r\n *ngIf=\"!isXSmall && TokenStorage.getOrgName()\"\r\n class=\"org-info\"\r\n [@fadeInOut]\r\n nz-button\r\n nzType=\"text\"\r\n nz-dropdown\r\n [nzDropdownMenu]=\"isOneUserMultiOrgs ? menuOrg : null\"\r\n [nzTrigger]=\"'click'\"\r\n style=\"height: var(--app-header-height); color: #ffffff\"\r\n>\r\n <nz-icon nzType=\"cluster\" nzTheme=\"outline\" />\r\n {{ TokenStorage.getOrgName() }}\r\n</button>\r\n\r\n<nz-dropdown-menu #menuOrg=\"nzDropdownMenu\">\r\n <ul nz-menu>\r\n @for (org of lstOrg; track $index) {\r\n <li *ngIf=\"$index > 0\" nz-menu-divider></li>\r\n <li nz-menu-item (click)=\"changeOrg(org)\">\r\n <nz-icon nzType=\"swap\" nzTheme=\"outline\" />&nbsp;&nbsp; {{ org.Name }}\r\n </li>\r\n }\r\n </ul>\r\n</nz-dropdown-menu>\r\n\r\n<button\r\n class=\"user-info\"\r\n nz-button\r\n nzType=\"text\"\r\n nz-dropdown\r\n [nzDropdownMenu]=\"menuUser\"\r\n [nzTrigger]=\"'click'\"\r\n style=\"height: var(--app-header-height); color: #ffffff\"\r\n>\r\n <nz-icon nzType=\"user\" nzTheme=\"outline\" />\r\n {{ TokenStorage.getUserFullname() }}\r\n</button>\r\n\r\n<nz-dropdown-menu #menuUser=\"nzDropdownMenu\">\r\n <ul nz-menu>\r\n <li *ngIf=\"!(!isXSmall && TokenStorage.getOrgName())\" nz-menu-item>\r\n <nz-icon nzType=\"cluster\" nzTheme=\"outline\" />&nbsp;&nbsp; {{ TokenStorage.getOrgName() }}\r\n </li>\r\n <li *ngIf=\"!(!isXSmall && TokenStorage.getOrgName())\" nz-menu-divider></li>\r\n <li nz-menu-item (click)=\"gotoSetting()\">\r\n <nz-icon nzType=\"setting\" nzTheme=\"outline\" />&nbsp;&nbsp; {{ TranslateKey.SETTING | translate }}\r\n </li>\r\n <li nz-menu-divider></li>\r\n <li nz-menu-item (click)=\"logout()\">\r\n <nz-icon nzType=\"logout\" nzTheme=\"outline\" />&nbsp;&nbsp; {{ TranslateKey.LOGOUT | translate }}\r\n </li>\r\n </ul>\r\n</nz-dropdown-menu>\r\n", styles: [".user-info:hover,.org-info:hover{background-color:#ffffff26}\n"] }]
8724
+ }] });
8725
+
8726
+ class HeaderSearchComponent extends BaseOverlayComponent {
8727
+ searchInputRef;
8728
+ isExpanded = false;
8729
+ searchValue = null;
8730
+ searchValueChange = new EventEmitter();
8731
+ onSearch = new EventEmitter();
8732
+ // Biến lưu trữ bộ đếm thời gian để có thể hủy nó khi cần
8733
+ blurTimeout;
8734
+ toggleSearch() {
8735
+ // Hủy ngay lệnh tự động đóng (nếu có) để tránh xung đột
8736
+ if (this.blurTimeout) {
8737
+ clearTimeout(this.blurTimeout);
8738
+ }
8739
+ if (!this.isExpanded) {
8740
+ this.isExpanded = true;
8741
+ setTimeout(() => this.searchInputRef.nativeElement.focus(), 150);
8742
+ }
8743
+ else if (!this.searchValue) {
8744
+ this.isExpanded = false;
8745
+ }
8746
+ else {
8747
+ this.performSearch();
8748
+ }
8749
+ }
8750
+ clearSearch(event) {
8751
+ event.stopPropagation();
8752
+ this.searchValue = '';
8753
+ this.searchInputRef.nativeElement.focus();
8754
+ this.performSearch();
8755
+ }
8756
+ // Bắt thêm sự kiện focus: Khi người dùng nhấp lại vào input thì không được đóng nó
8757
+ onFocus() {
8758
+ if (this.blurTimeout) {
8759
+ clearTimeout(this.blurTimeout);
8760
+ }
8761
+ }
8762
+ onBlur() {
8763
+ // Lưu lại bộ đếm để kiểm soát
8764
+ this.blurTimeout = setTimeout(() => {
8765
+ if (!this.searchValue?.trim()) {
8766
+ this.isExpanded = false;
8767
+ }
8768
+ }, 200); // Mình tăng lên 200ms để hoạt động an toàn hơn
8769
+ }
8770
+ performSearch() {
8771
+ this.searchValueChange.emit(this.searchValue);
8772
+ this.onSearch.emit(this.searchValue);
8773
+ }
8774
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: HeaderSearchComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
8775
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.7", type: HeaderSearchComponent, isStandalone: true, selector: "header-search", inputs: { searchValue: "searchValue" }, outputs: { searchValueChange: "searchValueChange", onSearch: "onSearch" }, viewQueries: [{ propertyName: "searchInputRef", first: true, predicate: ["searchInput"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"nz-search-wrapper\" [class.expanded]=\"isExpanded\">\r\n <input\r\n #searchInput\r\n type=\"text\"\r\n class=\"custom-search-input\"\r\n [(ngModel)]=\"searchValue\"\r\n placeholder=\"T\u00ECm ki\u1EBFm...\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n (keyup.enter)=\"performSearch()\"\r\n />\r\n\r\n <!-- (focus)=\"openOverlay(searchInput, dropdownTemplate, 300)\" -->\r\n\r\n <span class=\"suffix-wrap\" (mousedown)=\"$event.preventDefault()\" (click)=\"toggleSearch()\">\r\n <i\r\n nz-icon\r\n nzType=\"close-circle\"\r\n nzTheme=\"fill\"\r\n class=\"suffix-icon delete\"\r\n [class.show]=\"isExpanded && searchValue\"\r\n (click)=\"clearSearch($event)\"\r\n ></i>\r\n\r\n <i\r\n nz-icon\r\n nzType=\"search\"\r\n nzTheme=\"outline\"\r\n class=\"suffix-icon search\"\r\n [class.show]=\"!isExpanded || !searchValue\"\r\n [class.white]=\"!isExpanded\"\r\n ></i>\r\n </span>\r\n</div>\r\n\r\n<ng-template #dropdownTemplate>\r\n <div class=\"custom-dropdown full-width form-item-no-bottom\">xxxxxxxxxx</div>\r\n</ng-template>\r\n", styles: ["@charset \"UTF-8\";.nz-search-wrapper{position:relative;display:inline-flex;align-items:center;height:32px;width:32px;background-color:transparent;border:1px solid transparent;border-radius:6px;transition:all .3s cubic-bezier(.645,.045,.355,1);overflow:hidden}.nz-search-wrapper:hover:not(.expanded){background-color:#0000000a;cursor:pointer}.nz-search-wrapper.expanded{width:250px;background-color:#fff;border-color:#1890ff;box-shadow:0 0 0 2px #1890ff33}.nz-search-wrapper.expanded .custom-search-input{width:100%;padding:4px 32px 4px 11px;opacity:1}.custom-search-input{width:0;opacity:0;border:none;outline:none;background:transparent;padding:0;font-size:14px;color:#000000d9;transition:all .3s cubic-bezier(.645,.045,.355,1)}.custom-search-input::placeholder{color:#bfbfbf}.suffix-wrap{position:absolute;right:0;top:0;width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;cursor:pointer}.suffix-icon{position:absolute;top:-1px;left:4px;width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-size:16px;opacity:0;pointer-events:none;transition:opacity .2s ease}.suffix-icon.show{opacity:1;pointer-events:auto}.search{color:var(--primary-color)}.search.white{color:#fff}.delete{color:#bfbfbf}.delete:hover{color:#ff4d4f}.delete.show{animation:popIn .18s ease}.nz-search-wrapper{position:relative;display:inline-flex;align-items:center;height:36px;width:36px;background-color:transparent;border:1px solid transparent;border-radius:50%;transition:all .3s cubic-bezier(.645,.045,.355,1);overflow:hidden}.nz-search-wrapper:hover:not(.expanded){background-color:#ffffff26;cursor:pointer}.nz-search-wrapper.expanded{width:250px;background-color:#fff;border-color:#1890ff;box-shadow:0 0 0 2px #1890ff33;border-radius:6px}.nz-search-wrapper.expanded .custom-search-input{width:100%;padding:4px 40px 4px 11px;opacity:1}.suffix-wrap{position:absolute;right:0;top:0;width:40px;height:40px;display:inline-flex;align-items:center;justify-content:center;cursor:pointer}::ng-deep .no-arrow-popover{padding-top:4px!important}::ng-deep .no-arrow-popover .ant-popover-arrow{display:none!important}::ng-deep .no-arrow-popover .ant-popover-inner{border-radius:6px;box-shadow:0 4px 12px #00000026}@keyframes popIn{0%{transform:scale(.5)}70%{transform:scale(1.15)}to{transform:scale(1)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "ngmodule", type: NzButtonModule }, { 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"] }] });
8776
+ }
8777
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: HeaderSearchComponent, decorators: [{
8778
+ type: Component,
8779
+ args: [{ selector: 'header-search', imports: [CommonModule, FormsModule, NzIconModule, NzButtonModule], template: "<div class=\"nz-search-wrapper\" [class.expanded]=\"isExpanded\">\r\n <input\r\n #searchInput\r\n type=\"text\"\r\n class=\"custom-search-input\"\r\n [(ngModel)]=\"searchValue\"\r\n placeholder=\"T\u00ECm ki\u1EBFm...\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n (keyup.enter)=\"performSearch()\"\r\n />\r\n\r\n <!-- (focus)=\"openOverlay(searchInput, dropdownTemplate, 300)\" -->\r\n\r\n <span class=\"suffix-wrap\" (mousedown)=\"$event.preventDefault()\" (click)=\"toggleSearch()\">\r\n <i\r\n nz-icon\r\n nzType=\"close-circle\"\r\n nzTheme=\"fill\"\r\n class=\"suffix-icon delete\"\r\n [class.show]=\"isExpanded && searchValue\"\r\n (click)=\"clearSearch($event)\"\r\n ></i>\r\n\r\n <i\r\n nz-icon\r\n nzType=\"search\"\r\n nzTheme=\"outline\"\r\n class=\"suffix-icon search\"\r\n [class.show]=\"!isExpanded || !searchValue\"\r\n [class.white]=\"!isExpanded\"\r\n ></i>\r\n </span>\r\n</div>\r\n\r\n<ng-template #dropdownTemplate>\r\n <div class=\"custom-dropdown full-width form-item-no-bottom\">xxxxxxxxxx</div>\r\n</ng-template>\r\n", styles: ["@charset \"UTF-8\";.nz-search-wrapper{position:relative;display:inline-flex;align-items:center;height:32px;width:32px;background-color:transparent;border:1px solid transparent;border-radius:6px;transition:all .3s cubic-bezier(.645,.045,.355,1);overflow:hidden}.nz-search-wrapper:hover:not(.expanded){background-color:#0000000a;cursor:pointer}.nz-search-wrapper.expanded{width:250px;background-color:#fff;border-color:#1890ff;box-shadow:0 0 0 2px #1890ff33}.nz-search-wrapper.expanded .custom-search-input{width:100%;padding:4px 32px 4px 11px;opacity:1}.custom-search-input{width:0;opacity:0;border:none;outline:none;background:transparent;padding:0;font-size:14px;color:#000000d9;transition:all .3s cubic-bezier(.645,.045,.355,1)}.custom-search-input::placeholder{color:#bfbfbf}.suffix-wrap{position:absolute;right:0;top:0;width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;cursor:pointer}.suffix-icon{position:absolute;top:-1px;left:4px;width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-size:16px;opacity:0;pointer-events:none;transition:opacity .2s ease}.suffix-icon.show{opacity:1;pointer-events:auto}.search{color:var(--primary-color)}.search.white{color:#fff}.delete{color:#bfbfbf}.delete:hover{color:#ff4d4f}.delete.show{animation:popIn .18s ease}.nz-search-wrapper{position:relative;display:inline-flex;align-items:center;height:36px;width:36px;background-color:transparent;border:1px solid transparent;border-radius:50%;transition:all .3s cubic-bezier(.645,.045,.355,1);overflow:hidden}.nz-search-wrapper:hover:not(.expanded){background-color:#ffffff26;cursor:pointer}.nz-search-wrapper.expanded{width:250px;background-color:#fff;border-color:#1890ff;box-shadow:0 0 0 2px #1890ff33;border-radius:6px}.nz-search-wrapper.expanded .custom-search-input{width:100%;padding:4px 40px 4px 11px;opacity:1}.suffix-wrap{position:absolute;right:0;top:0;width:40px;height:40px;display:inline-flex;align-items:center;justify-content:center;cursor:pointer}::ng-deep .no-arrow-popover{padding-top:4px!important}::ng-deep .no-arrow-popover .ant-popover-arrow{display:none!important}::ng-deep .no-arrow-popover .ant-popover-inner{border-radius:6px;box-shadow:0 4px 12px #00000026}@keyframes popIn{0%{transform:scale(.5)}70%{transform:scale(1.15)}to{transform:scale(1)}}\n"] }]
8780
+ }], propDecorators: { searchInputRef: [{
8781
+ type: ViewChild,
8782
+ args: ['searchInput']
8783
+ }], searchValue: [{
8784
+ type: Input
8785
+ }], searchValueChange: [{
8786
+ type: Output
8787
+ }], onSearch: [{
8788
+ type: Output
8789
+ }] } });
8790
+
8366
8791
  class App_Menu {
8367
8792
  // #region properties
8368
8793
  App_Menu_Id;
@@ -8495,10 +8920,7 @@ class LayoutComponent extends BaseComponent {
8495
8920
  this.breakpointObserver.observe([Breakpoints.XSmall, Breakpoints.Small]).subscribe((result) => {
8496
8921
  this.isXSmall = result.matches;
8497
8922
  });
8498
- this.onRouteChange((url) => {
8499
- console.log('onRouteChange', url);
8500
- this.selectNodeByUrl(url);
8501
- });
8923
+ this.routeChange$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((url) => this.selectNodeByUrl(url));
8502
8924
  setTimeout(() => {
8503
8925
  this.isCollapsed = localStorage.getItem('MENU_isCollapsed') == '1' || this.device.isMobile;
8504
8926
  // if (this.isCollapsed) {
@@ -8519,11 +8941,8 @@ class LayoutComponent extends BaseComponent {
8519
8941
  });
8520
8942
  this.isCollapsed = localStorage.getItem('MENU_isCollapsed') == '1';
8521
8943
  }
8522
- divuser;
8523
8944
  ngOnDestroy() {
8524
8945
  SignalRService.disconnect();
8525
- this.unSubRouteChange();
8526
- console.log('unSubRouteChange');
8527
8946
  }
8528
8947
  getUserMenu(headerMenuId = '') {
8529
8948
  this.authService.getUserMenu(headerMenuId).then((res) => {
@@ -8673,7 +9092,7 @@ class LayoutComponent extends BaseComponent {
8673
9092
  }
8674
9093
  }
8675
9094
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: LayoutComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
8676
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.7", type: LayoutComponent, isStandalone: true, selector: "layout", viewQueries: [{ propertyName: "divuser", first: true, predicate: ["divuser"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<custom-noti></custom-noti>\r\n<app-global-spinner></app-global-spinner>\r\n<nz-layout class=\"app-layout\">\r\n <nz-header class=\"app-header\">\r\n <div nz-row nzAlign=\"middle\" class=\"header-content\">\r\n @if (isCollapsed) {\r\n <div @fadeInOut>\r\n &nbsp;\r\n <button nz-button nzType=\"text\" style=\"color: var(--theme-text-color)\" (click)=\"visibleMenuDrawer = true\">\r\n <nz-icon nzType=\"menu\" nzTheme=\"outline\" />\r\n </button>\r\n </div>\r\n }\r\n\r\n <div class=\"header-logo\" [style.width]=\"!isCollapsed ? siderWidthStorage : '100px'\">\r\n <div nz-flex nzJustify=\"center\" nzGap=\"small\">\r\n <img\r\n *ngIf=\"logoUrl$ | async as url\"\r\n [src]=\"url\"\r\n height=\"40px\"\r\n style=\"padding: 4px;\"\r\n hideIfError\r\n />\r\n @if (SYSTEM_NAME) {\r\n <h2 style=\"color: whitesmoke; margin-bottom: 0\">{{ SYSTEM_NAME }}</h2>\r\n } @else {\r\n -- o0o --\r\n }\r\n </div>\r\n </div>\r\n @if (!HEADER_MENU_IN_USE) {\r\n <box [width]=\"8\"></box>\r\n <app-breadcrumb [@fadeInOut] nz-col nzFlex=\"auto\" class=\"breadcrumb-header\"></app-breadcrumb>\r\n }\r\n <div *ngIf=\"HEADER_MENU_IN_USE\" nz-col nzFlex=\"auto\" class=\"header-menu\">\r\n <div style=\"overflow: auto\">\r\n <nz-segmented\r\n [nzOptions]=\"lstHeaderMenuDisplay\"\r\n [(ngModel)]=\"selectedHeaderMenuDisplay\"\r\n (nzValueChange)=\"handleValueChangeHeaderMenu($event)\"\r\n ></nz-segmented>\r\n </div>\r\n </div>\r\n <div #divuser>\r\n <layout-user></layout-user>\r\n </div>\r\n </div>\r\n </nz-header>\r\n <nz-layout class=\"body-layout\">\r\n <nz-sider\r\n class=\"menu-sidebar\"\r\n nzCollapsible\r\n [nzWidth]=\"siderWidth\"\r\n [nzCollapsedWidth]=\"0\"\r\n [(nzCollapsed)]=\"isCollapsed\"\r\n [nzTrigger]=\"null\"\r\n [nzTheme]=\"'dark'\"\r\n >\r\n <div class=\"menu-wapper\">\r\n @if (MENU_TYPE == 1) {\r\n <div class=\"nz-tree-wapper\">\r\n <nz-tree\r\n [nzData]=\"nodes\"\r\n [nzSearchValue]=\"searchValue\"\r\n [nzShowLine]=\"true\"\r\n [nzSelectedKeys]=\"selectedKeys\"\r\n [nzExpandedKeys]=\"expandedKeys\"\r\n (nzClick)=\"nzEvent($event)\"\r\n ></nz-tree>\r\n </div>\r\n } @else {\r\n <div class=\"nz-tree-wapper\">\r\n <ul nz-menu nzTheme=\"light\" nzMode=\"inline\" [nzInlineCollapsed]=\"isCollapsed\">\r\n @for (menuLv1 of lstMenu; track menuLv1.App_Menu_Id) {\r\n @if (menuLv1.SubMenu) {\r\n <ul nz-submenu [nzOpen]=\"menuLv1.Open\" [nzTitle]=\"menuLv1.Name\" [nzIcon]=\"menuLv1.Icon\">\r\n @for (menuLv2 of menuLv1.SubMenu; track menuLv2.App_Menu_Id) {\r\n @if (menuLv2.SubMenu) {\r\n <ul nz-submenu [nzOpen]=\"menuLv2.Open\" [nzTitle]=\"menuLv2.Name\" [nzIcon]=\"menuLv2.Icon\">\r\n @for (menuLv3 of menuLv2.SubMenu; track menuLv3.App_Menu_Id) {\r\n @if (menuLv3.SubMenu) {\r\n <ul nz-submenu [nzOpen]=\"menuLv3.Open\" [nzTitle]=\"menuLv3.Name\" [nzIcon]=\"menuLv3.Icon\">\r\n @for (menuLv4 of menuLv3.SubMenu; track menuLv4.App_Menu_Id) {\r\n @if (menuLv4.SubMenu) {\r\n <ul\r\n nz-submenu\r\n [nzOpen]=\"menuLv4.Open\"\r\n [nzTitle]=\"menuLv4.Name\"\r\n [nzIcon]=\"menuLv4.Icon\"\r\n >\r\n @for (menuLv5 of menuLv4.SubMenu; track menuLv5.App_Menu_Id) {}\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a\r\n [routerLink]=\"menuLv4.Url\"\r\n [innerHTML]=\"menuLv4.Name | highlight: searchValue\"\r\n ></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a [routerLink]=\"menuLv3.Url\" [innerHTML]=\"menuLv3.Name | highlight: searchValue\"></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a [routerLink]=\"menuLv2.Url\" [innerHTML]=\"menuLv2.Name | highlight: searchValue\"></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a [routerLink]=\"menuLv1.Url\" [innerHTML]=\"menuLv1.Name | highlight: searchValue\"></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n </div>\r\n }\r\n\r\n <nz-input-group [nzSuffix]=\"suffixTemplate\">\r\n <input nz-input placeholder=\"T\u00ECm menu\" [(ngModel)]=\"searchValue\" />\r\n </nz-input-group>\r\n <ng-template #suffixTemplate>\r\n <span class=\"suffix-wrap\">\r\n <icon-delete\r\n class=\"suffix-icon delete\"\r\n [class.show]=\"searchValue\"\r\n [size]=\"14\"\r\n (click)=\"searchValue = ''\"\r\n ></icon-delete>\r\n\r\n <icon-search class=\"suffix-icon search\" [class.show]=\"!searchValue\"></icon-search>\r\n </span>\r\n </ng-template>\r\n </div>\r\n <div class=\"sider-footer\" style=\"height: var(--app-footer-height)\">\r\n <div nz-col nzFlex=\"auto\" class=\"content-footer text-italic\" style=\"font-size: 0.8em; color: lightgray\">\r\n {{ SYSTEM_SUB_NAME_LEFT || \"-- o0o --\" }}\r\n\r\n <span style=\"float: right\" (click)=\"triggerCollapse()\">\r\n <nz-icon class=\"trigger\" [nzType]=\"isCollapsed ? 'menu-unfold' : 'menu-fold'\" />\r\n </span>\r\n </div>\r\n </div>\r\n </nz-sider>\r\n <nz-layout class=\"main-layout\">\r\n <nz-content class=\"content\">\r\n <div class=\"inner-content\">\r\n @if (HEADER_MENU_IN_USE) {\r\n <app-breadcrumb [@fadeInOut] nz-col nzFlex=\"auto\"></app-breadcrumb>\r\n <box [height]=\"8\"></box>\r\n }\r\n <router-outlet></router-outlet>\r\n </div>\r\n <div nz-row class=\"sider-footer\" style=\"height: var(--app-footer-height)\">\r\n <div nz-col nzFlex=\"auto\" class=\"content-footer text-italic\" style=\"font-size: 0.8em; color: lightgray\">\r\n {{ SYSTEM_SUB_NAME_RIGHT || \"-- o0o --\" }}\r\n </div>\r\n </div>\r\n <!-- <nz-back-top [nzTarget]=\"'.content'\" [nzVisibilityHeight]=\"500\"></nz-back-top> -->\r\n </nz-content>\r\n </nz-layout>\r\n </nz-layout>\r\n</nz-layout>\r\n\r\n<nz-drawer\r\n [nzWrapClassName]=\"'same-theme-color menu-drawer'\"\r\n [nzWidth]=\"350\"\r\n [nzClosable]=\"false\"\r\n [(nzVisible)]=\"visibleMenuDrawer\"\r\n [nzMaskClosable]=\"true\"\r\n nzPlacement=\"left\"\r\n nzTitle=\"\"\r\n (nzOnClose)=\"visibleMenuDrawer = false\"\r\n>\r\n <ng-container *nzDrawerContent>\r\n <div class=\"menu-wapper\">\r\n @if (MENU_TYPE == 1) {\r\n <div class=\"nz-tree-wapper in-drawer\">\r\n <nz-tree\r\n [nzData]=\"nodes\"\r\n [nzSearchValue]=\"searchValue\"\r\n [nzShowLine]=\"true\"\r\n [nzSelectedKeys]=\"selectedKeys\"\r\n [nzExpandedKeys]=\"expandedKeys\"\r\n (nzClick)=\"nzEvent($event)\"\r\n ></nz-tree>\r\n </div>\r\n } @else {\r\n <div class=\"nz-tree-wapper in-drawer\">\r\n <ul nz-menu nzTheme=\"light\" nzMode=\"inline\">\r\n @for (menuLv1 of lstMenu; track menuLv1.App_Menu_Id) {\r\n @if (menuLv1.SubMenu) {\r\n <ul nz-submenu [nzOpen]=\"menuLv1.Open\" [nzTitle]=\"menuLv1.Name\" [nzIcon]=\"menuLv1.Icon\">\r\n @for (menuLv2 of menuLv1.SubMenu; track menuLv2.App_Menu_Id) {\r\n @if (menuLv2.SubMenu) {\r\n <ul nz-submenu [nzOpen]=\"menuLv2.Open\" [nzTitle]=\"menuLv2.Name\" [nzIcon]=\"menuLv2.Icon\">\r\n @for (menuLv3 of menuLv2.SubMenu; track menuLv3.App_Menu_Id) {\r\n @if (menuLv3.SubMenu) {\r\n <ul nz-submenu [nzOpen]=\"menuLv3.Open\" [nzTitle]=\"menuLv3.Name\" [nzIcon]=\"menuLv3.Icon\">\r\n @for (menuLv4 of menuLv3.SubMenu; track menuLv4.App_Menu_Id) {\r\n @if (menuLv4.SubMenu) {\r\n <ul\r\n nz-submenu\r\n [nzOpen]=\"menuLv4.Open\"\r\n [nzTitle]=\"menuLv4.Name\"\r\n [nzIcon]=\"menuLv4.Icon\"\r\n >\r\n @for (menuLv5 of menuLv4.SubMenu; track menuLv5.App_Menu_Id) {}\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a\r\n [routerLink]=\"menuLv4.Url\"\r\n [innerHTML]=\"menuLv4.Name | highlight: searchValue\"\r\n ></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a [routerLink]=\"menuLv3.Url\" [innerHTML]=\"menuLv3.Name | highlight: searchValue\"></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a [routerLink]=\"menuLv2.Url\" [innerHTML]=\"menuLv2.Name | highlight: searchValue\"></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a [routerLink]=\"menuLv1.Url\" [innerHTML]=\"menuLv1.Name | highlight: searchValue\"></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n </div>\r\n }\r\n\r\n <nz-input-group [nzSuffix]=\"suffixTemplate\" [nzAddOnAfter]=\"afterTemplate\">\r\n <input nz-input placeholder=\"T\u00ECm menu\" [(ngModel)]=\"searchValue\" />\r\n </nz-input-group>\r\n <ng-template #suffixTemplate>\r\n <span class=\"suffix-wrap\">\r\n <icon-delete\r\n class=\"suffix-icon delete\"\r\n [class.show]=\"searchValue\"\r\n [size]=\"14\"\r\n (click)=\"searchValue = ''\"\r\n ></icon-delete>\r\n\r\n <icon-search class=\"suffix-icon search\" [class.show]=\"!searchValue\"></icon-search>\r\n </span>\r\n </ng-template>\r\n <ng-template #afterTemplate>\r\n <button nz-button (click)=\"triggerCollapse(); this.visibleMenuDrawer = false\">\r\n <nz-icon *ngIf=\"isCollapsed\" [nzType]=\"isCollapsed ? 'menu-unfold' : 'menu-fold'\" />\r\n </button>\r\n </ng-template>\r\n </div>\r\n </ng-container>\r\n</nz-drawer>\r\n", styles: ["@charset \"UTF-8\";:host{display:flex;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}html,body,app-root{height:100%;margin:0}.app-layout{display:flex;flex-direction:column;height:100vh}.app-header{position:fixed;top:0;left:0;width:100%;height:var(--app-header-height);background:var(--theme-color);color:var(--theme-text-color);box-shadow:0 1px 4px #00152914;z-index:1000;display:flex;align-items:center;padding:0}.header-content{width:100%}.header-logo{height:var(--app-header-height);text-align:center;color:var(--theme-text-color);transition:width .3s}.body-layout{display:flex;flex:1;margin-top:var(--app-header-height);height:calc(100vh - var(--app-header-height));overflow:hidden}.menu-sidebar{width:256px;background:#f0f2f5;overflow-y:auto;min-height:calc(100vh - var(--app-header-height))}.menu-wapper{min-height:calc(100% - var(--app-footer-height))}.main-layout{display:flex;flex-direction:column;flex:1;overflow:hidden}.content{flex:1;background:#f1f2f5;overflow-x:hidden;overflow-y:auto;height:100%}.inner-content{background:#f1f2f5;min-height:calc(100% - var(--app-footer-height));padding:8px}.content-footer{background:var(--theme-color);color:var(--theme-text-color);align-items:center;text-align:center}.sider-footer{background:var(--theme-color);color:var(--theme-text-color);align-items:center;text-align:right}.trigger{margin-right:8px}.menu-sidebar .ant-menu-inline .ant-menu-item{margin-top:0;margin-bottom:0}::ng-deep .menu-wapper .anticon-file{display:none}:host ::ng-deep .ant-back-top{right:30px;bottom:40px}::ng-deep .same-theme-color .ant-drawer-content{background:var(--theme-menu-color)}.nz-tree-wapper{height:calc(100vh - var(--app-header-height) - var(--app-footer-height) - 32px);overflow-y:auto}.nz-tree-wapper.in-drawer{height:calc(100vh - 32px);overflow-y:auto}::ng-deep .menu-drawer .ant-drawer-body{padding:0}::ng-deep .breadcrumb-header .ant-breadcrumb-link{color:var(--theme-text-color);cursor:pointer}::ng-deep .breadcrumb-header .ant-breadcrumb-separator{color:var(--theme-text-color)}::ng-deep .header-menu .ant-segmented-item:not(.ant-segmented-item-selected){color:var(--theme-text-color)}::ng-deep .header-menu .ant-segmented-item{border-left:1px solid}::ng-deep .header-menu .ant-segmented-item:last-child{border-right:1px solid}.suffix-wrap{position:relative;width:18px;height:18px;display:inline-flex;align-items:center;justify-content:center}.suffix-icon{position:absolute;display:flex;align-items:center;justify-content:center;opacity:0;pointer-events:none;transition:opacity .16s ease,transform .18s cubic-bezier(.4,0,.2,1);transform:scale(.6) translate(4px)}.suffix-icon.show{opacity:1;pointer-events:auto;transform:scale(1) translate(0)}.search{color:#00000073}.delete{color:#bfbfbf}.delete.show{animation:popIn .18s ease}@keyframes popIn{0%{transform:scale(.5)}70%{transform:scale(1.15)}to{transform:scale(1)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1$4.AsyncPipe, name: "async" }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: NzLayoutModule }, { kind: "component", type: i2$2.NzLayoutComponent, selector: "nz-layout", exportAs: ["nzLayout"] }, { kind: "component", type: i2$2.NzHeaderComponent, selector: "nz-header", exportAs: ["nzHeader"] }, { kind: "component", type: i2$2.NzContentComponent, selector: "nz-content", exportAs: ["nzContent"] }, { kind: "component", type: i2$2.NzSiderComponent, selector: "nz-sider", inputs: ["nzWidth", "nzTheme", "nzCollapsedWidth", "nzBreakpoint", "nzZeroTrigger", "nzTrigger", "nzReverseArrow", "nzCollapsible", "nzCollapsed"], outputs: ["nzCollapsedChange"], exportAs: ["nzSider"] }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "ngmodule", type: NzDropDownModule }, { kind: "directive", type: i4$2.NzMenuDirective, selector: "[nz-menu]", inputs: ["nzInlineIndent", "nzTheme", "nzMode", "nzInlineCollapsed", "nzSelectable"], outputs: ["nzClick"], exportAs: ["nzMenu"] }, { kind: "component", type: i4$2.NzMenuItemComponent, selector: "[nz-menu-item]", inputs: ["nzPaddingLeft", "nzDisabled", "nzSelected", "nzDanger", "nzMatchRouterExact", "nzMatchRouter"], exportAs: ["nzMenuItem"] }, { kind: "component", type: i4$2.NzSubMenuComponent, selector: "[nz-submenu]", inputs: ["nzMenuClassName", "nzPaddingLeft", "nzTitle", "nzIcon", "nzTriggerSubMenuAction", "nzOpen", "nzDisabled", "nzPlacement"], outputs: ["nzOpenChange"], exportAs: ["nzSubmenu"] }, { kind: "ngmodule", type: NzGridModule }, { kind: "directive", type: i4.NzColDirective, selector: "[nz-col],nz-col,nz-form-control,nz-form-label", inputs: ["nzFlex", "nzSpan", "nzOrder", "nzOffset", "nzPush", "nzPull", "nzXs", "nzSm", "nzMd", "nzLg", "nzXl", "nzXXl"], exportAs: ["nzCol"] }, { kind: "directive", type: i4.NzRowDirective, selector: "[nz-row],nz-row,nz-form-item", inputs: ["nzAlign", "nzJustify", "nzGutter"], exportAs: ["nzRow"] }, { kind: "ngmodule", type: NzFlexModule }, { kind: "directive", type: i9.NzFlexDirective, selector: "[nz-flex],nz-flex", inputs: ["nzVertical", "nzJustify", "nzAlign", "nzGap", "nzWrap", "nzFlex"], exportAs: ["nzFlex"] }, { kind: "ngmodule", type: NzButtonModule }, { kind: "component", type: i5$3.NzButtonComponent, selector: "button[nz-button], a[nz-button]", inputs: ["nzBlock", "nzGhost", "nzSearch", "nzLoading", "nzDanger", "disabled", "tabIndex", "nzType", "nzShape", "nzSize"], exportAs: ["nzButton"] }, { kind: "directive", type: i6$3.ɵ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: i7.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "component", type: Breadcrumb, selector: "app-breadcrumb" }, { kind: "component", type: GlobalSpinnerComponent, selector: "app-global-spinner" }, { kind: "ngmodule", type: NzTreeModule }, { kind: "component", type: i10.NzTreeComponent, selector: "nz-tree", inputs: ["nzShowIcon", "nzHideUnMatched", "nzBlockNode", "nzExpandAll", "nzSelectMode", "nzCheckStrictly", "nzShowExpand", "nzShowLine", "nzCheckable", "nzAsyncData", "nzDraggable", "nzMultiple", "nzExpandedIcon", "nzVirtualItemSize", "nzVirtualMaxBufferPx", "nzVirtualMinBufferPx", "nzVirtualHeight", "nzTreeTemplate", "nzBeforeDrop", "nzData", "nzExpandedKeys", "nzSelectedKeys", "nzCheckedKeys", "nzSearchValue", "nzSearchFunc"], outputs: ["nzExpandedKeysChange", "nzSelectedKeysChange", "nzCheckedKeysChange", "nzSearchValueChange", "nzClick", "nzDblClick", "nzContextMenu", "nzCheckboxChange", "nzExpandChange", "nzOnDragStart", "nzOnDragEnter", "nzOnDragOver", "nzOnDragLeave", "nzOnDrop", "nzOnDragEnd"], exportAs: ["nzTree"] }, { kind: "ngmodule", type: NzBackTopModule }, { kind: "ngmodule", type: NzDrawerModule }, { kind: "component", type: i4$1.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: i4$1.NzDrawerContentDirective, selector: "[nzDrawerContent]", exportAs: ["nzDrawerContent"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: NzInputModule }, { kind: "directive", type: i6$1.NzInputDirective, selector: "input[nz-input],textarea[nz-input]", inputs: ["nzBorderless", "nzSize", "nzStepperless", "nzStatus", "disabled"], exportAs: ["nzInput"] }, { kind: "component", type: i6$1.NzInputGroupComponent, selector: "nz-input-group", inputs: ["nzAddOnBeforeIcon", "nzAddOnAfterIcon", "nzPrefixIcon", "nzSuffixIcon", "nzAddOnBefore", "nzAddOnAfter", "nzPrefix", "nzStatus", "nzSuffix", "nzSize", "nzSearch", "nzCompact"], exportAs: ["nzInputGroup"] }, { kind: "directive", type: i6$1.NzInputGroupWhitSuffixOrPrefixDirective, selector: "nz-input-group[nzSuffix], nz-input-group[nzPrefix]" }, { kind: "component", type: Box, selector: "box", inputs: ["display", "width", "height"] }, { kind: "ngmodule", type: NzSegmentedModule }, { kind: "component", type: i14.NzSegmentedComponent, selector: "nz-segmented", inputs: ["nzBlock", "nzDisabled", "nzOptions", "nzSize"], outputs: ["nzValueChange"], exportAs: ["nzSegmented"] }, { kind: "component", type: LayoutUser, selector: "layout-user" }, { kind: "component", type: IconDelete, selector: "icon-delete", inputs: ["size"], outputs: ["click"] }, { kind: "component", type: IconSearch, selector: "icon-search", inputs: ["size"], outputs: ["click"] }, { kind: "pipe", type: HighlightPipe, name: "highlight" }, { kind: "directive", type: HideIfErrorDirective, selector: "img[hideIfError]" }, { kind: "component", type: CustomNotiComponent, selector: "custom-noti" }], animations: [fadeInOut] });
9095
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.7", type: LayoutComponent, isStandalone: true, selector: "layout", usesInheritance: true, ngImport: i0, template: "<nz-layout class=\"app-layout\">\r\n <nz-header class=\"app-header\">\r\n <div nz-row nzAlign=\"middle\" class=\"header-content\">\r\n @if (isCollapsed) {\r\n <div @fadeInOut>\r\n &nbsp;\r\n <button nz-button nzType=\"text\" style=\"color: var(--theme-text-color)\" (click)=\"visibleMenuDrawer = true\">\r\n <nz-icon nzType=\"menu\" nzTheme=\"outline\" />\r\n </button>\r\n </div>\r\n }\r\n\r\n <div class=\"header-logo\" [style.width]=\"!isCollapsed ? siderWidthStorage : '100px'\">\r\n <div nz-flex nzJustify=\"center\" nzGap=\"small\" style=\"line-height: var(--app-header-height)\">\r\n <img\r\n *ngIf=\"logoUrl$ | async as url\"\r\n [src]=\"url\"\r\n height=\"var(--app-header-height)\"\r\n style=\"padding: 4px\"\r\n hideIfError\r\n />\r\n @if (SYSTEM_NAME) {\r\n <h2 style=\"color: whitesmoke; margin-bottom: 0\">{{ SYSTEM_NAME }}</h2>\r\n } @else {\r\n -- o0o --\r\n }\r\n </div>\r\n </div>\r\n @if (!HEADER_MENU_IN_USE) {\r\n <box [width]=\"8\"></box>\r\n <app-breadcrumb [@fadeInOut] nz-col nzFlex=\"auto\" class=\"breadcrumb-header\"></app-breadcrumb>\r\n }\r\n @if (HEADER_MENU_IN_USE) {\r\n <div nz-col nzFlex=\"auto\" class=\"header-menu\">\r\n <div style=\"overflow: auto\">\r\n <nz-segmented\r\n [nzOptions]=\"lstHeaderMenuDisplay\"\r\n [(ngModel)]=\"selectedHeaderMenuDisplay\"\r\n (nzValueChange)=\"handleValueChangeHeaderMenu($event)\"\r\n ></nz-segmented>\r\n </div>\r\n </div>\r\n }\r\n\r\n <header-search></header-search>\r\n <app-notification-center></app-notification-center>\r\n <header-user></header-user>\r\n </div>\r\n </nz-header>\r\n <nz-layout class=\"body-layout\">\r\n <nz-sider\r\n class=\"menu-sidebar\"\r\n nzCollapsible\r\n [nzWidth]=\"siderWidth\"\r\n [nzCollapsedWidth]=\"0\"\r\n [(nzCollapsed)]=\"isCollapsed\"\r\n [nzTrigger]=\"null\"\r\n [nzTheme]=\"'dark'\"\r\n >\r\n <div class=\"menu-wapper\">\r\n @if (MENU_TYPE == 1) {\r\n <div class=\"nz-tree-wapper\">\r\n <nz-tree\r\n [nzData]=\"nodes\"\r\n [nzSearchValue]=\"searchValue\"\r\n [nzShowLine]=\"true\"\r\n [nzSelectedKeys]=\"selectedKeys\"\r\n [nzExpandedKeys]=\"expandedKeys\"\r\n (nzClick)=\"nzEvent($event)\"\r\n ></nz-tree>\r\n </div>\r\n } @else {\r\n <div class=\"nz-tree-wapper\">\r\n <ul nz-menu nzTheme=\"light\" nzMode=\"inline\" [nzInlineCollapsed]=\"isCollapsed\">\r\n @for (menuLv1 of lstMenu; track menuLv1.App_Menu_Id) {\r\n @if (menuLv1.SubMenu?.length) {\r\n <ul nz-submenu [nzOpen]=\"menuLv1.Open\" [nzTitle]=\"menuLv1.Name\" [nzIcon]=\"menuLv1.Icon\">\r\n @for (menuLv2 of menuLv1.SubMenu; track menuLv2.App_Menu_Id) {\r\n @if (menuLv2.SubMenu?.length) {\r\n <ul nz-submenu [nzOpen]=\"menuLv2.Open\" [nzTitle]=\"menuLv2.Name\" [nzIcon]=\"menuLv2.Icon\">\r\n @for (menuLv3 of menuLv2.SubMenu; track menuLv3.App_Menu_Id) {\r\n @if (menuLv3.SubMenu?.length) {\r\n <ul nz-submenu [nzOpen]=\"menuLv3.Open\" [nzTitle]=\"menuLv3.Name\" [nzIcon]=\"menuLv3.Icon\">\r\n @for (menuLv4 of menuLv3.SubMenu; track menuLv4.App_Menu_Id) {\r\n @if (menuLv4.SubMenu?.length) {\r\n <ul\r\n nz-submenu\r\n [nzOpen]=\"menuLv4.Open\"\r\n [nzTitle]=\"menuLv4.Name\"\r\n [nzIcon]=\"menuLv4.Icon\"\r\n >\r\n @for (menuLv5 of menuLv4.SubMenu; track menuLv5.App_Menu_Id) {}\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a\r\n [routerLink]=\"menuLv4.Url\"\r\n [innerHTML]=\"menuLv4.Name | highlight: searchValue\"\r\n ></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a [routerLink]=\"menuLv3.Url\" [innerHTML]=\"menuLv3.Name | highlight: searchValue\"></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a [routerLink]=\"menuLv2.Url\" [innerHTML]=\"menuLv2.Name | highlight: searchValue\"></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a [routerLink]=\"menuLv1.Url\" [innerHTML]=\"menuLv1.Name | highlight: searchValue\"></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n </div>\r\n }\r\n\r\n <nz-input-group [nzSuffix]=\"suffixTemplate\">\r\n <input nz-input placeholder=\"T\u00ECm menu\" [(ngModel)]=\"searchValue\" />\r\n </nz-input-group>\r\n <ng-template #suffixTemplate>\r\n <span class=\"suffix-wrap\">\r\n <icon-delete\r\n class=\"suffix-icon delete\"\r\n [class.show]=\"searchValue\"\r\n [size]=\"14\"\r\n (click)=\"searchValue = ''\"\r\n ></icon-delete>\r\n\r\n <icon-search class=\"suffix-icon search\" [class.show]=\"!searchValue\"></icon-search>\r\n </span>\r\n </ng-template>\r\n </div>\r\n <div class=\"sider-footer\" style=\"height: var(--app-footer-height)\">\r\n <div nz-col nzFlex=\"auto\" class=\"content-footer text-italic\" style=\"font-size: 0.8em; color: lightgray\">\r\n {{ SYSTEM_SUB_NAME_LEFT || \"-- o0o --\" }}\r\n\r\n <span style=\"float: right\" (click)=\"triggerCollapse()\">\r\n <nz-icon class=\"trigger\" [nzType]=\"isCollapsed ? 'menu-unfold' : 'menu-fold'\" />\r\n </span>\r\n </div>\r\n </div>\r\n </nz-sider>\r\n <nz-layout class=\"main-layout\">\r\n <nz-content class=\"content\">\r\n <div class=\"inner-content\">\r\n @if (HEADER_MENU_IN_USE) {\r\n <app-breadcrumb [@fadeInOut] nz-col nzFlex=\"auto\"></app-breadcrumb>\r\n <box [height]=\"8\"></box>\r\n }\r\n <router-outlet></router-outlet>\r\n </div>\r\n <div nz-row class=\"sider-footer\" style=\"height: var(--app-footer-height)\">\r\n <div nz-col nzFlex=\"auto\" class=\"content-footer text-italic\" style=\"font-size: 0.8em; color: lightgray\">\r\n {{ SYSTEM_SUB_NAME_RIGHT || \"-- o0o --\" }}\r\n </div>\r\n </div>\r\n <!-- <nz-back-top [nzTarget]=\"'.content'\" [nzVisibilityHeight]=\"500\"></nz-back-top> -->\r\n </nz-content>\r\n </nz-layout>\r\n </nz-layout>\r\n</nz-layout>\r\n\r\n<nz-drawer\r\n [nzWrapClassName]=\"'same-theme-color menu-drawer'\"\r\n [nzWidth]=\"350\"\r\n [nzClosable]=\"false\"\r\n [(nzVisible)]=\"visibleMenuDrawer\"\r\n [nzMaskClosable]=\"true\"\r\n nzPlacement=\"left\"\r\n nzTitle=\"\"\r\n (nzOnClose)=\"visibleMenuDrawer = false\"\r\n>\r\n <ng-container *nzDrawerContent>\r\n <div class=\"menu-wapper\">\r\n @if (MENU_TYPE == 1) {\r\n <div class=\"nz-tree-wapper in-drawer\">\r\n <nz-tree\r\n [nzData]=\"nodes\"\r\n [nzSearchValue]=\"searchValue\"\r\n [nzShowLine]=\"true\"\r\n [nzSelectedKeys]=\"selectedKeys\"\r\n [nzExpandedKeys]=\"expandedKeys\"\r\n (nzClick)=\"nzEvent($event)\"\r\n ></nz-tree>\r\n </div>\r\n } @else {\r\n <div class=\"nz-tree-wapper in-drawer\">\r\n <ul nz-menu nzTheme=\"light\" nzMode=\"inline\">\r\n @for (menuLv1 of lstMenu; track menuLv1.App_Menu_Id) {\r\n @if (menuLv1.SubMenu) {\r\n <ul nz-submenu [nzOpen]=\"menuLv1.Open\" [nzTitle]=\"menuLv1.Name\" [nzIcon]=\"menuLv1.Icon\">\r\n @for (menuLv2 of menuLv1.SubMenu; track menuLv2.App_Menu_Id) {\r\n @if (menuLv2.SubMenu) {\r\n <ul nz-submenu [nzOpen]=\"menuLv2.Open\" [nzTitle]=\"menuLv2.Name\" [nzIcon]=\"menuLv2.Icon\">\r\n @for (menuLv3 of menuLv2.SubMenu; track menuLv3.App_Menu_Id) {\r\n @if (menuLv3.SubMenu) {\r\n <ul nz-submenu [nzOpen]=\"menuLv3.Open\" [nzTitle]=\"menuLv3.Name\" [nzIcon]=\"menuLv3.Icon\">\r\n @for (menuLv4 of menuLv3.SubMenu; track menuLv4.App_Menu_Id) {\r\n @if (menuLv4.SubMenu) {\r\n <ul\r\n nz-submenu\r\n [nzOpen]=\"menuLv4.Open\"\r\n [nzTitle]=\"menuLv4.Name\"\r\n [nzIcon]=\"menuLv4.Icon\"\r\n >\r\n @for (menuLv5 of menuLv4.SubMenu; track menuLv5.App_Menu_Id) {}\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a\r\n [routerLink]=\"menuLv4.Url\"\r\n [innerHTML]=\"menuLv4.Name | highlight: searchValue\"\r\n ></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a [routerLink]=\"menuLv3.Url\" [innerHTML]=\"menuLv3.Name | highlight: searchValue\"></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a [routerLink]=\"menuLv2.Url\" [innerHTML]=\"menuLv2.Name | highlight: searchValue\"></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a [routerLink]=\"menuLv1.Url\" [innerHTML]=\"menuLv1.Name | highlight: searchValue\"></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n </div>\r\n }\r\n\r\n <nz-input-group [nzSuffix]=\"suffixTemplate\" [nzAddOnAfter]=\"afterTemplate\">\r\n <input nz-input placeholder=\"T\u00ECm menu\" [(ngModel)]=\"searchValue\" />\r\n </nz-input-group>\r\n <ng-template #suffixTemplate>\r\n <span class=\"suffix-wrap\">\r\n <icon-delete\r\n class=\"suffix-icon delete\"\r\n [class.show]=\"searchValue\"\r\n [size]=\"14\"\r\n (click)=\"searchValue = ''\"\r\n ></icon-delete>\r\n\r\n <icon-search class=\"suffix-icon search\" [class.show]=\"!searchValue\"></icon-search>\r\n </span>\r\n </ng-template>\r\n <ng-template #afterTemplate>\r\n <button nz-button (click)=\"triggerCollapse(); this.visibleMenuDrawer = false\">\r\n <nz-icon *ngIf=\"isCollapsed\" [nzType]=\"isCollapsed ? 'menu-unfold' : 'menu-fold'\" />\r\n </button>\r\n </ng-template>\r\n </div>\r\n </ng-container>\r\n</nz-drawer>\r\n", styles: ["@charset \"UTF-8\";:host{display:flex;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}html,body,app-root{height:100%;margin:0}.app-layout{display:flex;flex-direction:column;height:100vh}.app-header{position:fixed;top:0;left:0;width:100%;height:var(--app-header-height);background:var(--theme-color);color:var(--theme-text-color);box-shadow:0 1px 4px #00152914;z-index:1000;display:flex;align-items:center;padding:0}.header-content{width:100%}.header-logo{height:var(--app-header-height);text-align:center;color:var(--theme-text-color);transition:width .3s}.body-layout{display:flex;flex:1;margin-top:var(--app-header-height);height:calc(100vh - var(--app-header-height));overflow:hidden}.menu-sidebar{width:256px;background:#f0f2f5;overflow-y:auto;min-height:calc(100vh - var(--app-header-height))}.menu-wapper{min-height:calc(100% - var(--app-footer-height))}.main-layout{display:flex;flex-direction:column;flex:1;overflow:hidden}.content{flex:1;background:#fff;overflow-x:hidden;overflow-y:auto;height:100%}.inner-content{background:#fff;min-height:calc(100% - var(--app-footer-height));padding:8px}.content-footer{background:var(--theme-color);color:var(--theme-text-color);align-items:center;text-align:center}.sider-footer{background:var(--theme-color);color:var(--theme-text-color);align-items:center;text-align:right}.trigger{margin-right:8px}.menu-sidebar .ant-menu-inline .ant-menu-item{margin-top:0;margin-bottom:0}::ng-deep .menu-wapper .anticon-file{display:none}:host ::ng-deep .ant-back-top{right:30px;bottom:40px}::ng-deep .same-theme-color .ant-drawer-content{background:var(--theme-menu-color)}.nz-tree-wapper{height:calc(100vh - var(--app-header-height) - var(--app-footer-height) - 32px);overflow-y:auto}.nz-tree-wapper.in-drawer{height:calc(100vh - 32px);overflow-y:auto}::ng-deep .menu-drawer .ant-drawer-body{padding:0}::ng-deep .breadcrumb-header .ant-breadcrumb-link{color:var(--theme-text-color);cursor:pointer}::ng-deep .breadcrumb-header .ant-breadcrumb-separator{color:var(--theme-text-color)}::ng-deep .header-menu .ant-segmented-item:not(.ant-segmented-item-selected){color:var(--theme-text-color)}::ng-deep .header-menu .ant-segmented-item{border-left:1px solid}::ng-deep .header-menu .ant-segmented-item:last-child{border-right:1px solid}.suffix-wrap{position:relative;width:18px;height:18px;display:inline-flex;align-items:center;justify-content:center}.suffix-icon{position:absolute;display:flex;align-items:center;justify-content:center;opacity:0;pointer-events:none;transition:opacity .16s ease,transform .18s cubic-bezier(.4,0,.2,1);transform:scale(.6) translate(4px)}.suffix-icon.show{opacity:1;pointer-events:auto;transform:scale(1) translate(0)}.search{color:#00000073}.delete{color:#bfbfbf}.delete.show{animation:popIn .18s ease}@keyframes popIn{0%{transform:scale(.5)}70%{transform:scale(1.15)}to{transform:scale(1)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1$4.AsyncPipe, name: "async" }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: NzLayoutModule }, { kind: "component", type: i2$3.NzLayoutComponent, selector: "nz-layout", exportAs: ["nzLayout"] }, { kind: "component", type: i2$3.NzHeaderComponent, selector: "nz-header", exportAs: ["nzHeader"] }, { kind: "component", type: i2$3.NzContentComponent, selector: "nz-content", exportAs: ["nzContent"] }, { kind: "component", type: i2$3.NzSiderComponent, selector: "nz-sider", inputs: ["nzWidth", "nzTheme", "nzCollapsedWidth", "nzBreakpoint", "nzZeroTrigger", "nzTrigger", "nzReverseArrow", "nzCollapsible", "nzCollapsed"], outputs: ["nzCollapsedChange"], exportAs: ["nzSider"] }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "ngmodule", type: NzDropDownModule }, { kind: "directive", type: i4$4.NzMenuDirective, selector: "[nz-menu]", inputs: ["nzInlineIndent", "nzTheme", "nzMode", "nzInlineCollapsed", "nzSelectable"], outputs: ["nzClick"], exportAs: ["nzMenu"] }, { kind: "component", type: i4$4.NzMenuItemComponent, selector: "[nz-menu-item]", inputs: ["nzPaddingLeft", "nzDisabled", "nzSelected", "nzDanger", "nzMatchRouterExact", "nzMatchRouter"], exportAs: ["nzMenuItem"] }, { kind: "component", type: i4$4.NzSubMenuComponent, selector: "[nz-submenu]", inputs: ["nzMenuClassName", "nzPaddingLeft", "nzTitle", "nzIcon", "nzTriggerSubMenuAction", "nzOpen", "nzDisabled", "nzPlacement"], outputs: ["nzOpenChange"], exportAs: ["nzSubmenu"] }, { kind: "ngmodule", type: NzGridModule }, { kind: "directive", type: i4.NzColDirective, selector: "[nz-col],nz-col,nz-form-control,nz-form-label", inputs: ["nzFlex", "nzSpan", "nzOrder", "nzOffset", "nzPush", "nzPull", "nzXs", "nzSm", "nzMd", "nzLg", "nzXl", "nzXXl"], exportAs: ["nzCol"] }, { kind: "directive", type: i4.NzRowDirective, selector: "[nz-row],nz-row,nz-form-item", inputs: ["nzAlign", "nzJustify", "nzGutter"], exportAs: ["nzRow"] }, { kind: "ngmodule", type: NzFlexModule }, { kind: "directive", type: i5$3.NzFlexDirective, selector: "[nz-flex],nz-flex", inputs: ["nzVertical", "nzJustify", "nzAlign", "nzGap", "nzWrap", "nzFlex"], exportAs: ["nzFlex"] }, { 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$2.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "component", type: Breadcrumb, selector: "app-breadcrumb" }, { kind: "ngmodule", type: NzTreeModule }, { kind: "component", type: i10.NzTreeComponent, selector: "nz-tree", inputs: ["nzShowIcon", "nzHideUnMatched", "nzBlockNode", "nzExpandAll", "nzSelectMode", "nzCheckStrictly", "nzShowExpand", "nzShowLine", "nzCheckable", "nzAsyncData", "nzDraggable", "nzMultiple", "nzExpandedIcon", "nzVirtualItemSize", "nzVirtualMaxBufferPx", "nzVirtualMinBufferPx", "nzVirtualHeight", "nzTreeTemplate", "nzBeforeDrop", "nzData", "nzExpandedKeys", "nzSelectedKeys", "nzCheckedKeys", "nzSearchValue", "nzSearchFunc"], outputs: ["nzExpandedKeysChange", "nzSelectedKeysChange", "nzCheckedKeysChange", "nzSearchValueChange", "nzClick", "nzDblClick", "nzContextMenu", "nzCheckboxChange", "nzExpandChange", "nzOnDragStart", "nzOnDragEnter", "nzOnDragOver", "nzOnDragLeave", "nzOnDrop", "nzOnDragEnd"], exportAs: ["nzTree"] }, { kind: "ngmodule", type: NzBackTopModule }, { kind: "ngmodule", type: NzDrawerModule }, { kind: "component", type: i4$1.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: i4$1.NzDrawerContentDirective, selector: "[nzDrawerContent]", exportAs: ["nzDrawerContent"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: NzInputModule }, { kind: "directive", type: i6$1.NzInputDirective, selector: "input[nz-input],textarea[nz-input]", inputs: ["nzBorderless", "nzSize", "nzStepperless", "nzStatus", "disabled"], exportAs: ["nzInput"] }, { kind: "component", type: i6$1.NzInputGroupComponent, selector: "nz-input-group", inputs: ["nzAddOnBeforeIcon", "nzAddOnAfterIcon", "nzPrefixIcon", "nzSuffixIcon", "nzAddOnBefore", "nzAddOnAfter", "nzPrefix", "nzStatus", "nzSuffix", "nzSize", "nzSearch", "nzCompact"], exportAs: ["nzInputGroup"] }, { kind: "directive", type: i6$1.NzInputGroupWhitSuffixOrPrefixDirective, selector: "nz-input-group[nzSuffix], nz-input-group[nzPrefix]" }, { kind: "component", type: Box, selector: "box", inputs: ["display", "width", "height"] }, { kind: "ngmodule", type: NzSegmentedModule }, { kind: "component", type: i14.NzSegmentedComponent, selector: "nz-segmented", inputs: ["nzBlock", "nzDisabled", "nzOptions", "nzSize"], outputs: ["nzValueChange"], exportAs: ["nzSegmented"] }, { kind: "component", type: LayoutUser, selector: "header-user" }, { kind: "component", type: IconDelete, selector: "icon-delete", inputs: ["size"], outputs: ["click"] }, { kind: "component", type: IconSearch, selector: "icon-search", inputs: ["size"], outputs: ["click"] }, { kind: "pipe", type: HighlightPipe, name: "highlight" }, { kind: "directive", type: HideIfErrorDirective, selector: "img[hideIfError]" }, { kind: "component", type: NotificationCenterComponent, selector: "app-notification-center" }, { kind: "component", type: HeaderSearchComponent, selector: "header-search", inputs: ["searchValue"], outputs: ["searchValueChange", "onSearch"] }], animations: [fadeInOut] });
8677
9096
  }
8678
9097
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: LayoutComponent, decorators: [{
8679
9098
  type: Component,
@@ -8689,7 +9108,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImpor
8689
9108
  NzFlexModule,
8690
9109
  NzButtonModule,
8691
9110
  Breadcrumb,
8692
- GlobalSpinnerComponent,
8693
9111
  NzTreeModule,
8694
9112
  NzBackTopModule,
8695
9113
  NzDrawerModule,
@@ -8703,12 +9121,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImpor
8703
9121
  IconSearch,
8704
9122
  HighlightPipe,
8705
9123
  HideIfErrorDirective,
8706
- CustomNotiComponent,
8707
- ], animations: [fadeInOut], template: "<custom-noti></custom-noti>\r\n<app-global-spinner></app-global-spinner>\r\n<nz-layout class=\"app-layout\">\r\n <nz-header class=\"app-header\">\r\n <div nz-row nzAlign=\"middle\" class=\"header-content\">\r\n @if (isCollapsed) {\r\n <div @fadeInOut>\r\n &nbsp;\r\n <button nz-button nzType=\"text\" style=\"color: var(--theme-text-color)\" (click)=\"visibleMenuDrawer = true\">\r\n <nz-icon nzType=\"menu\" nzTheme=\"outline\" />\r\n </button>\r\n </div>\r\n }\r\n\r\n <div class=\"header-logo\" [style.width]=\"!isCollapsed ? siderWidthStorage : '100px'\">\r\n <div nz-flex nzJustify=\"center\" nzGap=\"small\">\r\n <img\r\n *ngIf=\"logoUrl$ | async as url\"\r\n [src]=\"url\"\r\n height=\"40px\"\r\n style=\"padding: 4px;\"\r\n hideIfError\r\n />\r\n @if (SYSTEM_NAME) {\r\n <h2 style=\"color: whitesmoke; margin-bottom: 0\">{{ SYSTEM_NAME }}</h2>\r\n } @else {\r\n -- o0o --\r\n }\r\n </div>\r\n </div>\r\n @if (!HEADER_MENU_IN_USE) {\r\n <box [width]=\"8\"></box>\r\n <app-breadcrumb [@fadeInOut] nz-col nzFlex=\"auto\" class=\"breadcrumb-header\"></app-breadcrumb>\r\n }\r\n <div *ngIf=\"HEADER_MENU_IN_USE\" nz-col nzFlex=\"auto\" class=\"header-menu\">\r\n <div style=\"overflow: auto\">\r\n <nz-segmented\r\n [nzOptions]=\"lstHeaderMenuDisplay\"\r\n [(ngModel)]=\"selectedHeaderMenuDisplay\"\r\n (nzValueChange)=\"handleValueChangeHeaderMenu($event)\"\r\n ></nz-segmented>\r\n </div>\r\n </div>\r\n <div #divuser>\r\n <layout-user></layout-user>\r\n </div>\r\n </div>\r\n </nz-header>\r\n <nz-layout class=\"body-layout\">\r\n <nz-sider\r\n class=\"menu-sidebar\"\r\n nzCollapsible\r\n [nzWidth]=\"siderWidth\"\r\n [nzCollapsedWidth]=\"0\"\r\n [(nzCollapsed)]=\"isCollapsed\"\r\n [nzTrigger]=\"null\"\r\n [nzTheme]=\"'dark'\"\r\n >\r\n <div class=\"menu-wapper\">\r\n @if (MENU_TYPE == 1) {\r\n <div class=\"nz-tree-wapper\">\r\n <nz-tree\r\n [nzData]=\"nodes\"\r\n [nzSearchValue]=\"searchValue\"\r\n [nzShowLine]=\"true\"\r\n [nzSelectedKeys]=\"selectedKeys\"\r\n [nzExpandedKeys]=\"expandedKeys\"\r\n (nzClick)=\"nzEvent($event)\"\r\n ></nz-tree>\r\n </div>\r\n } @else {\r\n <div class=\"nz-tree-wapper\">\r\n <ul nz-menu nzTheme=\"light\" nzMode=\"inline\" [nzInlineCollapsed]=\"isCollapsed\">\r\n @for (menuLv1 of lstMenu; track menuLv1.App_Menu_Id) {\r\n @if (menuLv1.SubMenu) {\r\n <ul nz-submenu [nzOpen]=\"menuLv1.Open\" [nzTitle]=\"menuLv1.Name\" [nzIcon]=\"menuLv1.Icon\">\r\n @for (menuLv2 of menuLv1.SubMenu; track menuLv2.App_Menu_Id) {\r\n @if (menuLv2.SubMenu) {\r\n <ul nz-submenu [nzOpen]=\"menuLv2.Open\" [nzTitle]=\"menuLv2.Name\" [nzIcon]=\"menuLv2.Icon\">\r\n @for (menuLv3 of menuLv2.SubMenu; track menuLv3.App_Menu_Id) {\r\n @if (menuLv3.SubMenu) {\r\n <ul nz-submenu [nzOpen]=\"menuLv3.Open\" [nzTitle]=\"menuLv3.Name\" [nzIcon]=\"menuLv3.Icon\">\r\n @for (menuLv4 of menuLv3.SubMenu; track menuLv4.App_Menu_Id) {\r\n @if (menuLv4.SubMenu) {\r\n <ul\r\n nz-submenu\r\n [nzOpen]=\"menuLv4.Open\"\r\n [nzTitle]=\"menuLv4.Name\"\r\n [nzIcon]=\"menuLv4.Icon\"\r\n >\r\n @for (menuLv5 of menuLv4.SubMenu; track menuLv5.App_Menu_Id) {}\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a\r\n [routerLink]=\"menuLv4.Url\"\r\n [innerHTML]=\"menuLv4.Name | highlight: searchValue\"\r\n ></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a [routerLink]=\"menuLv3.Url\" [innerHTML]=\"menuLv3.Name | highlight: searchValue\"></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a [routerLink]=\"menuLv2.Url\" [innerHTML]=\"menuLv2.Name | highlight: searchValue\"></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a [routerLink]=\"menuLv1.Url\" [innerHTML]=\"menuLv1.Name | highlight: searchValue\"></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n </div>\r\n }\r\n\r\n <nz-input-group [nzSuffix]=\"suffixTemplate\">\r\n <input nz-input placeholder=\"T\u00ECm menu\" [(ngModel)]=\"searchValue\" />\r\n </nz-input-group>\r\n <ng-template #suffixTemplate>\r\n <span class=\"suffix-wrap\">\r\n <icon-delete\r\n class=\"suffix-icon delete\"\r\n [class.show]=\"searchValue\"\r\n [size]=\"14\"\r\n (click)=\"searchValue = ''\"\r\n ></icon-delete>\r\n\r\n <icon-search class=\"suffix-icon search\" [class.show]=\"!searchValue\"></icon-search>\r\n </span>\r\n </ng-template>\r\n </div>\r\n <div class=\"sider-footer\" style=\"height: var(--app-footer-height)\">\r\n <div nz-col nzFlex=\"auto\" class=\"content-footer text-italic\" style=\"font-size: 0.8em; color: lightgray\">\r\n {{ SYSTEM_SUB_NAME_LEFT || \"-- o0o --\" }}\r\n\r\n <span style=\"float: right\" (click)=\"triggerCollapse()\">\r\n <nz-icon class=\"trigger\" [nzType]=\"isCollapsed ? 'menu-unfold' : 'menu-fold'\" />\r\n </span>\r\n </div>\r\n </div>\r\n </nz-sider>\r\n <nz-layout class=\"main-layout\">\r\n <nz-content class=\"content\">\r\n <div class=\"inner-content\">\r\n @if (HEADER_MENU_IN_USE) {\r\n <app-breadcrumb [@fadeInOut] nz-col nzFlex=\"auto\"></app-breadcrumb>\r\n <box [height]=\"8\"></box>\r\n }\r\n <router-outlet></router-outlet>\r\n </div>\r\n <div nz-row class=\"sider-footer\" style=\"height: var(--app-footer-height)\">\r\n <div nz-col nzFlex=\"auto\" class=\"content-footer text-italic\" style=\"font-size: 0.8em; color: lightgray\">\r\n {{ SYSTEM_SUB_NAME_RIGHT || \"-- o0o --\" }}\r\n </div>\r\n </div>\r\n <!-- <nz-back-top [nzTarget]=\"'.content'\" [nzVisibilityHeight]=\"500\"></nz-back-top> -->\r\n </nz-content>\r\n </nz-layout>\r\n </nz-layout>\r\n</nz-layout>\r\n\r\n<nz-drawer\r\n [nzWrapClassName]=\"'same-theme-color menu-drawer'\"\r\n [nzWidth]=\"350\"\r\n [nzClosable]=\"false\"\r\n [(nzVisible)]=\"visibleMenuDrawer\"\r\n [nzMaskClosable]=\"true\"\r\n nzPlacement=\"left\"\r\n nzTitle=\"\"\r\n (nzOnClose)=\"visibleMenuDrawer = false\"\r\n>\r\n <ng-container *nzDrawerContent>\r\n <div class=\"menu-wapper\">\r\n @if (MENU_TYPE == 1) {\r\n <div class=\"nz-tree-wapper in-drawer\">\r\n <nz-tree\r\n [nzData]=\"nodes\"\r\n [nzSearchValue]=\"searchValue\"\r\n [nzShowLine]=\"true\"\r\n [nzSelectedKeys]=\"selectedKeys\"\r\n [nzExpandedKeys]=\"expandedKeys\"\r\n (nzClick)=\"nzEvent($event)\"\r\n ></nz-tree>\r\n </div>\r\n } @else {\r\n <div class=\"nz-tree-wapper in-drawer\">\r\n <ul nz-menu nzTheme=\"light\" nzMode=\"inline\">\r\n @for (menuLv1 of lstMenu; track menuLv1.App_Menu_Id) {\r\n @if (menuLv1.SubMenu) {\r\n <ul nz-submenu [nzOpen]=\"menuLv1.Open\" [nzTitle]=\"menuLv1.Name\" [nzIcon]=\"menuLv1.Icon\">\r\n @for (menuLv2 of menuLv1.SubMenu; track menuLv2.App_Menu_Id) {\r\n @if (menuLv2.SubMenu) {\r\n <ul nz-submenu [nzOpen]=\"menuLv2.Open\" [nzTitle]=\"menuLv2.Name\" [nzIcon]=\"menuLv2.Icon\">\r\n @for (menuLv3 of menuLv2.SubMenu; track menuLv3.App_Menu_Id) {\r\n @if (menuLv3.SubMenu) {\r\n <ul nz-submenu [nzOpen]=\"menuLv3.Open\" [nzTitle]=\"menuLv3.Name\" [nzIcon]=\"menuLv3.Icon\">\r\n @for (menuLv4 of menuLv3.SubMenu; track menuLv4.App_Menu_Id) {\r\n @if (menuLv4.SubMenu) {\r\n <ul\r\n nz-submenu\r\n [nzOpen]=\"menuLv4.Open\"\r\n [nzTitle]=\"menuLv4.Name\"\r\n [nzIcon]=\"menuLv4.Icon\"\r\n >\r\n @for (menuLv5 of menuLv4.SubMenu; track menuLv5.App_Menu_Id) {}\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a\r\n [routerLink]=\"menuLv4.Url\"\r\n [innerHTML]=\"menuLv4.Name | highlight: searchValue\"\r\n ></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a [routerLink]=\"menuLv3.Url\" [innerHTML]=\"menuLv3.Name | highlight: searchValue\"></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a [routerLink]=\"menuLv2.Url\" [innerHTML]=\"menuLv2.Name | highlight: searchValue\"></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a [routerLink]=\"menuLv1.Url\" [innerHTML]=\"menuLv1.Name | highlight: searchValue\"></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n </div>\r\n }\r\n\r\n <nz-input-group [nzSuffix]=\"suffixTemplate\" [nzAddOnAfter]=\"afterTemplate\">\r\n <input nz-input placeholder=\"T\u00ECm menu\" [(ngModel)]=\"searchValue\" />\r\n </nz-input-group>\r\n <ng-template #suffixTemplate>\r\n <span class=\"suffix-wrap\">\r\n <icon-delete\r\n class=\"suffix-icon delete\"\r\n [class.show]=\"searchValue\"\r\n [size]=\"14\"\r\n (click)=\"searchValue = ''\"\r\n ></icon-delete>\r\n\r\n <icon-search class=\"suffix-icon search\" [class.show]=\"!searchValue\"></icon-search>\r\n </span>\r\n </ng-template>\r\n <ng-template #afterTemplate>\r\n <button nz-button (click)=\"triggerCollapse(); this.visibleMenuDrawer = false\">\r\n <nz-icon *ngIf=\"isCollapsed\" [nzType]=\"isCollapsed ? 'menu-unfold' : 'menu-fold'\" />\r\n </button>\r\n </ng-template>\r\n </div>\r\n </ng-container>\r\n</nz-drawer>\r\n", styles: ["@charset \"UTF-8\";:host{display:flex;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}html,body,app-root{height:100%;margin:0}.app-layout{display:flex;flex-direction:column;height:100vh}.app-header{position:fixed;top:0;left:0;width:100%;height:var(--app-header-height);background:var(--theme-color);color:var(--theme-text-color);box-shadow:0 1px 4px #00152914;z-index:1000;display:flex;align-items:center;padding:0}.header-content{width:100%}.header-logo{height:var(--app-header-height);text-align:center;color:var(--theme-text-color);transition:width .3s}.body-layout{display:flex;flex:1;margin-top:var(--app-header-height);height:calc(100vh - var(--app-header-height));overflow:hidden}.menu-sidebar{width:256px;background:#f0f2f5;overflow-y:auto;min-height:calc(100vh - var(--app-header-height))}.menu-wapper{min-height:calc(100% - var(--app-footer-height))}.main-layout{display:flex;flex-direction:column;flex:1;overflow:hidden}.content{flex:1;background:#f1f2f5;overflow-x:hidden;overflow-y:auto;height:100%}.inner-content{background:#f1f2f5;min-height:calc(100% - var(--app-footer-height));padding:8px}.content-footer{background:var(--theme-color);color:var(--theme-text-color);align-items:center;text-align:center}.sider-footer{background:var(--theme-color);color:var(--theme-text-color);align-items:center;text-align:right}.trigger{margin-right:8px}.menu-sidebar .ant-menu-inline .ant-menu-item{margin-top:0;margin-bottom:0}::ng-deep .menu-wapper .anticon-file{display:none}:host ::ng-deep .ant-back-top{right:30px;bottom:40px}::ng-deep .same-theme-color .ant-drawer-content{background:var(--theme-menu-color)}.nz-tree-wapper{height:calc(100vh - var(--app-header-height) - var(--app-footer-height) - 32px);overflow-y:auto}.nz-tree-wapper.in-drawer{height:calc(100vh - 32px);overflow-y:auto}::ng-deep .menu-drawer .ant-drawer-body{padding:0}::ng-deep .breadcrumb-header .ant-breadcrumb-link{color:var(--theme-text-color);cursor:pointer}::ng-deep .breadcrumb-header .ant-breadcrumb-separator{color:var(--theme-text-color)}::ng-deep .header-menu .ant-segmented-item:not(.ant-segmented-item-selected){color:var(--theme-text-color)}::ng-deep .header-menu .ant-segmented-item{border-left:1px solid}::ng-deep .header-menu .ant-segmented-item:last-child{border-right:1px solid}.suffix-wrap{position:relative;width:18px;height:18px;display:inline-flex;align-items:center;justify-content:center}.suffix-icon{position:absolute;display:flex;align-items:center;justify-content:center;opacity:0;pointer-events:none;transition:opacity .16s ease,transform .18s cubic-bezier(.4,0,.2,1);transform:scale(.6) translate(4px)}.suffix-icon.show{opacity:1;pointer-events:auto;transform:scale(1) translate(0)}.search{color:#00000073}.delete{color:#bfbfbf}.delete.show{animation:popIn .18s ease}@keyframes popIn{0%{transform:scale(.5)}70%{transform:scale(1.15)}to{transform:scale(1)}}\n"] }]
8708
- }], propDecorators: { divuser: [{
8709
- type: ViewChild,
8710
- args: ['divuser']
8711
- }] } });
9124
+ NotificationCenterComponent,
9125
+ HeaderSearchComponent,
9126
+ ], animations: [fadeInOut], template: "<nz-layout class=\"app-layout\">\r\n <nz-header class=\"app-header\">\r\n <div nz-row nzAlign=\"middle\" class=\"header-content\">\r\n @if (isCollapsed) {\r\n <div @fadeInOut>\r\n &nbsp;\r\n <button nz-button nzType=\"text\" style=\"color: var(--theme-text-color)\" (click)=\"visibleMenuDrawer = true\">\r\n <nz-icon nzType=\"menu\" nzTheme=\"outline\" />\r\n </button>\r\n </div>\r\n }\r\n\r\n <div class=\"header-logo\" [style.width]=\"!isCollapsed ? siderWidthStorage : '100px'\">\r\n <div nz-flex nzJustify=\"center\" nzGap=\"small\" style=\"line-height: var(--app-header-height)\">\r\n <img\r\n *ngIf=\"logoUrl$ | async as url\"\r\n [src]=\"url\"\r\n height=\"var(--app-header-height)\"\r\n style=\"padding: 4px\"\r\n hideIfError\r\n />\r\n @if (SYSTEM_NAME) {\r\n <h2 style=\"color: whitesmoke; margin-bottom: 0\">{{ SYSTEM_NAME }}</h2>\r\n } @else {\r\n -- o0o --\r\n }\r\n </div>\r\n </div>\r\n @if (!HEADER_MENU_IN_USE) {\r\n <box [width]=\"8\"></box>\r\n <app-breadcrumb [@fadeInOut] nz-col nzFlex=\"auto\" class=\"breadcrumb-header\"></app-breadcrumb>\r\n }\r\n @if (HEADER_MENU_IN_USE) {\r\n <div nz-col nzFlex=\"auto\" class=\"header-menu\">\r\n <div style=\"overflow: auto\">\r\n <nz-segmented\r\n [nzOptions]=\"lstHeaderMenuDisplay\"\r\n [(ngModel)]=\"selectedHeaderMenuDisplay\"\r\n (nzValueChange)=\"handleValueChangeHeaderMenu($event)\"\r\n ></nz-segmented>\r\n </div>\r\n </div>\r\n }\r\n\r\n <header-search></header-search>\r\n <app-notification-center></app-notification-center>\r\n <header-user></header-user>\r\n </div>\r\n </nz-header>\r\n <nz-layout class=\"body-layout\">\r\n <nz-sider\r\n class=\"menu-sidebar\"\r\n nzCollapsible\r\n [nzWidth]=\"siderWidth\"\r\n [nzCollapsedWidth]=\"0\"\r\n [(nzCollapsed)]=\"isCollapsed\"\r\n [nzTrigger]=\"null\"\r\n [nzTheme]=\"'dark'\"\r\n >\r\n <div class=\"menu-wapper\">\r\n @if (MENU_TYPE == 1) {\r\n <div class=\"nz-tree-wapper\">\r\n <nz-tree\r\n [nzData]=\"nodes\"\r\n [nzSearchValue]=\"searchValue\"\r\n [nzShowLine]=\"true\"\r\n [nzSelectedKeys]=\"selectedKeys\"\r\n [nzExpandedKeys]=\"expandedKeys\"\r\n (nzClick)=\"nzEvent($event)\"\r\n ></nz-tree>\r\n </div>\r\n } @else {\r\n <div class=\"nz-tree-wapper\">\r\n <ul nz-menu nzTheme=\"light\" nzMode=\"inline\" [nzInlineCollapsed]=\"isCollapsed\">\r\n @for (menuLv1 of lstMenu; track menuLv1.App_Menu_Id) {\r\n @if (menuLv1.SubMenu?.length) {\r\n <ul nz-submenu [nzOpen]=\"menuLv1.Open\" [nzTitle]=\"menuLv1.Name\" [nzIcon]=\"menuLv1.Icon\">\r\n @for (menuLv2 of menuLv1.SubMenu; track menuLv2.App_Menu_Id) {\r\n @if (menuLv2.SubMenu?.length) {\r\n <ul nz-submenu [nzOpen]=\"menuLv2.Open\" [nzTitle]=\"menuLv2.Name\" [nzIcon]=\"menuLv2.Icon\">\r\n @for (menuLv3 of menuLv2.SubMenu; track menuLv3.App_Menu_Id) {\r\n @if (menuLv3.SubMenu?.length) {\r\n <ul nz-submenu [nzOpen]=\"menuLv3.Open\" [nzTitle]=\"menuLv3.Name\" [nzIcon]=\"menuLv3.Icon\">\r\n @for (menuLv4 of menuLv3.SubMenu; track menuLv4.App_Menu_Id) {\r\n @if (menuLv4.SubMenu?.length) {\r\n <ul\r\n nz-submenu\r\n [nzOpen]=\"menuLv4.Open\"\r\n [nzTitle]=\"menuLv4.Name\"\r\n [nzIcon]=\"menuLv4.Icon\"\r\n >\r\n @for (menuLv5 of menuLv4.SubMenu; track menuLv5.App_Menu_Id) {}\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a\r\n [routerLink]=\"menuLv4.Url\"\r\n [innerHTML]=\"menuLv4.Name | highlight: searchValue\"\r\n ></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a [routerLink]=\"menuLv3.Url\" [innerHTML]=\"menuLv3.Name | highlight: searchValue\"></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a [routerLink]=\"menuLv2.Url\" [innerHTML]=\"menuLv2.Name | highlight: searchValue\"></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a [routerLink]=\"menuLv1.Url\" [innerHTML]=\"menuLv1.Name | highlight: searchValue\"></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n </div>\r\n }\r\n\r\n <nz-input-group [nzSuffix]=\"suffixTemplate\">\r\n <input nz-input placeholder=\"T\u00ECm menu\" [(ngModel)]=\"searchValue\" />\r\n </nz-input-group>\r\n <ng-template #suffixTemplate>\r\n <span class=\"suffix-wrap\">\r\n <icon-delete\r\n class=\"suffix-icon delete\"\r\n [class.show]=\"searchValue\"\r\n [size]=\"14\"\r\n (click)=\"searchValue = ''\"\r\n ></icon-delete>\r\n\r\n <icon-search class=\"suffix-icon search\" [class.show]=\"!searchValue\"></icon-search>\r\n </span>\r\n </ng-template>\r\n </div>\r\n <div class=\"sider-footer\" style=\"height: var(--app-footer-height)\">\r\n <div nz-col nzFlex=\"auto\" class=\"content-footer text-italic\" style=\"font-size: 0.8em; color: lightgray\">\r\n {{ SYSTEM_SUB_NAME_LEFT || \"-- o0o --\" }}\r\n\r\n <span style=\"float: right\" (click)=\"triggerCollapse()\">\r\n <nz-icon class=\"trigger\" [nzType]=\"isCollapsed ? 'menu-unfold' : 'menu-fold'\" />\r\n </span>\r\n </div>\r\n </div>\r\n </nz-sider>\r\n <nz-layout class=\"main-layout\">\r\n <nz-content class=\"content\">\r\n <div class=\"inner-content\">\r\n @if (HEADER_MENU_IN_USE) {\r\n <app-breadcrumb [@fadeInOut] nz-col nzFlex=\"auto\"></app-breadcrumb>\r\n <box [height]=\"8\"></box>\r\n }\r\n <router-outlet></router-outlet>\r\n </div>\r\n <div nz-row class=\"sider-footer\" style=\"height: var(--app-footer-height)\">\r\n <div nz-col nzFlex=\"auto\" class=\"content-footer text-italic\" style=\"font-size: 0.8em; color: lightgray\">\r\n {{ SYSTEM_SUB_NAME_RIGHT || \"-- o0o --\" }}\r\n </div>\r\n </div>\r\n <!-- <nz-back-top [nzTarget]=\"'.content'\" [nzVisibilityHeight]=\"500\"></nz-back-top> -->\r\n </nz-content>\r\n </nz-layout>\r\n </nz-layout>\r\n</nz-layout>\r\n\r\n<nz-drawer\r\n [nzWrapClassName]=\"'same-theme-color menu-drawer'\"\r\n [nzWidth]=\"350\"\r\n [nzClosable]=\"false\"\r\n [(nzVisible)]=\"visibleMenuDrawer\"\r\n [nzMaskClosable]=\"true\"\r\n nzPlacement=\"left\"\r\n nzTitle=\"\"\r\n (nzOnClose)=\"visibleMenuDrawer = false\"\r\n>\r\n <ng-container *nzDrawerContent>\r\n <div class=\"menu-wapper\">\r\n @if (MENU_TYPE == 1) {\r\n <div class=\"nz-tree-wapper in-drawer\">\r\n <nz-tree\r\n [nzData]=\"nodes\"\r\n [nzSearchValue]=\"searchValue\"\r\n [nzShowLine]=\"true\"\r\n [nzSelectedKeys]=\"selectedKeys\"\r\n [nzExpandedKeys]=\"expandedKeys\"\r\n (nzClick)=\"nzEvent($event)\"\r\n ></nz-tree>\r\n </div>\r\n } @else {\r\n <div class=\"nz-tree-wapper in-drawer\">\r\n <ul nz-menu nzTheme=\"light\" nzMode=\"inline\">\r\n @for (menuLv1 of lstMenu; track menuLv1.App_Menu_Id) {\r\n @if (menuLv1.SubMenu) {\r\n <ul nz-submenu [nzOpen]=\"menuLv1.Open\" [nzTitle]=\"menuLv1.Name\" [nzIcon]=\"menuLv1.Icon\">\r\n @for (menuLv2 of menuLv1.SubMenu; track menuLv2.App_Menu_Id) {\r\n @if (menuLv2.SubMenu) {\r\n <ul nz-submenu [nzOpen]=\"menuLv2.Open\" [nzTitle]=\"menuLv2.Name\" [nzIcon]=\"menuLv2.Icon\">\r\n @for (menuLv3 of menuLv2.SubMenu; track menuLv3.App_Menu_Id) {\r\n @if (menuLv3.SubMenu) {\r\n <ul nz-submenu [nzOpen]=\"menuLv3.Open\" [nzTitle]=\"menuLv3.Name\" [nzIcon]=\"menuLv3.Icon\">\r\n @for (menuLv4 of menuLv3.SubMenu; track menuLv4.App_Menu_Id) {\r\n @if (menuLv4.SubMenu) {\r\n <ul\r\n nz-submenu\r\n [nzOpen]=\"menuLv4.Open\"\r\n [nzTitle]=\"menuLv4.Name\"\r\n [nzIcon]=\"menuLv4.Icon\"\r\n >\r\n @for (menuLv5 of menuLv4.SubMenu; track menuLv5.App_Menu_Id) {}\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a\r\n [routerLink]=\"menuLv4.Url\"\r\n [innerHTML]=\"menuLv4.Name | highlight: searchValue\"\r\n ></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a [routerLink]=\"menuLv3.Url\" [innerHTML]=\"menuLv3.Name | highlight: searchValue\"></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a [routerLink]=\"menuLv2.Url\" [innerHTML]=\"menuLv2.Name | highlight: searchValue\"></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n } @else {\r\n <li nz-menu-item nzMatchRouter>\r\n <a [routerLink]=\"menuLv1.Url\" [innerHTML]=\"menuLv1.Name | highlight: searchValue\"></a>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n </div>\r\n }\r\n\r\n <nz-input-group [nzSuffix]=\"suffixTemplate\" [nzAddOnAfter]=\"afterTemplate\">\r\n <input nz-input placeholder=\"T\u00ECm menu\" [(ngModel)]=\"searchValue\" />\r\n </nz-input-group>\r\n <ng-template #suffixTemplate>\r\n <span class=\"suffix-wrap\">\r\n <icon-delete\r\n class=\"suffix-icon delete\"\r\n [class.show]=\"searchValue\"\r\n [size]=\"14\"\r\n (click)=\"searchValue = ''\"\r\n ></icon-delete>\r\n\r\n <icon-search class=\"suffix-icon search\" [class.show]=\"!searchValue\"></icon-search>\r\n </span>\r\n </ng-template>\r\n <ng-template #afterTemplate>\r\n <button nz-button (click)=\"triggerCollapse(); this.visibleMenuDrawer = false\">\r\n <nz-icon *ngIf=\"isCollapsed\" [nzType]=\"isCollapsed ? 'menu-unfold' : 'menu-fold'\" />\r\n </button>\r\n </ng-template>\r\n </div>\r\n </ng-container>\r\n</nz-drawer>\r\n", styles: ["@charset \"UTF-8\";:host{display:flex;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}html,body,app-root{height:100%;margin:0}.app-layout{display:flex;flex-direction:column;height:100vh}.app-header{position:fixed;top:0;left:0;width:100%;height:var(--app-header-height);background:var(--theme-color);color:var(--theme-text-color);box-shadow:0 1px 4px #00152914;z-index:1000;display:flex;align-items:center;padding:0}.header-content{width:100%}.header-logo{height:var(--app-header-height);text-align:center;color:var(--theme-text-color);transition:width .3s}.body-layout{display:flex;flex:1;margin-top:var(--app-header-height);height:calc(100vh - var(--app-header-height));overflow:hidden}.menu-sidebar{width:256px;background:#f0f2f5;overflow-y:auto;min-height:calc(100vh - var(--app-header-height))}.menu-wapper{min-height:calc(100% - var(--app-footer-height))}.main-layout{display:flex;flex-direction:column;flex:1;overflow:hidden}.content{flex:1;background:#fff;overflow-x:hidden;overflow-y:auto;height:100%}.inner-content{background:#fff;min-height:calc(100% - var(--app-footer-height));padding:8px}.content-footer{background:var(--theme-color);color:var(--theme-text-color);align-items:center;text-align:center}.sider-footer{background:var(--theme-color);color:var(--theme-text-color);align-items:center;text-align:right}.trigger{margin-right:8px}.menu-sidebar .ant-menu-inline .ant-menu-item{margin-top:0;margin-bottom:0}::ng-deep .menu-wapper .anticon-file{display:none}:host ::ng-deep .ant-back-top{right:30px;bottom:40px}::ng-deep .same-theme-color .ant-drawer-content{background:var(--theme-menu-color)}.nz-tree-wapper{height:calc(100vh - var(--app-header-height) - var(--app-footer-height) - 32px);overflow-y:auto}.nz-tree-wapper.in-drawer{height:calc(100vh - 32px);overflow-y:auto}::ng-deep .menu-drawer .ant-drawer-body{padding:0}::ng-deep .breadcrumb-header .ant-breadcrumb-link{color:var(--theme-text-color);cursor:pointer}::ng-deep .breadcrumb-header .ant-breadcrumb-separator{color:var(--theme-text-color)}::ng-deep .header-menu .ant-segmented-item:not(.ant-segmented-item-selected){color:var(--theme-text-color)}::ng-deep .header-menu .ant-segmented-item{border-left:1px solid}::ng-deep .header-menu .ant-segmented-item:last-child{border-right:1px solid}.suffix-wrap{position:relative;width:18px;height:18px;display:inline-flex;align-items:center;justify-content:center}.suffix-icon{position:absolute;display:flex;align-items:center;justify-content:center;opacity:0;pointer-events:none;transition:opacity .16s ease,transform .18s cubic-bezier(.4,0,.2,1);transform:scale(.6) translate(4px)}.suffix-icon.show{opacity:1;pointer-events:auto;transform:scale(1) translate(0)}.search{color:#00000073}.delete{color:#bfbfbf}.delete.show{animation:popIn .18s ease}@keyframes popIn{0%{transform:scale(.5)}70%{transform:scale(1.15)}to{transform:scale(1)}}\n"] }]
9127
+ }] });
8712
9128
 
8713
9129
  const URLs = {
8714
9130
  getById: '/api/App_Org/GetById',
@@ -8719,32 +9135,22 @@ const URLs = {
8719
9135
  delete: '/api/App_Org/Delete',
8720
9136
  };
8721
9137
  class OrgService extends HTTPService {
8722
- commonService = inject(CommonService);
9138
+ cms = inject(CommonService);
8723
9139
  getById(id) {
8724
- return this.commonService.ESP({
8725
- SPN: 'App_Org_getById',
8726
- Params: [id],
8727
- });
9140
+ let pr = new HttpParams().append('id', id);
9141
+ return this.postParams(AppGlobals.apiEndpoint + URLs.getById, pr);
8728
9142
  }
8729
9143
  getAll() {
8730
- return this.commonService.ESP({
8731
- SPN: 'App_Org_getAll',
8732
- });
9144
+ return this.post(AppGlobals.apiEndpoint + URLs.getAll);
8733
9145
  }
8734
9146
  getList(filter) {
8735
9147
  return this.postData(AppGlobals.apiEndpoint + URLs.getList, filter);
8736
9148
  }
8737
9149
  getPaging(filter) {
8738
- return this.commonService.ESP({
8739
- SPN: 'App_Org_getpaging',
8740
- Params: [filter],
8741
- });
9150
+ return this.postData(AppGlobals.apiEndpoint + URLs.getPaging, filter);
8742
9151
  }
8743
9152
  addOrEdit(obj) {
8744
- return this.commonService.ESP({
8745
- SPN: 'App_Org_addOrEdit',
8746
- Params: [obj],
8747
- });
9153
+ return this.postData(AppGlobals.apiEndpoint + URLs.addOrEdit, obj);
8748
9154
  }
8749
9155
  delete(id) {
8750
9156
  const params = new HttpParams().append('id', id);
@@ -8754,38 +9160,9 @@ class OrgService extends HTTPService {
8754
9160
  const params = new HttpParams().append('UserName', UserName);
8755
9161
  return this.getParams(`${AppGlobals.apiEndpoint}/api/public/LstOrgForLogin`, params);
8756
9162
  }
8757
- getUserInOrgStr(OrgId) {
8758
- return this.commonService.ESP({
8759
- SPN: 'App_Org_getUserInOrgStr',
8760
- Params: [OrgId],
8761
- });
8762
- }
8763
9163
  getUsersInOrg(orgId) {
8764
- return this.commonService.ESP({
8765
- SPN: 'App_Org_getUsersInOrg',
8766
- Params: [orgId],
8767
- });
8768
- }
8769
- addUsersToOrg(orgId, userIds) {
8770
- if (!orgId) {
8771
- return Promise.reject('Org ID is required');
8772
- }
8773
- return this.commonService.ESP({
8774
- SPN: 'App_Org_addUsersToOrg',
8775
- Params: [orgId, userIds.join(',')],
8776
- });
8777
- }
8778
- deleteUserFromOrg(orgId, userId) {
8779
- return this.commonService.ESP({
8780
- SPN: 'App_Org_deleteUserFromOrg',
8781
- Params: [orgId, userId],
8782
- });
8783
- }
8784
- checkImportOrg(data) {
8785
- return this.commonService.ESP({
8786
- SPN: 'App_Org_checkImportOrg',
8787
- Params: [data],
8788
- });
9164
+ const params = new HttpParams().append('OrgId', orgId);
9165
+ return this.postParams(`${AppGlobals.apiEndpoint}/api/App_Org/getUsersInOrg`, params);
8789
9166
  }
8790
9167
  importOrg(data) {
8791
9168
  return this.postData(`${AppGlobals.apiEndpoint}/api/Org/importOrg`, data);
@@ -8807,7 +9184,6 @@ class LoginComponent extends BaseComponent {
8807
9184
  orgService = inject(OrgService);
8808
9185
  settingService = inject(SettingService);
8809
9186
  vscService = inject(VscService);
8810
- loadingService = inject(LoadingService);
8811
9187
  fileService = inject(FileService);
8812
9188
  loginForm;
8813
9189
  visible = false;
@@ -8867,13 +9243,15 @@ class LoginComponent extends BaseComponent {
8867
9243
  }
8868
9244
  }, (err) => this.handleError(err));
8869
9245
  }
8870
- dologin() {
9246
+ async dologin() {
8871
9247
  for (const i in this.loginForm.controls) {
8872
9248
  this.loginForm.controls[i].markAsDirty();
8873
9249
  this.loginForm.controls[i].updateValueAndValidity();
8874
9250
  }
8875
9251
  if (this.loginForm.valid) {
8876
- this.sessionManager.login(this.loginForm.value.username, this.loginForm.value.password, this.loginForm.value.orgid, this.returnUrl);
9252
+ this.isLoading = true;
9253
+ await this.sessionManager.login(this.loginForm.value.username, this.loginForm.value.password, this.loginForm.value.orgid, this.returnUrl);
9254
+ this.isLoading = false;
8877
9255
  }
8878
9256
  this.vscService.checkVersion();
8879
9257
  }
@@ -8895,7 +9273,7 @@ class LoginComponent extends BaseComponent {
8895
9273
  .getFileVersion('LOGIN_BACKGROUND')
8896
9274
  .pipe(map((res) => `${AppGlobals.apiEndpoint}/api/file/image?code=LOGIN_BACKGROUND&v=${res || ''}`));
8897
9275
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: LoginComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
8898
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.7", type: LoginComponent, isStandalone: true, selector: "login", usesInheritance: true, ngImport: i0, template: "<div nz-row nzJustify=\"center\" class=\"login\">\r\n <div class=\"form-container\">\r\n <form nz-flex nzVertical=\"true\" nz-form [formGroup]=\"loginForm\" class=\"login-form\" (ngSubmit)=\"dologin()\">\r\n <div>\r\n <div style=\"text-align: center\">\r\n <img *ngIf=\"logoUrl$ | async as url\" width=\"150px\" [src]=\"url\" hideIfError />\r\n </div>\r\n <div class=\"form-field\" style=\"text-align: center; margin-bottom: 20px\">\r\n <h3 style=\"font-weight: bold; font-size: 20px\">{{ SYSTEM_NAME_LOGIN }}</h3>\r\n </div>\r\n </div>\r\n\r\n <div nz-row [nzJustify]=\"'center'\">\r\n <div nz-col nzSm=\"24\" nzMd=\"16\">\r\n <div nz-flex nzVertical=\"true\">\r\n <nz-form-item>\r\n <nz-form-control nzErrorTip=\"{{ 'REQUIRED' | translate }}\">\r\n <nz-input-group nzPrefixIcon=\"user\">\r\n <input type=\"text\" nz-input formControlName=\"username\" placeholder=\"{{ 'USERNAME' | translate }}\" />\r\n </nz-input-group>\r\n </nz-form-control>\r\n </nz-form-item>\r\n\r\n <nz-form-item>\r\n <nz-form-control nzErrorTip=\"{{ 'REQUIRED' | translate }}\">\r\n <nz-input-group\r\n nzPrefixIcon=\"lock\"\r\n [nzSuffix]=\"visible ? suffixTemplateHiddenPassword : suffixTemplateShowPassword\"\r\n >\r\n <input\r\n type=\"{{ passwordType }}\"\r\n nz-input\r\n formControlName=\"password\"\r\n placeholder=\"{{ 'PASSWORD' | translate }}\"\r\n />\r\n </nz-input-group>\r\n </nz-form-control>\r\n <ng-template #suffixTemplateShowPassword>\r\n <nz-icon\r\n nzType=\"eye\"\r\n nzTheme=\"outline\"\r\n nz-tooltip\r\n nzTooltipTitle=\"{{ 'SHOW' | translate }}\"\r\n nzTooltipPlacement=\"right\"\r\n (click)=\"visible = !visible; passwordType = 'text'\"\r\n />\r\n </ng-template>\r\n <ng-template #suffixTemplateHiddenPassword>\r\n <nz-icon\r\n nzType=\"eye-invisible\"\r\n nzTheme=\"outline\"\r\n nz-tooltip\r\n nzTooltipTitle=\"{{ 'HIDDEN' | translate }}\"\r\n nzTooltipPlacement=\"right\"\r\n (click)=\"visible = !visible; passwordType = 'password'\"\r\n />\r\n </ng-template>\r\n </nz-form-item>\r\n\r\n @if (isOneUserMultiOrgs) {\r\n <nz-form-item>\r\n <nz-form-control nzErrorTip=\"{{ 'REQUIRED' | translate }}\">\r\n <nz-input-group nzPrefixIcon=\"cluster\" nzHasFeedback=\"false\">\r\n <nz-select\r\n nzShowSearch\r\n nzAllowClear\r\n [nzBorderless]=\"true\"\r\n [nzSize]=\"'small'\"\r\n nzPlaceHolder=\"{{ 'ORG' | translate }}\"\r\n formControlName=\"orgid\"\r\n class=\"no-error-border\"\r\n (nzFocus)=\"onFocusOrg()\"\r\n >\r\n @for (item of lstOrg; track $index) {\r\n <nz-option [nzLabel]=\"item.TreeNodeName!\" [nzValue]=\"item.App_Org_Id\"></nz-option>\r\n }\r\n </nz-select>\r\n </nz-input-group>\r\n </nz-form-control>\r\n </nz-form-item>\r\n }\r\n\r\n <div nz-flex nzVertical=\"true\" nzGap=\"4px\">\r\n <button nz-button [nzType]=\"'primary'\" nzBlock [nzLoading]=\"loadingService.isLoading\">\r\n {{ \"LOGIN\" | translate }}\r\n </button>\r\n <!-- \r\n <nz-form-item nzJustify=\"end\">\r\n <nz-switch formControlName=\"langSwitch\" class=\"nz-switch-both-active-color\" nzCheckedChildren=\"VN\"\r\n nzUnCheckedChildren=\"EN\" (ngModelChange)=\"changeLanguage($event)\"></nz-switch>\r\n </nz-form-item> \r\n -->\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </form>\r\n </div>\r\n</div>\r\n\r\n<img *ngIf=\"bgUrl$ | async as url\" class=\"bg-image\" [src]=\"url\" hideIfError />\r\n", styles: [":host{display:flex;justify-content:center;align-items:center;height:80vh}.form-container{width:clamp(280px,30vw,420px);box-shadow:0 10px 20px 1px #001a2d59;background-color:#fff;padding:16px;border-radius:8px}.bg-image{position:fixed;top:0;left:0;width:100vw;height:100vh;object-fit:cover;object-position:center;z-index:-1;pointer-events:none}::ng-deep .login .ant-select-selector{height:auto!important}::ng-deep .login .ant-input-affix-wrapper,::ng-deep .login .ant-btn{border-radius:8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1$4.AsyncPipe, name: "async" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3$1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: NzFormModule }, { kind: "directive", type: i4.NzColDirective, selector: "[nz-col],nz-col,nz-form-control,nz-form-label", inputs: ["nzFlex", "nzSpan", "nzOrder", "nzOffset", "nzPush", "nzPull", "nzXs", "nzSm", "nzMd", "nzLg", "nzXl", "nzXXl"], exportAs: ["nzCol"] }, { kind: "directive", type: i4.NzRowDirective, selector: "[nz-row],nz-row,nz-form-item", inputs: ["nzAlign", "nzJustify", "nzGutter"], exportAs: ["nzRow"] }, { kind: "directive", type: i5.NzFormDirective, selector: "[nz-form]", inputs: ["nzLayout", "nzNoColon", "nzAutoTips", "nzDisableAutoTips", "nzTooltipIcon", "nzLabelAlign", "nzLabelWrap"], exportAs: ["nzForm"] }, { kind: "component", type: i5.NzFormItemComponent, selector: "nz-form-item", exportAs: ["nzFormItem"] }, { kind: "component", type: i5.NzFormControlComponent, selector: "nz-form-control", inputs: ["nzSuccessTip", "nzWarningTip", "nzErrorTip", "nzValidatingTip", "nzExtra", "nzAutoTips", "nzDisableAutoTips", "nzHasFeedback", "nzValidateStatus"], exportAs: ["nzFormControl"] }, { kind: "ngmodule", type: NzInputModule }, { kind: "directive", type: i6$1.NzInputDirective, selector: "input[nz-input],textarea[nz-input]", inputs: ["nzBorderless", "nzSize", "nzStepperless", "nzStatus", "disabled"], exportAs: ["nzInput"] }, { kind: "component", type: i6$1.NzInputGroupComponent, selector: "nz-input-group", inputs: ["nzAddOnBeforeIcon", "nzAddOnAfterIcon", "nzPrefixIcon", "nzSuffixIcon", "nzAddOnBefore", "nzAddOnAfter", "nzPrefix", "nzStatus", "nzSuffix", "nzSize", "nzSearch", "nzCompact"], exportAs: ["nzInputGroup"] }, { kind: "directive", type: i6$1.NzInputGroupWhitSuffixOrPrefixDirective, selector: "nz-input-group[nzSuffix], nz-input-group[nzPrefix]" }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "ngmodule", type: NzToolTipModule }, { kind: "directive", type: i11.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: "ngmodule", type: NzButtonModule }, { kind: "component", type: i5$3.NzButtonComponent, selector: "button[nz-button], a[nz-button]", inputs: ["nzBlock", "nzGhost", "nzSearch", "nzLoading", "nzDanger", "disabled", "tabIndex", "nzType", "nzShape", "nzSize"], exportAs: ["nzButton"] }, { kind: "directive", type: i6$3.ɵ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: i7.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "ngmodule", type: NzSwitchModule }, { kind: "ngmodule", type: NzFlexModule }, { kind: "directive", type: i9.NzFlexDirective, selector: "[nz-flex],nz-flex", inputs: ["nzVertical", "nzJustify", "nzAlign", "nzGap", "nzWrap", "nzFlex"], exportAs: ["nzFlex"] }, { kind: "ngmodule", type: NzSelectModule }, { kind: "component", type: i6$2.NzOptionComponent, selector: "nz-option", inputs: ["nzTitle", "nzLabel", "nzValue", "nzKey", "nzDisabled", "nzHide", "nzCustomContent"], exportAs: ["nzOption"] }, { kind: "component", type: i6$2.NzSelectComponent, selector: "nz-select", inputs: ["nzId", "nzSize", "nzStatus", "nzOptionHeightPx", "nzOptionOverflowSize", "nzDropdownClassName", "nzDropdownMatchSelectWidth", "nzDropdownStyle", "nzNotFoundContent", "nzPlaceHolder", "nzPlacement", "nzMaxTagCount", "nzDropdownRender", "nzCustomTemplate", "nzSuffixIcon", "nzClearIcon", "nzRemoveIcon", "nzMenuItemSelectedIcon", "nzTokenSeparators", "nzMaxTagPlaceholder", "nzMaxMultipleCount", "nzMode", "nzFilterOption", "compareWith", "nzAllowClear", "nzBorderless", "nzShowSearch", "nzLoading", "nzAutoFocus", "nzAutoClearSearchValue", "nzServerSearch", "nzDisabled", "nzOpen", "nzSelectOnTab", "nzBackdrop", "nzOptions", "nzShowArrow"], outputs: ["nzOnSearch", "nzScrollToBottom", "nzOpenChange", "nzBlur", "nzFocus"], exportAs: ["nzSelect"] }, { kind: "directive", type: HideIfErrorDirective, selector: "img[hideIfError]" }] });
9276
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.7", type: LoginComponent, isStandalone: true, selector: "login", usesInheritance: true, ngImport: i0, template: "<nz-spin [nzSpinning]=\"isLoading\">\r\n <div nz-row nzJustify=\"center\" class=\"login\">\r\n <div class=\"form-container\">\r\n <form nz-flex nzVertical=\"true\" nz-form [formGroup]=\"loginForm\" class=\"login-form\" (ngSubmit)=\"dologin()\">\r\n <div>\r\n <div style=\"text-align: center\">\r\n <img *ngIf=\"logoUrl$ | async as url\" width=\"150px\" [src]=\"url\" hideIfError />\r\n </div>\r\n <div class=\"form-field\" style=\"text-align: center; margin-bottom: 20px\">\r\n <h3 style=\"font-weight: bold; font-size: 20px\">{{ SYSTEM_NAME_LOGIN }}</h3>\r\n </div>\r\n </div>\r\n\r\n <div nz-row [nzJustify]=\"'center'\">\r\n <div nz-col nzSm=\"24\" nzMd=\"16\">\r\n <div nz-flex nzVertical=\"true\">\r\n <nz-form-item>\r\n <nz-form-control nzErrorTip=\"{{ 'REQUIRED' | translate }}\">\r\n <nz-input-group nzPrefixIcon=\"user\">\r\n <input type=\"text\" nz-input formControlName=\"username\" placeholder=\"{{ 'USERNAME' | translate }}\" />\r\n </nz-input-group>\r\n </nz-form-control>\r\n </nz-form-item>\r\n\r\n <nz-form-item>\r\n <nz-form-control nzErrorTip=\"{{ 'REQUIRED' | translate }}\">\r\n <nz-input-group\r\n nzPrefixIcon=\"lock\"\r\n [nzSuffix]=\"visible ? suffixTemplateHiddenPassword : suffixTemplateShowPassword\"\r\n >\r\n <input\r\n type=\"{{ passwordType }}\"\r\n nz-input\r\n formControlName=\"password\"\r\n placeholder=\"{{ 'PASSWORD' | translate }}\"\r\n />\r\n </nz-input-group>\r\n </nz-form-control>\r\n <ng-template #suffixTemplateShowPassword>\r\n <nz-icon\r\n nzType=\"eye\"\r\n nzTheme=\"outline\"\r\n nz-tooltip\r\n nzTooltipTitle=\"{{ 'SHOW' | translate }}\"\r\n nzTooltipPlacement=\"right\"\r\n (click)=\"visible = !visible; passwordType = 'text'\"\r\n />\r\n </ng-template>\r\n <ng-template #suffixTemplateHiddenPassword>\r\n <nz-icon\r\n nzType=\"eye-invisible\"\r\n nzTheme=\"outline\"\r\n nz-tooltip\r\n nzTooltipTitle=\"{{ 'HIDDEN' | translate }}\"\r\n nzTooltipPlacement=\"right\"\r\n (click)=\"visible = !visible; passwordType = 'password'\"\r\n />\r\n </ng-template>\r\n </nz-form-item>\r\n\r\n @if (isOneUserMultiOrgs) {\r\n <nz-form-item>\r\n <nz-form-control nzErrorTip=\"{{ 'REQUIRED' | translate }}\">\r\n <nz-input-group nzPrefixIcon=\"cluster\" nzHasFeedback=\"false\">\r\n <nz-select\r\n nzShowSearch\r\n nzAllowClear\r\n [nzBorderless]=\"true\"\r\n [nzSize]=\"'small'\"\r\n nzPlaceHolder=\"{{ 'ORG' | translate }}\"\r\n formControlName=\"orgid\"\r\n class=\"no-error-border\"\r\n (nzFocus)=\"onFocusOrg()\"\r\n >\r\n @for (item of lstOrg; track $index) {\r\n <nz-option [nzLabel]=\"item.TreeNodeName!\" [nzValue]=\"item.App_Org_Id\"></nz-option>\r\n }\r\n </nz-select>\r\n </nz-input-group>\r\n </nz-form-control>\r\n </nz-form-item>\r\n }\r\n\r\n <div nz-flex nzVertical=\"true\" nzGap=\"4px\">\r\n <button nz-button [nzType]=\"'primary'\" nzBlock>\r\n {{ \"LOGIN\" | translate }}\r\n </button>\r\n <!-- \r\n <nz-form-item nzJustify=\"end\">\r\n <nz-switch formControlName=\"langSwitch\" class=\"nz-switch-both-active-color\" nzCheckedChildren=\"VN\"\r\n nzUnCheckedChildren=\"EN\" (ngModelChange)=\"changeLanguage($event)\"></nz-switch>\r\n </nz-form-item> \r\n --></div>\r\n </div>\r\n </div>\r\n </div>\r\n </form>\r\n </div>\r\n </div>\r\n</nz-spin>\r\n\r\n<img *ngIf=\"bgUrl$ | async as url\" class=\"bg-image\" [src]=\"url\" hideIfError />\r\n", styles: [":host{display:flex;justify-content:center;align-items:center;height:80vh}.form-container{width:clamp(280px,30vw,420px);box-shadow:0 10px 20px 1px #001a2d59;background-color:#fff;padding:16px;border-radius:8px}.bg-image{position:fixed;top:0;left:0;width:100vw;height:100vh;object-fit:cover;object-position:center;z-index:-1;pointer-events:none}::ng-deep .login .ant-select-selector{height:auto!important}::ng-deep .login .ant-input-affix-wrapper,::ng-deep .login .ant-btn{border-radius:8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1$4.AsyncPipe, name: "async" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3$1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: NzFormModule }, { kind: "directive", type: i4.NzColDirective, selector: "[nz-col],nz-col,nz-form-control,nz-form-label", inputs: ["nzFlex", "nzSpan", "nzOrder", "nzOffset", "nzPush", "nzPull", "nzXs", "nzSm", "nzMd", "nzLg", "nzXl", "nzXXl"], exportAs: ["nzCol"] }, { kind: "directive", type: i4.NzRowDirective, selector: "[nz-row],nz-row,nz-form-item", inputs: ["nzAlign", "nzJustify", "nzGutter"], exportAs: ["nzRow"] }, { kind: "directive", type: i5.NzFormDirective, selector: "[nz-form]", inputs: ["nzLayout", "nzNoColon", "nzAutoTips", "nzDisableAutoTips", "nzTooltipIcon", "nzLabelAlign", "nzLabelWrap"], exportAs: ["nzForm"] }, { kind: "component", type: i5.NzFormItemComponent, selector: "nz-form-item", exportAs: ["nzFormItem"] }, { kind: "component", type: i5.NzFormControlComponent, selector: "nz-form-control", inputs: ["nzSuccessTip", "nzWarningTip", "nzErrorTip", "nzValidatingTip", "nzExtra", "nzAutoTips", "nzDisableAutoTips", "nzHasFeedback", "nzValidateStatus"], exportAs: ["nzFormControl"] }, { kind: "ngmodule", type: NzInputModule }, { kind: "directive", type: i6$1.NzInputDirective, selector: "input[nz-input],textarea[nz-input]", inputs: ["nzBorderless", "nzSize", "nzStepperless", "nzStatus", "disabled"], exportAs: ["nzInput"] }, { kind: "component", type: i6$1.NzInputGroupComponent, selector: "nz-input-group", inputs: ["nzAddOnBeforeIcon", "nzAddOnAfterIcon", "nzPrefixIcon", "nzSuffixIcon", "nzAddOnBefore", "nzAddOnAfter", "nzPrefix", "nzStatus", "nzSuffix", "nzSize", "nzSearch", "nzCompact"], exportAs: ["nzInputGroup"] }, { kind: "directive", type: i6$1.NzInputGroupWhitSuffixOrPrefixDirective, selector: "nz-input-group[nzSuffix], nz-input-group[nzPrefix]" }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "ngmodule", type: NzToolTipModule }, { kind: "directive", type: i11.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: "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$2.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "ngmodule", type: NzSwitchModule }, { kind: "ngmodule", type: NzFlexModule }, { kind: "directive", type: i5$3.NzFlexDirective, selector: "[nz-flex],nz-flex", inputs: ["nzVertical", "nzJustify", "nzAlign", "nzGap", "nzWrap", "nzFlex"], exportAs: ["nzFlex"] }, { kind: "ngmodule", type: NzSelectModule }, { kind: "component", type: i6$2.NzOptionComponent, selector: "nz-option", inputs: ["nzTitle", "nzLabel", "nzValue", "nzKey", "nzDisabled", "nzHide", "nzCustomContent"], exportAs: ["nzOption"] }, { kind: "component", type: i6$2.NzSelectComponent, selector: "nz-select", inputs: ["nzId", "nzSize", "nzStatus", "nzOptionHeightPx", "nzOptionOverflowSize", "nzDropdownClassName", "nzDropdownMatchSelectWidth", "nzDropdownStyle", "nzNotFoundContent", "nzPlaceHolder", "nzPlacement", "nzMaxTagCount", "nzDropdownRender", "nzCustomTemplate", "nzSuffixIcon", "nzClearIcon", "nzRemoveIcon", "nzMenuItemSelectedIcon", "nzTokenSeparators", "nzMaxTagPlaceholder", "nzMaxMultipleCount", "nzMode", "nzFilterOption", "compareWith", "nzAllowClear", "nzBorderless", "nzShowSearch", "nzLoading", "nzAutoFocus", "nzAutoClearSearchValue", "nzServerSearch", "nzDisabled", "nzOpen", "nzSelectOnTab", "nzBackdrop", "nzOptions", "nzShowArrow"], outputs: ["nzOnSearch", "nzScrollToBottom", "nzOpenChange", "nzBlur", "nzFocus"], exportAs: ["nzSelect"] }, { kind: "directive", type: HideIfErrorDirective, selector: "img[hideIfError]" }, { kind: "component", type: NzSpinComponent, selector: "nz-spin", inputs: ["nzIndicator", "nzSize", "nzTip", "nzDelay", "nzSimple", "nzSpinning"], exportAs: ["nzSpin"] }] });
8899
9277
  }
8900
9278
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: LoginComponent, decorators: [{
8901
9279
  type: Component,
@@ -8913,12 +9291,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImpor
8913
9291
  NzFlexModule,
8914
9292
  NzSelectModule,
8915
9293
  HideIfErrorDirective,
8916
- ], template: "<div nz-row nzJustify=\"center\" class=\"login\">\r\n <div class=\"form-container\">\r\n <form nz-flex nzVertical=\"true\" nz-form [formGroup]=\"loginForm\" class=\"login-form\" (ngSubmit)=\"dologin()\">\r\n <div>\r\n <div style=\"text-align: center\">\r\n <img *ngIf=\"logoUrl$ | async as url\" width=\"150px\" [src]=\"url\" hideIfError />\r\n </div>\r\n <div class=\"form-field\" style=\"text-align: center; margin-bottom: 20px\">\r\n <h3 style=\"font-weight: bold; font-size: 20px\">{{ SYSTEM_NAME_LOGIN }}</h3>\r\n </div>\r\n </div>\r\n\r\n <div nz-row [nzJustify]=\"'center'\">\r\n <div nz-col nzSm=\"24\" nzMd=\"16\">\r\n <div nz-flex nzVertical=\"true\">\r\n <nz-form-item>\r\n <nz-form-control nzErrorTip=\"{{ 'REQUIRED' | translate }}\">\r\n <nz-input-group nzPrefixIcon=\"user\">\r\n <input type=\"text\" nz-input formControlName=\"username\" placeholder=\"{{ 'USERNAME' | translate }}\" />\r\n </nz-input-group>\r\n </nz-form-control>\r\n </nz-form-item>\r\n\r\n <nz-form-item>\r\n <nz-form-control nzErrorTip=\"{{ 'REQUIRED' | translate }}\">\r\n <nz-input-group\r\n nzPrefixIcon=\"lock\"\r\n [nzSuffix]=\"visible ? suffixTemplateHiddenPassword : suffixTemplateShowPassword\"\r\n >\r\n <input\r\n type=\"{{ passwordType }}\"\r\n nz-input\r\n formControlName=\"password\"\r\n placeholder=\"{{ 'PASSWORD' | translate }}\"\r\n />\r\n </nz-input-group>\r\n </nz-form-control>\r\n <ng-template #suffixTemplateShowPassword>\r\n <nz-icon\r\n nzType=\"eye\"\r\n nzTheme=\"outline\"\r\n nz-tooltip\r\n nzTooltipTitle=\"{{ 'SHOW' | translate }}\"\r\n nzTooltipPlacement=\"right\"\r\n (click)=\"visible = !visible; passwordType = 'text'\"\r\n />\r\n </ng-template>\r\n <ng-template #suffixTemplateHiddenPassword>\r\n <nz-icon\r\n nzType=\"eye-invisible\"\r\n nzTheme=\"outline\"\r\n nz-tooltip\r\n nzTooltipTitle=\"{{ 'HIDDEN' | translate }}\"\r\n nzTooltipPlacement=\"right\"\r\n (click)=\"visible = !visible; passwordType = 'password'\"\r\n />\r\n </ng-template>\r\n </nz-form-item>\r\n\r\n @if (isOneUserMultiOrgs) {\r\n <nz-form-item>\r\n <nz-form-control nzErrorTip=\"{{ 'REQUIRED' | translate }}\">\r\n <nz-input-group nzPrefixIcon=\"cluster\" nzHasFeedback=\"false\">\r\n <nz-select\r\n nzShowSearch\r\n nzAllowClear\r\n [nzBorderless]=\"true\"\r\n [nzSize]=\"'small'\"\r\n nzPlaceHolder=\"{{ 'ORG' | translate }}\"\r\n formControlName=\"orgid\"\r\n class=\"no-error-border\"\r\n (nzFocus)=\"onFocusOrg()\"\r\n >\r\n @for (item of lstOrg; track $index) {\r\n <nz-option [nzLabel]=\"item.TreeNodeName!\" [nzValue]=\"item.App_Org_Id\"></nz-option>\r\n }\r\n </nz-select>\r\n </nz-input-group>\r\n </nz-form-control>\r\n </nz-form-item>\r\n }\r\n\r\n <div nz-flex nzVertical=\"true\" nzGap=\"4px\">\r\n <button nz-button [nzType]=\"'primary'\" nzBlock [nzLoading]=\"loadingService.isLoading\">\r\n {{ \"LOGIN\" | translate }}\r\n </button>\r\n <!-- \r\n <nz-form-item nzJustify=\"end\">\r\n <nz-switch formControlName=\"langSwitch\" class=\"nz-switch-both-active-color\" nzCheckedChildren=\"VN\"\r\n nzUnCheckedChildren=\"EN\" (ngModelChange)=\"changeLanguage($event)\"></nz-switch>\r\n </nz-form-item> \r\n -->\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </form>\r\n </div>\r\n</div>\r\n\r\n<img *ngIf=\"bgUrl$ | async as url\" class=\"bg-image\" [src]=\"url\" hideIfError />\r\n", styles: [":host{display:flex;justify-content:center;align-items:center;height:80vh}.form-container{width:clamp(280px,30vw,420px);box-shadow:0 10px 20px 1px #001a2d59;background-color:#fff;padding:16px;border-radius:8px}.bg-image{position:fixed;top:0;left:0;width:100vw;height:100vh;object-fit:cover;object-position:center;z-index:-1;pointer-events:none}::ng-deep .login .ant-select-selector{height:auto!important}::ng-deep .login .ant-input-affix-wrapper,::ng-deep .login .ant-btn{border-radius:8px}\n"] }]
9294
+ NzSpinComponent,
9295
+ ], template: "<nz-spin [nzSpinning]=\"isLoading\">\r\n <div nz-row nzJustify=\"center\" class=\"login\">\r\n <div class=\"form-container\">\r\n <form nz-flex nzVertical=\"true\" nz-form [formGroup]=\"loginForm\" class=\"login-form\" (ngSubmit)=\"dologin()\">\r\n <div>\r\n <div style=\"text-align: center\">\r\n <img *ngIf=\"logoUrl$ | async as url\" width=\"150px\" [src]=\"url\" hideIfError />\r\n </div>\r\n <div class=\"form-field\" style=\"text-align: center; margin-bottom: 20px\">\r\n <h3 style=\"font-weight: bold; font-size: 20px\">{{ SYSTEM_NAME_LOGIN }}</h3>\r\n </div>\r\n </div>\r\n\r\n <div nz-row [nzJustify]=\"'center'\">\r\n <div nz-col nzSm=\"24\" nzMd=\"16\">\r\n <div nz-flex nzVertical=\"true\">\r\n <nz-form-item>\r\n <nz-form-control nzErrorTip=\"{{ 'REQUIRED' | translate }}\">\r\n <nz-input-group nzPrefixIcon=\"user\">\r\n <input type=\"text\" nz-input formControlName=\"username\" placeholder=\"{{ 'USERNAME' | translate }}\" />\r\n </nz-input-group>\r\n </nz-form-control>\r\n </nz-form-item>\r\n\r\n <nz-form-item>\r\n <nz-form-control nzErrorTip=\"{{ 'REQUIRED' | translate }}\">\r\n <nz-input-group\r\n nzPrefixIcon=\"lock\"\r\n [nzSuffix]=\"visible ? suffixTemplateHiddenPassword : suffixTemplateShowPassword\"\r\n >\r\n <input\r\n type=\"{{ passwordType }}\"\r\n nz-input\r\n formControlName=\"password\"\r\n placeholder=\"{{ 'PASSWORD' | translate }}\"\r\n />\r\n </nz-input-group>\r\n </nz-form-control>\r\n <ng-template #suffixTemplateShowPassword>\r\n <nz-icon\r\n nzType=\"eye\"\r\n nzTheme=\"outline\"\r\n nz-tooltip\r\n nzTooltipTitle=\"{{ 'SHOW' | translate }}\"\r\n nzTooltipPlacement=\"right\"\r\n (click)=\"visible = !visible; passwordType = 'text'\"\r\n />\r\n </ng-template>\r\n <ng-template #suffixTemplateHiddenPassword>\r\n <nz-icon\r\n nzType=\"eye-invisible\"\r\n nzTheme=\"outline\"\r\n nz-tooltip\r\n nzTooltipTitle=\"{{ 'HIDDEN' | translate }}\"\r\n nzTooltipPlacement=\"right\"\r\n (click)=\"visible = !visible; passwordType = 'password'\"\r\n />\r\n </ng-template>\r\n </nz-form-item>\r\n\r\n @if (isOneUserMultiOrgs) {\r\n <nz-form-item>\r\n <nz-form-control nzErrorTip=\"{{ 'REQUIRED' | translate }}\">\r\n <nz-input-group nzPrefixIcon=\"cluster\" nzHasFeedback=\"false\">\r\n <nz-select\r\n nzShowSearch\r\n nzAllowClear\r\n [nzBorderless]=\"true\"\r\n [nzSize]=\"'small'\"\r\n nzPlaceHolder=\"{{ 'ORG' | translate }}\"\r\n formControlName=\"orgid\"\r\n class=\"no-error-border\"\r\n (nzFocus)=\"onFocusOrg()\"\r\n >\r\n @for (item of lstOrg; track $index) {\r\n <nz-option [nzLabel]=\"item.TreeNodeName!\" [nzValue]=\"item.App_Org_Id\"></nz-option>\r\n }\r\n </nz-select>\r\n </nz-input-group>\r\n </nz-form-control>\r\n </nz-form-item>\r\n }\r\n\r\n <div nz-flex nzVertical=\"true\" nzGap=\"4px\">\r\n <button nz-button [nzType]=\"'primary'\" nzBlock>\r\n {{ \"LOGIN\" | translate }}\r\n </button>\r\n <!-- \r\n <nz-form-item nzJustify=\"end\">\r\n <nz-switch formControlName=\"langSwitch\" class=\"nz-switch-both-active-color\" nzCheckedChildren=\"VN\"\r\n nzUnCheckedChildren=\"EN\" (ngModelChange)=\"changeLanguage($event)\"></nz-switch>\r\n </nz-form-item> \r\n --></div>\r\n </div>\r\n </div>\r\n </div>\r\n </form>\r\n </div>\r\n </div>\r\n</nz-spin>\r\n\r\n<img *ngIf=\"bgUrl$ | async as url\" class=\"bg-image\" [src]=\"url\" hideIfError />\r\n", styles: [":host{display:flex;justify-content:center;align-items:center;height:80vh}.form-container{width:clamp(280px,30vw,420px);box-shadow:0 10px 20px 1px #001a2d59;background-color:#fff;padding:16px;border-radius:8px}.bg-image{position:fixed;top:0;left:0;width:100vw;height:100vh;object-fit:cover;object-position:center;z-index:-1;pointer-events:none}::ng-deep .login .ant-select-selector{height:auto!important}::ng-deep .login .ant-input-affix-wrapper,::ng-deep .login .ant-btn{border-radius:8px}\n"] }]
8917
9296
  }] });
8918
9297
 
8919
9298
  /**
8920
9299
  * Generated bundle index. Do not edit.
8921
9300
  */
8922
9301
 
8923
- export { ABAC_RULES_TOKEN, ActionRule, ActionRuleLine, AnimatedDigitComponent, AppGlobals, AppStorage, App_Org, AuthGuard, AuthService, AutoFocusDirective, BarGraphComponent, BaseComponent, BaseGuardChangeComponent, BaseOverlayComponent, Box, Breadcrumb, CheckModel, CommonService, CustomNotiComponent, CustomNotiService, DashcardComponent, DateInputParserDirective, DateTimeHelper, DicDomainPipe, DoughnutGraphComponent, DownloadHelper, ENUM_ResponseType, ExpandableSearchComponent, ExtendCheckbox, ExtendDatePicker, ExtendDateRangePicker, ExtendInput, ExtendInputNumber, ExtendPaginationComponent, ExtendSelectComponent, ExtendTableComponent, ExtendTextArea, GlobalSpinnerComponent, GridFilter, H3Icon, HTTPService, HasPermissionDirective, HasPermissionPipe, Height, HideIfErrorDirective, HighlightPipe, IconAdd, IconDelete, IconEdit, IconSave, IconSearch, IconView, LayoutComponent, LimitWordsPipe, LineGraphComponent, LoadingService, LoginComponent, NoPermission, NotiService, NullIfEmptyDirective, NumberOnlyDirective, OrderOption, PagingData, PagingModel, PdfViewerComponent, PermissionComponent, ReadMoreProComponent, RouteMonitorService, SessionManagerService, TableHeader, ThemeService, TokenStorage, TranslateKey, URLs$7 as URLs, UnsavedChangesGuard, UpperCaseFirsLetterEachWordDirective, UppercaseDirective, UppercaseFirstLetterDirective, VscService, WF_TemplateActionRef, WF_TransitionRule, WF_TransitionRuleLine, Width, Workflow, WorkflowAction, WorkflowActionEditorOption, WorkflowActionRef, WorkflowEditorComponent, WorkflowEditorOption, WorkflowStage, WorkflowStageEditorOption, XLSXHelper, authInterceptor };
9302
+ export { ABAC_RULES_TOKEN, ActionRule, ActionRuleLine, AnimatedDigitComponent, AppGlobals, AppStorage, App_Org, AuthGuard, AuthService, AutoFocusDirective, BarGraphComponent, BaseComponent, BaseGuardChangeComponent, BaseOverlayComponent, Box, Breadcrumb, CheckModel, CommonService, CustomNotiComponent, CustomNotiService, DashcardComponent, DateInputParserDirective, DateTimeHelper, DicDomainPipe, DoughnutGraphComponent, DownloadHelper, ENUM_ResponseType, ExpandableSearchComponent, ExtendCheckbox, ExtendDatePicker, ExtendDateRangePicker, ExtendInput, ExtendInputNumber, ExtendPaginationComponent, ExtendSelectComponent, ExtendTableComponent, ExtendTextArea, GlobalSpinnerComponent, GridFilter, H3Icon, HTTPService, HasPermissionDirective, HasPermissionPipe, Height, HideIfErrorDirective, HighlightPipe, IconAdd, IconCheck, IconClose, IconDelete, IconEdit, IconSave, IconSearch, IconView, LayoutComponent, LimitWordsPipe, LineGraphComponent, LoadingService, LoginComponent, NoPermission, NotiService, NullIfEmptyDirective, NumberOnlyDirective, OrderOption, PagingData, PagingModel, PdfViewerComponent, PermissionComponent, ReadMoreProComponent, RouteMonitorService, SessionManagerService, TableHeader, ThemeService, TokenStorage, TranslateKey, URLs$7 as URLs, UnsavedChangesGuard, UpperCaseFirsLetterEachWordDirective, UppercaseDirective, UppercaseFirstLetterDirective, VscService, WF_TemplateActionRef, WF_TransitionRule, WF_TransitionRuleLine, Width, Workflow, WorkflowAction, WorkflowActionEditorOption, WorkflowActionRef, WorkflowEditorComponent, WorkflowEditorOption, WorkflowStage, WorkflowStageEditorOption, XLSXHelper, authInterceptor };
8924
9303
  //# sourceMappingURL=brggroup-share-lib.mjs.map