@sd-angular/core 19.0.0-beta.94 → 19.0.0-beta.96

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 (194) hide show
  1. package/README.md +10 -10
  2. package/components/anchor/src/components/anchor/anchor.component.d.ts +4 -1
  3. package/components/anchor/src/components/anchor-item/anchor-item.component.d.ts +2 -1
  4. package/components/anchor/src/components/anchor-vertical/anchor-vertical-list.component.d.ts +3 -1
  5. package/components/badge/src/badge.component.d.ts +3 -4
  6. package/components/button/src/button.component.d.ts +2 -2
  7. package/components/document-builder/src/components/header-footer-builder/header-footer-builder.component.d.ts +2 -2
  8. package/components/document-builder/src/document-builder.model.d.ts +2 -2
  9. package/components/editor/src/models/editor.model.d.ts +2 -2
  10. package/components/editor/src/plugins/image-upload/utils/validate.utils.d.ts +2 -2
  11. package/components/form-generic/src/components/form-builder/components/attribute-table/attribute-table.component.d.ts +4 -2
  12. package/components/form-generic/src/components/form-builder/components/attribute-template/attribute-template.component.d.ts +2 -2
  13. package/components/form-generic/src/components/form-builder/components/configure-validation/configure-validation.component.d.ts +2 -2
  14. package/components/form-generic/src/components/form-builder/components/group/attribute/group-attribute.component.d.ts +23 -0
  15. package/components/form-generic/src/components/form-builder/components/group/index.d.ts +1 -0
  16. package/components/form-generic/src/components/form-builder/components/index.d.ts +1 -0
  17. package/components/form-generic/src/components/form-builder/components/table/control/table-control.component.d.ts +3 -0
  18. package/components/form-generic/src/components/form-builder/form-builder.component.d.ts +61 -18
  19. package/components/form-generic/src/components/form-render/form-render.component.d.ts +2 -2
  20. package/components/form-generic/src/models/form-generic-component.model.d.ts +22 -2
  21. package/components/index.d.ts +1 -2
  22. package/components/modal/src/modal.component.d.ts +5 -3
  23. package/components/preview/index.d.ts +3 -0
  24. package/components/preview/src/preview-image/preview-image.component.d.ts +84 -24
  25. package/components/preview/src/preview-image/preview-image.types.d.ts +53 -0
  26. package/components/preview/src/preview-pdf/preview-pdf.component.d.ts +186 -0
  27. package/components/preview/src/preview-pdf/preview-pdf.types.d.ts +84 -0
  28. package/components/quick-action/src/quick-action.component.d.ts +5 -6
  29. package/components/section/src/section.component.d.ts +1 -2
  30. package/components/table/src/components/column-filter/column-filter.component.d.ts +3 -3
  31. package/components/table/src/table.component.d.ts +2 -2
  32. package/components/upload-file/src/upload-file.component.d.ts +4 -1
  33. package/configurations/src/sd-core.configuration.d.ts +2 -1
  34. package/fesm2022/sd-angular-core-components-anchor.mjs +19 -6
  35. package/fesm2022/sd-angular-core-components-anchor.mjs.map +1 -1
  36. package/fesm2022/sd-angular-core-components-button.mjs +1 -1
  37. package/fesm2022/sd-angular-core-components-button.mjs.map +1 -1
  38. package/fesm2022/sd-angular-core-components-code-editor.mjs +3 -3
  39. package/fesm2022/sd-angular-core-components-code-editor.mjs.map +1 -1
  40. package/fesm2022/sd-angular-core-components-document-builder.mjs +3 -3
  41. package/fesm2022/sd-angular-core-components-document-builder.mjs.map +1 -1
  42. package/fesm2022/sd-angular-core-components-editor.mjs +3 -3
  43. package/fesm2022/sd-angular-core-components-editor.mjs.map +1 -1
  44. package/fesm2022/sd-angular-core-components-form-generic.mjs +627 -317
  45. package/fesm2022/sd-angular-core-components-form-generic.mjs.map +1 -1
  46. package/fesm2022/sd-angular-core-components-history.mjs +3 -3
  47. package/fesm2022/sd-angular-core-components-history.mjs.map +1 -1
  48. package/fesm2022/sd-angular-core-components-import-excel.mjs +5 -5
  49. package/fesm2022/sd-angular-core-components-import-excel.mjs.map +1 -1
  50. package/fesm2022/sd-angular-core-components-modal.mjs +8 -3
  51. package/fesm2022/sd-angular-core-components-modal.mjs.map +1 -1
  52. package/fesm2022/sd-angular-core-components-preview.mjs +1963 -91
  53. package/fesm2022/sd-angular-core-components-preview.mjs.map +1 -1
  54. package/fesm2022/sd-angular-core-components-quick-action.mjs +8 -19
  55. package/fesm2022/sd-angular-core-components-quick-action.mjs.map +1 -1
  56. package/fesm2022/sd-angular-core-components-tab-router.mjs +31 -26
  57. package/fesm2022/sd-angular-core-components-tab-router.mjs.map +1 -1
  58. package/fesm2022/sd-angular-core-components-table.mjs +32 -29
  59. package/fesm2022/sd-angular-core-components-table.mjs.map +1 -1
  60. package/fesm2022/sd-angular-core-components-upload-file.mjs +12 -8
  61. package/fesm2022/sd-angular-core-components-upload-file.mjs.map +1 -1
  62. package/fesm2022/sd-angular-core-components.mjs +1 -2
  63. package/fesm2022/sd-angular-core-components.mjs.map +1 -1
  64. package/fesm2022/sd-angular-core-configurations.mjs.map +1 -1
  65. package/fesm2022/sd-angular-core-directives.mjs +2 -2
  66. package/fesm2022/sd-angular-core-directives.mjs.map +1 -1
  67. package/fesm2022/sd-angular-core-forms-autocomplete.mjs +2 -2
  68. package/fesm2022/sd-angular-core-forms-autocomplete.mjs.map +1 -1
  69. package/fesm2022/sd-angular-core-forms-checkbox.mjs +6 -13
  70. package/fesm2022/sd-angular-core-forms-checkbox.mjs.map +1 -1
  71. package/fesm2022/sd-angular-core-forms-chip-calendar.mjs +6 -5
  72. package/fesm2022/sd-angular-core-forms-chip-calendar.mjs.map +1 -1
  73. package/fesm2022/sd-angular-core-forms-chip.mjs +6 -12
  74. package/fesm2022/sd-angular-core-forms-chip.mjs.map +1 -1
  75. package/fesm2022/sd-angular-core-forms-date-range.mjs +33 -26
  76. package/fesm2022/sd-angular-core-forms-date-range.mjs.map +1 -1
  77. package/fesm2022/sd-angular-core-forms-date.mjs +29 -19
  78. package/fesm2022/sd-angular-core-forms-date.mjs.map +1 -1
  79. package/fesm2022/sd-angular-core-forms-datetime.mjs +98 -57
  80. package/fesm2022/sd-angular-core-forms-datetime.mjs.map +1 -1
  81. package/fesm2022/sd-angular-core-forms-input-number.mjs +2 -2
  82. package/fesm2022/sd-angular-core-forms-input-number.mjs.map +1 -1
  83. package/fesm2022/sd-angular-core-forms-input.mjs +25 -10
  84. package/fesm2022/sd-angular-core-forms-input.mjs.map +1 -1
  85. package/fesm2022/sd-angular-core-forms-radio.mjs +7 -15
  86. package/fesm2022/sd-angular-core-forms-radio.mjs.map +1 -1
  87. package/fesm2022/sd-angular-core-forms-select.mjs +4 -4
  88. package/fesm2022/sd-angular-core-forms-select.mjs.map +1 -1
  89. package/fesm2022/sd-angular-core-forms-switch.mjs +6 -14
  90. package/fesm2022/sd-angular-core-forms-switch.mjs.map +1 -1
  91. package/fesm2022/sd-angular-core-forms-textarea.mjs +5 -5
  92. package/fesm2022/sd-angular-core-forms-textarea.mjs.map +1 -1
  93. package/fesm2022/sd-angular-core-handlers.mjs +2 -2
  94. package/fesm2022/sd-angular-core-handlers.mjs.map +1 -1
  95. package/fesm2022/sd-angular-core-i18n.mjs +1610 -38
  96. package/fesm2022/sd-angular-core-i18n.mjs.map +1 -1
  97. package/fesm2022/sd-angular-core-interceptors.mjs +2 -2
  98. package/fesm2022/sd-angular-core-interceptors.mjs.map +1 -1
  99. package/fesm2022/sd-angular-core-models.mjs +6 -0
  100. package/fesm2022/sd-angular-core-models.mjs.map +1 -0
  101. package/fesm2022/sd-angular-core-modules-layout.mjs +87 -39
  102. package/fesm2022/sd-angular-core-modules-layout.mjs.map +1 -1
  103. package/fesm2022/sd-angular-core-services-confirm.mjs +2 -2
  104. package/fesm2022/sd-angular-core-services-confirm.mjs.map +1 -1
  105. package/fesm2022/sd-angular-core-services-docx.mjs +2 -2
  106. package/fesm2022/sd-angular-core-services-docx.mjs.map +1 -1
  107. package/fesm2022/sd-angular-core-services-excel.mjs +27 -23
  108. package/fesm2022/sd-angular-core-services-excel.mjs.map +1 -1
  109. package/fesm2022/sd-angular-core-services-notify.mjs +21 -21
  110. package/fesm2022/sd-angular-core-services-notify.mjs.map +1 -1
  111. package/fesm2022/sd-angular-core-utilities-extensions.mjs +74 -830
  112. package/fesm2022/sd-angular-core-utilities-extensions.mjs.map +1 -1
  113. package/fesm2022/sd-angular-core-utilities-models.mjs +36 -136
  114. package/fesm2022/sd-angular-core-utilities-models.mjs.map +1 -1
  115. package/fesm2022/sd-angular-core.mjs +0 -1
  116. package/fesm2022/sd-angular-core.mjs.map +1 -1
  117. package/forms/autocomplete/src/autocomplete.component.d.ts +1 -2
  118. package/forms/checkbox/src/checkbox.component.d.ts +3 -3
  119. package/forms/chip/src/chip.component.d.ts +4 -4
  120. package/forms/chip-calendar/src/chip-calendar.component.d.ts +4 -4
  121. package/forms/date/src/date.component.d.ts +3 -5
  122. package/forms/date-range/src/date-range.component.d.ts +3 -5
  123. package/forms/datetime/src/datetime.component.d.ts +2 -2
  124. package/forms/datetime/src/popup/sd-datetime-picker.component.d.ts +10 -11
  125. package/forms/input/src/input.component.d.ts +1 -2
  126. package/forms/input-number/src/input-number.component.d.ts +1 -2
  127. package/forms/radio/src/radio.component.d.ts +3 -3
  128. package/forms/select/src/select.component.d.ts +5 -5
  129. package/forms/switch/src/switch.component.d.ts +3 -3
  130. package/forms/textarea/src/textarea.component.d.ts +1 -2
  131. package/i18n/index.d.ts +5 -5
  132. package/i18n/src/en.d.ts +406 -2
  133. package/i18n/src/i18n.messages.d.ts +2 -0
  134. package/i18n/src/i18n.pipe.d.ts +9 -0
  135. package/i18n/src/i18n.service.d.ts +14 -0
  136. package/i18n/src/i18n.token.d.ts +1 -0
  137. package/i18n/src/i18n.types.d.ts +31 -0
  138. package/i18n/src/ja.d.ts +2 -0
  139. package/i18n/src/ko.d.ts +2 -0
  140. package/i18n/src/vi.d.ts +2 -312
  141. package/i18n/src/zh.d.ts +2 -0
  142. package/models/index.d.ts +1 -0
  143. package/models/src/language.model.d.ts +2 -0
  144. package/modules/layout/modules/home/components/home-page/home-page.component.d.ts +25 -0
  145. package/package.json +82 -89
  146. package/public-api.d.ts +0 -1
  147. package/sd-angular-core-19.0.0-beta.96.tgz +0 -0
  148. package/services/notify/index.d.ts +1 -1
  149. package/services/notify/src/components/toast/toast.component.d.ts +3 -3
  150. package/services/notify/src/components/toast-container.component.d.ts +3 -4
  151. package/services/notify/src/notify.model.d.ts +1 -1
  152. package/services/notify/src/notify.service.d.ts +5 -5
  153. package/utilities/extensions/src/array.extension.d.ts +1 -7
  154. package/utilities/extensions/src/color.extension.d.ts +5 -20
  155. package/utilities/extensions/src/date.extension.d.ts +1 -18
  156. package/utilities/extensions/src/number.extension.d.ts +1 -10
  157. package/utilities/extensions/src/string.extension.d.ts +30 -4
  158. package/utilities/extensions/src/utility.extension.d.ts +6 -0
  159. package/utilities/models/src/color.model.d.ts +4 -1
  160. package/utilities/models/src/empty.model.d.ts +3 -0
  161. package/utilities/models/src/filter.model.d.ts +12 -24
  162. package/utilities/models/src/maybe-async.model.d.ts +10 -4
  163. package/utilities/models/src/nested-key-of.model.d.ts +4 -5
  164. package/utilities/models/src/operator.model.d.ts +9 -4
  165. package/utilities/models/src/order.model.d.ts +4 -5
  166. package/utilities/models/src/paging.model.d.ts +8 -16
  167. package/utilities/models/src/pattern.model.d.ts +13 -0
  168. package/utilities/models/src/size.model.d.ts +4 -1
  169. package/components/anchor-v2/index.d.ts +0 -1
  170. package/components/anchor-v2/src/components/anchor-item-v2/anchor-item-v2.component.d.ts +0 -12
  171. package/components/anchor-v2/src/components/anchor-v2/anchor-v2.component.d.ts +0 -19
  172. package/components/anchor-v2/src/components/anchor-vertical-v2/anchor-vertical-list-v2.component.d.ts +0 -16
  173. package/components/anchor-v2/src/components/index.d.ts +0 -2
  174. package/components/anchor-v2/src/index.d.ts +0 -2
  175. package/components/anchor-v2/src/models/index.d.ts +0 -1
  176. package/components/anchor-v2/src/models/sd-anchor-v2.model.d.ts +0 -7
  177. package/components/workflow/index.d.ts +0 -2
  178. package/components/workflow/src/configurations/index.d.ts +0 -1
  179. package/components/workflow/src/configurations/workflow.configuration.d.ts +0 -10
  180. package/fesm2022/sd-angular-core-components-anchor-v2.mjs +0 -151
  181. package/fesm2022/sd-angular-core-components-anchor-v2.mjs.map +0 -1
  182. package/fesm2022/sd-angular-core-components-workflow.mjs +0 -17
  183. package/fesm2022/sd-angular-core-components-workflow.mjs.map +0 -1
  184. package/fesm2022/sd-angular-core-services-firebase.mjs +0 -38
  185. package/fesm2022/sd-angular-core-services-firebase.mjs.map +0 -1
  186. package/i18n/src/sd-i18n.messages.d.ts +0 -2
  187. package/i18n/src/sd-i18n.pipe.d.ts +0 -9
  188. package/i18n/src/sd-i18n.service.d.ts +0 -12
  189. package/i18n/src/sd-i18n.token.d.ts +0 -1
  190. package/i18n/src/sd-i18n.types.d.ts +0 -5
  191. package/sd-angular-core-19.0.0-beta.94.tgz +0 -0
  192. package/services/firebase/index.d.ts +0 -2
  193. package/services/firebase/src/firebase.model.d.ts +0 -8
  194. package/services/firebase/src/firebase.service.d.ts +0 -14
