@sdcorejs/angular 21.1.3 → 21.1.5

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 (168) hide show
  1. package/README.md +19 -14
  2. package/fesm2022/sdcorejs-angular-components-anchor.mjs +14 -14
  3. package/fesm2022/sdcorejs-angular-components-anchor.mjs.map +1 -1
  4. package/fesm2022/sdcorejs-angular-components-audit-diff.mjs +332 -0
  5. package/fesm2022/sdcorejs-angular-components-audit-diff.mjs.map +1 -0
  6. package/fesm2022/sdcorejs-angular-components-badge.mjs +1 -0
  7. package/fesm2022/sdcorejs-angular-components-badge.mjs.map +1 -1
  8. package/fesm2022/sdcorejs-angular-components-breadcrumb.mjs +121 -0
  9. package/fesm2022/sdcorejs-angular-components-breadcrumb.mjs.map +1 -0
  10. package/fesm2022/sdcorejs-angular-components-data-state.mjs +68 -0
  11. package/fesm2022/sdcorejs-angular-components-data-state.mjs.map +1 -0
  12. package/fesm2022/sdcorejs-angular-components-document-builder.mjs +18 -23
  13. package/fesm2022/sdcorejs-angular-components-document-builder.mjs.map +1 -1
  14. package/fesm2022/sdcorejs-angular-components-editor.mjs +6 -4
  15. package/fesm2022/sdcorejs-angular-components-editor.mjs.map +1 -1
  16. package/fesm2022/sdcorejs-angular-components-form-generic.mjs +495 -838
  17. package/fesm2022/sdcorejs-angular-components-form-generic.mjs.map +1 -1
  18. package/fesm2022/sdcorejs-angular-components-import-excel.mjs +24 -34
  19. package/fesm2022/sdcorejs-angular-components-import-excel.mjs.map +1 -1
  20. package/fesm2022/sdcorejs-angular-components-job-progress.mjs +97 -0
  21. package/fesm2022/sdcorejs-angular-components-job-progress.mjs.map +1 -0
  22. package/fesm2022/sdcorejs-angular-components-mini-editor.mjs +10 -20
  23. package/fesm2022/sdcorejs-angular-components-mini-editor.mjs.map +1 -1
  24. package/fesm2022/sdcorejs-angular-components-modal.mjs +61 -4
  25. package/fesm2022/sdcorejs-angular-components-modal.mjs.map +1 -1
  26. package/fesm2022/sdcorejs-angular-components-preview.mjs +1438 -218
  27. package/fesm2022/sdcorejs-angular-components-preview.mjs.map +1 -1
  28. package/fesm2022/sdcorejs-angular-components-query-bar.mjs +4 -4
  29. package/fesm2022/sdcorejs-angular-components-query-bar.mjs.map +1 -1
  30. package/fesm2022/sdcorejs-angular-components-query-builder.mjs +1 -1
  31. package/fesm2022/sdcorejs-angular-components-query-builder.mjs.map +1 -1
  32. package/fesm2022/sdcorejs-angular-components-side-drawer.mjs +39 -2
  33. package/fesm2022/sdcorejs-angular-components-side-drawer.mjs.map +1 -1
  34. package/fesm2022/sdcorejs-angular-components-tab-router.mjs +16 -22
  35. package/fesm2022/sdcorejs-angular-components-tab-router.mjs.map +1 -1
  36. package/fesm2022/sdcorejs-angular-components-tab.mjs +48 -4
  37. package/fesm2022/sdcorejs-angular-components-tab.mjs.map +1 -1
  38. package/fesm2022/sdcorejs-angular-components-table.mjs +96 -63
  39. package/fesm2022/sdcorejs-angular-components-table.mjs.map +1 -1
  40. package/fesm2022/sdcorejs-angular-components-tree.mjs +186 -17
  41. package/fesm2022/sdcorejs-angular-components-tree.mjs.map +1 -1
  42. package/fesm2022/sdcorejs-angular-components-upload-file.mjs +15 -22
  43. package/fesm2022/sdcorejs-angular-components-upload-file.mjs.map +1 -1
  44. package/fesm2022/sdcorejs-angular-components.mjs +4 -0
  45. package/fesm2022/sdcorejs-angular-components.mjs.map +1 -1
  46. package/fesm2022/sdcorejs-angular-directives.mjs +29 -41
  47. package/fesm2022/sdcorejs-angular-directives.mjs.map +1 -1
  48. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs +7 -7
  49. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs.map +1 -1
  50. package/fesm2022/sdcorejs-angular-forms-checkbox.mjs +20 -71
  51. package/fesm2022/sdcorejs-angular-forms-checkbox.mjs.map +1 -1
  52. package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs +6 -3
  53. package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs.map +1 -1
  54. package/fesm2022/sdcorejs-angular-forms-chip.mjs +6 -3
  55. package/fesm2022/sdcorejs-angular-forms-chip.mjs.map +1 -1
  56. package/fesm2022/sdcorejs-angular-forms-date-range.mjs +16 -13
  57. package/fesm2022/sdcorejs-angular-forms-date-range.mjs.map +1 -1
  58. package/fesm2022/sdcorejs-angular-forms-date.mjs +42 -65
  59. package/fesm2022/sdcorejs-angular-forms-date.mjs.map +1 -1
  60. package/fesm2022/sdcorejs-angular-forms-datetime.mjs +51 -66
  61. package/fesm2022/sdcorejs-angular-forms-datetime.mjs.map +1 -1
  62. package/fesm2022/sdcorejs-angular-forms-entity-picker.mjs +384 -0
  63. package/fesm2022/sdcorejs-angular-forms-entity-picker.mjs.map +1 -0
  64. package/fesm2022/sdcorejs-angular-forms-input-color.mjs +1 -1
  65. package/fesm2022/sdcorejs-angular-forms-input-color.mjs.map +1 -1
  66. package/fesm2022/sdcorejs-angular-forms-input-number.mjs +7 -5
  67. package/fesm2022/sdcorejs-angular-forms-input-number.mjs.map +1 -1
  68. package/fesm2022/sdcorejs-angular-forms-input.mjs +290 -56
  69. package/fesm2022/sdcorejs-angular-forms-input.mjs.map +1 -1
  70. package/fesm2022/sdcorejs-angular-forms-models.mjs +155 -2
  71. package/fesm2022/sdcorejs-angular-forms-models.mjs.map +1 -1
  72. package/fesm2022/sdcorejs-angular-forms-radio.mjs +44 -66
  73. package/fesm2022/sdcorejs-angular-forms-radio.mjs.map +1 -1
  74. package/fesm2022/sdcorejs-angular-forms-select.mjs +6 -20
  75. package/fesm2022/sdcorejs-angular-forms-select.mjs.map +1 -1
  76. package/fesm2022/sdcorejs-angular-forms-switch.mjs +19 -64
  77. package/fesm2022/sdcorejs-angular-forms-switch.mjs.map +1 -1
  78. package/fesm2022/sdcorejs-angular-forms-textarea.mjs +6 -5
  79. package/fesm2022/sdcorejs-angular-forms-textarea.mjs.map +1 -1
  80. package/fesm2022/sdcorejs-angular-forms-time-range.mjs +277 -0
  81. package/fesm2022/sdcorejs-angular-forms-time-range.mjs.map +1 -0
  82. package/fesm2022/sdcorejs-angular-forms-time.mjs +307 -0
  83. package/fesm2022/sdcorejs-angular-forms-time.mjs.map +1 -0
  84. package/fesm2022/sdcorejs-angular-forms-tree-select.mjs +210 -0
  85. package/fesm2022/sdcorejs-angular-forms-tree-select.mjs.map +1 -0
  86. package/fesm2022/sdcorejs-angular-forms.mjs +73 -4
  87. package/fesm2022/sdcorejs-angular-forms.mjs.map +1 -1
  88. package/fesm2022/sdcorejs-angular-i18n.mjs +375 -10
  89. package/fesm2022/sdcorejs-angular-i18n.mjs.map +1 -1
  90. package/fesm2022/sdcorejs-angular-interceptors.mjs +12 -17
  91. package/fesm2022/sdcorejs-angular-interceptors.mjs.map +1 -1
  92. package/fesm2022/sdcorejs-angular-modules-layout.mjs +994 -168
  93. package/fesm2022/sdcorejs-angular-modules-layout.mjs.map +1 -1
  94. package/fesm2022/sdcorejs-angular-pipes.mjs +5 -7
  95. package/fesm2022/sdcorejs-angular-pipes.mjs.map +1 -1
  96. package/fesm2022/sdcorejs-angular-services-api.mjs +407 -137
  97. package/fesm2022/sdcorejs-angular-services-api.mjs.map +1 -1
  98. package/fesm2022/sdcorejs-angular-services-cache.mjs +515 -105
  99. package/fesm2022/sdcorejs-angular-services-cache.mjs.map +1 -1
  100. package/fesm2022/sdcorejs-angular-services-confirm.mjs +5 -7
  101. package/fesm2022/sdcorejs-angular-services-confirm.mjs.map +1 -1
  102. package/fesm2022/sdcorejs-angular-services-docx.mjs +7 -10
  103. package/fesm2022/sdcorejs-angular-services-docx.mjs.map +1 -1
  104. package/fesm2022/sdcorejs-angular-services-loading.mjs +339 -74
  105. package/fesm2022/sdcorejs-angular-services-loading.mjs.map +1 -1
  106. package/fesm2022/sdcorejs-angular-services-notify.mjs +7 -10
  107. package/fesm2022/sdcorejs-angular-services-notify.mjs.map +1 -1
  108. package/fesm2022/sdcorejs-angular-services-persistence.mjs +899 -0
  109. package/fesm2022/sdcorejs-angular-services-persistence.mjs.map +1 -0
  110. package/fesm2022/sdcorejs-angular-services-storage.mjs +324 -122
  111. package/fesm2022/sdcorejs-angular-services-storage.mjs.map +1 -1
  112. package/fesm2022/sdcorejs-angular-services-task.mjs +389 -0
  113. package/fesm2022/sdcorejs-angular-services-task.mjs.map +1 -0
  114. package/fesm2022/sdcorejs-angular-services-unsaved-changes.mjs +255 -0
  115. package/fesm2022/sdcorejs-angular-services-unsaved-changes.mjs.map +1 -0
  116. package/fesm2022/sdcorejs-angular-services-viewport.mjs +76 -0
  117. package/fesm2022/sdcorejs-angular-services-viewport.mjs.map +1 -0
  118. package/fesm2022/sdcorejs-angular-services.mjs +4 -0
  119. package/fesm2022/sdcorejs-angular-services.mjs.map +1 -1
  120. package/package.json +49 -1
  121. package/types/sdcorejs-angular-components-audit-diff.d.ts +74 -0
  122. package/types/sdcorejs-angular-components-badge.d.ts +1 -1
  123. package/types/sdcorejs-angular-components-breadcrumb.d.ts +53 -0
  124. package/types/sdcorejs-angular-components-data-state.d.ts +44 -0
  125. package/types/sdcorejs-angular-components-document-builder.d.ts +5 -5
  126. package/types/sdcorejs-angular-components-form-generic.d.ts +67 -104
  127. package/types/sdcorejs-angular-components-import-excel.d.ts +4 -14
  128. package/types/sdcorejs-angular-components-job-progress.d.ts +38 -0
  129. package/types/sdcorejs-angular-components-mini-editor.d.ts +9 -9
  130. package/types/sdcorejs-angular-components-modal.d.ts +7 -1
  131. package/types/sdcorejs-angular-components-preview.d.ts +181 -28
  132. package/types/sdcorejs-angular-components-side-drawer.d.ts +7 -1
  133. package/types/sdcorejs-angular-components-tab.d.ts +9 -2
  134. package/types/sdcorejs-angular-components-table.d.ts +8 -7
  135. package/types/sdcorejs-angular-components-tree.d.ts +24 -2
  136. package/types/sdcorejs-angular-components-upload-file.d.ts +5 -4
  137. package/types/sdcorejs-angular-components.d.ts +4 -0
  138. package/types/sdcorejs-angular-directives.d.ts +10 -8
  139. package/types/sdcorejs-angular-forms-autocomplete.d.ts +3 -4
  140. package/types/sdcorejs-angular-forms-checkbox.d.ts +4 -8
  141. package/types/sdcorejs-angular-forms-date-range.d.ts +6 -7
  142. package/types/sdcorejs-angular-forms-date.d.ts +2 -2
  143. package/types/sdcorejs-angular-forms-datetime.d.ts +2 -2
  144. package/types/sdcorejs-angular-forms-entity-picker.d.ts +128 -0
  145. package/types/sdcorejs-angular-forms-input-number.d.ts +1 -1
  146. package/types/sdcorejs-angular-forms-input.d.ts +74 -11
  147. package/types/sdcorejs-angular-forms-models.d.ts +86 -3
  148. package/types/sdcorejs-angular-forms-radio.d.ts +12 -8
  149. package/types/sdcorejs-angular-forms-switch.d.ts +4 -7
  150. package/types/sdcorejs-angular-forms-time-range.d.ts +98 -0
  151. package/types/sdcorejs-angular-forms-time.d.ts +117 -0
  152. package/types/sdcorejs-angular-forms-tree-select.d.ts +76 -0
  153. package/types/sdcorejs-angular-forms.d.ts +15 -5
  154. package/types/sdcorejs-angular-i18n.d.ts +72 -2
  155. package/types/sdcorejs-angular-interceptors.d.ts +5 -6
  156. package/types/sdcorejs-angular-modules-layout.d.ts +354 -17
  157. package/types/sdcorejs-angular-pipes.d.ts +2 -2
  158. package/types/sdcorejs-angular-services-api.d.ts +68 -24
  159. package/types/sdcorejs-angular-services-cache.d.ts +52 -16
  160. package/types/sdcorejs-angular-services-confirm.d.ts +3 -2
  161. package/types/sdcorejs-angular-services-docx.d.ts +2 -3
  162. package/types/sdcorejs-angular-services-loading.d.ts +16 -8
  163. package/types/sdcorejs-angular-services-persistence.d.ts +159 -0
  164. package/types/sdcorejs-angular-services-storage.d.ts +26 -8
  165. package/types/sdcorejs-angular-services-task.d.ts +104 -0
  166. package/types/sdcorejs-angular-services-unsaved-changes.d.ts +83 -0
  167. package/types/sdcorejs-angular-services-viewport.d.ts +42 -0
  168. package/types/sdcorejs-angular-services.d.ts +4 -0
