@sdcorejs/angular 21.1.1 → 21.1.3
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.
- package/README.md +124 -807
- package/fesm2022/sdcorejs-angular-components-form-generic.mjs +150 -60
- package/fesm2022/sdcorejs-angular-components-form-generic.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-import-excel.mjs +2 -7
- package/fesm2022/sdcorejs-angular-components-import-excel.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-query-bar.mjs +7 -15
- package/fesm2022/sdcorejs-angular-components-query-bar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-query-builder.mjs +1 -1
- package/fesm2022/sdcorejs-angular-components-query-builder.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-tab-router.mjs +60 -30
- package/fesm2022/sdcorejs-angular-components-tab-router.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-table.mjs +34 -33
- package/fesm2022/sdcorejs-angular-components-table.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-tree.mjs +2 -1
- package/fesm2022/sdcorejs-angular-components-tree.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-upload-file.mjs +2 -1
- package/fesm2022/sdcorejs-angular-components-upload-file.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs +2 -1
- package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs +2 -1
- package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-chip.mjs +2 -1
- package/fesm2022/sdcorejs-angular-forms-chip.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-date-range.mjs +2 -1
- package/fesm2022/sdcorejs-angular-forms-date-range.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-date.mjs +6 -5
- package/fesm2022/sdcorejs-angular-forms-date.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-datetime.mjs +14 -465
- package/fesm2022/sdcorejs-angular-forms-datetime.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-input-color.mjs +5 -3
- package/fesm2022/sdcorejs-angular-forms-input-color.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-input-number.mjs +9 -6
- package/fesm2022/sdcorejs-angular-forms-input-number.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-input.mjs +10 -6
- package/fesm2022/sdcorejs-angular-forms-input.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-select.mjs +2 -1
- package/fesm2022/sdcorejs-angular-forms-select.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-textarea.mjs +2 -1
- package/fesm2022/sdcorejs-angular-forms-textarea.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-modules-icon.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-modules-layout.mjs +1 -1
- package/fesm2022/sdcorejs-angular-modules-layout.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-modules.mjs +0 -1
- package/fesm2022/sdcorejs-angular-modules.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-pipes.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-loading.mjs +23 -14
- package/fesm2022/sdcorejs-angular-services-loading.mjs.map +1 -1
- package/package.json +2 -5
- package/types/sdcorejs-angular-components-form-generic.d.ts +25 -2
- package/types/sdcorejs-angular-forms-date.d.ts +1 -1
- package/types/sdcorejs-angular-forms-datetime.d.ts +1 -1
- package/types/sdcorejs-angular-forms-input-color.d.ts +3 -1
- package/types/sdcorejs-angular-forms-input-number.d.ts +3 -1
- package/types/sdcorejs-angular-forms-input.d.ts +3 -1
- package/types/sdcorejs-angular-modules-icon.d.ts +2 -3
- package/types/sdcorejs-angular-modules.d.ts +0 -1
- package/types/sdcorejs-angular-services-loading.d.ts +1 -1
- package/fesm2022/sdcorejs-angular-modules-authom.mjs +0 -360
- package/fesm2022/sdcorejs-angular-modules-authom.mjs.map +0 -1
- package/types/sdcorejs-angular-modules-authom.d.ts +0 -70
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { InjectionToken, Injectable, Pipe, Input, ChangeDetectionStrategy, Component, viewChild, input, inject, ChangeDetectorRef, ElementRef, HostListener, booleanAttribute, signal, Injector, afterNextRender, NgModuleFactory, createNgModule } from '@angular/core';
|
|
3
3
|
import * as i2 from '@angular/router';
|
|
4
|
-
import { Router, RoutesRecognized, NavigationEnd, RouterOutlet, ActivatedRoute } from '@angular/router';
|
|
4
|
+
import { Router, RoutesRecognized, NavigationEnd, NavigationSkipped, NavigationCancel, NavigationError, NavigationSkippedCode, RouterOutlet, ActivatedRoute } from '@angular/router';
|
|
5
5
|
import * as i1$1 from '@angular/common';
|
|
6
6
|
import { CommonModule } from '@angular/common';
|
|
7
7
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
8
8
|
import { BehaviorSubject, Subscription, from, isObservable, lastValueFrom, Subject } from 'rxjs';
|
|
9
|
-
import { debounceTime, startWith, filter, concatMap, take } from 'rxjs/operators';
|
|
9
|
+
import { debounceTime, startWith, filter, map, concatMap, take } from 'rxjs/operators';
|
|
10
10
|
import { SdNotifyService } from '@sdcorejs/angular/services/notify';
|
|
11
11
|
import { I18nService } from '@sdcorejs/angular/i18n';
|
|
12
12
|
import { Utilities } from '@sdcorejs/utils/fns';
|
|
@@ -260,11 +260,11 @@ class SdTabRouterNavComponent {
|
|
|
260
260
|
moveItemInArray(this.tabs(), event.previousIndex, event.currentIndex);
|
|
261
261
|
};
|
|
262
262
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdTabRouterNavComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
263
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SdTabRouterNavComponent, isStandalone: true, selector: "sd-tab-router-nav", inputs: { tabs: { classPropertyName: "tabs", publicName: "tabs", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "window:resize": "onResize()" } }, viewQueries: [{ propertyName: "tabRouterNav", first: true, predicate: ["tabRouterNav"], descendants: true, isSignal: true }], ngImport: i0, template: "<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.key) {\n <sd-tab-router-item [tab]=\"tab\" cdkDrag [cdkDragBoundary]=\"elementRef.nativeElement\"></sd-tab-router-item>\n }\n</div>\n", styles: [".tab-router__nav{background:#f9f9f9;overflow:hidden}.tab-router__nav--compact::ng-deep .tab-router__name{display:none}.tab-router__nav--compact::ng-deep .tab-router__icon{margin:0!important}.tab-router__nav--compact::ng-deep .tab-router__item--active{min-width:240px}.tab-router__nav--compact::ng-deep .tab-router__item--active .tab-router__icon{margin-right:8px!important}.tab-router__nav--compact::ng-deep .tab-router__item--active .tab-router__name{display:-webkit-box}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: SdTabRouterItemComponent, selector: "sd-tab-router-item", inputs: ["tab"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
263
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SdTabRouterNavComponent, isStandalone: true, selector: "sd-tab-router-nav", inputs: { tabs: { classPropertyName: "tabs", publicName: "tabs", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "window:resize": "onResize()" } }, viewQueries: [{ propertyName: "tabRouterNav", first: true, predicate: ["tabRouterNav"], descendants: true, isSignal: true }], ngImport: i0, template: "<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", styles: [".tab-router__nav{background:#f9f9f9;overflow:hidden}.tab-router__nav--compact::ng-deep .tab-router__name{display:none}.tab-router__nav--compact::ng-deep .tab-router__icon{margin:0!important}.tab-router__nav--compact::ng-deep .tab-router__item--active{min-width:240px}.tab-router__nav--compact::ng-deep .tab-router__item--active .tab-router__icon{margin-right:8px!important}.tab-router__nav--compact::ng-deep .tab-router__item--active .tab-router__name{display:-webkit-box}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: SdTabRouterItemComponent, selector: "sd-tab-router-item", inputs: ["tab"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
264
264
|
}
|
|
265
265
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdTabRouterNavComponent, decorators: [{
|
|
266
266
|
type: Component,
|
|
267
|
-
args: [{ selector: 'sd-tab-router-nav', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, DragDropModule, SdTabRouterItemComponent], template: "<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.key) {\n <sd-tab-router-item [tab]=\"tab\" cdkDrag [cdkDragBoundary]=\"elementRef.nativeElement\"></sd-tab-router-item>\n }\n</div>\n", styles: [".tab-router__nav{background:#f9f9f9;overflow:hidden}.tab-router__nav--compact::ng-deep .tab-router__name{display:none}.tab-router__nav--compact::ng-deep .tab-router__icon{margin:0!important}.tab-router__nav--compact::ng-deep .tab-router__item--active{min-width:240px}.tab-router__nav--compact::ng-deep .tab-router__item--active .tab-router__icon{margin-right:8px!important}.tab-router__nav--compact::ng-deep .tab-router__item--active .tab-router__name{display:-webkit-box}\n"] }]
|
|
267
|
+
args: [{ selector: 'sd-tab-router-nav', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, DragDropModule, SdTabRouterItemComponent], template: "<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", styles: [".tab-router__nav{background:#f9f9f9;overflow:hidden}.tab-router__nav--compact::ng-deep .tab-router__name{display:none}.tab-router__nav--compact::ng-deep .tab-router__icon{margin:0!important}.tab-router__nav--compact::ng-deep .tab-router__item--active{min-width:240px}.tab-router__nav--compact::ng-deep .tab-router__item--active .tab-router__icon{margin-right:8px!important}.tab-router__nav--compact::ng-deep .tab-router__item--active .tab-router__name{display:-webkit-box}\n"] }]
|
|
268
268
|
}], propDecorators: { tabRouterNav: [{ type: i0.ViewChild, args: ['tabRouterNav', { isSignal: true }] }], tabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabs", required: false }] }], onResize: [{
|
|
269
269
|
type: HostListener,
|
|
270
270
|
args: ['window:resize']
|
|
@@ -284,10 +284,8 @@ class SdTabRouterOutletComponent {
|
|
|
284
284
|
#tabDecoratorService = inject(SdTabDecoratorService);
|
|
285
285
|
#rootRoute;
|
|
286
286
|
#subscription = new Subscription();
|
|
287
|
-
//
|
|
288
|
-
|
|
289
|
-
// còn lastSuccessfulNavigation và window.history.state không đáng tin cậy với mọi case.
|
|
290
|
-
#pendingNavigationState = {};
|
|
287
|
+
// Lưu state theo navigation id để các navigation chồng lấn không ghi đè lẫn nhau.
|
|
288
|
+
#pendingNavigationStates = new Map();
|
|
291
289
|
// Serialize mọi #activeRoute (router events + initial sync) để tránh race tạo duplicate tab.
|
|
292
290
|
#activationQueue = Promise.resolve();
|
|
293
291
|
constructor() {
|
|
@@ -296,13 +294,23 @@ class SdTabRouterOutletComponent {
|
|
|
296
294
|
// KHÔNG unwrap event.routerEvent (vd Scroll wrap NavigationEnd):
|
|
297
295
|
// Angular emit NavigationEnd RAW trước, RouterScroller emit Scroll(NavigationEnd) sau.
|
|
298
296
|
// Nếu unwrap thêm Scroll → handler fire 2 lần cho 1 nav → race condition tạo duplicate tabs.
|
|
299
|
-
//
|
|
297
|
+
// Navigation thành công cần CẢ HAI event vì mỗi event chứa data ở thời điểm khác nhau.
|
|
300
298
|
// - RoutesRecognized: navigation đang in-flight → getCurrentNavigation().extras.state đọc được
|
|
301
299
|
// - NavigationEnd: navigation hoàn tất → routerState.root đã update với route mới (cần cho lazy routes)
|
|
302
|
-
|
|
300
|
+
// Các terminal event khác chỉ xử lý same-URL forceReload hoặc dọn state theo navigation id.
|
|
301
|
+
filter((event) => event instanceof RoutesRecognized ||
|
|
302
|
+
event instanceof NavigationEnd ||
|
|
303
|
+
event instanceof NavigationSkipped ||
|
|
304
|
+
event instanceof NavigationCancel ||
|
|
305
|
+
event instanceof NavigationError),
|
|
306
|
+
// Chụp getCurrentNavigation đồng bộ vì concatMap có thể chạy sau khi Angular đã xoá navigation hiện tại.
|
|
307
|
+
map((event) => ({
|
|
308
|
+
event,
|
|
309
|
+
navigationState: this.#router.getCurrentNavigation()?.extras?.state ?? {},
|
|
310
|
+
})),
|
|
303
311
|
// Serialize: #handleEvent async (await getBestInjector). 2 nav liên tiếp
|
|
304
312
|
// không await xen kẽ → tránh race đọc this.tabs() = [] khi tab đầu chưa kịp set.
|
|
305
|
-
concatMap(
|
|
313
|
+
concatMap(context => from(this.#handleEvent(context))))
|
|
306
314
|
.subscribe());
|
|
307
315
|
this.#subscription.add(this.#tabRouterService.actions.subscribe((event) => {
|
|
308
316
|
if (this.disabled())
|
|
@@ -319,31 +327,45 @@ class SdTabRouterOutletComponent {
|
|
|
319
327
|
}
|
|
320
328
|
ngOnDestroy() {
|
|
321
329
|
this.#subscription.unsubscribe();
|
|
330
|
+
this.#pendingNavigationStates.clear();
|
|
322
331
|
}
|
|
323
332
|
#scheduleActivation = (task) => {
|
|
324
333
|
const run = this.#activationQueue.then(task);
|
|
325
334
|
this.#activationQueue = run.catch(() => undefined);
|
|
326
335
|
return run;
|
|
327
336
|
};
|
|
328
|
-
#handleEvent = async (event) => {
|
|
337
|
+
#handleEvent = async ({ event, navigationState }) => {
|
|
329
338
|
if (this.disabled()) {
|
|
330
|
-
this.#
|
|
339
|
+
this.#pendingNavigationStates.clear();
|
|
331
340
|
return;
|
|
332
341
|
}
|
|
333
342
|
if (event instanceof RoutesRecognized) {
|
|
334
|
-
|
|
335
|
-
// getCurrentNavigation() trả về Navigation object với extras.state nguyên vẹn.
|
|
336
|
-
this.#pendingNavigationState = this.#router.getCurrentNavigation()?.extras?.state ?? {};
|
|
343
|
+
this.#pendingNavigationStates.set(event.id, navigationState);
|
|
337
344
|
return;
|
|
338
345
|
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
346
|
+
if (event instanceof NavigationCancel || event instanceof NavigationError) {
|
|
347
|
+
this.#pendingNavigationStates.delete(event.id);
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
let state;
|
|
351
|
+
let fullUrl;
|
|
352
|
+
if (event instanceof NavigationSkipped) {
|
|
353
|
+
this.#pendingNavigationStates.delete(event.id);
|
|
354
|
+
if (event.code !== NavigationSkippedCode.IgnoredSameUrlNavigation || navigationState['forceReload'] !== true) {
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
state = navigationState;
|
|
358
|
+
fullUrl = event.url;
|
|
359
|
+
}
|
|
360
|
+
else {
|
|
361
|
+
state = this.#pendingNavigationStates.get(event.id) ?? navigationState;
|
|
362
|
+
this.#pendingNavigationStates.delete(event.id);
|
|
363
|
+
fullUrl = event.urlAfterRedirects || event.url;
|
|
364
|
+
}
|
|
343
365
|
await this.#scheduleActivation(async () => {
|
|
344
366
|
const route = this.#getActivatedRouteSnapshot(this.#router.routerState.snapshot.root);
|
|
345
367
|
this.#rootRoute = this.#router.routerState.root;
|
|
346
|
-
await this.#activeRoute(
|
|
368
|
+
await this.#activeRoute(fullUrl, route, state);
|
|
347
369
|
});
|
|
348
370
|
};
|
|
349
371
|
// Bù initial navigation nếu NavigationEnd đã fire trước khi outlet subscribe.
|
|
@@ -418,7 +440,7 @@ class SdTabRouterOutletComponent {
|
|
|
418
440
|
const params = { ...(route.params || {}) };
|
|
419
441
|
const data = { ...(route.data || {}) };
|
|
420
442
|
const [url] = fullUrl.split('?');
|
|
421
|
-
// Tab identity = hash(url + queryParams). Cùng key
|
|
443
|
+
// Tab identity = hash(url + queryParams). Cùng key mặc định giữ tab cũ; forceReload mới tạo lại.
|
|
422
444
|
const key = Utilities.hash({ url, queryParams });
|
|
423
445
|
let existedIndex = -1;
|
|
424
446
|
let activatedIndex = -1;
|
|
@@ -445,6 +467,7 @@ class SdTabRouterOutletComponent {
|
|
|
445
467
|
}
|
|
446
468
|
}
|
|
447
469
|
const replaceTab = state['replaceTab'];
|
|
470
|
+
const forceReload = state['forceReload'] === true;
|
|
448
471
|
// Resolve injector phù hợp với route. Cần xử lý 3 trường hợp:
|
|
449
472
|
// - Standalone route (Angular đã set _injector trên routeConfig sau khi activate)
|
|
450
473
|
// - NgModule lazy load (cần createNgModule từ class)
|
|
@@ -514,15 +537,22 @@ class SdTabRouterOutletComponent {
|
|
|
514
537
|
updatedTabs = updatedTabs.filter((_, i) => i !== activatedIndex);
|
|
515
538
|
}
|
|
516
539
|
if (existedIndex >= 0) {
|
|
517
|
-
//
|
|
518
|
-
//
|
|
519
|
-
// component → tab bị "reload" mỗi khi click lại hoặc navigate cùng URL.
|
|
540
|
+
// Mặc định tab đã tồn tại chỉ được activate, không thay tab object. forceReload là nhánh
|
|
541
|
+
// explicit duy nhất thay SdTab + injector để body và nav item được tạo lại.
|
|
520
542
|
//
|
|
521
543
|
// splice phía trên có thể đã shift index nếu activatedIndex < existedIndex.
|
|
522
544
|
const idx = replaceTab && activatedIndex >= 0 && activatedIndex < existedIndex ? existedIndex - 1 : existedIndex;
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
545
|
+
if (forceReload) {
|
|
546
|
+
updatedTabs = updatedTabs.map((tab, index) => (index === idx ? newTab : tab));
|
|
547
|
+
this.#tabRouterService.setCurrentTab(newTab);
|
|
548
|
+
this.#tabRouterService.pushEvent(newTab, SdTabActivated);
|
|
549
|
+
this.tabs.set(updatedTabs);
|
|
550
|
+
}
|
|
551
|
+
else {
|
|
552
|
+
this.#tabRouterService.setCurrentTab(updatedTabs[idx]);
|
|
553
|
+
this.#tabRouterService.pushEvent(updatedTabs[idx], SdTabActivated);
|
|
554
|
+
this.tabs.set(updatedTabs);
|
|
555
|
+
}
|
|
526
556
|
}
|
|
527
557
|
else {
|
|
528
558
|
// Tab chưa tồn tại → thêm mới ở cuối.
|
|
@@ -555,11 +585,11 @@ class SdTabRouterOutletComponent {
|
|
|
555
585
|
return null;
|
|
556
586
|
};
|
|
557
587
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdTabRouterOutletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
558
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SdTabRouterOutletComponent, isStandalone: true, selector: "sd-tab-router-outlet", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "tabRouterNav", first: true, predicate: ["tabRouterNav"], descendants: true, isSignal: true }], ngImport: i0, template: "@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.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\"
|
|
588
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SdTabRouterOutletComponent, isStandalone: true, selector: "sd-tab-router-outlet", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "tabRouterNav", first: true, predicate: ["tabRouterNav"], descendants: true, isSignal: true }], ngImport: i0, template: "@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", styles: [":host{display:flex;flex-direction:column;width:100%;min-height:0;height:100vh}:host ::ng-deep .sd-loading{max-width:100%;max-height:100%}.tab-router__list{flex:1;min-height:0}.tab-router__disabled-outlet{flex:1;width:100%;min-height:0;overflow:auto}.tab-router__pane{display:none;position:relative;height:100%;width:100%}.tab-router__pane.active{display:block}.tab-router__content{position:absolute;inset:0;overflow:auto;height:100%;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: SdTabRouterNavComponent, selector: "sd-tab-router-nav", inputs: ["tabs"] }] });
|
|
559
589
|
}
|
|
560
590
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdTabRouterOutletComponent, decorators: [{
|
|
561
591
|
type: Component,
|
|
562
|
-
args: [{ selector: 'sd-tab-router-outlet', standalone: true, imports: [CommonModule, MatTooltipModule, RouterOutlet, SdTabRouterNavComponent], template: "@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.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\"
|
|
592
|
+
args: [{ selector: 'sd-tab-router-outlet', standalone: true, imports: [CommonModule, MatTooltipModule, RouterOutlet, SdTabRouterNavComponent], template: "@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", styles: [":host{display:flex;flex-direction:column;width:100%;min-height:0;height:100vh}:host ::ng-deep .sd-loading{max-width:100%;max-height:100%}.tab-router__list{flex:1;min-height:0}.tab-router__disabled-outlet{flex:1;width:100%;min-height:0;overflow:auto}.tab-router__pane{display:none;position:relative;height:100%;width:100%}.tab-router__pane.active{display:block}.tab-router__content{position:absolute;inset:0;overflow:auto;height:100%;width:100%}\n"] }]
|
|
563
593
|
}], ctorParameters: () => [], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], tabRouterNav: [{ type: i0.ViewChild, args: ['tabRouterNav', { isSignal: true }] }] } });
|
|
564
594
|
// Custom Injector cho từng tab: override ActivatedRoute thành route của TAB ĐÓ
|
|
565
595
|
// (không phải route hiện tại của router). Nếu không override, mọi tab sẽ inject ActivatedRoute
|
|
@@ -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.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 { ActivatedRoute, ActivatedRouteSnapshot, NavigationEnd, Router, RouterOutlet, RoutesRecognized } 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 } 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\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 // State của navigation hiện tại (replaceTab, switchTab, ...) được capture ở RoutesRecognized\n // và dùng lại ở NavigationEnd. Lý do: tại NavigationEnd, getCurrentNavigation() đã trả về null,\n // còn lastSuccessfulNavigation và window.history.state không đáng tin cậy với mọi case.\n #pendingNavigationState: 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 // Hybrid: cần CẢ HAI event vì mỗi event chứa data khác nhau ở 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 filter((event): event is RoutesRecognized | NavigationEnd => event instanceof RoutesRecognized || event instanceof NavigationEnd),\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(event => from(this.#handleEvent(event)))\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 }\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: RoutesRecognized | NavigationEnd): Promise<void> => {\n if (this.disabled()) {\n this.#pendingNavigationState = {};\n return;\n }\n if (event instanceof RoutesRecognized) {\n // Capture state ngay lúc nav còn in-flight. Đây là điểm duy nhất chắc chắn\n // getCurrentNavigation() trả về Navigation object với extras.state nguyên vẹn.\n this.#pendingNavigationState = this.#router.getCurrentNavigation()?.extras?.state ?? {};\n return;\n }\n // NavigationEnd: dùng routerState.snapshot.root (canonical state tại NavigationEnd),\n // KHÔNG dùng injected ActivatedRoute.snapshot — có thể chưa sync trên initial load.\n const navigationState = this.#pendingNavigationState;\n this.#pendingNavigationState = {};\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(event.urlAfterRedirects || event.url, route, navigationState);\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 = cùng tab, không 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\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 // Tab đã tồn tại (cùng url + queryParams) → CHỈ activate, KHÔNG thay tab object.\n // Lý do: thay tab object = đổi reference của tab.injector → ngComponentOutlet recreate\n // component → tab bị \"reload\" mỗi khi click lại hoặc navigate cùng URL.\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 this.#tabRouterService.setCurrentTab(updatedTabs[idx]);\n this.#tabRouterService.pushEvent(updatedTabs[idx], SdTabActivated);\n this.tabs.set(updatedTabs);\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.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\">\n </div>\n }\n </div>\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 } 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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"}
|