@@ -1,16 +1,16 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Injectable, Pipe, Input, ChangeDetectionStrategy, Component, viewChild, input, inject, ChangeDetectorRef, ElementRef, HostListener, booleanAttribute, signal, Injector, NgModuleFactory, createNgModule } from '@angular/core';
3
3
  import * as i2 from '@angular/router';
4
- import { Router, ActivatedRoute, RouterEvent, RoutesRecognized, NavigationEnd, RouterOutlet } from '@angular/router';
4
+ import { Router, ActivatedRoute, RoutesRecognized, NavigationEnd, RouterOutlet } from '@angular/router';
5
5
  import * as i1$1 from '@angular/common';
6
6
  import { CommonModule } from '@angular/common';
7
7
  import * as i3 from '@angular/material/icon';
8
8
  import { MatIconModule } from '@angular/material/icon';
9
9
  import { MatTooltipModule } from '@angular/material/tooltip';
10
- import { BehaviorSubject, Subscription, isObservable, lastValueFrom, Subject } from 'rxjs';
11
- import { debounceTime, startWith, map, filter, take } from 'rxjs/operators';
10
+ import { BehaviorSubject, Subscription, from, isObservable, lastValueFrom, Subject } from 'rxjs';
11
+ import { debounceTime, startWith, filter, concatMap, take } from 'rxjs/operators';
12
12
  import { SdNotifyService } from '@sd-angular/core/services/notify';
13
- import { SdI18nService } from '@sd-angular/core/i18n';
13
+ import { I18nService } from '@sd-angular/core/i18n';
14
14
  import { SdUtilities } from '@sd-angular/core/utilities';
15
15
  import * as i1 from '@angular/cdk/drag-drop';
16
16
  import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