@@ -17,11 +17,13 @@ class SdSideDrawer {
17
17
  width = input('480px', ...(ngDevMode ? [{ debugName: "width" }] : /* istanbul ignore next */ []));
18
18
  hideClose = input(false, { ...(ngDevMode ? { debugName: "hideClose" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
19
19
  disableBackdropClose = input(false, { ...(ngDevMode ? { debugName: "disableBackdropClose" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
20
+ beforeClose = input(undefined, ...(ngDevMode ? [{ debugName: "beforeClose" }] : /* istanbul ignore next */ []));
20
21
  // Custom CSS class added to the root side-drawer container
21
22
  drawerClass = input('', ...(ngDevMode ? [{ debugName: "drawerClass" }] : /* istanbul ignore next */ []));
22
23
  autoIdInput = input(undefined, { ...(ngDevMode ? { debugName: "autoIdInput" } : /* istanbul ignore next */ {}), alias: 'autoId' });
23
24
  autoId = computed(() => (this.autoIdInput() ? `components-side-drawer-${this.autoIdInput()}` : undefined), ...(ngDevMode ? [{ debugName: "autoId" }] : /* istanbul ignore next */ []));
24
25
  sdClosed = output();
26
+ sdCloseError = output();
25
27
  #embeddedViewRef;
26
28
  #isOpenedSignal = signal(false, ...(ngDevMode ? [{ debugName: "#isOpenedSignal" }] : /* istanbul ignore next */ []));
27
29
  #isLoadingSignal = signal(false, ...(ngDevMode ? [{ debugName: "#isLoadingSignal" }] : /* istanbul ignore next */ []));
@@ -32,6 +34,7 @@ class SdSideDrawer {
32
34
  isHovered$;
33
35
  #destroy$ = new Subject();
34
36
  #previousBodyOverflow = null;
37
+ #closeRequest;
35
38
  #viewContainerRef = inject(ViewContainerRef);
36
39
  #ar = inject(ApplicationRef);
37
40
  #injector = inject(Injector);
@@ -72,6 +75,40 @@ class SdSideDrawer {
72
75
  document.body.style.overflow = 'hidden';
73
76
  };
74
77
  close = () => {
78
+ if (this.beforeClose()) {
79
+ void this.requestClose();
80
+ return;
81
+ }
82
+ this.forceClose();
83
+ };
84
+ requestClose = () => {
85
+ const guard = this.beforeClose();
86
+ if (!guard) {
87
+ this.forceClose();
88
+ return Promise.resolve(true);
89
+ }
90
+ if (this.#closeRequest)
91
+ return this.#closeRequest;
92
+ const request = Promise.resolve()
93
+ .then(() => guard())
94
+ .then(canClose => {
95
+ if (!canClose)
96
+ return false;
97
+ this.forceClose();
98
+ return true;
99
+ })
100
+ .catch((error) => {
101
+ this.sdCloseError.emit(error);
102
+ return false;
103
+ });
104
+ this.#closeRequest = request;
105
+ void request.finally(() => {
106
+ if (this.#closeRequest === request)
107
+ this.#closeRequest = undefined;
108
+ });
109
+ return request;
110
+ };
111
+ forceClose = () => {
75
112
  this.#ref.markForCheck();
76
113
  this.#isOpenedSignal.set(false);
77
114
  this.sdClosed.emit();
@@ -113,12 +150,12 @@ class SdSideDrawer {
113
150
  this.isHovered$ = merge(mouseEnter$, mouseLeave$).pipe(startWith(false), distinctUntilChanged(), takeUntil(this.#destroy$));
114
151
  }
115
152
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdSideDrawer, deps: [], target: i0.ɵɵFactoryTarget.Component });
116
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SdSideDrawer, isStandalone: true, selector: "sd-side-drawer", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, hideClose: { classPropertyName: "hideClose", publicName: "hideClose", isSignal: true, isRequired: false, transformFunction: null }, disableBackdropClose: { classPropertyName: "disableBackdropClose", publicName: "disableBackdropClose", isSignal: true, isRequired: false, transformFunction: null }, drawerClass: { classPropertyName: "drawerClass", publicName: "drawerClass", isSignal: true, isRequired: false, transformFunction: null }, autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sdClosed: "sdClosed" }, viewQueries: [{ propertyName: "portal", first: true, predicate: CdkPortal, descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template cdkPortal>\n @let _isOpened = isOpened();\n <div\n [id]=\"id\"\n class=\"sd-side-drawer\"\n [ngStyle]=\"{ width: width() }\"\n [ngClass]=\"drawerClass()\"\n [class.sd-side-drawer-active]=\"_isOpened\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-opened]=\"dataOpened()\"\n [attr.data-loading]=\"dataLoading()\"\n #drawerContainer>\n @if (_isOpened) {\n <ng-container>\n <div class=\"sd-side-drawer-header\">\n <div class=\"sd-side-drawer-header-left\">\n <ng-content select=\"[sdHeaderLeft]\">\n <div class=\"sd-side-drawer-title\">{{ title() }}</div>\n </ng-content>\n </div>\n <div class=\"sd-side-drawer-header-right\">\n <ng-content select=\"[sdHeaderRight]\"></ng-content>\n @if (!hideClose()) {\n <button type=\"button\" class=\"sd-side-drawer-close-btn\" (click)=\"close()\" aria-label=\"Close\">\n <sd-icon name=\"close\"></sd-icon>\n </button>\n }\n </div>\n </div>\n @if (_isOpened) {\n <div class=\"sd-side-drawer-body\">\n <div class=\"sd-side-drawer-content\">\n <ng-content></ng-content>\n </div>\n </div>\n }\n <div class=\"sd-side-drawer-footer\">\n <div class=\"sd-side-drawer-footer-left\"><ng-content select=\"[sdFooterLeft]\"></ng-content></div>\n <div class=\"sd-side-drawer-footer-right\"><ng-content select=\"[sdFooterRight]\"></ng-content></div>\n </div>\n </ng-container>\n }\n </div>\n @if (_isOpened) {\n <div\n aria-hidden=\"true\"\n class=\"sd-side-drawer-backdrop\"\n (click)=\"disableBackdropClose() ? null : close()\"\n (wheel)=\"preventScroll($event)\"\n (touchmove)=\"preventScroll($event)\"></div>\n }\n</ng-template>\n", styles: [".sd-side-drawer{--sd-side-drawer-inset: 10px;--sd-side-drawer-radius: var(--sd-overlay-radius, 24px);--sd-side-drawer-surface: var(--sd-surface, #fff);--sd-side-drawer-border: var(--sd-border, #dde0e5);--sd-side-drawer-shadow: 0 6px 18px rgba(15, 23, 42, .18), 0 1px 3px rgba(15, 23, 42, .12);position:fixed;right:var(--sd-side-drawer-inset);top:var(--sd-side-drawer-inset);bottom:var(--sd-side-drawer-inset);max-width:calc(100vw - var(--sd-side-drawer-inset) - var(--sd-side-drawer-inset));background-color:var(--sd-side-drawer-surface);color:var(--sd-text);z-index:999;display:flex;flex-direction:column;opacity:0;visibility:hidden;transform:translate3d(calc(100% + var(--sd-side-drawer-inset)),0,0);transition:all .3s ease-in-out;pointer-events:none;overflow:hidden;border-radius:var(--sd-side-drawer-radius);box-shadow:var(--sd-side-drawer-shadow)}.sd-side-drawer-active{opacity:1;visibility:visible;pointer-events:all;transform:translateZ(0)}.sd-side-drawer-header{min-height:64px;padding:16px;display:flex;align-items:center;justify-content:space-between;gap:16px}.sd-side-drawer-header-left{display:flex;align-items:center;flex:1 1 auto;min-width:0}.sd-side-drawer-header-right{display:flex;align-items:center;gap:8px;flex:0 0 auto}.sd-side-drawer-title{font-size:20px;line-height:28px;font-weight:500;min-width:0}.sd-side-drawer-close-btn{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;box-sizing:border-box;width:32px;height:32px;padding:0;border:0;border-radius:50%;background:transparent;color:var(--sd-text-secondary);line-height:0;cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;transition:background-color 80ms ease,color 80ms ease}.sd-side-drawer-close-btn:hover{background:var(--sd-surface-muted);color:var(--sd-text)}.sd-side-drawer-close-btn:active{background:var(--sd-border)}.sd-side-drawer-close-btn:focus{outline:none}.sd-side-drawer-close-btn:focus-visible{outline:2px solid var(--sd-primary);outline-offset:2px}.sd-side-drawer-close-btn sd-icon{display:block;width:20px;height:20px;font-size:20px;line-height:20px}.sd-side-drawer-body{flex:1;position:relative}.sd-side-drawer-content{position:absolute;padding:0;inset:0;overflow:auto}.sd-side-drawer-footer{border-top:1px solid var(--sd-side-drawer-border);padding:16px;background-color:var(--sd-side-drawer-surface);display:flex;align-items:center;justify-content:space-between;gap:16px}.sd-side-drawer-footer-left,.sd-side-drawer-footer-right{display:flex;align-items:center;gap:8px;min-width:0}.sd-side-drawer-footer-left{flex:1 1 auto}.sd-side-drawer-footer-right{flex:0 0 auto;margin-left:auto;justify-content:flex-end}.sd-side-drawer-footer-left:empty,.sd-side-drawer-footer-right:empty{display:none}.sd-side-drawer-footer:has(.sd-side-drawer-footer-left:empty):has(.sd-side-drawer-footer-right:empty){display:none}.sd-side-drawer-backdrop{background-color:#0006;border:0;outline:none!important;position:fixed;inset:0;z-index:99;width:100%;height:100%;transition:all .3s ease-in-out}\n"], dependencies: [{ kind: "component", type: SdIcon, selector: "sd-icon", inputs: ["name", "fontIcon", "color", "set", "fontSet", "size", "strokeWidth", "absoluteStrokeWidth", "ariaLabel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: PortalModule }, { kind: "directive", type: i2.CdkPortal, selector: "[cdkPortal]", exportAs: ["cdkPortal"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
153
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SdSideDrawer, isStandalone: true, selector: "sd-side-drawer", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, hideClose: { classPropertyName: "hideClose", publicName: "hideClose", isSignal: true, isRequired: false, transformFunction: null }, disableBackdropClose: { classPropertyName: "disableBackdropClose", publicName: "disableBackdropClose", isSignal: true, isRequired: false, transformFunction: null }, beforeClose: { classPropertyName: "beforeClose", publicName: "beforeClose", isSignal: true, isRequired: false, transformFunction: null }, drawerClass: { classPropertyName: "drawerClass", publicName: "drawerClass", isSignal: true, isRequired: false, transformFunction: null }, autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sdClosed: "sdClosed", sdCloseError: "sdCloseError" }, viewQueries: [{ propertyName: "portal", first: true, predicate: CdkPortal, descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template cdkPortal>\n @let _isOpened = isOpened();\n <div\n [id]=\"id\"\n class=\"sd-side-drawer\"\n [ngStyle]=\"{ width: width() }\"\n [ngClass]=\"drawerClass()\"\n [class.sd-side-drawer-active]=\"_isOpened\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-opened]=\"dataOpened()\"\n [attr.data-loading]=\"dataLoading()\"\n #drawerContainer>\n @if (_isOpened) {\n <ng-container>\n <div class=\"sd-side-drawer-header\">\n <div class=\"sd-side-drawer-header-left\">\n <ng-content select=\"[sdHeaderLeft]\">\n <div class=\"sd-side-drawer-title\">{{ title() }}</div>\n </ng-content>\n </div>\n <div class=\"sd-side-drawer-header-right\">\n <ng-content select=\"[sdHeaderRight]\"></ng-content>\n @if (!hideClose()) {\n <button type=\"button\" class=\"sd-side-drawer-close-btn\" (click)=\"close()\" aria-label=\"Close\">\n <sd-icon name=\"close\"></sd-icon>\n </button>\n }\n </div>\n </div>\n @if (_isOpened) {\n <div class=\"sd-side-drawer-body\">\n <div class=\"sd-side-drawer-content\">\n <ng-content></ng-content>\n </div>\n </div>\n }\n <div class=\"sd-side-drawer-footer\">\n <div class=\"sd-side-drawer-footer-left\"><ng-content select=\"[sdFooterLeft]\"></ng-content></div>\n <div class=\"sd-side-drawer-footer-right\"><ng-content select=\"[sdFooterRight]\"></ng-content></div>\n </div>\n </ng-container>\n }\n </div>\n @if (_isOpened) {\n <div\n aria-hidden=\"true\"\n class=\"sd-side-drawer-backdrop\"\n (click)=\"disableBackdropClose() ? null : close()\"\n (wheel)=\"preventScroll($event)\"\n (touchmove)=\"preventScroll($event)\"></div>\n }\n</ng-template>\n", styles: [".sd-side-drawer{--sd-side-drawer-inset: 10px;--sd-side-drawer-radius: var(--sd-overlay-radius, 24px);--sd-side-drawer-surface: var(--sd-surface, #fff);--sd-side-drawer-border: var(--sd-border, #dde0e5);--sd-side-drawer-shadow: 0 6px 18px rgba(15, 23, 42, .18), 0 1px 3px rgba(15, 23, 42, .12);position:fixed;right:var(--sd-side-drawer-inset);top:var(--sd-side-drawer-inset);bottom:var(--sd-side-drawer-inset);max-width:calc(100vw - var(--sd-side-drawer-inset) - var(--sd-side-drawer-inset));background-color:var(--sd-side-drawer-surface);color:var(--sd-text);z-index:999;display:flex;flex-direction:column;opacity:0;visibility:hidden;transform:translate3d(calc(100% + var(--sd-side-drawer-inset)),0,0);transition:all .3s ease-in-out;pointer-events:none;overflow:hidden;border-radius:var(--sd-side-drawer-radius);box-shadow:var(--sd-side-drawer-shadow)}.sd-side-drawer-active{opacity:1;visibility:visible;pointer-events:all;transform:translateZ(0)}.sd-side-drawer-header{min-height:64px;padding:16px;display:flex;align-items:center;justify-content:space-between;gap:16px}.sd-side-drawer-header-left{display:flex;align-items:center;flex:1 1 auto;min-width:0}.sd-side-drawer-header-right{display:flex;align-items:center;gap:8px;flex:0 0 auto}.sd-side-drawer-title{font-size:20px;line-height:28px;font-weight:500;min-width:0}.sd-side-drawer-close-btn{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;box-sizing:border-box;width:32px;height:32px;padding:0;border:0;border-radius:50%;background:transparent;color:var(--sd-text-secondary);line-height:0;cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;transition:background-color 80ms ease,color 80ms ease}.sd-side-drawer-close-btn:hover{background:var(--sd-surface-muted);color:var(--sd-text)}.sd-side-drawer-close-btn:active{background:var(--sd-border)}.sd-side-drawer-close-btn:focus{outline:none}.sd-side-drawer-close-btn:focus-visible{outline:2px solid var(--sd-primary);outline-offset:2px}.sd-side-drawer-close-btn sd-icon{display:block;width:20px;height:20px;font-size:20px;line-height:20px}.sd-side-drawer-body{flex:1;position:relative}.sd-side-drawer-content{position:absolute;padding:0;inset:0;overflow:auto}.sd-side-drawer-footer{border-top:1px solid var(--sd-side-drawer-border);padding:16px;background-color:var(--sd-side-drawer-surface);display:flex;align-items:center;justify-content:space-between;gap:16px}.sd-side-drawer-footer-left,.sd-side-drawer-footer-right{display:flex;align-items:center;gap:8px;min-width:0}.sd-side-drawer-footer-left{flex:1 1 auto}.sd-side-drawer-footer-right{flex:0 0 auto;margin-left:auto;justify-content:flex-end}.sd-side-drawer-footer-left:empty,.sd-side-drawer-footer-right:empty{display:none}.sd-side-drawer-footer:has(.sd-side-drawer-footer-left:empty):has(.sd-side-drawer-footer-right:empty){display:none}.sd-side-drawer-backdrop{background-color:#0006;border:0;outline:none!important;position:fixed;inset:0;z-index:99;width:100%;height:100%;transition:all .3s ease-in-out}\n"], dependencies: [{ kind: "component", type: SdIcon, selector: "sd-icon", inputs: ["name", "fontIcon", "color", "set", "fontSet", "size", "strokeWidth", "absoluteStrokeWidth", "ariaLabel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: PortalModule }, { kind: "directive", type: i2.CdkPortal, selector: "[cdkPortal]", exportAs: ["cdkPortal"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
117
154
  }
118
155
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdSideDrawer, decorators: [{
119
156
  type: Component,
120
157
  args: [{ selector: 'sd-side-drawer', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [SdIcon, CommonModule, PortalModule], template: "<ng-template cdkPortal>\n @let _isOpened = isOpened();\n <div\n [id]=\"id\"\n class=\"sd-side-drawer\"\n [ngStyle]=\"{ width: width() }\"\n [ngClass]=\"drawerClass()\"\n [class.sd-side-drawer-active]=\"_isOpened\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-opened]=\"dataOpened()\"\n [attr.data-loading]=\"dataLoading()\"\n #drawerContainer>\n @if (_isOpened) {\n <ng-container>\n <div class=\"sd-side-drawer-header\">\n <div class=\"sd-side-drawer-header-left\">\n <ng-content select=\"[sdHeaderLeft]\">\n <div class=\"sd-side-drawer-title\">{{ title() }}</div>\n </ng-content>\n </div>\n <div class=\"sd-side-drawer-header-right\">\n <ng-content select=\"[sdHeaderRight]\"></ng-content>\n @if (!hideClose()) {\n <button type=\"button\" class=\"sd-side-drawer-close-btn\" (click)=\"close()\" aria-label=\"Close\">\n <sd-icon name=\"close\"></sd-icon>\n </button>\n }\n </div>\n </div>\n @if (_isOpened) {\n <div class=\"sd-side-drawer-body\">\n <div class=\"sd-side-drawer-content\">\n <ng-content></ng-content>\n </div>\n </div>\n }\n <div class=\"sd-side-drawer-footer\">\n <div class=\"sd-side-drawer-footer-left\"><ng-content select=\"[sdFooterLeft]\"></ng-content></div>\n <div class=\"sd-side-drawer-footer-right\"><ng-content select=\"[sdFooterRight]\"></ng-content></div>\n </div>\n </ng-container>\n }\n </div>\n @if (_isOpened) {\n <div\n aria-hidden=\"true\"\n class=\"sd-side-drawer-backdrop\"\n (click)=\"disableBackdropClose() ? null : close()\"\n (wheel)=\"preventScroll($event)\"\n (touchmove)=\"preventScroll($event)\"></div>\n }\n</ng-template>\n", styles: [".sd-side-drawer{--sd-side-drawer-inset: 10px;--sd-side-drawer-radius: var(--sd-overlay-radius, 24px);--sd-side-drawer-surface: var(--sd-surface, #fff);--sd-side-drawer-border: var(--sd-border, #dde0e5);--sd-side-drawer-shadow: 0 6px 18px rgba(15, 23, 42, .18), 0 1px 3px rgba(15, 23, 42, .12);position:fixed;right:var(--sd-side-drawer-inset);top:var(--sd-side-drawer-inset);bottom:var(--sd-side-drawer-inset);max-width:calc(100vw - var(--sd-side-drawer-inset) - var(--sd-side-drawer-inset));background-color:var(--sd-side-drawer-surface);color:var(--sd-text);z-index:999;display:flex;flex-direction:column;opacity:0;visibility:hidden;transform:translate3d(calc(100% + var(--sd-side-drawer-inset)),0,0);transition:all .3s ease-in-out;pointer-events:none;overflow:hidden;border-radius:var(--sd-side-drawer-radius);box-shadow:var(--sd-side-drawer-shadow)}.sd-side-drawer-active{opacity:1;visibility:visible;pointer-events:all;transform:translateZ(0)}.sd-side-drawer-header{min-height:64px;padding:16px;display:flex;align-items:center;justify-content:space-between;gap:16px}.sd-side-drawer-header-left{display:flex;align-items:center;flex:1 1 auto;min-width:0}.sd-side-drawer-header-right{display:flex;align-items:center;gap:8px;flex:0 0 auto}.sd-side-drawer-title{font-size:20px;line-height:28px;font-weight:500;min-width:0}.sd-side-drawer-close-btn{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;box-sizing:border-box;width:32px;height:32px;padding:0;border:0;border-radius:50%;background:transparent;color:var(--sd-text-secondary);line-height:0;cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;transition:background-color 80ms ease,color 80ms ease}.sd-side-drawer-close-btn:hover{background:var(--sd-surface-muted);color:var(--sd-text)}.sd-side-drawer-close-btn:active{background:var(--sd-border)}.sd-side-drawer-close-btn:focus{outline:none}.sd-side-drawer-close-btn:focus-visible{outline:2px solid var(--sd-primary);outline-offset:2px}.sd-side-drawer-close-btn sd-icon{display:block;width:20px;height:20px;font-size:20px;line-height:20px}.sd-side-drawer-body{flex:1;position:relative}.sd-side-drawer-content{position:absolute;padding:0;inset:0;overflow:auto}.sd-side-drawer-footer{border-top:1px solid var(--sd-side-drawer-border);padding:16px;background-color:var(--sd-side-drawer-surface);display:flex;align-items:center;justify-content:space-between;gap:16px}.sd-side-drawer-footer-left,.sd-side-drawer-footer-right{display:flex;align-items:center;gap:8px;min-width:0}.sd-side-drawer-footer-left{flex:1 1 auto}.sd-side-drawer-footer-right{flex:0 0 auto;margin-left:auto;justify-content:flex-end}.sd-side-drawer-footer-left:empty,.sd-side-drawer-footer-right:empty{display:none}.sd-side-drawer-footer:has(.sd-side-drawer-footer-left:empty):has(.sd-side-drawer-footer-right:empty){display:none}.sd-side-drawer-backdrop{background-color:#0006;border:0;outline:none!important;position:fixed;inset:0;z-index:99;width:100%;height:100%;transition:all .3s ease-in-out}\n"] }]
121
- }], ctorParameters: () => [], propDecorators: { portal: [{ type: i0.ViewChild, args: [i0.forwardRef(() => CdkPortal), { isSignal: true }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], hideClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideClose", required: false }] }], disableBackdropClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "disableBackdropClose", required: false }] }], drawerClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "drawerClass", required: false }] }], autoIdInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoId", required: false }] }], sdClosed: [{ type: i0.Output, args: ["sdClosed"] }] } });
158
+ }], ctorParameters: () => [], propDecorators: { portal: [{ type: i0.ViewChild, args: [i0.forwardRef(() => CdkPortal), { isSignal: true }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], hideClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideClose", required: false }] }], disableBackdropClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "disableBackdropClose", required: false }] }], beforeClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "beforeClose", required: false }] }], drawerClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "drawerClass", required: false }] }], autoIdInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoId", required: false }] }], sdClosed: [{ type: i0.Output, args: ["sdClosed"] }], sdCloseError: [{ type: i0.Output, args: ["sdCloseError"] }] } });
122
159
 
123
160
  /**
124
161
  * Generated bundle index. Do not edit.
@@ -1 +1 @@
1
- {"version":3,"file":"sdcorejs-angular-components-side-drawer.mjs","sources":["../../../projects/sdcorejs-angular/components/side-drawer/src/side-drawer.component.ts","../../../projects/sdcorejs-angular/components/side-drawer/src/side-drawer.component.html","../../../projects/sdcorejs-angular/components/side-drawer/sdcorejs-angular-components-side-drawer.ts"],"sourcesContent":["import { CdkPortal, DomPortalOutlet, PortalModule } from '@angular/cdk/portal';\nimport { CommonModule } from '@angular/common';\nimport {\n ApplicationRef,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n DestroyRef,\n EmbeddedViewRef,\n Injector,\n ViewContainerRef,\n afterNextRender,\n booleanAttribute,\n computed,\n inject,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { SdLoadingService } from '@sdcorejs/angular/services';\nimport { Utilities } from '@sdcorejs/utils/fns';\nimport { fromEvent, merge, Observable, Subject } from 'rxjs';\nimport { map, takeUntil, startWith, distinctUntilChanged } from 'rxjs/operators';\nimport { SdIcon } from '@sdcorejs/angular/modules/icon';\n\n@Component({\n selector: 'sd-side-drawer',\n templateUrl: './side-drawer.component.html',\n styleUrl: './side-drawer.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [SdIcon, CommonModule, PortalModule],\n})\nexport class SdSideDrawer {\n id = `I${Utilities.generateUuid()}`;\n\n portal = viewChild.required(CdkPortal);\n\n title = input<string>('');\n width = input<string>('480px');\n hideClose = input<boolean, boolean | ''>(false, { transform: booleanAttribute });\n disableBackdropClose = input<boolean, boolean | ''>(false, { transform: booleanAttribute });\n\n // Custom CSS class added to the root side-drawer container\n drawerClass = input<any>('');\n\n readonly autoIdInput = input<string | undefined | null>(undefined, { alias: 'autoId' });\n readonly autoId = computed(() => (this.autoIdInput() ? `components-side-drawer-${this.autoIdInput()}` : undefined));\n\n sdClosed = output<void>();\n\n #embeddedViewRef!: EmbeddedViewRef<any>;\n\n readonly #isOpenedSignal = signal(false);\n readonly #isLoadingSignal = signal(false);\n readonly isOpened = this.#isOpenedSignal.asReadonly();\n readonly isLoading = this.#isLoadingSignal.asReadonly();\n readonly dataOpened = computed(() => (this.#isOpenedSignal() ? 'true' : 'false'));\n readonly dataLoading = computed(() => (this.#isLoadingSignal() ? 'true' : 'false'));\n\n isHovered$!: Observable<boolean>;\n #destroy$ = new Subject<void>();\n #previousBodyOverflow: string | null = null;\n\n #viewContainerRef = inject(ViewContainerRef);\n #ar = inject(ApplicationRef);\n #injector = inject(Injector);\n #ref = inject(ChangeDetectorRef);\n #loadingService = inject(SdLoadingService);\n #destroyRef = inject(DestroyRef);\n\n constructor() {\n // Thay thế ngAfterViewInit, tự động chạy nội dung này khi DOM sẵn sàng để render\n afterNextRender(() => {\n // 1. Gắn portal vào body và lưu lại EmbeddedViewRef\n const outlet = new DomPortalOutlet(document.body, this.#ar, this.#injector);\n this.#embeddedViewRef = outlet.attachTemplatePortal(this.portal());\n\n // 2. Setup sự kiện hover ngay sau khi DOM thật đã được in ra\n this.#setupHoverSubscription();\n });\n\n // Thay thế ngOnDestroy bằng logic destroy trực tiếp\n this.#destroyRef.onDestroy(() => {\n this.#destroy$.next();\n this.#destroy$.complete();\n\n if (this.#embeddedViewRef) {\n this.#embeddedViewRef.destroy();\n }\n\n if (this.#isOpenedSignal()) {\n if (this.#previousBodyOverflow !== null) {\n document.body.style.overflow = this.#previousBodyOverflow;\n } else {\n document.body.style.overflow = '';\n }\n }\n });\n }\n\n open = () => {\n this.#ref.markForCheck();\n this.#isOpenedSignal.set(true);\n\n // Chặn scroll ở document body\n this.#previousBodyOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n };\n\n close = () => {\n this.#ref.markForCheck();\n this.#isOpenedSignal.set(false);\n this.sdClosed.emit();\n this.stopLoading();\n\n // Khôi phục lại scroll ở document body\n if (this.#previousBodyOverflow !== null) {\n document.body.style.overflow = this.#previousBodyOverflow;\n this.#previousBodyOverflow = null;\n } else {\n document.body.style.overflow = '';\n }\n };\n\n startLoading = () => {\n this.#isLoadingSignal.set(true);\n this.#loadingService.stop(`#${this.id}`);\n this.#loadingService.start(`#${this.id}`);\n };\n\n stopLoading = () => {\n this.#isLoadingSignal.set(false);\n this.#loadingService.stop(`#${this.id}`);\n };\n\n preventScroll = (event: Event) => {\n event.preventDefault();\n };\n\n #setupHoverSubscription(): void {\n if (!this.#embeddedViewRef) return;\n\n // 3. Lấy DOM element trực tiếp từ rootNodes của EmbeddedViewRef\n const rootNodes = this.#embeddedViewRef.rootNodes;\n const element = rootNodes.find(\n node => node.nodeType === Node.ELEMENT_NODE && (node as HTMLElement).classList?.contains('sd-side-drawer')\n );\n\n if (!element) {\n console.warn('SdSideDrawer: Cannot find sd-side-drawer element to attach hover event');\n return;\n }\n\n // 4. Gắn event listeners trực tiếp lên element thật\n const mouseEnter$ = fromEvent(element, 'mouseenter').pipe(map(() => true));\n const mouseLeave$ = fromEvent(element, 'mouseleave').pipe(map(() => false));\n\n this.isHovered$ = merge(mouseEnter$, mouseLeave$).pipe(startWith(false), distinctUntilChanged(), takeUntil(this.#destroy$));\n }\n}\n","<ng-template cdkPortal>\n @let _isOpened = isOpened();\n <div\n [id]=\"id\"\n class=\"sd-side-drawer\"\n [ngStyle]=\"{ width: width() }\"\n [ngClass]=\"drawerClass()\"\n [class.sd-side-drawer-active]=\"_isOpened\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-opened]=\"dataOpened()\"\n [attr.data-loading]=\"dataLoading()\"\n #drawerContainer>\n @if (_isOpened) {\n <ng-container>\n <div class=\"sd-side-drawer-header\">\n <div class=\"sd-side-drawer-header-left\">\n <ng-content select=\"[sdHeaderLeft]\">\n <div class=\"sd-side-drawer-title\">{{ title() }}</div>\n </ng-content>\n </div>\n <div class=\"sd-side-drawer-header-right\">\n <ng-content select=\"[sdHeaderRight]\"></ng-content>\n @if (!hideClose()) {\n <button type=\"button\" class=\"sd-side-drawer-close-btn\" (click)=\"close()\" aria-label=\"Close\">\n <sd-icon name=\"close\"></sd-icon>\n </button>\n }\n </div>\n </div>\n @if (_isOpened) {\n <div class=\"sd-side-drawer-body\">\n <div class=\"sd-side-drawer-content\">\n <ng-content></ng-content>\n </div>\n </div>\n }\n <div class=\"sd-side-drawer-footer\">\n <div class=\"sd-side-drawer-footer-left\"><ng-content select=\"[sdFooterLeft]\"></ng-content></div>\n <div class=\"sd-side-drawer-footer-right\"><ng-content select=\"[sdFooterRight]\"></ng-content></div>\n </div>\n </ng-container>\n }\n </div>\n @if (_isOpened) {\n <div\n aria-hidden=\"true\"\n class=\"sd-side-drawer-backdrop\"\n (click)=\"disableBackdropClose() ? null : close()\"\n (wheel)=\"preventScroll($event)\"\n (touchmove)=\"preventScroll($event)\"></div>\n }\n</ng-template>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sdcorejs-angular-components-side-drawer.mjs","sources":["../../../projects/sdcorejs-angular/components/side-drawer/src/side-drawer.component.ts","../../../projects/sdcorejs-angular/components/side-drawer/src/side-drawer.component.html","../../../projects/sdcorejs-angular/components/side-drawer/sdcorejs-angular-components-side-drawer.ts"],"sourcesContent":["import { CdkPortal, DomPortalOutlet, PortalModule } from '@angular/cdk/portal';\nimport { CommonModule } from '@angular/common';\nimport {\n ApplicationRef,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n DestroyRef,\n EmbeddedViewRef,\n Injector,\n ViewContainerRef,\n afterNextRender,\n booleanAttribute,\n computed,\n inject,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { SdLoadingService } from '@sdcorejs/angular/services';\nimport { Utilities } from '@sdcorejs/utils/fns';\nimport { fromEvent, merge, Observable, Subject } from 'rxjs';\nimport { map, takeUntil, startWith, distinctUntilChanged } from 'rxjs/operators';\nimport { SdIcon } from '@sdcorejs/angular/modules/icon';\n\nexport type SdSideDrawerBeforeClose = () => boolean | Promise<boolean>;\n\n@Component({\n selector: 'sd-side-drawer',\n templateUrl: './side-drawer.component.html',\n styleUrl: './side-drawer.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [SdIcon, CommonModule, PortalModule],\n})\nexport class SdSideDrawer {\n id = `I${Utilities.generateUuid()}`;\n\n portal = viewChild.required(CdkPortal);\n\n title = input<string>('');\n width = input<string>('480px');\n hideClose = input<boolean, boolean | ''>(false, { transform: booleanAttribute });\n disableBackdropClose = input<boolean, boolean | ''>(false, { transform: booleanAttribute });\n beforeClose = input<SdSideDrawerBeforeClose | undefined>(undefined);\n\n // Custom CSS class added to the root side-drawer container\n drawerClass = input<any>('');\n\n readonly autoIdInput = input<string | undefined | null>(undefined, { alias: 'autoId' });\n readonly autoId = computed(() => (this.autoIdInput() ? `components-side-drawer-${this.autoIdInput()}` : undefined));\n\n sdClosed = output<void>();\n sdCloseError = output<unknown>();\n\n #embeddedViewRef!: EmbeddedViewRef<any>;\n\n readonly #isOpenedSignal = signal(false);\n readonly #isLoadingSignal = signal(false);\n readonly isOpened = this.#isOpenedSignal.asReadonly();\n readonly isLoading = this.#isLoadingSignal.asReadonly();\n readonly dataOpened = computed(() => (this.#isOpenedSignal() ? 'true' : 'false'));\n readonly dataLoading = computed(() => (this.#isLoadingSignal() ? 'true' : 'false'));\n\n isHovered$!: Observable<boolean>;\n #destroy$ = new Subject<void>();\n #previousBodyOverflow: string | null = null;\n #closeRequest?: Promise<boolean>;\n\n #viewContainerRef = inject(ViewContainerRef);\n #ar = inject(ApplicationRef);\n #injector = inject(Injector);\n #ref = inject(ChangeDetectorRef);\n #loadingService = inject(SdLoadingService);\n #destroyRef = inject(DestroyRef);\n\n constructor() {\n // Thay thế ngAfterViewInit, tự động chạy nội dung này khi DOM sẵn sàng để render\n afterNextRender(() => {\n // 1. Gắn portal vào body và lưu lại EmbeddedViewRef\n const outlet = new DomPortalOutlet(document.body, this.#ar, this.#injector);\n this.#embeddedViewRef = outlet.attachTemplatePortal(this.portal());\n\n // 2. Setup sự kiện hover ngay sau khi DOM thật đã được in ra\n this.#setupHoverSubscription();\n });\n\n // Thay thế ngOnDestroy bằng logic destroy trực tiếp\n this.#destroyRef.onDestroy(() => {\n this.#destroy$.next();\n this.#destroy$.complete();\n\n if (this.#embeddedViewRef) {\n this.#embeddedViewRef.destroy();\n }\n\n if (this.#isOpenedSignal()) {\n if (this.#previousBodyOverflow !== null) {\n document.body.style.overflow = this.#previousBodyOverflow;\n } else {\n document.body.style.overflow = '';\n }\n }\n });\n }\n\n open = () => {\n this.#ref.markForCheck();\n this.#isOpenedSignal.set(true);\n\n // Chặn scroll ở document body\n this.#previousBodyOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n };\n\n close = () => {\n if (this.beforeClose()) {\n void this.requestClose();\n return;\n }\n this.forceClose();\n };\n\n requestClose = (): Promise<boolean> => {\n const guard = this.beforeClose();\n if (!guard) {\n this.forceClose();\n return Promise.resolve(true);\n }\n if (this.#closeRequest) return this.#closeRequest;\n\n const request = Promise.resolve()\n .then(() => guard())\n .then(canClose => {\n if (!canClose) return false;\n this.forceClose();\n return true;\n })\n .catch((error: unknown) => {\n this.sdCloseError.emit(error);\n return false;\n });\n\n this.#closeRequest = request;\n void request.finally(() => {\n if (this.#closeRequest === request) this.#closeRequest = undefined;\n });\n return request;\n };\n\n forceClose = () => {\n this.#ref.markForCheck();\n this.#isOpenedSignal.set(false);\n this.sdClosed.emit();\n this.stopLoading();\n\n // Khôi phục lại scroll ở document body\n if (this.#previousBodyOverflow !== null) {\n document.body.style.overflow = this.#previousBodyOverflow;\n this.#previousBodyOverflow = null;\n } else {\n document.body.style.overflow = '';\n }\n };\n\n startLoading = () => {\n this.#isLoadingSignal.set(true);\n this.#loadingService.stop(`#${this.id}`);\n this.#loadingService.start(`#${this.id}`);\n };\n\n stopLoading = () => {\n this.#isLoadingSignal.set(false);\n this.#loadingService.stop(`#${this.id}`);\n };\n\n preventScroll = (event: Event) => {\n event.preventDefault();\n };\n\n #setupHoverSubscription(): void {\n if (!this.#embeddedViewRef) return;\n\n // 3. Lấy DOM element trực tiếp từ rootNodes của EmbeddedViewRef\n const rootNodes = this.#embeddedViewRef.rootNodes;\n const element = rootNodes.find(\n node => node.nodeType === Node.ELEMENT_NODE && (node as HTMLElement).classList?.contains('sd-side-drawer')\n );\n\n if (!element) {\n console.warn('SdSideDrawer: Cannot find sd-side-drawer element to attach hover event');\n return;\n }\n\n // 4. Gắn event listeners trực tiếp lên element thật\n const mouseEnter$ = fromEvent(element, 'mouseenter').pipe(map(() => true));\n const mouseLeave$ = fromEvent(element, 'mouseleave').pipe(map(() => false));\n\n this.isHovered$ = merge(mouseEnter$, mouseLeave$).pipe(startWith(false), distinctUntilChanged(), takeUntil(this.#destroy$));\n }\n}\n","<ng-template cdkPortal>\n @let _isOpened = isOpened();\n <div\n [id]=\"id\"\n class=\"sd-side-drawer\"\n [ngStyle]=\"{ width: width() }\"\n [ngClass]=\"drawerClass()\"\n [class.sd-side-drawer-active]=\"_isOpened\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-opened]=\"dataOpened()\"\n [attr.data-loading]=\"dataLoading()\"\n #drawerContainer>\n @if (_isOpened) {\n <ng-container>\n <div class=\"sd-side-drawer-header\">\n <div class=\"sd-side-drawer-header-left\">\n <ng-content select=\"[sdHeaderLeft]\">\n <div class=\"sd-side-drawer-title\">{{ title() }}</div>\n </ng-content>\n </div>\n <div class=\"sd-side-drawer-header-right\">\n <ng-content select=\"[sdHeaderRight]\"></ng-content>\n @if (!hideClose()) {\n <button type=\"button\" class=\"sd-side-drawer-close-btn\" (click)=\"close()\" aria-label=\"Close\">\n <sd-icon name=\"close\"></sd-icon>\n </button>\n }\n </div>\n </div>\n @if (_isOpened) {\n <div class=\"sd-side-drawer-body\">\n <div class=\"sd-side-drawer-content\">\n <ng-content></ng-content>\n </div>\n </div>\n }\n <div class=\"sd-side-drawer-footer\">\n <div class=\"sd-side-drawer-footer-left\"><ng-content select=\"[sdFooterLeft]\"></ng-content></div>\n <div class=\"sd-side-drawer-footer-right\"><ng-content select=\"[sdFooterRight]\"></ng-content></div>\n </div>\n </ng-container>\n }\n </div>\n @if (_isOpened) {\n <div\n aria-hidden=\"true\"\n class=\"sd-side-drawer-backdrop\"\n (click)=\"disableBackdropClose() ? null : close()\"\n (wheel)=\"preventScroll($event)\"\n (touchmove)=\"preventScroll($event)\"></div>\n }\n</ng-template>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;;;;;MAoCa,YAAY,CAAA;AACvB,IAAA,EAAE,GAAG,CAAA,CAAA,EAAI,SAAS,CAAC,YAAY,EAAE,EAAE;AAEnC,IAAA,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;AAEtC,IAAA,KAAK,GAAG,KAAK,CAAS,EAAE,4EAAC;AACzB,IAAA,KAAK,GAAG,KAAK,CAAS,OAAO,4EAAC;IAC9B,SAAS,GAAG,KAAK,CAAwB,KAAK,iFAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;IAChF,oBAAoB,GAAG,KAAK,CAAwB,KAAK,4FAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;AAC3F,IAAA,WAAW,GAAG,KAAK,CAAsC,SAAS,kFAAC;;AAGnE,IAAA,WAAW,GAAG,KAAK,CAAM,EAAE,kFAAC;IAEnB,WAAW,GAAG,KAAK,CAA4B,SAAS,mFAAI,KAAK,EAAE,QAAQ,EAAA,CAAG;IAC9E,MAAM,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,WAAW,EAAE,GAAG,CAAA,uBAAA,EAA0B,IAAI,CAAC,WAAW,EAAE,CAAA,CAAE,GAAG,SAAS,CAAC,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,QAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAC;IAEnH,QAAQ,GAAG,MAAM,EAAQ;IACzB,YAAY,GAAG,MAAM,EAAW;AAEhC,IAAA,gBAAgB;AAEP,IAAA,eAAe,GAAG,MAAM,CAAC,KAAK,sFAAC;AAC/B,IAAA,gBAAgB,GAAG,MAAM,CAAC,KAAK,uFAAC;AAChC,IAAA,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE;AAC5C,IAAA,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE;IAC9C,UAAU,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,eAAe,EAAE,GAAG,MAAM,GAAG,OAAO,CAAC,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,YAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAC;IACxE,WAAW,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,gBAAgB,EAAE,GAAG,MAAM,GAAG,OAAO,CAAC,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,aAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAC;AAEnF,IAAA,UAAU;AACV,IAAA,SAAS,GAAG,IAAI,OAAO,EAAQ;IAC/B,qBAAqB,GAAkB,IAAI;AAC3C,IAAA,aAAa;AAEb,IAAA,iBAAiB,GAAG,MAAM,CAAC,gBAAgB,CAAC;AAC5C,IAAA,GAAG,GAAG,MAAM,CAAC,cAAc,CAAC;AAC5B,IAAA,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC;AAC5B,IAAA,IAAI,GAAG,MAAM,CAAC,iBAAiB,CAAC;AAChC,IAAA,eAAe,GAAG,MAAM,CAAC,gBAAgB,CAAC;AAC1C,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC;AAEhC,IAAA,WAAA,GAAA;;QAEE,eAAe,CAAC,MAAK;;AAEnB,YAAA,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC;AAC3E,YAAA,IAAI,CAAC,gBAAgB,GAAG,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;;YAGlE,IAAI,CAAC,uBAAuB,EAAE;AAChC,QAAA,CAAC,CAAC;;AAGF,QAAA,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,MAAK;AAC9B,YAAA,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE;AACrB,YAAA,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE;AAEzB,YAAA,IAAI,IAAI,CAAC,gBAAgB,EAAE;AACzB,gBAAA,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE;YACjC;AAEA,YAAA,IAAI,IAAI,CAAC,eAAe,EAAE,EAAE;AAC1B,gBAAA,IAAI,IAAI,CAAC,qBAAqB,KAAK,IAAI,EAAE;oBACvC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,qBAAqB;gBAC3D;qBAAO;oBACL,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,EAAE;gBACnC;YACF;AACF,QAAA,CAAC,CAAC;IACJ;IAEA,IAAI,GAAG,MAAK;AACV,QAAA,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;AACxB,QAAA,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC;;QAG9B,IAAI,CAAC,qBAAqB,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ;QACzD,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,QAAQ;AACzC,IAAA,CAAC;IAED,KAAK,GAAG,MAAK;AACX,QAAA,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE;AACtB,YAAA,KAAK,IAAI,CAAC,YAAY,EAAE;YACxB;QACF;QACA,IAAI,CAAC,UAAU,EAAE;AACnB,IAAA,CAAC;IAED,YAAY,GAAG,MAAuB;AACpC,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE;QAChC,IAAI,CAAC,KAAK,EAAE;YACV,IAAI,CAAC,UAAU,EAAE;AACjB,YAAA,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;QAC9B;QACA,IAAI,IAAI,CAAC,aAAa;YAAE,OAAO,IAAI,CAAC,aAAa;AAEjD,QAAA,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO;AAC5B,aAAA,IAAI,CAAC,MAAM,KAAK,EAAE;aAClB,IAAI,CAAC,QAAQ,IAAG;AACf,YAAA,IAAI,CAAC,QAAQ;AAAE,gBAAA,OAAO,KAAK;YAC3B,IAAI,CAAC,UAAU,EAAE;AACjB,YAAA,OAAO,IAAI;AACb,QAAA,CAAC;AACA,aAAA,KAAK,CAAC,CAAC,KAAc,KAAI;AACxB,YAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC;AAC7B,YAAA,OAAO,KAAK;AACd,QAAA,CAAC,CAAC;AAEJ,QAAA,IAAI,CAAC,aAAa,GAAG,OAAO;AAC5B,QAAA,KAAK,OAAO,CAAC,OAAO,CAAC,MAAK;AACxB,YAAA,IAAI,IAAI,CAAC,aAAa,KAAK,OAAO;AAAE,gBAAA,IAAI,CAAC,aAAa,GAAG,SAAS;AACpE,QAAA,CAAC,CAAC;AACF,QAAA,OAAO,OAAO;AAChB,IAAA,CAAC;IAED,UAAU,GAAG,MAAK;AAChB,QAAA,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;AACxB,QAAA,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC;AAC/B,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;QACpB,IAAI,CAAC,WAAW,EAAE;;AAGlB,QAAA,IAAI,IAAI,CAAC,qBAAqB,KAAK,IAAI,EAAE;YACvC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,qBAAqB;AACzD,YAAA,IAAI,CAAC,qBAAqB,GAAG,IAAI;QACnC;aAAO;YACL,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,EAAE;QACnC;AACF,IAAA,CAAC;IAED,YAAY,GAAG,MAAK;AAClB,QAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC;QAC/B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA,CAAA,EAAI,IAAI,CAAC,EAAE,CAAA,CAAE,CAAC;QACxC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAA,CAAA,EAAI,IAAI,CAAC,EAAE,CAAA,CAAE,CAAC;AAC3C,IAAA,CAAC;IAED,WAAW,GAAG,MAAK;AACjB,QAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC;QAChC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA,CAAA,EAAI,IAAI,CAAC,EAAE,CAAA,CAAE,CAAC;AAC1C,IAAA,CAAC;AAED,IAAA,aAAa,GAAG,CAAC,KAAY,KAAI;QAC/B,KAAK,CAAC,cAAc,EAAE;AACxB,IAAA,CAAC;IAED,uBAAuB,GAAA;QACrB,IAAI,CAAC,IAAI,CAAC,gBAAgB;YAAE;;AAG5B,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,SAAS;QACjD,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAC5B,IAAI,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,YAAY,IAAK,IAAoB,CAAC,SAAS,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAC3G;QAED,IAAI,CAAC,OAAO,EAAE;AACZ,YAAA,OAAO,CAAC,IAAI,CAAC,wEAAwE,CAAC;YACtF;QACF;;AAGA,QAAA,MAAM,WAAW,GAAG,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC;AAC1E,QAAA,MAAM,WAAW,GAAG,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,CAAC;QAE3E,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,oBAAoB,EAAE,EAAE,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC7H;wGApKW,YAAY,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;4FAAZ,YAAY,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,oBAAA,EAAA,EAAA,iBAAA,EAAA,sBAAA,EAAA,UAAA,EAAA,sBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,QAAA,EAAA,UAAA,EAAA,YAAA,EAAA,cAAA,EAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,QAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAGK,SAAS,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECvCvC,i3DAoDA,6hGDlBY,MAAM,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,OAAA,EAAA,KAAA,EAAA,SAAA,EAAA,MAAA,EAAA,aAAA,EAAA,qBAAA,EAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAE,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAE,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,SAAA,EAAA,QAAA,EAAA,aAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAEjC,YAAY,EAAA,UAAA,EAAA,CAAA;kBARxB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,gBAAgB,EAAA,eAAA,EAGT,uBAAuB,CAAC,MAAM,EAAA,UAAA,EACnC,IAAI,EAAA,OAAA,EACP,CAAC,MAAM,EAAE,YAAY,EAAE,YAAY,CAAC,EAAA,QAAA,EAAA,i3DAAA,EAAA,MAAA,EAAA,CAAA,q+FAAA,CAAA,EAAA;kHAKjB,SAAS,CAAA,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,KAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,OAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,KAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,OAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,SAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,WAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,oBAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,sBAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,WAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,aAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,WAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,aAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,WAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,QAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,QAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,MAAA,EAAA,IAAA,EAAA,CAAA,UAAA,CAAA,EAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,MAAA,EAAA,IAAA,EAAA,CAAA,cAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CAAA;;AEvCvC;;AAEG;;;;"}
@@ -1,6 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, Injectable, Pipe, Input, ChangeDetectionStrategy, Component, viewChild, input, inject, ChangeDetectorRef, ElementRef, HostListener, booleanAttribute, signal, Injector, afterNextRender, NgModuleFactory, createNgModule } from '@angular/core';
3
- import * as i2 from '@angular/router';
2
+ import { InjectionToken, Injectable, inject, Pipe, ChangeDetectorRef, Input, ChangeDetectionStrategy, Component, viewChild, input, ElementRef, HostListener, booleanAttribute, signal, Injector, afterNextRender, NgModuleFactory, createNgModule } from '@angular/core';
4
3
  import { Router, RoutesRecognized, NavigationEnd, NavigationSkipped, NavigationCancel, NavigationError, NavigationSkippedCode, RouterOutlet, ActivatedRoute } from '@angular/router';
5
4
  import * as i1$1 from '@angular/common';
6
5
  import { CommonModule } from '@angular/common';
@@ -117,10 +116,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
117
116
 
118
117
  class SdTabDecoratorService {
119
118
  static tabRouterService = new BehaviorSubject(undefined);
120
- constructor(tabRouterService) {
119
+ constructor() {
120
+ const tabRouterService = inject(SdTabRouterService);
121
121
  SdTabDecoratorService.tabRouterService.next(tabRouterService);
122
122
  }
123
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdTabDecoratorService, deps: [{ token: SdTabRouterService }], target: i0.ɵɵFactoryTarget.Injectable });
123
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdTabDecoratorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
124
124
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdTabDecoratorService, providedIn: 'root' });
125
125
  }
126
126
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdTabDecoratorService, decorators: [{
@@ -128,13 +128,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
128
128
  args: [{
129
129
  providedIn: 'root',
130
130
  }]
131
- }], ctorParameters: () => [{ type: SdTabRouterService }] });
131
+ }], ctorParameters: () => [] });
132
132
 
133
133
  class SdTabInfoPipe {
134
- tabRouterService;
135
- constructor(tabRouterService) {
136
- this.tabRouterService = tabRouterService;
137
- }
134
+ tabRouterService = inject(SdTabRouterService);
135
+ constructor() { }
138
136
  transform(tabInfo, tab) {
139
137
  if (tabInfo) {
140
138
  return tabInfo;
@@ -155,7 +153,7 @@ class SdTabInfoPipe {
155
153
  icon: undefined,
156
154
  };
157
155
  }
158
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdTabInfoPipe, deps: [{ token: SdTabRouterService }], target: i0.ɵɵFactoryTarget.Pipe });
156
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdTabInfoPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
159
157
  static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.17", ngImport: i0, type: SdTabInfoPipe, isStandalone: true, name: "sdTabInfo" });
160
158
  }
161
159
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdTabInfoPipe, decorators: [{
@@ -164,20 +162,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
164
162
  name: 'sdTabInfo',
165
163
  standalone: true,
166
164
  }]
167
- }], ctorParameters: () => [{ type: SdTabRouterService }] });
165
+ }], ctorParameters: () => [] });
168
166
 
169
167
  class SdTabRouterItemComponent {
170
- cdRef;
171
- tabRouterService;
172
- router;
168
+ cdRef = inject(ChangeDetectorRef);
169
+ tabRouterService = inject(SdTabRouterService);
170
+ router = inject(Router);
173
171
  tab;
174
172
  #subsctiption = new Subscription();
175
173
  tabInfo;
176
- constructor(cdRef, tabRouterService, router) {
177
- this.cdRef = cdRef;
178
- this.tabRouterService = tabRouterService;
179
- this.router = router;
180
- }
174
+ constructor() { }
181
175
  ngOnInit() {
182
176
  this.#subsctiption.add(this.tabRouterService.events.pipe(debounceTime(100)).subscribe(() => {
183
177
  this.cdRef.markForCheck();
@@ -219,13 +213,13 @@ class SdTabRouterItemComponent {
219
213
  #closeTab = () => {
220
214
  this.tabRouterService.close(this.tab);
221
215
  };
222
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdTabRouterItemComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: SdTabRouterService }, { token: i2.Router }], target: i0.ɵɵFactoryTarget.Component });
216
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdTabRouterItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
223
217
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SdTabRouterItemComponent, isStandalone: true, selector: "sd-tab-router-item", inputs: { tab: "tab" }, ngImport: i0, template: "<a\n [href]=\"[tab.url]\"\n class=\"tab-router__item d-flex align-items-center gap-8\"\n [class.tab-router__item--active]=\"tab.isActive\"\n (click)=\"onTabClick($event)\"\n (mousedown)=\"onMousedown($event)\"\n (mouseup)=\"onMouseup($event)\">\n @let info = tabInfo | sdTabInfo: tab;\n @if (info) {\n <sd-badge\n style=\"overflow: hidden;white-space: nowrap;\"\n [icon]=\"info.icon\"\n [title]=\"info.icon\"\n [tooltip]=\"info.tooltip || info.name\"\n [title]=\"info.name\"\n [color]=\"info.color\"\n (click)=\"onTabClick($event)\"></sd-badge>\n <button\n aria-hidden=\"true\"\n class=\"tab-router__close d-flex align-items-center justify-content-center ml-auto p-0\"\n (click)=\"close($event)\"\n (mousedown)=\"$event.stopPropagation()\">\n <sd-icon aria-hidden=\"true\" fontIcon=\"close\"></sd-icon>\n </button>\n }\n</a>\n", styles: [":host{display:block;overflow:hidden;position:relative;flex:1 1 64px;max-width:240px}:host:after{content:\"\";position:absolute;right:0;top:0;bottom:0;height:16px;width:1px;background:#dde0e5;margin:auto}:host:last-child:after{content:none}:host::ng-deep .tab-router__item sd-badge .c-badge-title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;width:184px}.flex-1{flex:1}.tab-router__icon{background-color:#5c6bc0;width:16px;height:16px;line-height:16px;text-align:center;font-size:10px;color:#fff;border-radius:2px;text-transform:uppercase}.tab-router__icon sd-icon{height:10px;width:10px;font-size:10px}.tab-router__close{color:#757575;outline:none;border:0;background:none;border-radius:50%;height:16px;width:16px}.tab-router__close:hover{background-color:#0000001f}.tab-router__close sd-icon{font-size:12px;height:12px;width:12px}.tab-router__item{background:#f2f3f4;padding:8px;color:inherit;text-decoration:none;font-size:12px;line-height:16px;overflow:hidden}.tab-router__item:hover{background-color:#fff}.tab-router__name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tab-router__item--active{border-radius:8px 8px 0 0;background-color:#fff}\n"], dependencies: [{ kind: "component", type: SdIcon, selector: "sd-icon", inputs: ["name", "fontIcon", "color", "set", "fontSet", "size", "strokeWidth", "absoluteStrokeWidth", "ariaLabel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "component", type: SdBadge, selector: "sd-badge", inputs: ["type", "color", "primary", "secondary", "success", "info", "warning", "error", "fontSet", "title", "description", "tooltip", "icon", "size"], outputs: ["click"] }, { kind: "pipe", type: SdTabInfoPipe, name: "sdTabInfo" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
224
218
  }
225
219
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdTabRouterItemComponent, decorators: [{
226
220
  type: Component,
227
221
  args: [{ selector: 'sd-tab-router-item', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [SdIcon, CommonModule, SdBadge, SdTabInfoPipe], template: "<a\n [href]=\"[tab.url]\"\n class=\"tab-router__item d-flex align-items-center gap-8\"\n [class.tab-router__item--active]=\"tab.isActive\"\n (click)=\"onTabClick($event)\"\n (mousedown)=\"onMousedown($event)\"\n (mouseup)=\"onMouseup($event)\">\n @let info = tabInfo | sdTabInfo: tab;\n @if (info) {\n <sd-badge\n style=\"overflow: hidden;white-space: nowrap;\"\n [icon]=\"info.icon\"\n [title]=\"info.icon\"\n [tooltip]=\"info.tooltip || info.name\"\n [title]=\"info.name\"\n [color]=\"info.color\"\n (click)=\"onTabClick($event)\"></sd-badge>\n <button\n aria-hidden=\"true\"\n class=\"tab-router__close d-flex align-items-center justify-content-center ml-auto p-0\"\n (click)=\"close($event)\"\n (mousedown)=\"$event.stopPropagation()\">\n <sd-icon aria-hidden=\"true\" fontIcon=\"close\"></sd-icon>\n </button>\n }\n</a>\n", styles: [":host{display:block;overflow:hidden;position:relative;flex:1 1 64px;max-width:240px}:host:after{content:\"\";position:absolute;right:0;top:0;bottom:0;height:16px;width:1px;background:#dde0e5;margin:auto}:host:last-child:after{content:none}:host::ng-deep .tab-router__item sd-badge .c-badge-title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;width:184px}.flex-1{flex:1}.tab-router__icon{background-color:#5c6bc0;width:16px;height:16px;line-height:16px;text-align:center;font-size:10px;color:#fff;border-radius:2px;text-transform:uppercase}.tab-router__icon sd-icon{height:10px;width:10px;font-size:10px}.tab-router__close{color:#757575;outline:none;border:0;background:none;border-radius:50%;height:16px;width:16px}.tab-router__close:hover{background-color:#0000001f}.tab-router__close sd-icon{font-size:12px;height:12px;width:12px}.tab-router__item{background:#f2f3f4;padding:8px;color:inherit;text-decoration:none;font-size:12px;line-height:16px;overflow:hidden}.tab-router__item:hover{background-color:#fff}.tab-router__name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tab-router__item--active{border-radius:8px 8px 0 0;background-color:#fff}\n"] }]
228
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: SdTabRouterService }, { type: i2.Router }], propDecorators: { tab: [{
222
+ }], ctorParameters: () => [], propDecorators: { tab: [{
229
223
  type: Input,
230
224
  args: [{ required: true }]
231
225
  }] } });
@@ -404,7 +398,7 @@ class SdTabRouterOutletComponent {
404
398
  canClose = typeof result === 'boolean' ? result : await result;
405
399
  }
406
400
  catch {
407
- canClose = true;
401
+ canClose = false;
408
402
  }
409
403
  if (!canClose)
410
404
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"sdcorejs-angular-components-tab-router.mjs","sources":["../../../projects/sdcorejs-angular/components/tab-router/src/events/tab-router.event.ts","../../../projects/sdcorejs-angular/components/tab-router/src/models/tab-router.model.ts","../../../projects/sdcorejs-angular/components/tab-router/src/services/tab-router.service.ts","../../../projects/sdcorejs-angular/components/tab-router/src/services/tab-decorator.service.ts","../../../projects/sdcorejs-angular/components/tab-router/src/pipes/tab-info.pipe.ts","../../../projects/sdcorejs-angular/components/tab-router/src/components/tab-router-item/tab-router-item.component.ts","../../../projects/sdcorejs-angular/components/tab-router/src/components/tab-router-item/tab-router-item.component.html","../../../projects/sdcorejs-angular/components/tab-router/src/components/tab-router-nav/tab-router-nav.component.ts","../../../projects/sdcorejs-angular/components/tab-router/src/components/tab-router-nav/tab-router-nav.component.html","../../../projects/sdcorejs-angular/components/tab-router/src/components/tab-router-outlet/tab-router-outlet.component.ts","../../../projects/sdcorejs-angular/components/tab-router/src/components/tab-router-outlet/tab-router-outlet.component.html","../../../projects/sdcorejs-angular/components/tab-router/src/decorators/tab.decorator.ts","../../../projects/sdcorejs-angular/components/tab-router/sdcorejs-angular-components-tab-router.ts"],"sourcesContent":["import { SdTab } from '../models/tab-router.model';\n\nexport class SdTabBase {\n #tab: SdTab | undefined;\n\n constructor(tab: SdTab | undefined) {\n this.#tab = tab;\n }\n\n get tab(): SdTab | undefined {\n return this.#tab;\n }\n}\n\nexport class SdTabActivated extends SdTabBase {}\n\nexport class SdTabDeactivated extends SdTabBase {}\n\nexport declare type SdTabEvent = SdTabActivated | SdTabDeactivated;\n","import { InjectionToken, Type } from '@angular/core';\nimport { Color } from '@sdcorejs/utils/models';\nimport { Subject } from 'rxjs';\n\nexport interface SdTabInfo {\n name: string;\n icon?: string;\n tooltip?: string;\n color?: Color;\n}\n\nexport interface SdTab {\n component: Type<any>;\n injector?: any;\n key: string;\n isActive: boolean;\n url: string;\n params?: Record<string, string | number>;\n queryParams?: Record<string, string | number>;\n data?: Record<string, any>;\n tabInfoChanges: Subject<SdTabInfo>;\n beforeClose?: () => boolean | Promise<boolean>; // Return true thì mới được close\n}\n\nexport const SD_TAB = new InjectionToken<SdTab>('SD_TAB');\n","import { Injectable, Type } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\nimport { SdTabAction } from '../actions/tab-router.action';\nimport { SdTabComponentBuilder } from '../decorators/tab.decorator';\nimport { SdTabBase, SdTabEvent } from '../events/tab-router.event';\nimport { SdTab } from '../models/tab-router.model';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class SdTabRouterService {\n events = new BehaviorSubject<SdTabEvent>(new SdTabBase(undefined));\n actions = new BehaviorSubject<SdTabAction | undefined>(undefined);\n builders = new BehaviorSubject<SdTabComponentBuilder[]>([]);\n currentTabChanges = new BehaviorSubject<SdTab | undefined>(undefined);\n newTabs = new BehaviorSubject<SdTab | undefined>(undefined);\n updateTabs = new BehaviorSubject<SdTab | undefined>(undefined);\n #currentTab: SdTab | undefined = undefined;\n #componentBuilders: SdTabComponentBuilder[] = [];\n\n addBuilder = (builder: SdTabComponentBuilder) => {\n if (!this.#componentBuilders.some(e => e.component === builder.component)) {\n this.#componentBuilders.push(builder);\n this.builders.next(this.#componentBuilders);\n }\n };\n\n get currentTab() {\n return this.#currentTab;\n }\n\n get currentKey() {\n return this.#currentTab?.key || null;\n }\n\n // select = (tabOrKey: string | SdTab): void => {\n // const tab = this.#tabs.find(e => {\n // if (typeof (tabOrKey) === 'string') {\n // return e.key === tabOrKey;\n // }\n // return e.key === tabOrKey?.key;\n // });\n // if (tab) {\n // this.#currentTab = tab;\n // }\n // }\n\n // add = (tab: SdTab): void => {\n // if (!tab.key) {\n // this.notifyService.notify.warning('Tab key is required');\n // }\n // if (!tab.component) {\n // this.notifyService.notify.warning('Tab component is required');\n // }\n // const existedTab = this.#tabs.find(e => e.key === tab.key);\n // if (!existedTab) {\n // this.#tabs.push(tab);\n // this.select(tab);\n // } else {\n // this.select(existedTab);\n // }\n // }\n\n // remove = (tabOrKey: string | SdTab): void => {\n // this.#tabs = this.#tabs.filter(e => {\n // if (typeof (tabOrKey) === 'string') {\n // return e.key !== tabOrKey;\n // }\n // return e.key !== tabOrKey?.key;\n // });\n // }\n\n setCurrentTab = (tab: SdTab): void => {\n this.#currentTab = tab;\n this.currentTabChanges.next(tab);\n };\n\n pushEvent = (tab: SdTab, Event: Type<SdTabEvent>) => {\n this.events.next(new Event(tab));\n };\n\n setOptions = () => {};\n\n close = (tab?: SdTab) => {\n tab = tab || this.#currentTab;\n if (tab) {\n this.actions.next({\n type: 'close',\n tab,\n });\n }\n };\n\n // Gọi hàm này để thực hiện update tab\n updateTab = (tab: SdTab) => {};\n}\n","import { Injectable } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\nimport { SdTabRouterService } from './tab-router.service';\n@Injectable({\n providedIn: 'root',\n})\nexport class SdTabDecoratorService {\n static tabRouterService = new BehaviorSubject<SdTabRouterService | undefined>(undefined);\n constructor(tabRouterService: SdTabRouterService) {\n SdTabDecoratorService.tabRouterService.next(tabRouterService);\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { SdTab, SdTabInfo } from '../models/tab-router.model';\nimport { SdTabRouterService } from '../services/tab-router.service';\n@Pipe({\n name: 'sdTabInfo',\n standalone: true,\n})\nexport class SdTabInfoPipe implements PipeTransform {\n constructor(private tabRouterService: SdTabRouterService) {}\n transform(tabInfo: SdTabInfo | undefined | null, tab: SdTab): SdTabInfo {\n if (tabInfo) {\n return tabInfo;\n }\n const builders = this.tabRouterService.builders.getValue();\n const builder = builders.find(e => e.component === tab.component);\n if (builder) {\n const { url, params, queryParams, data } = tab;\n return {\n name: typeof builder.name === 'function' ? builder.name({ url, params, queryParams, data }) : builder.name,\n icon: typeof builder.icon === 'function' ? builder.icon({ url, params, queryParams }) : builder.icon,\n tooltip: typeof builder.tooltip === 'function' ? builder.tooltip({ url, params, queryParams }) : builder.tooltip,\n color: typeof builder.color === 'function' ? builder.color({ url, params, queryParams }) : builder.color,\n };\n }\n return {\n name: tab.url,\n icon: undefined,\n };\n }\n}\n","import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport { debounceTime, startWith } from 'rxjs/operators';\n\nimport { SdBadge } from '@sdcorejs/angular/components/badge';\nimport { SdTab, SdTabInfo } from '../../models';\nimport { SdTabRouterService } from '../../services/tab-router.service';\nimport { Router } from '@angular/router';\nimport { CommonModule } from '@angular/common';\nimport { SdTabInfoPipe } from '../../pipes/tab-info.pipe';\nimport { SdIcon } from '@sdcorejs/angular/modules/icon';\n\n@Component({\n selector: 'sd-tab-router-item',\n templateUrl: './tab-router-item.component.html',\n styleUrl: './tab-router-item.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [SdIcon, CommonModule, SdBadge, SdTabInfoPipe],\n})\nexport class SdTabRouterItemComponent implements OnInit, OnDestroy {\n @Input({ required: true }) tab!: SdTab;\n\n #subsctiption: Subscription = new Subscription();\n tabInfo?: SdTabInfo;\n constructor(\n private cdRef: ChangeDetectorRef,\n private tabRouterService: SdTabRouterService,\n private router: Router\n ) {}\n\n ngOnInit(): void {\n this.#subsctiption.add(\n this.tabRouterService.events.pipe(debounceTime(100)).subscribe(() => {\n this.cdRef.markForCheck();\n })\n );\n\n this.#subsctiption.add(\n this.tab.tabInfoChanges.pipe(startWith(null)).subscribe(tabInfo => {\n if (tabInfo) {\n this.tabInfo = tabInfo;\n this.cdRef.markForCheck();\n }\n })\n );\n }\n\n ngOnDestroy(): void {\n this.#subsctiption.unsubscribe();\n }\n\n onTabClick = (event: Event) => {\n event.preventDefault();\n this.router.navigate([this.tab.url], {\n queryParams: this.tab.queryParams,\n state: { switchTab: true },\n });\n };\n\n close = (event: Event) => {\n event.preventDefault();\n event.stopPropagation();\n this.#closeTab();\n };\n\n onMousedown = (event: MouseEvent) => {\n if (event.button === 1) {\n event.preventDefault();\n }\n };\n\n onMouseup = (event: MouseEvent) => {\n if (event.button === 1) {\n event.preventDefault();\n event.stopPropagation();\n this.#closeTab();\n }\n };\n\n #closeTab = () => {\n this.tabRouterService.close(this.tab);\n };\n}\n","<a\n [href]=\"[tab.url]\"\n class=\"tab-router__item d-flex align-items-center gap-8\"\n [class.tab-router__item--active]=\"tab.isActive\"\n (click)=\"onTabClick($event)\"\n (mousedown)=\"onMousedown($event)\"\n (mouseup)=\"onMouseup($event)\">\n @let info = tabInfo | sdTabInfo: tab;\n @if (info) {\n <sd-badge\n style=\"overflow: hidden;white-space: nowrap;\"\n [icon]=\"info.icon\"\n [title]=\"info.icon\"\n [tooltip]=\"info.tooltip || info.name\"\n [title]=\"info.name\"\n [color]=\"info.color\"\n (click)=\"onTabClick($event)\"></sd-badge>\n <button\n aria-hidden=\"true\"\n class=\"tab-router__close d-flex align-items-center justify-content-center ml-auto p-0\"\n (click)=\"close($event)\"\n (mousedown)=\"$event.stopPropagation()\">\n <sd-icon aria-hidden=\"true\" fontIcon=\"close\"></sd-icon>\n </button>\n }\n</a>\n","import { CdkDragDrop, DragDropModule, moveItemInArray } from '@angular/cdk/drag-drop';\nimport { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, HostListener, inject, input, viewChild } from '@angular/core';\n\nimport { SdTab } from '../../models/tab-router.model';\nimport { SdTabRouterItemComponent } from '../tab-router-item/tab-router-item.component';\nimport { CommonModule } from '@angular/common';\n\n@Component({\n selector: 'sd-tab-router-nav',\n templateUrl: './tab-router-nav.component.html',\n styleUrl: './tab-router-nav.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [CommonModule, DragDropModule, SdTabRouterItemComponent],\n})\nexport class SdTabRouterNavComponent {\n tabRouterNav = viewChild<ElementRef>('tabRouterNav');\n\n tabs = input<SdTab[]>([]);\n mode: 'default' | 'compact' = 'default';\n cdRef = inject(ChangeDetectorRef);\n elementRef = inject<ElementRef<any>>(ElementRef);\n\n @HostListener('window:resize')\n onResize(): void {\n this.checkUI();\n }\n\n checkUI = () => {\n const width = this.tabRouterNav()?.nativeElement.clientWidth ?? 0;\n const tabs = this.tabs();\n if (tabs.length === 0) {\n this.mode = 'default';\n this.cdRef.markForCheck();\n return;\n }\n\n const nameWidth = (width - tabs.length * 68) / tabs.length;\n if (nameWidth <= 20) {\n this.mode = 'compact';\n } else {\n this.mode = 'default';\n }\n this.cdRef.markForCheck();\n };\n\n onDrop = (event: CdkDragDrop<SdTab[]>) => {\n moveItemInArray(this.tabs(), event.previousIndex, event.currentIndex);\n };\n}\n","<div\n #tabRouterNav\n cdkDropList\n cdkDropListLockAxis=\"x\"\n cdkDropListOrientation=\"horizontal\"\n (cdkDropListDropped)=\"onDrop($event)\"\n class=\"tab-router__nav tab-router__nav--{{ mode }} d-flex align-items-center flex-nowrap\"\n [class.d-none]=\"tabs().length > 1\">\n @for (tab of tabs(); track tab.injector ?? tab.key) {\n <sd-tab-router-item [tab]=\"tab\" cdkDrag [cdkDragBoundary]=\"elementRef.nativeElement\"></sd-tab-router-item>\n }\n</div>\n","import {\n afterNextRender,\n booleanAttribute,\n Component,\n Injector,\n OnDestroy,\n Type,\n inject,\n input,\n signal,\n viewChild,\n createNgModule,\n NgModuleFactory,\n} from '@angular/core';\nimport {\n ActivatedRoute,\n ActivatedRouteSnapshot,\n NavigationCancel,\n NavigationEnd,\n NavigationError,\n NavigationSkipped,\n NavigationSkippedCode,\n Router,\n RouterOutlet,\n RoutesRecognized,\n} from '@angular/router';\nimport { CommonModule } from '@angular/common';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { from, Subject, Subscription, isObservable, lastValueFrom } from 'rxjs';\nimport { concatMap, filter, map } from 'rxjs/operators';\n\nimport { SdNotifyService } from '@sdcorejs/angular/services/notify';\nimport { I18nService } from '@sdcorejs/angular/i18n';\nimport { Utilities } from '@sdcorejs/utils/fns';\nimport { SdTabActivated, SdTabDeactivated } from '../../events/tab-router.event';\nimport { SdTabAction } from '../../actions/tab-router.action';\nimport { SdTab, SD_TAB } from '../../models';\nimport { SdTabDecoratorService } from '../../services/tab-decorator.service';\nimport { SdTabRouterService } from '../../services/tab-router.service';\nimport { SdTabRouterNavComponent } from '../tab-router-nav/tab-router-nav.component';\n\ntype TabRouterNavigationEvent = RoutesRecognized | NavigationEnd | NavigationSkipped | NavigationCancel | NavigationError;\n\ninterface TabRouterNavigationContext {\n event: TabRouterNavigationEvent;\n navigationState: Record<string, any>;\n}\n\n@Component({\n selector: 'sd-tab-router-outlet',\n templateUrl: './tab-router-outlet.component.html',\n styleUrl: './tab-router-outlet.component.scss',\n standalone: true,\n imports: [CommonModule, MatTooltipModule, RouterOutlet, SdTabRouterNavComponent],\n})\nexport class SdTabRouterOutletComponent implements OnDestroy {\n disabled = input(false, { transform: booleanAttribute });\n\n tabRouterNav = viewChild<SdTabRouterNavComponent>('tabRouterNav');\n\n tabs = signal<SdTab[]>([]);\n\n #router = inject(Router);\n #injector = inject(Injector);\n #tabRouterService = inject(SdTabRouterService);\n #sdNotifyService = inject(SdNotifyService);\n readonly #i18n = inject(I18nService);\n // Inject để đảm bảo SdTabDecoratorService được khởi tạo (nó register BehaviorSubject\n // tĩnh để @SdTab decorator có thể truy cập SdTabRouterService). Không dùng trực tiếp ở đây.\n #tabDecoratorService = inject(SdTabDecoratorService);\n\n #rootRoute?: ActivatedRoute;\n #subscription = new Subscription();\n\n // Lưu state theo navigation id để các navigation chồng lấn không ghi đè lẫn nhau.\n #pendingNavigationStates = new Map<number, Record<string, any>>();\n // Serialize mọi #activeRoute (router events + initial sync) để tránh race tạo duplicate tab.\n #activationQueue: Promise<void> = Promise.resolve();\n\n constructor() {\n this.#subscription.add(\n this.#router.events\n .pipe(\n // KHÔNG unwrap event.routerEvent (vd Scroll wrap NavigationEnd):\n // Angular emit NavigationEnd RAW trước, RouterScroller emit Scroll(NavigationEnd) sau.\n // Nếu unwrap thêm Scroll → handler fire 2 lần cho 1 nav → race condition tạo duplicate tabs.\n // Navigation thành công cần CẢ HAI event vì mỗi event chứa data ở thời điểm khác nhau.\n // - RoutesRecognized: navigation đang in-flight → getCurrentNavigation().extras.state đọc được\n // - NavigationEnd: navigation hoàn tất → routerState.root đã update với route mới (cần cho lazy routes)\n // Các terminal event khác chỉ xử lý same-URL forceReload hoặc dọn state theo navigation id.\n filter(\n (event): event is TabRouterNavigationEvent =>\n event instanceof RoutesRecognized ||\n event instanceof NavigationEnd ||\n event instanceof NavigationSkipped ||\n event instanceof NavigationCancel ||\n event instanceof NavigationError\n ),\n // Chụp getCurrentNavigation đồng bộ vì concatMap có thể chạy sau khi Angular đã xoá navigation hiện tại.\n map(\n (event): TabRouterNavigationContext => ({\n event,\n navigationState: this.#router.getCurrentNavigation()?.extras?.state ?? {},\n })\n ),\n // Serialize: #handleEvent async (await getBestInjector). 2 nav liên tiếp\n // không await xen kẽ → tránh race đọc this.tabs() = [] khi tab đầu chưa kịp set.\n concatMap(context => from(this.#handleEvent(context)))\n )\n .subscribe()\n );\n\n this.#subscription.add(\n this.#tabRouterService.actions.subscribe((event: SdTabAction | undefined) => {\n if (this.disabled()) return;\n\n if (event?.type === 'close') {\n this.#closeTab(event.tab);\n }\n })\n );\n\n // Initial navigation có thể hoàn tất trước khi outlet subscribe router.events\n // (blocking init hoặc outlet mount muộn). Catch-up sau first render.\n afterNextRender(() => {\n void this.#syncCurrentRoute();\n });\n }\n\n ngOnDestroy(): void {\n this.#subscription.unsubscribe();\n this.#pendingNavigationStates.clear();\n }\n\n #scheduleActivation = (task: () => Promise<void>): Promise<void> => {\n const run = this.#activationQueue.then(task);\n this.#activationQueue = run.catch(() => undefined);\n return run;\n };\n\n #handleEvent = async ({ event, navigationState }: TabRouterNavigationContext): Promise<void> => {\n if (this.disabled()) {\n this.#pendingNavigationStates.clear();\n return;\n }\n if (event instanceof RoutesRecognized) {\n this.#pendingNavigationStates.set(event.id, navigationState);\n return;\n }\n\n if (event instanceof NavigationCancel || event instanceof NavigationError) {\n this.#pendingNavigationStates.delete(event.id);\n return;\n }\n\n let state: Record<string, any>;\n let fullUrl: string;\n if (event instanceof NavigationSkipped) {\n this.#pendingNavigationStates.delete(event.id);\n if (event.code !== NavigationSkippedCode.IgnoredSameUrlNavigation || navigationState['forceReload'] !== true) {\n return;\n }\n state = navigationState;\n fullUrl = event.url;\n } else {\n state = this.#pendingNavigationStates.get(event.id) ?? navigationState;\n this.#pendingNavigationStates.delete(event.id);\n fullUrl = event.urlAfterRedirects || event.url;\n }\n\n await this.#scheduleActivation(async () => {\n const route = this.#getActivatedRouteSnapshot(this.#router.routerState.snapshot.root);\n this.#rootRoute = this.#router.routerState.root;\n await this.#activeRoute(fullUrl, route, state);\n });\n };\n\n // Bù initial navigation nếu NavigationEnd đã fire trước khi outlet subscribe.\n #syncCurrentRoute = (): Promise<void> => {\n if (this.disabled() || !this.#router.navigated) {\n return Promise.resolve();\n }\n\n const route = this.#getActivatedRouteSnapshot(this.#router.routerState.snapshot.root);\n if (!route?.component) {\n return Promise.resolve();\n }\n\n const [urlPath] = this.#router.url.split('?');\n const key = Utilities.hash({\n url: urlPath,\n queryParams: { ...(route.queryParams || {}) },\n });\n\n if (this.tabs().some(tab => tab.key === key)) {\n return Promise.resolve();\n }\n\n return this.#scheduleActivation(async () => {\n if (this.tabs().some(tab => tab.key === key)) {\n return;\n }\n this.#rootRoute = this.#router.routerState.root;\n await this.#activeRoute(this.#router.url, route, {});\n });\n };\n\n tabTrackBy = (index: number, tab: SdTab) => tab.key;\n\n #closeTab = async (tab: SdTab): Promise<void> => {\n if (this.disabled()) return;\n\n if (tab.beforeClose) {\n let canClose: boolean;\n try {\n const result = tab.beforeClose();\n canClose = typeof result === 'boolean' ? result : await result;\n } catch {\n canClose = true;\n }\n if (!canClose) return;\n }\n\n const currentTabs = this.tabs();\n const { isActive, key: activeKey } = tab;\n\n if (isActive) {\n const activeIndex = currentTabs.findIndex(({ key }) => key === activeKey);\n const nextTab = currentTabs[activeIndex + 1] || currentTabs[activeIndex - 1];\n\n this.tabs.set(currentTabs.filter(({ key }) => key !== activeKey));\n\n if (nextTab) {\n this.#router.navigate([nextTab.url], {\n queryParams: { ...(nextTab.queryParams || {}) },\n state: { switchTab: true },\n });\n } else {\n this.#router.navigateByUrl('/', { state: { switchTab: true } });\n }\n } else {\n this.tabs.set(currentTabs.filter(({ key }) => key !== tab.key));\n this.tabRouterNav()?.checkUI();\n }\n };\n\n #activeRoute = async (fullUrl: string, route: ActivatedRouteSnapshot | null, state: Record<string, any> = {}) => {\n if (this.disabled()) return;\n if (!route?.component) return;\n\n const component = route.component as Type<any>;\n const queryParams = { ...(route.queryParams || {}) };\n const params = { ...(route.params || {}) };\n const data = { ...(route.data || {}) };\n const [url] = fullUrl.split('?');\n // Tab identity = hash(url + queryParams). Cùng key mặc định giữ tab cũ; forceReload mới tạo lại.\n const key = Utilities.hash({ url, queryParams });\n\n let existedIndex = -1;\n let activatedIndex = -1;\n\n const currentTabs = this.tabs();\n\n // QUAN TRỌNG: scan READ-ONLY, KHÔNG mutate tab.isActive trong loop này.\n //\n // Lý do: NavigationEnd có thể fire nhiều lần cho 1 user-action (do nested outlets,\n // redirect, hoặc Angular internal). Vì #activeRoute là async (await getBestInjector),\n // 2 invocations có thể chạy concurrent và interleave với nhau.\n //\n // Nếu mutate tab.isActive = false ở đây, call thứ 2 sẽ thấy isActive đã bị call 1\n // set false rồi → không tìm thấy active tab → activatedIndex stay -1 → splice bỏ qua\n // → tab cũ không bị remove → xuất hiện duplicate tabs.\n //\n // Cách fix: chỉ ĐỌC isActive, sau đó dùng .map() ở dưới để tạo tab objects mới qua spread.\n for (let i = 0; i < currentTabs.length; i++) {\n const tab = currentTabs[i];\n if (tab.key === key) {\n existedIndex = i;\n } else if (tab.isActive) {\n activatedIndex = i;\n this.#tabRouterService.pushEvent(tab, SdTabDeactivated);\n }\n }\n\n const replaceTab = state['replaceTab'];\n const forceReload = state['forceReload'] === true;\n\n // Resolve injector phù hợp với route. Cần xử lý 3 trường hợp:\n // - Standalone route (Angular đã set _injector trên routeConfig sau khi activate)\n // - NgModule lazy load (cần createNgModule từ class)\n // - Fallback: root injector\n const getBestInjector = async (snapshot: ActivatedRouteSnapshot): Promise<Injector> => {\n // Standalone route: Angular tự lưu environment injector trên routeConfig._injector\n const routeInjector = (snapshot as any)._resolvedGui || (snapshot as any).routeConfig?._injector;\n if (routeInjector) return routeInjector;\n\n // NgModule lazy: phải gọi lại loadChildren() để lấy module class rồi createNgModule\n const loadChildren = snapshot.parent?.routeConfig?.loadChildren;\n if (typeof loadChildren === 'function') {\n let loaded: any = await loadChildren();\n\n if (isObservable(loaded)) {\n loaded = await lastValueFrom(loaded);\n }\n\n // ES module có thể export default\n if (loaded && typeof loaded === 'object' && 'default' in loaded) {\n loaded = loaded.default;\n }\n\n // Angular cũ: NgModuleFactory\n if (loaded instanceof NgModuleFactory) {\n return loaded.create(this.#injector).injector;\n }\n\n // Angular mới: NgModule class. Bọc try/catch vì createNgModule throw nếu không phải NgModule.\n if (typeof loaded === 'function' && !Array.isArray(loaded)) {\n try {\n return createNgModule(loaded, this.#injector).injector;\n } catch {\n return this.#injector;\n }\n }\n }\n return this.#injector;\n };\n\n const finalInjector = await getBestInjector(route);\n // Refresh root sau await: lazy route tree có thể hoàn tất trong lúc resolve injector.\n this.#rootRoute = this.#router.routerState.root;\n const activatedRoute = this.#findActivatedRouteForSnapshot(this.#rootRoute, route);\n\n const sdInjector = new SdOutletInjector(activatedRoute, finalInjector);\n const newTab: SdTab = {\n key,\n component,\n injector: sdInjector,\n isActive: true,\n url,\n params,\n queryParams,\n data,\n tabInfoChanges: new Subject(),\n };\n sdInjector.setTab(newTab);\n\n // Tạo updatedTabs qua spread thay vì mutate (xem lý do ở for loop phía trên).\n // Với tab có isActive không đổi: giữ nguyên reference (tránh trigger ngComponentOutlet\n // re-evaluate không cần thiết). Với tab cần đổi isActive: tạo object mới qua spread,\n // các nested fields (component, injector) vẫn giữ same reference nên component không bị recreate.\n let updatedTabs = currentTabs.map(tab => {\n if (tab.key === key) return tab.isActive ? tab : { ...tab, isActive: true };\n return tab.isActive ? { ...tab, isActive: false } : tab;\n });\n\n // replaceTab: thay vì mở tab mới song song, xoá tab đang active rồi mở tab mới ở cuối.\n // Use case: từ tab \"chi tiết\" bấm \"chỉnh sửa\" với replaceTab → tab chi tiết bị xoá,\n // tab chỉnh sửa thay thế (giữ số tab không tăng).\n if (replaceTab && activatedIndex >= 0) {\n updatedTabs = updatedTabs.filter((_, i) => i !== activatedIndex);\n }\n\n if (existedIndex >= 0) {\n // Mặc định tab đã tồn tại chỉ được activate, không thay tab object. forceReload là nhánh\n // explicit duy nhất thay SdTab + injector để body và nav item được tạo lại.\n //\n // splice phía trên có thể đã shift index nếu activatedIndex < existedIndex.\n const idx = replaceTab && activatedIndex >= 0 && activatedIndex < existedIndex ? existedIndex - 1 : existedIndex;\n if (forceReload) {\n updatedTabs = updatedTabs.map((tab, index) => (index === idx ? newTab : tab));\n this.#tabRouterService.setCurrentTab(newTab);\n this.#tabRouterService.pushEvent(newTab, SdTabActivated);\n this.tabs.set(updatedTabs);\n } else {\n this.#tabRouterService.setCurrentTab(updatedTabs[idx]);\n this.#tabRouterService.pushEvent(updatedTabs[idx], SdTabActivated);\n this.tabs.set(updatedTabs);\n }\n } else {\n // Tab chưa tồn tại → thêm mới ở cuối.\n this.#tabRouterService.setCurrentTab(newTab);\n this.tabs.set([...updatedTabs, newTab]);\n\n if (this.tabs().length > 30) {\n this.#sdNotifyService.warning(this.#i18n.t('core.component.tab-router.too-many-tabs'));\n }\n }\n\n this.tabRouterNav()?.checkUI();\n };\n\n // Lần xuống deepest firstChild để lấy snapshot của route lá (route thực sự render component).\n #getActivatedRouteSnapshot = (snapshot: ActivatedRouteSnapshot): ActivatedRouteSnapshot | null => {\n let node = snapshot;\n while (node.firstChild) node = node.firstChild;\n return node;\n };\n\n // DFS match leaf snapshot → ActivatedRoute instance (ổn định hơn so với so sánh component class).\n #findActivatedRouteForSnapshot = (activatedRoute: ActivatedRoute, targetSnapshot: ActivatedRouteSnapshot): ActivatedRoute | null => {\n if (activatedRoute.snapshot === targetSnapshot) {\n return activatedRoute;\n }\n for (const child of activatedRoute.children) {\n const result = this.#findActivatedRouteForSnapshot(child, targetSnapshot);\n if (result) {\n return result;\n }\n }\n return null;\n };\n}\n\n// Custom Injector cho từng tab: override ActivatedRoute thành route của TAB ĐÓ\n// (không phải route hiện tại của router). Nếu không override, mọi tab sẽ inject ActivatedRoute\n// của route đang active → component cũ trong tab inactive nhận data sai khi user navigate.\nclass SdOutletInjector implements Injector {\n #tab?: SdTab;\n\n constructor(\n private route: ActivatedRoute | null,\n private parentInjector: Injector\n ) {}\n\n setTab(tab: SdTab): void {\n this.#tab = tab;\n }\n\n get(token: any, notFoundValue?: any): any {\n if (token === ActivatedRoute) {\n return this.route || notFoundValue;\n }\n if (token === SD_TAB) {\n return this.#tab ?? notFoundValue;\n }\n return this.parentInjector.get(token, notFoundValue);\n }\n}\n","@if (disabled()) {\n <div class=\"tab-router__disabled-outlet\">\n <router-outlet></router-outlet>\n </div>\n} @else {\n <sd-tab-router-nav [tabs]=\"tabs()\" #tabRouterNav></sd-tab-router-nav>\n <div class=\"tab-router__list\">\n @for (tab of tabs(); track tab.injector ?? tab.key) {\n <div class=\"tab-router__pane\" [class.active]=\"tab.isActive\" [id]=\"tab.key\">\n <div class=\"tab-router__content\">\n <ng-container *ngComponentOutlet=\"tab.component; injector: tab.injector\"></ng-container>\n </div>\n </div>\n } @empty {\n <div class=\"tab-router__empty\"></div>\n }\n </div>\n}\n","import { Type } from '@angular/core';\nimport { Color } from '@sdcorejs/utils/models';\nimport { filter, take } from 'rxjs/operators';\nimport { SdTabDecoratorService } from '../services/tab-decorator.service';\n\nexport interface SdTabComponentArgs {\n url?: string;\n params?: any;\n queryParams?: any;\n data?: Record<string, any>;\n}\n\nexport declare interface SdTabComponentBuilder {\n component: Type<any>;\n name: string | ((args: SdTabComponentArgs) => string);\n icon?: string | ((args: SdTabComponentArgs) => string);\n tooltip?: string | ((args: SdTabComponentArgs) => string);\n color?: Color | ((args: SdTabComponentArgs) => Color);\n}\n\nexport function SdTabComponent<T>(builder: SdTabComponentBuilder) {\n return (constructor: T) => {\n SdTabDecoratorService.tabRouterService\n .pipe(\n filter(service => service !== undefined && service !== null),\n take(1)\n )\n .subscribe(service => {\n service.addBuilder(builder);\n });\n };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1.SdTabRouterService"],"mappings":"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"}
1
+ {"version":3,"file":"sdcorejs-angular-components-tab-router.mjs","sources":["../../../projects/sdcorejs-angular/components/tab-router/src/events/tab-router.event.ts","../../../projects/sdcorejs-angular/components/tab-router/src/models/tab-router.model.ts","../../../projects/sdcorejs-angular/components/tab-router/src/services/tab-router.service.ts","../../../projects/sdcorejs-angular/components/tab-router/src/services/tab-decorator.service.ts","../../../projects/sdcorejs-angular/components/tab-router/src/pipes/tab-info.pipe.ts","../../../projects/sdcorejs-angular/components/tab-router/src/components/tab-router-item/tab-router-item.component.ts","../../../projects/sdcorejs-angular/components/tab-router/src/components/tab-router-item/tab-router-item.component.html","../../../projects/sdcorejs-angular/components/tab-router/src/components/tab-router-nav/tab-router-nav.component.ts","../../../projects/sdcorejs-angular/components/tab-router/src/components/tab-router-nav/tab-router-nav.component.html","../../../projects/sdcorejs-angular/components/tab-router/src/components/tab-router-outlet/tab-router-outlet.component.ts","../../../projects/sdcorejs-angular/components/tab-router/src/components/tab-router-outlet/tab-router-outlet.component.html","../../../projects/sdcorejs-angular/components/tab-router/src/decorators/tab.decorator.ts","../../../projects/sdcorejs-angular/components/tab-router/sdcorejs-angular-components-tab-router.ts"],"sourcesContent":["import { SdTab } from '../models/tab-router.model';\n\nexport class SdTabBase {\n #tab: SdTab | undefined;\n\n constructor(tab: SdTab | undefined) {\n this.#tab = tab;\n }\n\n get tab(): SdTab | undefined {\n return this.#tab;\n }\n}\n\nexport class SdTabActivated extends SdTabBase {}\n\nexport class SdTabDeactivated extends SdTabBase {}\n\nexport declare type SdTabEvent = SdTabActivated | SdTabDeactivated;\n","import { InjectionToken, Type } from '@angular/core';\nimport { Color } from '@sdcorejs/utils/models';\nimport { Subject } from 'rxjs';\n\nexport interface SdTabInfo {\n name: string;\n icon?: string;\n tooltip?: string;\n color?: Color;\n}\n\nexport interface SdTab {\n component: Type<any>;\n injector?: any;\n key: string;\n isActive: boolean;\n url: string;\n params?: Record<string, string | number>;\n queryParams?: Record<string, string | number>;\n data?: Record<string, any>;\n tabInfoChanges: Subject<SdTabInfo>;\n beforeClose?: () => boolean | Promise<boolean>; // Return true thì mới được close\n}\n\nexport const SD_TAB = new InjectionToken<SdTab>('SD_TAB');\n","import { Injectable, Type } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\nimport { SdTabAction } from '../actions/tab-router.action';\nimport { SdTabComponentBuilder } from '../decorators/tab.decorator';\nimport { SdTabBase, SdTabEvent } from '../events/tab-router.event';\nimport { SdTab } from '../models/tab-router.model';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class SdTabRouterService {\n events = new BehaviorSubject<SdTabEvent>(new SdTabBase(undefined));\n actions = new BehaviorSubject<SdTabAction | undefined>(undefined);\n builders = new BehaviorSubject<SdTabComponentBuilder[]>([]);\n currentTabChanges = new BehaviorSubject<SdTab | undefined>(undefined);\n newTabs = new BehaviorSubject<SdTab | undefined>(undefined);\n updateTabs = new BehaviorSubject<SdTab | undefined>(undefined);\n #currentTab: SdTab | undefined = undefined;\n #componentBuilders: SdTabComponentBuilder[] = [];\n\n addBuilder = (builder: SdTabComponentBuilder) => {\n if (!this.#componentBuilders.some(e => e.component === builder.component)) {\n this.#componentBuilders.push(builder);\n this.builders.next(this.#componentBuilders);\n }\n };\n\n get currentTab() {\n return this.#currentTab;\n }\n\n get currentKey() {\n return this.#currentTab?.key || null;\n }\n\n // select = (tabOrKey: string | SdTab): void => {\n // const tab = this.#tabs.find(e => {\n // if (typeof (tabOrKey) === 'string') {\n // return e.key === tabOrKey;\n // }\n // return e.key === tabOrKey?.key;\n // });\n // if (tab) {\n // this.#currentTab = tab;\n // }\n // }\n\n // add = (tab: SdTab): void => {\n // if (!tab.key) {\n // this.notifyService.notify.warning('Tab key is required');\n // }\n // if (!tab.component) {\n // this.notifyService.notify.warning('Tab component is required');\n // }\n // const existedTab = this.#tabs.find(e => e.key === tab.key);\n // if (!existedTab) {\n // this.#tabs.push(tab);\n // this.select(tab);\n // } else {\n // this.select(existedTab);\n // }\n // }\n\n // remove = (tabOrKey: string | SdTab): void => {\n // this.#tabs = this.#tabs.filter(e => {\n // if (typeof (tabOrKey) === 'string') {\n // return e.key !== tabOrKey;\n // }\n // return e.key !== tabOrKey?.key;\n // });\n // }\n\n setCurrentTab = (tab: SdTab): void => {\n this.#currentTab = tab;\n this.currentTabChanges.next(tab);\n };\n\n pushEvent = (tab: SdTab, Event: Type<SdTabEvent>) => {\n this.events.next(new Event(tab));\n };\n\n setOptions = () => {};\n\n close = (tab?: SdTab) => {\n tab = tab || this.#currentTab;\n if (tab) {\n this.actions.next({\n type: 'close',\n tab,\n });\n }\n };\n\n // Gọi hàm này để thực hiện update tab\n updateTab = (tab: SdTab) => {};\n}\n","import { Injectable, inject } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\nimport { SdTabRouterService } from './tab-router.service';\n@Injectable({\n providedIn: 'root',\n})\nexport class SdTabDecoratorService {\n static tabRouterService = new BehaviorSubject<SdTabRouterService | undefined>(undefined);\n\n /** Inserted by Angular inject() migration for backwards compatibility */\n constructor(...args: unknown[]);\n constructor() {\n const tabRouterService = inject(SdTabRouterService);\n\n SdTabDecoratorService.tabRouterService.next(tabRouterService);\n }\n}\n","import { Pipe, PipeTransform, inject } from '@angular/core';\nimport { SdTab, SdTabInfo } from '../models/tab-router.model';\nimport { SdTabRouterService } from '../services/tab-router.service';\n@Pipe({\n name: 'sdTabInfo',\n standalone: true,\n})\nexport class SdTabInfoPipe implements PipeTransform {\n private tabRouterService = inject(SdTabRouterService);\n\n /** Inserted by Angular inject() migration for backwards compatibility */\n constructor(...args: unknown[]);\n\n constructor() {}\n transform(tabInfo: SdTabInfo | undefined | null, tab: SdTab): SdTabInfo {\n if (tabInfo) {\n return tabInfo;\n }\n const builders = this.tabRouterService.builders.getValue();\n const builder = builders.find(e => e.component === tab.component);\n if (builder) {\n const { url, params, queryParams, data } = tab;\n return {\n name: typeof builder.name === 'function' ? builder.name({ url, params, queryParams, data }) : builder.name,\n icon: typeof builder.icon === 'function' ? builder.icon({ url, params, queryParams }) : builder.icon,\n tooltip: typeof builder.tooltip === 'function' ? builder.tooltip({ url, params, queryParams }) : builder.tooltip,\n color: typeof builder.color === 'function' ? builder.color({ url, params, queryParams }) : builder.color,\n };\n }\n return {\n name: tab.url,\n icon: undefined,\n };\n }\n}\n","import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnDestroy, OnInit, inject } from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport { debounceTime, startWith } from 'rxjs/operators';\n\nimport { SdBadge } from '@sdcorejs/angular/components/badge';\nimport { SdTab, SdTabInfo } from '../../models';\nimport { SdTabRouterService } from '../../services/tab-router.service';\nimport { Router } from '@angular/router';\nimport { CommonModule } from '@angular/common';\nimport { SdTabInfoPipe } from '../../pipes/tab-info.pipe';\nimport { SdIcon } from '@sdcorejs/angular/modules/icon';\n\n@Component({\n selector: 'sd-tab-router-item',\n templateUrl: './tab-router-item.component.html',\n styleUrl: './tab-router-item.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [SdIcon, CommonModule, SdBadge, SdTabInfoPipe],\n})\nexport class SdTabRouterItemComponent implements OnInit, OnDestroy {\n private cdRef = inject(ChangeDetectorRef);\n private tabRouterService = inject(SdTabRouterService);\n private router = inject(Router);\n\n @Input({ required: true }) tab!: SdTab;\n\n #subsctiption: Subscription = new Subscription();\n tabInfo?: SdTabInfo;\n\n /** Inserted by Angular inject() migration for backwards compatibility */\n constructor(...args: unknown[]);\n constructor() {}\n\n ngOnInit(): void {\n this.#subsctiption.add(\n this.tabRouterService.events.pipe(debounceTime(100)).subscribe(() => {\n this.cdRef.markForCheck();\n })\n );\n\n this.#subsctiption.add(\n this.tab.tabInfoChanges.pipe(startWith(null)).subscribe(tabInfo => {\n if (tabInfo) {\n this.tabInfo = tabInfo;\n this.cdRef.markForCheck();\n }\n })\n );\n }\n\n ngOnDestroy(): void {\n this.#subsctiption.unsubscribe();\n }\n\n onTabClick = (event: Event) => {\n event.preventDefault();\n this.router.navigate([this.tab.url], {\n queryParams: this.tab.queryParams,\n state: { switchTab: true },\n });\n };\n\n close = (event: Event) => {\n event.preventDefault();\n event.stopPropagation();\n this.#closeTab();\n };\n\n onMousedown = (event: MouseEvent) => {\n if (event.button === 1) {\n event.preventDefault();\n }\n };\n\n onMouseup = (event: MouseEvent) => {\n if (event.button === 1) {\n event.preventDefault();\n event.stopPropagation();\n this.#closeTab();\n }\n };\n\n #closeTab = () => {\n this.tabRouterService.close(this.tab);\n };\n}\n","<a\n [href]=\"[tab.url]\"\n class=\"tab-router__item d-flex align-items-center gap-8\"\n [class.tab-router__item--active]=\"tab.isActive\"\n (click)=\"onTabClick($event)\"\n (mousedown)=\"onMousedown($event)\"\n (mouseup)=\"onMouseup($event)\">\n @let info = tabInfo | sdTabInfo: tab;\n @if (info) {\n <sd-badge\n style=\"overflow: hidden;white-space: nowrap;\"\n [icon]=\"info.icon\"\n [title]=\"info.icon\"\n [tooltip]=\"info.tooltip || info.name\"\n [title]=\"info.name\"\n [color]=\"info.color\"\n (click)=\"onTabClick($event)\"></sd-badge>\n <button\n aria-hidden=\"true\"\n class=\"tab-router__close d-flex align-items-center justify-content-center ml-auto p-0\"\n (click)=\"close($event)\"\n (mousedown)=\"$event.stopPropagation()\">\n <sd-icon aria-hidden=\"true\" fontIcon=\"close\"></sd-icon>\n </button>\n }\n</a>\n","import { CdkDragDrop, DragDropModule, moveItemInArray } from '@angular/cdk/drag-drop';\nimport { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, HostListener, inject, input, viewChild } from '@angular/core';\n\nimport { SdTab } from '../../models/tab-router.model';\nimport { SdTabRouterItemComponent } from '../tab-router-item/tab-router-item.component';\nimport { CommonModule } from '@angular/common';\n\n@Component({\n selector: 'sd-tab-router-nav',\n templateUrl: './tab-router-nav.component.html',\n styleUrl: './tab-router-nav.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [CommonModule, DragDropModule, SdTabRouterItemComponent],\n})\nexport class SdTabRouterNavComponent {\n tabRouterNav = viewChild<ElementRef>('tabRouterNav');\n\n tabs = input<SdTab[]>([]);\n mode: 'default' | 'compact' = 'default';\n cdRef = inject(ChangeDetectorRef);\n elementRef = inject<ElementRef<any>>(ElementRef);\n\n @HostListener('window:resize')\n onResize(): void {\n this.checkUI();\n }\n\n checkUI = () => {\n const width = this.tabRouterNav()?.nativeElement.clientWidth ?? 0;\n const tabs = this.tabs();\n if (tabs.length === 0) {\n this.mode = 'default';\n this.cdRef.markForCheck();\n return;\n }\n\n const nameWidth = (width - tabs.length * 68) / tabs.length;\n if (nameWidth <= 20) {\n this.mode = 'compact';\n } else {\n this.mode = 'default';\n }\n this.cdRef.markForCheck();\n };\n\n onDrop = (event: CdkDragDrop<SdTab[]>) => {\n moveItemInArray(this.tabs(), event.previousIndex, event.currentIndex);\n };\n}\n","<div\n #tabRouterNav\n cdkDropList\n cdkDropListLockAxis=\"x\"\n cdkDropListOrientation=\"horizontal\"\n (cdkDropListDropped)=\"onDrop($event)\"\n class=\"tab-router__nav tab-router__nav--{{ mode }} d-flex align-items-center flex-nowrap\"\n [class.d-none]=\"tabs().length > 1\">\n @for (tab of tabs(); track tab.injector ?? tab.key) {\n <sd-tab-router-item [tab]=\"tab\" cdkDrag [cdkDragBoundary]=\"elementRef.nativeElement\"></sd-tab-router-item>\n }\n</div>\n","import {\n afterNextRender,\n booleanAttribute,\n Component,\n Injector,\n OnDestroy,\n Type,\n inject,\n input,\n signal,\n viewChild,\n createNgModule,\n NgModuleFactory,\n} from '@angular/core';\nimport {\n ActivatedRoute,\n ActivatedRouteSnapshot,\n NavigationCancel,\n NavigationEnd,\n NavigationError,\n NavigationSkipped,\n NavigationSkippedCode,\n Router,\n RouterOutlet,\n RoutesRecognized,\n} from '@angular/router';\nimport { CommonModule } from '@angular/common';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { from, Subject, Subscription, isObservable, lastValueFrom } from 'rxjs';\nimport { concatMap, filter, map } from 'rxjs/operators';\n\nimport { SdNotifyService } from '@sdcorejs/angular/services/notify';\nimport { I18nService } from '@sdcorejs/angular/i18n';\nimport { Utilities } from '@sdcorejs/utils/fns';\nimport { SdTabActivated, SdTabDeactivated } from '../../events/tab-router.event';\nimport { SdTabAction } from '../../actions/tab-router.action';\nimport { SdTab, SD_TAB } from '../../models';\nimport { SdTabDecoratorService } from '../../services/tab-decorator.service';\nimport { SdTabRouterService } from '../../services/tab-router.service';\nimport { SdTabRouterNavComponent } from '../tab-router-nav/tab-router-nav.component';\n\ntype TabRouterNavigationEvent = RoutesRecognized | NavigationEnd | NavigationSkipped | NavigationCancel | NavigationError;\n\ninterface TabRouterNavigationContext {\n event: TabRouterNavigationEvent;\n navigationState: Record<string, any>;\n}\n\n@Component({\n selector: 'sd-tab-router-outlet',\n templateUrl: './tab-router-outlet.component.html',\n styleUrl: './tab-router-outlet.component.scss',\n standalone: true,\n imports: [CommonModule, MatTooltipModule, RouterOutlet, SdTabRouterNavComponent],\n})\nexport class SdTabRouterOutletComponent implements OnDestroy {\n disabled = input(false, { transform: booleanAttribute });\n\n tabRouterNav = viewChild<SdTabRouterNavComponent>('tabRouterNav');\n\n tabs = signal<SdTab[]>([]);\n\n #router = inject(Router);\n #injector = inject(Injector);\n #tabRouterService = inject(SdTabRouterService);\n #sdNotifyService = inject(SdNotifyService);\n readonly #i18n = inject(I18nService);\n // Inject để đảm bảo SdTabDecoratorService được khởi tạo (nó register BehaviorSubject\n // tĩnh để @SdTab decorator có thể truy cập SdTabRouterService). Không dùng trực tiếp ở đây.\n #tabDecoratorService = inject(SdTabDecoratorService);\n\n #rootRoute?: ActivatedRoute;\n #subscription = new Subscription();\n\n // Lưu state theo navigation id để các navigation chồng lấn không ghi đè lẫn nhau.\n #pendingNavigationStates = new Map<number, Record<string, any>>();\n // Serialize mọi #activeRoute (router events + initial sync) để tránh race tạo duplicate tab.\n #activationQueue: Promise<void> = Promise.resolve();\n\n constructor() {\n this.#subscription.add(\n this.#router.events\n .pipe(\n // KHÔNG unwrap event.routerEvent (vd Scroll wrap NavigationEnd):\n // Angular emit NavigationEnd RAW trước, RouterScroller emit Scroll(NavigationEnd) sau.\n // Nếu unwrap thêm Scroll → handler fire 2 lần cho 1 nav → race condition tạo duplicate tabs.\n // Navigation thành công cần CẢ HAI event vì mỗi event chứa data ở thời điểm khác nhau.\n // - RoutesRecognized: navigation đang in-flight → getCurrentNavigation().extras.state đọc được\n // - NavigationEnd: navigation hoàn tất → routerState.root đã update với route mới (cần cho lazy routes)\n // Các terminal event khác chỉ xử lý same-URL forceReload hoặc dọn state theo navigation id.\n filter(\n (event): event is TabRouterNavigationEvent =>\n event instanceof RoutesRecognized ||\n event instanceof NavigationEnd ||\n event instanceof NavigationSkipped ||\n event instanceof NavigationCancel ||\n event instanceof NavigationError\n ),\n // Chụp getCurrentNavigation đồng bộ vì concatMap có thể chạy sau khi Angular đã xoá navigation hiện tại.\n map(\n (event): TabRouterNavigationContext => ({\n event,\n navigationState: this.#router.getCurrentNavigation()?.extras?.state ?? {},\n })\n ),\n // Serialize: #handleEvent async (await getBestInjector). 2 nav liên tiếp\n // không await xen kẽ → tránh race đọc this.tabs() = [] khi tab đầu chưa kịp set.\n concatMap(context => from(this.#handleEvent(context)))\n )\n .subscribe()\n );\n\n this.#subscription.add(\n this.#tabRouterService.actions.subscribe((event: SdTabAction | undefined) => {\n if (this.disabled()) return;\n\n if (event?.type === 'close') {\n this.#closeTab(event.tab);\n }\n })\n );\n\n // Initial navigation có thể hoàn tất trước khi outlet subscribe router.events\n // (blocking init hoặc outlet mount muộn). Catch-up sau first render.\n afterNextRender(() => {\n void this.#syncCurrentRoute();\n });\n }\n\n ngOnDestroy(): void {\n this.#subscription.unsubscribe();\n this.#pendingNavigationStates.clear();\n }\n\n #scheduleActivation = (task: () => Promise<void>): Promise<void> => {\n const run = this.#activationQueue.then(task);\n this.#activationQueue = run.catch(() => undefined);\n return run;\n };\n\n #handleEvent = async ({ event, navigationState }: TabRouterNavigationContext): Promise<void> => {\n if (this.disabled()) {\n this.#pendingNavigationStates.clear();\n return;\n }\n if (event instanceof RoutesRecognized) {\n this.#pendingNavigationStates.set(event.id, navigationState);\n return;\n }\n\n if (event instanceof NavigationCancel || event instanceof NavigationError) {\n this.#pendingNavigationStates.delete(event.id);\n return;\n }\n\n let state: Record<string, any>;\n let fullUrl: string;\n if (event instanceof NavigationSkipped) {\n this.#pendingNavigationStates.delete(event.id);\n if (event.code !== NavigationSkippedCode.IgnoredSameUrlNavigation || navigationState['forceReload'] !== true) {\n return;\n }\n state = navigationState;\n fullUrl = event.url;\n } else {\n state = this.#pendingNavigationStates.get(event.id) ?? navigationState;\n this.#pendingNavigationStates.delete(event.id);\n fullUrl = event.urlAfterRedirects || event.url;\n }\n\n await this.#scheduleActivation(async () => {\n const route = this.#getActivatedRouteSnapshot(this.#router.routerState.snapshot.root);\n this.#rootRoute = this.#router.routerState.root;\n await this.#activeRoute(fullUrl, route, state);\n });\n };\n\n // Bù initial navigation nếu NavigationEnd đã fire trước khi outlet subscribe.\n #syncCurrentRoute = (): Promise<void> => {\n if (this.disabled() || !this.#router.navigated) {\n return Promise.resolve();\n }\n\n const route = this.#getActivatedRouteSnapshot(this.#router.routerState.snapshot.root);\n if (!route?.component) {\n return Promise.resolve();\n }\n\n const [urlPath] = this.#router.url.split('?');\n const key = Utilities.hash({\n url: urlPath,\n queryParams: { ...(route.queryParams || {}) },\n });\n\n if (this.tabs().some(tab => tab.key === key)) {\n return Promise.resolve();\n }\n\n return this.#scheduleActivation(async () => {\n if (this.tabs().some(tab => tab.key === key)) {\n return;\n }\n this.#rootRoute = this.#router.routerState.root;\n await this.#activeRoute(this.#router.url, route, {});\n });\n };\n\n tabTrackBy = (index: number, tab: SdTab) => tab.key;\n\n #closeTab = async (tab: SdTab): Promise<void> => {\n if (this.disabled()) return;\n\n if (tab.beforeClose) {\n let canClose: boolean;\n try {\n const result = tab.beforeClose();\n canClose = typeof result === 'boolean' ? result : await result;\n } catch {\n canClose = false;\n }\n if (!canClose) return;\n }\n\n const currentTabs = this.tabs();\n const { isActive, key: activeKey } = tab;\n\n if (isActive) {\n const activeIndex = currentTabs.findIndex(({ key }) => key === activeKey);\n const nextTab = currentTabs[activeIndex + 1] || currentTabs[activeIndex - 1];\n\n this.tabs.set(currentTabs.filter(({ key }) => key !== activeKey));\n\n if (nextTab) {\n this.#router.navigate([nextTab.url], {\n queryParams: { ...(nextTab.queryParams || {}) },\n state: { switchTab: true },\n });\n } else {\n this.#router.navigateByUrl('/', { state: { switchTab: true } });\n }\n } else {\n this.tabs.set(currentTabs.filter(({ key }) => key !== tab.key));\n this.tabRouterNav()?.checkUI();\n }\n };\n\n #activeRoute = async (fullUrl: string, route: ActivatedRouteSnapshot | null, state: Record<string, any> = {}) => {\n if (this.disabled()) return;\n if (!route?.component) return;\n\n const component = route.component as Type<any>;\n const queryParams = { ...(route.queryParams || {}) };\n const params = { ...(route.params || {}) };\n const data = { ...(route.data || {}) };\n const [url] = fullUrl.split('?');\n // Tab identity = hash(url + queryParams). Cùng key mặc định giữ tab cũ; forceReload mới tạo lại.\n const key = Utilities.hash({ url, queryParams });\n\n let existedIndex = -1;\n let activatedIndex = -1;\n\n const currentTabs = this.tabs();\n\n // QUAN TRỌNG: scan READ-ONLY, KHÔNG mutate tab.isActive trong loop này.\n //\n // Lý do: NavigationEnd có thể fire nhiều lần cho 1 user-action (do nested outlets,\n // redirect, hoặc Angular internal). Vì #activeRoute là async (await getBestInjector),\n // 2 invocations có thể chạy concurrent và interleave với nhau.\n //\n // Nếu mutate tab.isActive = false ở đây, call thứ 2 sẽ thấy isActive đã bị call 1\n // set false rồi → không tìm thấy active tab → activatedIndex stay -1 → splice bỏ qua\n // → tab cũ không bị remove → xuất hiện duplicate tabs.\n //\n // Cách fix: chỉ ĐỌC isActive, sau đó dùng .map() ở dưới để tạo tab objects mới qua spread.\n for (let i = 0; i < currentTabs.length; i++) {\n const tab = currentTabs[i];\n if (tab.key === key) {\n existedIndex = i;\n } else if (tab.isActive) {\n activatedIndex = i;\n this.#tabRouterService.pushEvent(tab, SdTabDeactivated);\n }\n }\n\n const replaceTab = state['replaceTab'];\n const forceReload = state['forceReload'] === true;\n\n // Resolve injector phù hợp với route. Cần xử lý 3 trường hợp:\n // - Standalone route (Angular đã set _injector trên routeConfig sau khi activate)\n // - NgModule lazy load (cần createNgModule từ class)\n // - Fallback: root injector\n const getBestInjector = async (snapshot: ActivatedRouteSnapshot): Promise<Injector> => {\n // Standalone route: Angular tự lưu environment injector trên routeConfig._injector\n const routeInjector = (snapshot as any)._resolvedGui || (snapshot as any).routeConfig?._injector;\n if (routeInjector) return routeInjector;\n\n // NgModule lazy: phải gọi lại loadChildren() để lấy module class rồi createNgModule\n const loadChildren = snapshot.parent?.routeConfig?.loadChildren;\n if (typeof loadChildren === 'function') {\n let loaded: any = await loadChildren();\n\n if (isObservable(loaded)) {\n loaded = await lastValueFrom(loaded);\n }\n\n // ES module có thể export default\n if (loaded && typeof loaded === 'object' && 'default' in loaded) {\n loaded = loaded.default;\n }\n\n // Angular cũ: NgModuleFactory\n if (loaded instanceof NgModuleFactory) {\n return loaded.create(this.#injector).injector;\n }\n\n // Angular mới: NgModule class. Bọc try/catch vì createNgModule throw nếu không phải NgModule.\n if (typeof loaded === 'function' && !Array.isArray(loaded)) {\n try {\n return createNgModule(loaded, this.#injector).injector;\n } catch {\n return this.#injector;\n }\n }\n }\n return this.#injector;\n };\n\n const finalInjector = await getBestInjector(route);\n // Refresh root sau await: lazy route tree có thể hoàn tất trong lúc resolve injector.\n this.#rootRoute = this.#router.routerState.root;\n const activatedRoute = this.#findActivatedRouteForSnapshot(this.#rootRoute, route);\n\n const sdInjector = new SdOutletInjector(activatedRoute, finalInjector);\n const newTab: SdTab = {\n key,\n component,\n injector: sdInjector,\n isActive: true,\n url,\n params,\n queryParams,\n data,\n tabInfoChanges: new Subject(),\n };\n sdInjector.setTab(newTab);\n\n // Tạo updatedTabs qua spread thay vì mutate (xem lý do ở for loop phía trên).\n // Với tab có isActive không đổi: giữ nguyên reference (tránh trigger ngComponentOutlet\n // re-evaluate không cần thiết). Với tab cần đổi isActive: tạo object mới qua spread,\n // các nested fields (component, injector) vẫn giữ same reference nên component không bị recreate.\n let updatedTabs = currentTabs.map(tab => {\n if (tab.key === key) return tab.isActive ? tab : { ...tab, isActive: true };\n return tab.isActive ? { ...tab, isActive: false } : tab;\n });\n\n // replaceTab: thay vì mở tab mới song song, xoá tab đang active rồi mở tab mới ở cuối.\n // Use case: từ tab \"chi tiết\" bấm \"chỉnh sửa\" với replaceTab → tab chi tiết bị xoá,\n // tab chỉnh sửa thay thế (giữ số tab không tăng).\n if (replaceTab && activatedIndex >= 0) {\n updatedTabs = updatedTabs.filter((_, i) => i !== activatedIndex);\n }\n\n if (existedIndex >= 0) {\n // Mặc định tab đã tồn tại chỉ được activate, không thay tab object. forceReload là nhánh\n // explicit duy nhất thay SdTab + injector để body và nav item được tạo lại.\n //\n // splice phía trên có thể đã shift index nếu activatedIndex < existedIndex.\n const idx = replaceTab && activatedIndex >= 0 && activatedIndex < existedIndex ? existedIndex - 1 : existedIndex;\n if (forceReload) {\n updatedTabs = updatedTabs.map((tab, index) => (index === idx ? newTab : tab));\n this.#tabRouterService.setCurrentTab(newTab);\n this.#tabRouterService.pushEvent(newTab, SdTabActivated);\n this.tabs.set(updatedTabs);\n } else {\n this.#tabRouterService.setCurrentTab(updatedTabs[idx]);\n this.#tabRouterService.pushEvent(updatedTabs[idx], SdTabActivated);\n this.tabs.set(updatedTabs);\n }\n } else {\n // Tab chưa tồn tại → thêm mới ở cuối.\n this.#tabRouterService.setCurrentTab(newTab);\n this.tabs.set([...updatedTabs, newTab]);\n\n if (this.tabs().length > 30) {\n this.#sdNotifyService.warning(this.#i18n.t('core.component.tab-router.too-many-tabs'));\n }\n }\n\n this.tabRouterNav()?.checkUI();\n };\n\n // Lần xuống deepest firstChild để lấy snapshot của route lá (route thực sự render component).\n #getActivatedRouteSnapshot = (snapshot: ActivatedRouteSnapshot): ActivatedRouteSnapshot | null => {\n let node = snapshot;\n while (node.firstChild) node = node.firstChild;\n return node;\n };\n\n // DFS match leaf snapshot → ActivatedRoute instance (ổn định hơn so với so sánh component class).\n #findActivatedRouteForSnapshot = (activatedRoute: ActivatedRoute, targetSnapshot: ActivatedRouteSnapshot): ActivatedRoute | null => {\n if (activatedRoute.snapshot === targetSnapshot) {\n return activatedRoute;\n }\n for (const child of activatedRoute.children) {\n const result = this.#findActivatedRouteForSnapshot(child, targetSnapshot);\n if (result) {\n return result;\n }\n }\n return null;\n };\n}\n\n// Custom Injector cho từng tab: override ActivatedRoute thành route của TAB ĐÓ\n// (không phải route hiện tại của router). Nếu không override, mọi tab sẽ inject ActivatedRoute\n// của route đang active → component cũ trong tab inactive nhận data sai khi user navigate.\nclass SdOutletInjector implements Injector {\n #tab?: SdTab;\n\n constructor(\n private route: ActivatedRoute | null,\n private parentInjector: Injector\n ) {}\n\n setTab(tab: SdTab): void {\n this.#tab = tab;\n }\n\n get(token: any, notFoundValue?: any): any {\n if (token === ActivatedRoute) {\n return this.route || notFoundValue;\n }\n if (token === SD_TAB) {\n return this.#tab ?? notFoundValue;\n }\n return this.parentInjector.get(token, notFoundValue);\n }\n}\n","@if (disabled()) {\n <div class=\"tab-router__disabled-outlet\">\n <router-outlet></router-outlet>\n </div>\n} @else {\n <sd-tab-router-nav [tabs]=\"tabs()\" #tabRouterNav></sd-tab-router-nav>\n <div class=\"tab-router__list\">\n @for (tab of tabs(); track tab.injector ?? tab.key) {\n <div class=\"tab-router__pane\" [class.active]=\"tab.isActive\" [id]=\"tab.key\">\n <div class=\"tab-router__content\">\n <ng-container *ngComponentOutlet=\"tab.component; injector: tab.injector\"></ng-container>\n </div>\n </div>\n } @empty {\n <div class=\"tab-router__empty\"></div>\n }\n </div>\n}\n","import { Type } from '@angular/core';\nimport { Color } from '@sdcorejs/utils/models';\nimport { filter, take } from 'rxjs/operators';\nimport { SdTabDecoratorService } from '../services/tab-decorator.service';\n\nexport interface SdTabComponentArgs {\n url?: string;\n params?: any;\n queryParams?: any;\n data?: Record<string, any>;\n}\n\nexport declare interface SdTabComponentBuilder {\n component: Type<any>;\n name: string | ((args: SdTabComponentArgs) => string);\n icon?: string | ((args: SdTabComponentArgs) => string);\n tooltip?: string | ((args: SdTabComponentArgs) => string);\n color?: Color | ((args: SdTabComponentArgs) => Color);\n}\n\nexport function SdTabComponent<T>(builder: SdTabComponentBuilder) {\n return (constructor: T) => {\n SdTabDecoratorService.tabRouterService\n .pipe(\n filter(service => service !== undefined && service !== null),\n take(1)\n )\n .subscribe(service => {\n service.addBuilder(builder);\n });\n };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}