@@ -299,7 +299,7 @@ class SdTabRouterOutletComponent {
299
299
  #injector = inject(Injector);
300
300
  #tabRouterService = inject(SdTabRouterService);
301
301
  #sdNotifyService = inject(SdNotifyService);
302
- #i18n = inject(SdI18nService);
302
+ #i18n = inject(I18nService);
303
303
  // Inject để đảm bảo SdTabDecoratorService được khởi tạo (nó register BehaviorSubject
304
304
  // tĩnh để @SdTab decorator có thể truy cập SdTabRouterService). Không dùng trực tiếp ở đây.
305
305
  #tabDecoratorService = inject(SdTabDecoratorService);
@@ -312,30 +312,17 @@ class SdTabRouterOutletComponent {
312
312
  constructor() {
313
313
  this.#subscription.add(this.#router.events
314
314
  .pipe(
315
- // Một số event của Angular bọc trong wrapper có .routerEvent unwrap về RouterEvent gốc.
316
- map((event) => (event instanceof RouterEvent ? event : event.routerEvent)),
315
+ // KHÔNG unwrap event.routerEvent (vd Scroll wrap NavigationEnd):
316
+ // Angular emit NavigationEnd RAW trước, RouterScroller emit Scroll(NavigationEnd) sau.
317
+ // Nếu unwrap thêm Scroll → handler fire 2 lần cho 1 nav → race condition tạo duplicate tabs.
317
318
  // Hybrid: cần CẢ HAI event vì mỗi event chứa data khác nhau ở thời điểm khác nhau.
318
319
  // - RoutesRecognized: navigation đang in-flight → getCurrentNavigation().extras.state đọc được
319
320
  // - NavigationEnd: navigation hoàn tất → routerState.root đã update với route mới (cần cho lazy routes)
320
- filter(event => event instanceof RoutesRecognized || event instanceof NavigationEnd))
321
- .subscribe(async (event) => {
322
- if (this.disabled()) {
323
- this.#pendingNavigationState = {};
324
- return;
325
- }
326
- if (event instanceof RoutesRecognized) {
327
- // Capture state ngay lúc nav còn in-flight. Đây là điểm duy nhất chắc chắn
328
- // getCurrentNavigation() trả về Navigation object với extras.state nguyên vẹn.
329
- this.#pendingNavigationState = this.#router.getCurrentNavigation()?.extras?.state ?? {};
330
- return;
331
- }
332
- // NavigationEnd: dùng activatedRoute.snapshot và routerState.root MỚI nhất
333
- // (chứa route component đã được activate, cả lazy lẫn standalone routes).
334
- const route = this.#getActivatedRouteSnapshot(this.#activatedRoute.snapshot);
335
- this.#rootRoute = this.#router.routerState.root;
336
- await this.#activeRoute(event.urlAfterRedirects || event.url, route, this.#pendingNavigationState);
337
- this.#pendingNavigationState = {};
338
- }));
321
+ filter((event) => event instanceof RoutesRecognized || event instanceof NavigationEnd),
322
+ // Serialize: #handleEvent async (await getBestInjector). 2 nav liên tiếp
323
+ // không await xen kẽ → tránh race đọc this.tabs() = [] khi tab đầu chưa kịp set.
324
+ concatMap(event => from(this.#handleEvent(event))))
325
+ .subscribe());
339
326
  this.#subscription.add(this.#tabRouterService.actions.subscribe((event) => {
340
327
  if (this.disabled())
341
328
  return;
@@ -347,6 +334,24 @@ class SdTabRouterOutletComponent {
347
334
  ngOnDestroy() {
348
335
  this.#subscription.unsubscribe();
349
336
  }
337
+ #handleEvent = async (event) => {
338
+ if (this.disabled()) {
339
+ this.#pendingNavigationState = {};
340
+ return;
341
+ }
342
+ if (event instanceof RoutesRecognized) {
343
+ // Capture state ngay lúc nav còn in-flight. Đây là điểm duy nhất chắc chắn
344
+ // getCurrentNavigation() trả về Navigation object với extras.state nguyên vẹn.
345
+ this.#pendingNavigationState = this.#router.getCurrentNavigation()?.extras?.state ?? {};
346
+ return;
347
+ }
348
+ // NavigationEnd: dùng activatedRoute.snapshot và routerState.root MỚI nhất
349
+ // (chứa route component đã được activate, cả lazy lẫn standalone routes).
350
+ const route = this.#getActivatedRouteSnapshot(this.#activatedRoute.snapshot);
351
+ this.#rootRoute = this.#router.routerState.root;
352
+ await this.#activeRoute(event.urlAfterRedirects || event.url, route, this.#pendingNavigationState);
353
+ this.#pendingNavigationState = {};
354
+ };
350
355
  tabTrackBy = (index, tab) => tab.key;
351
356
  #closeTab = (tab) => {
352
357
  if (this.disabled())
@@ -1 +1 @@
1
- {"version":3,"file":"sd-angular-core-components-tab-router.mjs","sources":["../../../projects/sd-angular/components/tab-router/src/events/tab-router.event.ts","../../../projects/sd-angular/components/tab-router/src/services/tab-router.service.ts","../../../projects/sd-angular/components/tab-router/src/services/tab-decorator.service.ts","../../../projects/sd-angular/components/tab-router/src/pipes/tab-info.pipe.ts","../../../projects/sd-angular/components/tab-router/src/components/tab-router-item/tab-router-item.component.ts","../../../projects/sd-angular/components/tab-router/src/components/tab-router-item/tab-router-item.component.html","../../../projects/sd-angular/components/tab-router/src/components/tab-router-nav/tab-router-nav.component.ts","../../../projects/sd-angular/components/tab-router/src/components/tab-router-nav/tab-router-nav.component.html","../../../projects/sd-angular/components/tab-router/src/components/tab-router-outlet/tab-router-outlet.component.ts","../../../projects/sd-angular/components/tab-router/src/components/tab-router-outlet/tab-router-outlet.component.html","../../../projects/sd-angular/components/tab-router/src/decorators/tab.decorator.ts","../../../projects/sd-angular/components/tab-router/sd-angular-core-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 { Injectable, Type } from '@angular/core';\r\nimport { BehaviorSubject } from 'rxjs';\r\nimport { SdTabAction } from '../actions/tab-router.action';\r\nimport { SdTabComponentBuilder } from '../decorators/tab.decorator';\r\nimport { SdTabBase, SdTabEvent } from '../events/tab-router.event';\r\nimport { SdTab } from '../models/tab-router.model';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class SdTabRouterService {\r\n events = new BehaviorSubject<SdTabEvent>(new SdTabBase(undefined));\r\n actions = new BehaviorSubject<SdTabAction | undefined>(undefined);\r\n builders = new BehaviorSubject<SdTabComponentBuilder[]>([]);\r\n currentTabChanges = new BehaviorSubject<SdTab | undefined>(undefined);\r\n newTabs = new BehaviorSubject<SdTab | undefined>(undefined);\r\n updateTabs = new BehaviorSubject<SdTab | undefined>(undefined);\r\n #currentTab: SdTab | undefined = undefined;\r\n #componentBuilders: SdTabComponentBuilder[] = [];\r\n constructor() {}\r\n\r\n addBuilder = (builder: SdTabComponentBuilder) => {\r\n if (!this.#componentBuilders.some(e => e.component === builder.component)) {\r\n this.#componentBuilders.push(builder);\r\n this.builders.next(this.#componentBuilders);\r\n }\r\n };\r\n\r\n get currentTab() {\r\n return this.#currentTab;\r\n }\r\n\r\n get currentKey() {\r\n return this.#currentTab?.key || null;\r\n }\r\n\r\n // select = (tabOrKey: string | SdTab): void => {\r\n // const tab = this.#tabs.find(e => {\r\n // if (typeof (tabOrKey) === 'string') {\r\n // return e.key === tabOrKey;\r\n // }\r\n // return e.key === tabOrKey?.key;\r\n // });\r\n // if (tab) {\r\n // this.#currentTab = tab;\r\n // }\r\n // }\r\n\r\n // add = (tab: SdTab): void => {\r\n // if (!tab.key) {\r\n // this.notifyService.notify.warning('Tab key is required');\r\n // }\r\n // if (!tab.component) {\r\n // this.notifyService.notify.warning('Tab component is required');\r\n // }\r\n // const existedTab = this.#tabs.find(e => e.key === tab.key);\r\n // if (!existedTab) {\r\n // this.#tabs.push(tab);\r\n // this.select(tab);\r\n // } else {\r\n // this.select(existedTab);\r\n // }\r\n // }\r\n\r\n // remove = (tabOrKey: string | SdTab): void => {\r\n // this.#tabs = this.#tabs.filter(e => {\r\n // if (typeof (tabOrKey) === 'string') {\r\n // return e.key !== tabOrKey;\r\n // }\r\n // return e.key !== tabOrKey?.key;\r\n // });\r\n // }\r\n\r\n setCurrentTab = (tab: SdTab): void => {\r\n this.#currentTab = tab;\r\n this.currentTabChanges.next(tab);\r\n };\r\n\r\n pushEvent = (tab: SdTab, Event: Type<SdTabEvent>) => {\r\n this.events.next(new Event(tab));\r\n };\r\n\r\n setOptions = () => {};\r\n\r\n close = (tab?: SdTab) => {\r\n tab = tab || this.#currentTab;\r\n if (tab) {\r\n this.actions.next({\r\n type: 'close',\r\n tab,\r\n });\r\n }\r\n };\r\n\r\n // Gọi hàm này để thực hiện update tab\r\n updateTab = (tab: SdTab) => {};\r\n}\r\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';\r\nimport { Subscription } from 'rxjs';\r\nimport { debounceTime, startWith } from 'rxjs/operators';\r\n\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { SdBadge } from '@sd-angular/core/components/badge';\r\nimport { SdTab, SdTabInfo } from '../../models';\r\nimport { SdTabRouterService } from '../../services/tab-router.service';\r\nimport { Router } from '@angular/router';\r\nimport { CommonModule } from '@angular/common';\r\nimport { SdTabInfoPipe } from '../../pipes/tab-info.pipe';\r\n\r\n@Component({\r\n selector: 'sd-tab-router-item',\r\n templateUrl: './tab-router-item.component.html',\r\n styleUrls: ['./tab-router-item.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n standalone: true,\r\n imports: [CommonModule, MatIconModule, SdBadge, SdTabInfoPipe],\r\n})\r\nexport class SdTabRouterItemComponent implements OnInit, OnDestroy {\r\n @Input({ required: true }) tab!: SdTab;\r\n\r\n #subsctiption: Subscription = new Subscription();\r\n tabInfo?: SdTabInfo;\r\n constructor(\r\n private cdRef: ChangeDetectorRef,\r\n private tabRouterService: SdTabRouterService,\r\n private router: Router\r\n ) {}\r\n\r\n ngOnInit(): void {\r\n this.#subsctiption.add(\r\n this.tabRouterService.events.pipe(debounceTime(100)).subscribe(() => {\r\n this.cdRef.markForCheck();\r\n })\r\n );\r\n\r\n this.#subsctiption.add(\r\n this.tab.tabInfoChanges.pipe(startWith(null)).subscribe(tabInfo => {\r\n if (tabInfo) {\r\n this.tabInfo = tabInfo;\r\n this.cdRef.markForCheck();\r\n }\r\n })\r\n );\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.#subsctiption.unsubscribe();\r\n }\r\n\r\n onTabClick = (event: Event) => {\r\n event.preventDefault();\r\n this.router.navigate([this.tab.url], {\r\n queryParams: this.tab.queryParams,\r\n state: { switchTab: true },\r\n });\r\n };\r\n\r\n close = (event: Event) => {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.#closeTab();\r\n };\r\n\r\n onMousedown = (event: MouseEvent) => {\r\n if (event.button === 1) {\r\n event.preventDefault();\r\n }\r\n };\r\n\r\n onMouseup = (event: MouseEvent) => {\r\n if (event.button === 1) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.#closeTab();\r\n }\r\n };\r\n\r\n #closeTab = async () => {\r\n if (this.tab?.beforeClose) {\r\n //\r\n if (this.tab?.beforeClose()) {\r\n const result = this.tab?.beforeClose();\r\n if (typeof result === 'boolean') {\r\n if (result) {\r\n this.tabRouterService.close(this.tab);\r\n }\r\n } else {\r\n if (await result) {\r\n this.tabRouterService.close(this.tab);\r\n }\r\n }\r\n }\r\n } else {\r\n this.tabRouterService.close(this.tab);\r\n }\r\n };\r\n}\r\n","<a\r\n [href]=\"[tab.url]\"\r\n class=\"tab-router__item d-flex align-items-center gap-8\"\r\n [class.tab-router__item--active]=\"tab.isActive\"\r\n (click)=\"onTabClick($event)\"\r\n (mousedown)=\"onMousedown($event)\"\r\n (mouseup)=\"onMouseup($event)\">\r\n @let info = tabInfo | sdTabInfo: tab;\r\n @if (info) {\r\n <sd-badge\r\n style=\"overflow: hidden;white-space: nowrap;\"\r\n [icon]=\"info.icon\"\r\n [title]=\"info.icon\"\r\n [tooltip]=\"info.tooltip || info.name\"\r\n [title]=\"info.name\"\r\n [color]=\"info.color\"\r\n (click)=\"onTabClick($event)\"></sd-badge>\r\n <button\r\n aria-hidden=\"true\"\r\n class=\"tab-router__close d-flex align-items-center justify-content-center ml-auto p-0\"\r\n (click)=\"close($event)\"\r\n (mousedown)=\"$event.stopPropagation()\">\r\n <mat-icon aria-hidden=\"true\" fontIcon=\"close\"></mat-icon>\r\n </button>\r\n }\r\n</a>\r\n","import { CdkDragDrop, DragDropModule, moveItemInArray } from '@angular/cdk/drag-drop';\r\nimport {\r\n ChangeDetectionStrategy,\r\n ChangeDetectorRef,\r\n Component,\r\n ElementRef,\r\n HostListener,\r\n inject,\r\n input,\r\n viewChild,\r\n} from '@angular/core';\r\n\r\nimport { SdTab } from '../../models/tab-router.model';\r\nimport { SdTabRouterItemComponent } from '../tab-router-item/tab-router-item.component';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n@Component({\r\n selector: 'sd-tab-router-nav',\r\n templateUrl: './tab-router-nav.component.html',\r\n styleUrls: ['./tab-router-nav.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n standalone: true,\r\n imports: [CommonModule, DragDropModule, SdTabRouterItemComponent],\r\n})\r\nexport class SdTabRouterNavComponent {\r\n tabRouterNav = viewChild<ElementRef>('tabRouterNav');\r\n\r\n tabs = input<SdTab[]>([]);\r\n mode: 'default' | 'compact' = 'default';\r\n cdRef = inject(ChangeDetectorRef);\r\n elementRef = inject<ElementRef<any>>(ElementRef);\r\n\r\n @HostListener('window:resize')\r\n onResize(): void {\r\n this.checkUI();\r\n }\r\n\r\n checkUI = () => {\r\n const width = this.tabRouterNav()?.nativeElement.clientWidth ?? 0;\r\n const tabs = this.tabs();\r\n if (tabs.length === 0) {\r\n this.mode = 'default';\r\n this.cdRef.markForCheck();\r\n return;\r\n }\r\n\r\n const nameWidth = (width - tabs.length * 68) / tabs.length;\r\n if (nameWidth <= 20) {\r\n this.mode = 'compact';\r\n } else {\r\n this.mode = 'default';\r\n }\r\n this.cdRef.markForCheck();\r\n };\r\n\r\n onDrop = (event: CdkDragDrop<SdTab[]>) => {\r\n moveItemInArray(this.tabs(), event.previousIndex, event.currentIndex);\r\n };\r\n}\r\n","<div\r\n #tabRouterNav\r\n cdkDropList\r\n cdkDropListLockAxis=\"x\"\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"onDrop($event)\"\r\n class=\"tab-router__nav tab-router__nav--{{ mode }} d-flex align-items-center flex-nowrap\"\r\n [class.d-none]=\"tabs().length > 1\">\r\n @for (tab of tabs(); track tab.key) {\r\n <sd-tab-router-item [tab]=\"tab\" cdkDrag [cdkDragBoundary]=\"elementRef.nativeElement\"></sd-tab-router-item>\r\n }\r\n</div>\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport {\r\n booleanAttribute,\r\n Component,\r\n Injector,\r\n OnDestroy,\r\n Type,\r\n inject,\r\n input,\r\n signal,\r\n viewChild,\r\n createNgModule,\r\n NgModuleFactory,\r\n} from '@angular/core';\r\nimport {\r\n ActivatedRoute,\r\n ActivatedRouteSnapshot,\r\n NavigationEnd,\r\n Router,\r\n RouterOutlet,\r\n RouterEvent,\r\n RoutesRecognized,\r\n} from '@angular/router';\r\nimport { CommonModule } from '@angular/common';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { MatTooltipModule } from '@angular/material/tooltip';\r\nimport { Subject, Subscription, isObservable, lastValueFrom } from 'rxjs';\r\nimport { filter, map } from 'rxjs/operators';\r\n\r\nimport { SdNotifyService } from '@sd-angular/core/services/notify';\r\nimport { SdI18nService } from '@sd-angular/core/i18n';\r\nimport { SdUtilities } from '@sd-angular/core/utilities';\r\nimport { SdTabActivated, SdTabDeactivated } from '../../events/tab-router.event';\r\nimport { SdTabAction } from '../../actions/tab-router.action';\r\nimport { SdTab } from '../../models';\r\nimport { SdTabDecoratorService } from '../../services/tab-decorator.service';\r\nimport { SdTabRouterService } from '../../services/tab-router.service';\r\nimport { SdTabRouterNavComponent } from '../tab-router-nav/tab-router-nav.component';\r\n\r\n// eslint-disable-next-line @angular-eslint/no-unused-standalone-imports\r\n@Component({\r\n selector: 'sd-tab-router-outlet',\r\n templateUrl: './tab-router-outlet.component.html',\r\n styleUrls: ['./tab-router-outlet.component.scss'],\r\n standalone: true,\r\n imports: [CommonModule, MatIconModule, MatTooltipModule, RouterOutlet, SdTabRouterNavComponent],\r\n})\r\nexport class SdTabRouterOutletComponent implements OnDestroy {\r\n disabled = input(false, { transform: booleanAttribute });\r\n\r\n tabRouterNav = viewChild<SdTabRouterNavComponent>('tabRouterNav');\r\n\r\n tabs = signal<SdTab[]>([]);\r\n\r\n #router = inject(Router);\r\n #activatedRoute = inject(ActivatedRoute);\r\n #injector = inject(Injector);\r\n #tabRouterService = inject(SdTabRouterService);\r\n #sdNotifyService = inject(SdNotifyService);\r\n readonly #i18n = inject(SdI18nService);\r\n // Inject để đảm bảo SdTabDecoratorService được khởi tạo (nó register BehaviorSubject\r\n // tĩnh để @SdTab decorator có thể truy cập SdTabRouterService). Không dùng trực tiếp ở đây.\r\n #tabDecoratorService = inject(SdTabDecoratorService);\r\n\r\n #rootRoute?: ActivatedRoute;\r\n #subscription = new Subscription();\r\n\r\n // State của navigation hiện tại (replaceTab, switchTab, ...) được capture ở RoutesRecognized\r\n // và dùng lại ở NavigationEnd. Lý do: tại NavigationEnd, getCurrentNavigation() đã trả về null,\r\n // còn lastSuccessfulNavigation và window.history.state không đáng tin cậy với mọi case.\r\n #pendingNavigationState: Record<string, any> = {};\r\n\r\n constructor() {\r\n this.#subscription.add(\r\n this.#router.events\r\n .pipe(\r\n // Một số event của Angular bọc trong wrapper có .routerEvent → unwrap về RouterEvent gốc.\r\n map((event: any) => (event instanceof RouterEvent ? event : event.routerEvent)),\r\n // Hybrid: cần CẢ HAI event vì mỗi event chứa data khác nhau ở thời điểm khác nhau.\r\n // - RoutesRecognized: navigation đang in-flight → getCurrentNavigation().extras.state đọc được\r\n // - NavigationEnd: navigation hoàn tất → routerState.root đã update với route mới (cần cho lazy routes)\r\n filter(event => event instanceof RoutesRecognized || event instanceof NavigationEnd)\r\n )\r\n .subscribe(async (event: any) => {\r\n if (this.disabled()) {\r\n this.#pendingNavigationState = {};\r\n return;\r\n }\r\n\r\n if (event instanceof RoutesRecognized) {\r\n // Capture state ngay lúc nav còn in-flight. Đây là điểm duy nhất chắc chắn\r\n // getCurrentNavigation() trả về Navigation object với extras.state nguyên vẹn.\r\n this.#pendingNavigationState = this.#router.getCurrentNavigation()?.extras?.state ?? {};\r\n return;\r\n }\r\n // NavigationEnd: dùng activatedRoute.snapshot và routerState.root MỚI nhất\r\n // (chứa route component đã được activate, cả lazy lẫn standalone routes).\r\n const route = this.#getActivatedRouteSnapshot(this.#activatedRoute.snapshot);\r\n this.#rootRoute = this.#router.routerState.root;\r\n await this.#activeRoute(event.urlAfterRedirects || event.url, route, this.#pendingNavigationState);\r\n this.#pendingNavigationState = {};\r\n })\r\n );\r\n\r\n this.#subscription.add(\r\n this.#tabRouterService.actions.subscribe((event: SdTabAction | undefined) => {\r\n if (this.disabled()) return;\r\n\r\n if (event?.type === 'close') {\r\n this.#closeTab(event.tab);\r\n }\r\n })\r\n );\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.#subscription.unsubscribe();\r\n }\r\n\r\n tabTrackBy = (index: number, tab: SdTab) => tab.key;\r\n\r\n #closeTab = (tab: SdTab) => {\r\n if (this.disabled()) return;\r\n\r\n const currentTabs = this.tabs();\r\n const { isActive, key: activeKey } = tab;\r\n\r\n if (isActive) {\r\n const activeIndex = currentTabs.findIndex(({ key }) => key === activeKey);\r\n const nextTab = currentTabs[activeIndex + 1] || currentTabs[activeIndex - 1];\r\n\r\n this.tabs.set(currentTabs.filter(({ key }) => key !== activeKey));\r\n\r\n if (nextTab) {\r\n this.#router.navigate([nextTab.url], {\r\n queryParams: { ...(nextTab.queryParams || {}) },\r\n state: { switchTab: true },\r\n });\r\n } else {\r\n this.#router.navigateByUrl('/', { state: { switchTab: true } });\r\n }\r\n } else {\r\n this.tabs.set(currentTabs.filter(({ key }) => key !== tab.key));\r\n this.tabRouterNav()?.checkUI();\r\n }\r\n };\r\n\r\n #activeRoute = async (\r\n fullUrl: string,\r\n route: ActivatedRouteSnapshot | null,\r\n state: Record<string, any> = {}\r\n ) => {\r\n if (this.disabled()) return;\r\n if (!route?.component) return;\r\n\r\n const component = route.component as Type<any>;\r\n const queryParams = { ...(route.queryParams || {}) };\r\n const params = { ...(route.params || {}) };\r\n const data = { ...(route.data || {}) };\r\n const [url] = fullUrl.split('?');\r\n // Tab identity = hash(url + queryParams). Cùng key = cùng tab, không tạo lại.\r\n const key = SdUtilities.hash({ url, queryParams });\r\n\r\n let existedIndex = -1;\r\n let activatedIndex = -1;\r\n\r\n const currentTabs = this.tabs();\r\n\r\n // QUAN TRỌNG: scan READ-ONLY, KHÔNG mutate tab.isActive trong loop này.\r\n //\r\n // Lý do: NavigationEnd có thể fire nhiều lần cho 1 user-action (do nested outlets,\r\n // redirect, hoặc Angular internal). Vì #activeRoute là async (await getBestInjector),\r\n // 2 invocations có thể chạy concurrent và interleave với nhau.\r\n //\r\n // Nếu mutate tab.isActive = false ở đây, call thứ 2 sẽ thấy isActive đã bị call 1\r\n // set false rồi → không tìm thấy active tab → activatedIndex stay -1 → splice bỏ qua\r\n // → tab cũ không bị remove → xuất hiện duplicate tabs.\r\n //\r\n // Cách fix: chỉ ĐỌC isActive, sau đó dùng .map() ở dưới để tạo tab objects mới qua spread.\r\n for (let i = 0; i < currentTabs.length; i++) {\r\n const tab = currentTabs[i];\r\n if (tab.key === key) {\r\n existedIndex = i;\r\n } else if (tab.isActive) {\r\n activatedIndex = i;\r\n this.#tabRouterService.pushEvent(tab, SdTabDeactivated);\r\n }\r\n }\r\n\r\n const replaceTab = state['replaceTab'];\r\n\r\n // Resolve injector phù hợp với route. Cần xử lý 3 trường hợp:\r\n // - Standalone route (Angular đã set _injector trên routeConfig sau khi activate)\r\n // - NgModule lazy load (cần createNgModule từ class)\r\n // - Fallback: root injector\r\n const getBestInjector = async (snapshot: ActivatedRouteSnapshot): Promise<Injector> => {\r\n // Standalone route: Angular tự lưu environment injector trên routeConfig._injector\r\n const routeInjector = (snapshot as any)._resolvedGui || (snapshot as any).routeConfig?._injector;\r\n if (routeInjector) return routeInjector;\r\n\r\n // NgModule lazy: phải gọi lại loadChildren() để lấy module class rồi createNgModule\r\n const loadChildren = snapshot.parent?.routeConfig?.loadChildren;\r\n if (typeof loadChildren === 'function') {\r\n let loaded: any = await loadChildren();\r\n\r\n if (isObservable(loaded)) {\r\n loaded = await lastValueFrom(loaded);\r\n }\r\n\r\n // ES module có thể export default\r\n if (loaded && typeof loaded === 'object' && 'default' in loaded) {\r\n loaded = loaded.default;\r\n }\r\n\r\n // Angular cũ: NgModuleFactory\r\n if (loaded instanceof NgModuleFactory) {\r\n return loaded.create(this.#injector).injector;\r\n }\r\n\r\n // Angular mới: NgModule class. Bọc try/catch vì createNgModule throw nếu không phải NgModule.\r\n if (typeof loaded === 'function' && !Array.isArray(loaded)) {\r\n try {\r\n return createNgModule(loaded, this.#injector).injector;\r\n } catch {\r\n return this.#injector;\r\n }\r\n }\r\n }\r\n return this.#injector;\r\n };\r\n\r\n const finalInjector = await getBestInjector(route);\r\n const activatedRoute = this.#getActivatedRoute(this.#rootRoute!, component);\r\n\r\n const newTab: SdTab = {\r\n key,\r\n component,\r\n injector: new SdOutletInjector(activatedRoute, finalInjector),\r\n isActive: true,\r\n url,\r\n params,\r\n queryParams,\r\n data,\r\n tabInfoChanges: new Subject(),\r\n };\r\n\r\n // Tạo updatedTabs qua spread thay vì mutate (xem lý do ở for loop phía trên).\r\n // Với tab có isActive không đổi: giữ nguyên reference (tránh trigger ngComponentOutlet\r\n // re-evaluate không cần thiết). Với tab cần đổi isActive: tạo object mới qua spread,\r\n // các nested fields (component, injector) vẫn giữ same reference nên component không bị recreate.\r\n let updatedTabs = currentTabs.map(tab => {\r\n if (tab.key === key) return tab.isActive ? tab : { ...tab, isActive: true };\r\n return tab.isActive ? { ...tab, isActive: false } : tab;\r\n });\r\n\r\n // replaceTab: thay vì mở tab mới song song, xoá tab đang active rồi mở tab mới ở cuối.\r\n // Use case: từ tab \"chi tiết\" bấm \"chỉnh sửa\" với replaceTab → tab chi tiết bị xoá,\r\n // tab chỉnh sửa thay thế (giữ số tab không tăng).\r\n if (replaceTab && activatedIndex >= 0) {\r\n updatedTabs = updatedTabs.filter((_, i) => i !== activatedIndex);\r\n }\r\n\r\n if (existedIndex >= 0) {\r\n // Tab đã tồn tại (cùng url + queryParams) → CHỈ activate, KHÔNG thay tab object.\r\n // Lý do: thay tab object = đổi reference của tab.injector → ngComponentOutlet recreate\r\n // component → tab bị \"reload\" mỗi khi click lại hoặc navigate cùng URL.\r\n //\r\n // splice phía trên có thể đã shift index nếu activatedIndex < existedIndex.\r\n const idx = replaceTab && activatedIndex >= 0 && activatedIndex < existedIndex\r\n ? existedIndex - 1\r\n : existedIndex;\r\n this.#tabRouterService.setCurrentTab(updatedTabs[idx]);\r\n this.#tabRouterService.pushEvent(updatedTabs[idx], SdTabActivated);\r\n this.tabs.set(updatedTabs);\r\n } else {\r\n // Tab chưa tồn tại → thêm mới ở cuối.\r\n this.#tabRouterService.setCurrentTab(newTab);\r\n this.tabs.set([...updatedTabs, newTab]);\r\n\r\n if (this.tabs().length > 30) {\r\n this.#sdNotifyService.warning(this.#i18n.t('core.component.tab-router.too-many-tabs'));\r\n }\r\n }\r\n\r\n this.tabRouterNav()?.checkUI();\r\n };\r\n\r\n // Lần xuống deepest firstChild để lấy snapshot của route lá (route thực sự render component).\r\n #getActivatedRouteSnapshot = (snapshot: ActivatedRouteSnapshot): ActivatedRouteSnapshot | null => {\r\n let node = snapshot;\r\n while (node.firstChild) node = node.firstChild;\r\n return node;\r\n };\r\n\r\n // DFS tìm ActivatedRoute (không phải snapshot) trong tree theo component class.\r\n // Cần ActivatedRoute thật vì SdOutletInjector sẽ inject nó vào component qua DI.\r\n #getActivatedRoute = (activatedRoute: ActivatedRoute, component: any): ActivatedRoute | null => {\r\n if (activatedRoute.component === component) return activatedRoute;\r\n for (const child of activatedRoute.children) {\r\n const result = this.#getActivatedRoute(child, component);\r\n if (result) return result;\r\n }\r\n return null;\r\n };\r\n}\r\n\r\n// Custom Injector cho từng tab: override ActivatedRoute thành route của TAB ĐÓ\r\n// (không phải route hiện tại của router). Nếu không override, mọi tab sẽ inject ActivatedRoute\r\n// của route đang active → component cũ trong tab inactive nhận data sai khi user navigate.\r\nclass SdOutletInjector implements Injector {\r\n constructor(\r\n private route: ActivatedRoute | null,\r\n private parentInjector: Injector\r\n ) {}\r\n\r\n get(token: any, notFoundValue?: any): any {\r\n if (token === ActivatedRoute) {\r\n return this.route || notFoundValue;\r\n }\r\n return this.parentInjector.get(token, notFoundValue);\r\n }\r\n}\r\n","@if (disabled()) {\r\n <div class=\"tab-router__disabled-outlet\">\r\n <router-outlet></router-outlet>\r\n </div>\r\n} @else {\r\n <sd-tab-router-nav [tabs]=\"tabs()\" #tabRouterNav></sd-tab-router-nav>\r\n <div class=\"tab-router__list\">\r\n @for (tab of tabs(); track tab.key) {\r\n <div class=\"tab-router__pane\" [class.active]=\"tab.isActive\" [id]=\"tab.key\">\r\n <div class=\"tab-router__content\">\r\n <ng-container *ngComponentOutlet=\"tab.component; injector: tab.injector\"></ng-container>\r\n </div>\r\n </div>\r\n } @empty {\r\n <div class=\"tab-router__empty\">\r\n </div>\r\n }\r\n </div>\r\n}","import { Type } from '@angular/core';\r\nimport { SdColor } from '@sd-angular/core/utilities/models';\r\nimport { filter, take } from 'rxjs/operators';\r\nimport { SdTabDecoratorService } from '../services/tab-decorator.service';\r\n\r\nexport interface SdTabComponentArgs {\r\n url?: string;\r\n params?: any;\r\n queryParams?: any;\r\n data?: Record<string, any>;\r\n}\r\n\r\nexport declare interface SdTabComponentBuilder {\r\n component: Type<any>;\r\n name: string | ((args: SdTabComponentArgs) => string);\r\n icon?: string | ((args: SdTabComponentArgs) => string);\r\n tooltip?: string | ((args: SdTabComponentArgs) => string);\r\n color?: SdColor | ((args: SdTabComponentArgs) => SdColor);\r\n}\r\n\r\nexport function SdTabComponent<T>(builder: SdTabComponentBuilder) {\r\n return (constructor: T) => {\r\n SdTabDecoratorService.tabRouterService\r\n .pipe(\r\n filter(service => service !== undefined && service !== null),\r\n take(1)\r\n )\r\n .subscribe(service => {\r\n service.addBuilder(builder);\r\n });\r\n };\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1.SdTabRouterService","i1"],"mappings":"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"}
1
+ {"version":3,"file":"sd-angular-core-components-tab-router.mjs","sources":["../../../projects/sd-angular/components/tab-router/src/events/tab-router.event.ts","../../../projects/sd-angular/components/tab-router/src/services/tab-router.service.ts","../../../projects/sd-angular/components/tab-router/src/services/tab-decorator.service.ts","../../../projects/sd-angular/components/tab-router/src/pipes/tab-info.pipe.ts","../../../projects/sd-angular/components/tab-router/src/components/tab-router-item/tab-router-item.component.ts","../../../projects/sd-angular/components/tab-router/src/components/tab-router-item/tab-router-item.component.html","../../../projects/sd-angular/components/tab-router/src/components/tab-router-nav/tab-router-nav.component.ts","../../../projects/sd-angular/components/tab-router/src/components/tab-router-nav/tab-router-nav.component.html","../../../projects/sd-angular/components/tab-router/src/components/tab-router-outlet/tab-router-outlet.component.ts","../../../projects/sd-angular/components/tab-router/src/components/tab-router-outlet/tab-router-outlet.component.html","../../../projects/sd-angular/components/tab-router/src/decorators/tab.decorator.ts","../../../projects/sd-angular/components/tab-router/sd-angular-core-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 { Injectable, Type } from '@angular/core';\r\nimport { BehaviorSubject } from 'rxjs';\r\nimport { SdTabAction } from '../actions/tab-router.action';\r\nimport { SdTabComponentBuilder } from '../decorators/tab.decorator';\r\nimport { SdTabBase, SdTabEvent } from '../events/tab-router.event';\r\nimport { SdTab } from '../models/tab-router.model';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class SdTabRouterService {\r\n events = new BehaviorSubject<SdTabEvent>(new SdTabBase(undefined));\r\n actions = new BehaviorSubject<SdTabAction | undefined>(undefined);\r\n builders = new BehaviorSubject<SdTabComponentBuilder[]>([]);\r\n currentTabChanges = new BehaviorSubject<SdTab | undefined>(undefined);\r\n newTabs = new BehaviorSubject<SdTab | undefined>(undefined);\r\n updateTabs = new BehaviorSubject<SdTab | undefined>(undefined);\r\n #currentTab: SdTab | undefined = undefined;\r\n #componentBuilders: SdTabComponentBuilder[] = [];\r\n constructor() {}\r\n\r\n addBuilder = (builder: SdTabComponentBuilder) => {\r\n if (!this.#componentBuilders.some(e => e.component === builder.component)) {\r\n this.#componentBuilders.push(builder);\r\n this.builders.next(this.#componentBuilders);\r\n }\r\n };\r\n\r\n get currentTab() {\r\n return this.#currentTab;\r\n }\r\n\r\n get currentKey() {\r\n return this.#currentTab?.key || null;\r\n }\r\n\r\n // select = (tabOrKey: string | SdTab): void => {\r\n // const tab = this.#tabs.find(e => {\r\n // if (typeof (tabOrKey) === 'string') {\r\n // return e.key === tabOrKey;\r\n // }\r\n // return e.key === tabOrKey?.key;\r\n // });\r\n // if (tab) {\r\n // this.#currentTab = tab;\r\n // }\r\n // }\r\n\r\n // add = (tab: SdTab): void => {\r\n // if (!tab.key) {\r\n // this.notifyService.notify.warning('Tab key is required');\r\n // }\r\n // if (!tab.component) {\r\n // this.notifyService.notify.warning('Tab component is required');\r\n // }\r\n // const existedTab = this.#tabs.find(e => e.key === tab.key);\r\n // if (!existedTab) {\r\n // this.#tabs.push(tab);\r\n // this.select(tab);\r\n // } else {\r\n // this.select(existedTab);\r\n // }\r\n // }\r\n\r\n // remove = (tabOrKey: string | SdTab): void => {\r\n // this.#tabs = this.#tabs.filter(e => {\r\n // if (typeof (tabOrKey) === 'string') {\r\n // return e.key !== tabOrKey;\r\n // }\r\n // return e.key !== tabOrKey?.key;\r\n // });\r\n // }\r\n\r\n setCurrentTab = (tab: SdTab): void => {\r\n this.#currentTab = tab;\r\n this.currentTabChanges.next(tab);\r\n };\r\n\r\n pushEvent = (tab: SdTab, Event: Type<SdTabEvent>) => {\r\n this.events.next(new Event(tab));\r\n };\r\n\r\n setOptions = () => {};\r\n\r\n close = (tab?: SdTab) => {\r\n tab = tab || this.#currentTab;\r\n if (tab) {\r\n this.actions.next({\r\n type: 'close',\r\n tab,\r\n });\r\n }\r\n };\r\n\r\n // Gọi hàm này để thực hiện update tab\r\n updateTab = (tab: SdTab) => {};\r\n}\r\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';\r\nimport { Subscription } from 'rxjs';\r\nimport { debounceTime, startWith } from 'rxjs/operators';\r\n\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { SdBadge } from '@sd-angular/core/components/badge';\r\nimport { SdTab, SdTabInfo } from '../../models';\r\nimport { SdTabRouterService } from '../../services/tab-router.service';\r\nimport { Router } from '@angular/router';\r\nimport { CommonModule } from '@angular/common';\r\nimport { SdTabInfoPipe } from '../../pipes/tab-info.pipe';\r\n\r\n@Component({\r\n selector: 'sd-tab-router-item',\r\n templateUrl: './tab-router-item.component.html',\r\n styleUrls: ['./tab-router-item.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n standalone: true,\r\n imports: [CommonModule, MatIconModule, SdBadge, SdTabInfoPipe],\r\n})\r\nexport class SdTabRouterItemComponent implements OnInit, OnDestroy {\r\n @Input({ required: true }) tab!: SdTab;\r\n\r\n #subsctiption: Subscription = new Subscription();\r\n tabInfo?: SdTabInfo;\r\n constructor(\r\n private cdRef: ChangeDetectorRef,\r\n private tabRouterService: SdTabRouterService,\r\n private router: Router\r\n ) {}\r\n\r\n ngOnInit(): void {\r\n this.#subsctiption.add(\r\n this.tabRouterService.events.pipe(debounceTime(100)).subscribe(() => {\r\n this.cdRef.markForCheck();\r\n })\r\n );\r\n\r\n this.#subsctiption.add(\r\n this.tab.tabInfoChanges.pipe(startWith(null)).subscribe(tabInfo => {\r\n if (tabInfo) {\r\n this.tabInfo = tabInfo;\r\n this.cdRef.markForCheck();\r\n }\r\n })\r\n );\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.#subsctiption.unsubscribe();\r\n }\r\n\r\n onTabClick = (event: Event) => {\r\n event.preventDefault();\r\n this.router.navigate([this.tab.url], {\r\n queryParams: this.tab.queryParams,\r\n state: { switchTab: true },\r\n });\r\n };\r\n\r\n close = (event: Event) => {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.#closeTab();\r\n };\r\n\r\n onMousedown = (event: MouseEvent) => {\r\n if (event.button === 1) {\r\n event.preventDefault();\r\n }\r\n };\r\n\r\n onMouseup = (event: MouseEvent) => {\r\n if (event.button === 1) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.#closeTab();\r\n }\r\n };\r\n\r\n #closeTab = async () => {\r\n if (this.tab?.beforeClose) {\r\n //\r\n if (this.tab?.beforeClose()) {\r\n const result = this.tab?.beforeClose();\r\n if (typeof result === 'boolean') {\r\n if (result) {\r\n this.tabRouterService.close(this.tab);\r\n }\r\n } else {\r\n if (await result) {\r\n this.tabRouterService.close(this.tab);\r\n }\r\n }\r\n }\r\n } else {\r\n this.tabRouterService.close(this.tab);\r\n }\r\n };\r\n}\r\n","<a\r\n [href]=\"[tab.url]\"\r\n class=\"tab-router__item d-flex align-items-center gap-8\"\r\n [class.tab-router__item--active]=\"tab.isActive\"\r\n (click)=\"onTabClick($event)\"\r\n (mousedown)=\"onMousedown($event)\"\r\n (mouseup)=\"onMouseup($event)\">\r\n @let info = tabInfo | sdTabInfo: tab;\r\n @if (info) {\r\n <sd-badge\r\n style=\"overflow: hidden;white-space: nowrap;\"\r\n [icon]=\"info.icon\"\r\n [title]=\"info.icon\"\r\n [tooltip]=\"info.tooltip || info.name\"\r\n [title]=\"info.name\"\r\n [color]=\"info.color\"\r\n (click)=\"onTabClick($event)\"></sd-badge>\r\n <button\r\n aria-hidden=\"true\"\r\n class=\"tab-router__close d-flex align-items-center justify-content-center ml-auto p-0\"\r\n (click)=\"close($event)\"\r\n (mousedown)=\"$event.stopPropagation()\">\r\n <mat-icon aria-hidden=\"true\" fontIcon=\"close\"></mat-icon>\r\n </button>\r\n }\r\n</a>\r\n","import { CdkDragDrop, DragDropModule, moveItemInArray } from '@angular/cdk/drag-drop';\r\nimport {\r\n ChangeDetectionStrategy,\r\n ChangeDetectorRef,\r\n Component,\r\n ElementRef,\r\n HostListener,\r\n inject,\r\n input,\r\n viewChild,\r\n} from '@angular/core';\r\n\r\nimport { SdTab } from '../../models/tab-router.model';\r\nimport { SdTabRouterItemComponent } from '../tab-router-item/tab-router-item.component';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n@Component({\r\n selector: 'sd-tab-router-nav',\r\n templateUrl: './tab-router-nav.component.html',\r\n styleUrls: ['./tab-router-nav.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n standalone: true,\r\n imports: [CommonModule, DragDropModule, SdTabRouterItemComponent],\r\n})\r\nexport class SdTabRouterNavComponent {\r\n tabRouterNav = viewChild<ElementRef>('tabRouterNav');\r\n\r\n tabs = input<SdTab[]>([]);\r\n mode: 'default' | 'compact' = 'default';\r\n cdRef = inject(ChangeDetectorRef);\r\n elementRef = inject<ElementRef<any>>(ElementRef);\r\n\r\n @HostListener('window:resize')\r\n onResize(): void {\r\n this.checkUI();\r\n }\r\n\r\n checkUI = () => {\r\n const width = this.tabRouterNav()?.nativeElement.clientWidth ?? 0;\r\n const tabs = this.tabs();\r\n if (tabs.length === 0) {\r\n this.mode = 'default';\r\n this.cdRef.markForCheck();\r\n return;\r\n }\r\n\r\n const nameWidth = (width - tabs.length * 68) / tabs.length;\r\n if (nameWidth <= 20) {\r\n this.mode = 'compact';\r\n } else {\r\n this.mode = 'default';\r\n }\r\n this.cdRef.markForCheck();\r\n };\r\n\r\n onDrop = (event: CdkDragDrop<SdTab[]>) => {\r\n moveItemInArray(this.tabs(), event.previousIndex, event.currentIndex);\r\n };\r\n}\r\n","<div\r\n #tabRouterNav\r\n cdkDropList\r\n cdkDropListLockAxis=\"x\"\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"onDrop($event)\"\r\n class=\"tab-router__nav tab-router__nav--{{ mode }} d-flex align-items-center flex-nowrap\"\r\n [class.d-none]=\"tabs().length > 1\">\r\n @for (tab of tabs(); track tab.key) {\r\n <sd-tab-router-item [tab]=\"tab\" cdkDrag [cdkDragBoundary]=\"elementRef.nativeElement\"></sd-tab-router-item>\r\n }\r\n</div>\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport {\r\n booleanAttribute,\r\n Component,\r\n Injector,\r\n OnDestroy,\r\n Type,\r\n inject,\r\n input,\r\n signal,\r\n viewChild,\r\n createNgModule,\r\n NgModuleFactory,\r\n} from '@angular/core';\r\nimport {\r\n ActivatedRoute,\r\n ActivatedRouteSnapshot,\r\n NavigationEnd,\r\n Router,\r\n RouterOutlet,\r\n RoutesRecognized,\r\n} from '@angular/router';\r\nimport { CommonModule } from '@angular/common';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { MatTooltipModule } from '@angular/material/tooltip';\r\nimport { from, Subject, Subscription, isObservable, lastValueFrom } from 'rxjs';\r\nimport { concatMap, filter } from 'rxjs/operators';\r\n\r\nimport { SdNotifyService } from '@sd-angular/core/services/notify';\r\nimport { I18nService } from '@sd-angular/core/i18n';\r\nimport { SdUtilities } from '@sd-angular/core/utilities';\r\nimport { SdTabActivated, SdTabDeactivated } from '../../events/tab-router.event';\r\nimport { SdTabAction } from '../../actions/tab-router.action';\r\nimport { SdTab } from '../../models';\r\nimport { SdTabDecoratorService } from '../../services/tab-decorator.service';\r\nimport { SdTabRouterService } from '../../services/tab-router.service';\r\nimport { SdTabRouterNavComponent } from '../tab-router-nav/tab-router-nav.component';\r\n\r\n// eslint-disable-next-line @angular-eslint/no-unused-standalone-imports\r\n@Component({\r\n selector: 'sd-tab-router-outlet',\r\n templateUrl: './tab-router-outlet.component.html',\r\n styleUrls: ['./tab-router-outlet.component.scss'],\r\n standalone: true,\r\n imports: [CommonModule, MatIconModule, MatTooltipModule, RouterOutlet, SdTabRouterNavComponent],\r\n})\r\nexport class SdTabRouterOutletComponent implements OnDestroy {\r\n disabled = input(false, { transform: booleanAttribute });\r\n\r\n tabRouterNav = viewChild<SdTabRouterNavComponent>('tabRouterNav');\r\n\r\n tabs = signal<SdTab[]>([]);\r\n\r\n #router = inject(Router);\r\n #activatedRoute = inject(ActivatedRoute);\r\n #injector = inject(Injector);\r\n #tabRouterService = inject(SdTabRouterService);\r\n #sdNotifyService = inject(SdNotifyService);\r\n readonly #i18n = inject(I18nService);\r\n // Inject để đảm bảo SdTabDecoratorService được khởi tạo (nó register BehaviorSubject\r\n // tĩnh để @SdTab decorator có thể truy cập SdTabRouterService). Không dùng trực tiếp ở đây.\r\n #tabDecoratorService = inject(SdTabDecoratorService);\r\n\r\n #rootRoute?: ActivatedRoute;\r\n #subscription = new Subscription();\r\n\r\n // State của navigation hiện tại (replaceTab, switchTab, ...) được capture ở RoutesRecognized\r\n // và dùng lại ở NavigationEnd. Lý do: tại NavigationEnd, getCurrentNavigation() đã trả về null,\r\n // còn lastSuccessfulNavigation và window.history.state không đáng tin cậy với mọi case.\r\n #pendingNavigationState: Record<string, any> = {};\r\n\r\n constructor() {\r\n this.#subscription.add(\r\n this.#router.events\r\n .pipe(\r\n // KHÔNG unwrap event.routerEvent (vd Scroll wrap NavigationEnd):\r\n // Angular emit NavigationEnd RAW trước, RouterScroller emit Scroll(NavigationEnd) sau.\r\n // Nếu unwrap thêm Scroll → handler fire 2 lần cho 1 nav → race condition tạo duplicate tabs.\r\n // Hybrid: cần CẢ HAI event vì mỗi event chứa data khác nhau ở thời điểm khác nhau.\r\n // - RoutesRecognized: navigation đang in-flight → getCurrentNavigation().extras.state đọc được\r\n // - NavigationEnd: navigation hoàn tất → routerState.root đã update với route mới (cần cho lazy routes)\r\n filter((event): event is RoutesRecognized | NavigationEnd =>\r\n event instanceof RoutesRecognized || event instanceof NavigationEnd),\r\n // Serialize: #handleEvent async (await getBestInjector). 2 nav liên tiếp\r\n // không await xen kẽ → tránh race đọc this.tabs() = [] khi tab đầu chưa kịp set.\r\n concatMap(event => from(this.#handleEvent(event)))\r\n )\r\n .subscribe()\r\n );\r\n\r\n this.#subscription.add(\r\n this.#tabRouterService.actions.subscribe((event: SdTabAction | undefined) => {\r\n if (this.disabled()) return;\r\n\r\n if (event?.type === 'close') {\r\n this.#closeTab(event.tab);\r\n }\r\n })\r\n );\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.#subscription.unsubscribe();\r\n }\r\n\r\n #handleEvent = async (event: RoutesRecognized | NavigationEnd): Promise<void> => {\r\n if (this.disabled()) {\r\n this.#pendingNavigationState = {};\r\n return;\r\n }\r\n if (event instanceof RoutesRecognized) {\r\n // Capture state ngay lúc nav còn in-flight. Đây là điểm duy nhất chắc chắn\r\n // getCurrentNavigation() trả về Navigation object với extras.state nguyên vẹn.\r\n this.#pendingNavigationState = this.#router.getCurrentNavigation()?.extras?.state ?? {};\r\n return;\r\n }\r\n // NavigationEnd: dùng activatedRoute.snapshot và routerState.root MỚI nhất\r\n // (chứa route component đã được activate, cả lazy lẫn standalone routes).\r\n const route = this.#getActivatedRouteSnapshot(this.#activatedRoute.snapshot);\r\n this.#rootRoute = this.#router.routerState.root;\r\n await this.#activeRoute(event.urlAfterRedirects || event.url, route, this.#pendingNavigationState);\r\n this.#pendingNavigationState = {};\r\n };\r\n\r\n tabTrackBy = (index: number, tab: SdTab) => tab.key;\r\n\r\n #closeTab = (tab: SdTab) => {\r\n if (this.disabled()) return;\r\n\r\n const currentTabs = this.tabs();\r\n const { isActive, key: activeKey } = tab;\r\n\r\n if (isActive) {\r\n const activeIndex = currentTabs.findIndex(({ key }) => key === activeKey);\r\n const nextTab = currentTabs[activeIndex + 1] || currentTabs[activeIndex - 1];\r\n\r\n this.tabs.set(currentTabs.filter(({ key }) => key !== activeKey));\r\n\r\n if (nextTab) {\r\n this.#router.navigate([nextTab.url], {\r\n queryParams: { ...(nextTab.queryParams || {}) },\r\n state: { switchTab: true },\r\n });\r\n } else {\r\n this.#router.navigateByUrl('/', { state: { switchTab: true } });\r\n }\r\n } else {\r\n this.tabs.set(currentTabs.filter(({ key }) => key !== tab.key));\r\n this.tabRouterNav()?.checkUI();\r\n }\r\n };\r\n\r\n #activeRoute = async (\r\n fullUrl: string,\r\n route: ActivatedRouteSnapshot | null,\r\n state: Record<string, any> = {}\r\n ) => {\r\n if (this.disabled()) return;\r\n if (!route?.component) return;\r\n\r\n const component = route.component as Type<any>;\r\n const queryParams = { ...(route.queryParams || {}) };\r\n const params = { ...(route.params || {}) };\r\n const data = { ...(route.data || {}) };\r\n const [url] = fullUrl.split('?');\r\n // Tab identity = hash(url + queryParams). Cùng key = cùng tab, không tạo lại.\r\n const key = SdUtilities.hash({ url, queryParams });\r\n\r\n let existedIndex = -1;\r\n let activatedIndex = -1;\r\n\r\n const currentTabs = this.tabs();\r\n\r\n // QUAN TRỌNG: scan READ-ONLY, KHÔNG mutate tab.isActive trong loop này.\r\n //\r\n // Lý do: NavigationEnd có thể fire nhiều lần cho 1 user-action (do nested outlets,\r\n // redirect, hoặc Angular internal). Vì #activeRoute là async (await getBestInjector),\r\n // 2 invocations có thể chạy concurrent và interleave với nhau.\r\n //\r\n // Nếu mutate tab.isActive = false ở đây, call thứ 2 sẽ thấy isActive đã bị call 1\r\n // set false rồi → không tìm thấy active tab → activatedIndex stay -1 → splice bỏ qua\r\n // → tab cũ không bị remove → xuất hiện duplicate tabs.\r\n //\r\n // Cách fix: chỉ ĐỌC isActive, sau đó dùng .map() ở dưới để tạo tab objects mới qua spread.\r\n for (let i = 0; i < currentTabs.length; i++) {\r\n const tab = currentTabs[i];\r\n if (tab.key === key) {\r\n existedIndex = i;\r\n } else if (tab.isActive) {\r\n activatedIndex = i;\r\n this.#tabRouterService.pushEvent(tab, SdTabDeactivated);\r\n }\r\n }\r\n\r\n const replaceTab = state['replaceTab'];\r\n\r\n // Resolve injector phù hợp với route. Cần xử lý 3 trường hợp:\r\n // - Standalone route (Angular đã set _injector trên routeConfig sau khi activate)\r\n // - NgModule lazy load (cần createNgModule từ class)\r\n // - Fallback: root injector\r\n const getBestInjector = async (snapshot: ActivatedRouteSnapshot): Promise<Injector> => {\r\n // Standalone route: Angular tự lưu environment injector trên routeConfig._injector\r\n const routeInjector = (snapshot as any)._resolvedGui || (snapshot as any).routeConfig?._injector;\r\n if (routeInjector) return routeInjector;\r\n\r\n // NgModule lazy: phải gọi lại loadChildren() để lấy module class rồi createNgModule\r\n const loadChildren = snapshot.parent?.routeConfig?.loadChildren;\r\n if (typeof loadChildren === 'function') {\r\n let loaded: any = await loadChildren();\r\n\r\n if (isObservable(loaded)) {\r\n loaded = await lastValueFrom(loaded);\r\n }\r\n\r\n // ES module có thể export default\r\n if (loaded && typeof loaded === 'object' && 'default' in loaded) {\r\n loaded = loaded.default;\r\n }\r\n\r\n // Angular cũ: NgModuleFactory\r\n if (loaded instanceof NgModuleFactory) {\r\n return loaded.create(this.#injector).injector;\r\n }\r\n\r\n // Angular mới: NgModule class. Bọc try/catch vì createNgModule throw nếu không phải NgModule.\r\n if (typeof loaded === 'function' && !Array.isArray(loaded)) {\r\n try {\r\n return createNgModule(loaded, this.#injector).injector;\r\n } catch {\r\n return this.#injector;\r\n }\r\n }\r\n }\r\n return this.#injector;\r\n };\r\n\r\n const finalInjector = await getBestInjector(route);\r\n const activatedRoute = this.#getActivatedRoute(this.#rootRoute!, component);\r\n\r\n const newTab: SdTab = {\r\n key,\r\n component,\r\n injector: new SdOutletInjector(activatedRoute, finalInjector),\r\n isActive: true,\r\n url,\r\n params,\r\n queryParams,\r\n data,\r\n tabInfoChanges: new Subject(),\r\n };\r\n\r\n // Tạo updatedTabs qua spread thay vì mutate (xem lý do ở for loop phía trên).\r\n // Với tab có isActive không đổi: giữ nguyên reference (tránh trigger ngComponentOutlet\r\n // re-evaluate không cần thiết). Với tab cần đổi isActive: tạo object mới qua spread,\r\n // các nested fields (component, injector) vẫn giữ same reference nên component không bị recreate.\r\n let updatedTabs = currentTabs.map(tab => {\r\n if (tab.key === key) return tab.isActive ? tab : { ...tab, isActive: true };\r\n return tab.isActive ? { ...tab, isActive: false } : tab;\r\n });\r\n\r\n // replaceTab: thay vì mở tab mới song song, xoá tab đang active rồi mở tab mới ở cuối.\r\n // Use case: từ tab \"chi tiết\" bấm \"chỉnh sửa\" với replaceTab → tab chi tiết bị xoá,\r\n // tab chỉnh sửa thay thế (giữ số tab không tăng).\r\n if (replaceTab && activatedIndex >= 0) {\r\n updatedTabs = updatedTabs.filter((_, i) => i !== activatedIndex);\r\n }\r\n\r\n if (existedIndex >= 0) {\r\n // Tab đã tồn tại (cùng url + queryParams) → CHỈ activate, KHÔNG thay tab object.\r\n // Lý do: thay tab object = đổi reference của tab.injector → ngComponentOutlet recreate\r\n // component → tab bị \"reload\" mỗi khi click lại hoặc navigate cùng URL.\r\n //\r\n // splice phía trên có thể đã shift index nếu activatedIndex < existedIndex.\r\n const idx = replaceTab && activatedIndex >= 0 && activatedIndex < existedIndex\r\n ? existedIndex - 1\r\n : existedIndex;\r\n this.#tabRouterService.setCurrentTab(updatedTabs[idx]);\r\n this.#tabRouterService.pushEvent(updatedTabs[idx], SdTabActivated);\r\n this.tabs.set(updatedTabs);\r\n } else {\r\n // Tab chưa tồn tại → thêm mới ở cuối.\r\n this.#tabRouterService.setCurrentTab(newTab);\r\n this.tabs.set([...updatedTabs, newTab]);\r\n\r\n if (this.tabs().length > 30) {\r\n this.#sdNotifyService.warning(this.#i18n.t('core.component.tab-router.too-many-tabs'));\r\n }\r\n }\r\n\r\n this.tabRouterNav()?.checkUI();\r\n };\r\n\r\n // Lần xuống deepest firstChild để lấy snapshot của route lá (route thực sự render component).\r\n #getActivatedRouteSnapshot = (snapshot: ActivatedRouteSnapshot): ActivatedRouteSnapshot | null => {\r\n let node = snapshot;\r\n while (node.firstChild) node = node.firstChild;\r\n return node;\r\n };\r\n\r\n // DFS tìm ActivatedRoute (không phải snapshot) trong tree theo component class.\r\n // Cần ActivatedRoute thật vì SdOutletInjector sẽ inject nó vào component qua DI.\r\n #getActivatedRoute = (activatedRoute: ActivatedRoute, component: any): ActivatedRoute | null => {\r\n if (activatedRoute.component === component) return activatedRoute;\r\n for (const child of activatedRoute.children) {\r\n const result = this.#getActivatedRoute(child, component);\r\n if (result) return result;\r\n }\r\n return null;\r\n };\r\n}\r\n\r\n// Custom Injector cho từng tab: override ActivatedRoute thành route của TAB ĐÓ\r\n// (không phải route hiện tại của router). Nếu không override, mọi tab sẽ inject ActivatedRoute\r\n// của route đang active → component cũ trong tab inactive nhận data sai khi user navigate.\r\nclass SdOutletInjector implements Injector {\r\n constructor(\r\n private route: ActivatedRoute | null,\r\n private parentInjector: Injector\r\n ) {}\r\n\r\n get(token: any, notFoundValue?: any): any {\r\n if (token === ActivatedRoute) {\r\n return this.route || notFoundValue;\r\n }\r\n return this.parentInjector.get(token, notFoundValue);\r\n }\r\n}\r\n","@if (disabled()) {\r\n <div class=\"tab-router__disabled-outlet\">\r\n <router-outlet></router-outlet>\r\n </div>\r\n} @else {\r\n <sd-tab-router-nav [tabs]=\"tabs()\" #tabRouterNav></sd-tab-router-nav>\r\n <div class=\"tab-router__list\">\r\n @for (tab of tabs(); track tab.key) {\r\n <div class=\"tab-router__pane\" [class.active]=\"tab.isActive\" [id]=\"tab.key\">\r\n <div class=\"tab-router__content\">\r\n <ng-container *ngComponentOutlet=\"tab.component; injector: tab.injector\"></ng-container>\r\n </div>\r\n </div>\r\n } @empty {\r\n <div class=\"tab-router__empty\">\r\n </div>\r\n }\r\n </div>\r\n}","import { Type } from '@angular/core';\r\nimport { SdColor } from '@sd-angular/core/utilities/models';\r\nimport { filter, take } from 'rxjs/operators';\r\nimport { SdTabDecoratorService } from '../services/tab-decorator.service';\r\n\r\nexport interface SdTabComponentArgs {\r\n url?: string;\r\n params?: any;\r\n queryParams?: any;\r\n data?: Record<string, any>;\r\n}\r\n\r\nexport declare interface SdTabComponentBuilder {\r\n component: Type<any>;\r\n name: string | ((args: SdTabComponentArgs) => string);\r\n icon?: string | ((args: SdTabComponentArgs) => string);\r\n tooltip?: string | ((args: SdTabComponentArgs) => string);\r\n color?: SdColor | ((args: SdTabComponentArgs) => SdColor);\r\n}\r\n\r\nexport function SdTabComponent<T>(builder: SdTabComponentBuilder) {\r\n return (constructor: T) => {\r\n SdTabDecoratorService.tabRouterService\r\n .pipe(\r\n filter(service => service !== undefined && service !== null),\r\n take(1)\r\n )\r\n .subscribe(service => {\r\n service.addBuilder(builder);\r\n });\r\n };\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1.SdTabRouterService","i1"],"mappings":"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"}