@sd-angular/core 19.0.0-beta.49 → 19.0.0-beta.50
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/components/tab-router/src/components/tab-router-outlet/tab-router-outlet.component.d.ts +3 -15
- package/fesm2022/sd-angular-core-components-tab-router.mjs +140 -223
- package/fesm2022/sd-angular-core-components-tab-router.mjs.map +1 -1
- package/fesm2022/sd-angular-core-modules-layout.mjs +419 -454
- package/fesm2022/sd-angular-core-modules-layout.mjs.map +1 -1
- package/modules/layout/components/layout-main/layout-main.component.d.ts +7 -12
- package/modules/layout/components/sidebar-v1/components/sidebar/sidebar.component.d.ts +22 -30
- package/modules/layout/components/sidebar-v1/components/user/user.component.d.ts +10 -19
- package/modules/layout/components/sidebar-v1/main.component.d.ts +14 -14
- package/modules/layout/configurations/layout.configuration.d.ts +46 -6
- package/modules/layout/modules/forbidden/pages/root/root.component.d.ts +3 -8
- package/modules/layout/modules/home/components/home-page/home-page.component.d.ts +2 -5
- package/modules/layout/modules/not-found/pages/root/root.component.d.ts +3 -8
- package/modules/layout/services/index.d.ts +1 -0
- package/modules/layout/services/layout.service.d.ts +10 -0
- package/modules/layout/services/storage/storage.service.d.ts +0 -4
- package/package.json +63 -63
- package/sd-angular-core-19.0.0-beta.49.tgz +0 -0
package/components/tab-router/src/components/tab-router-outlet/tab-router-outlet.component.d.ts
CHANGED
|
@@ -1,24 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ActivatedRoute, Router } from '@angular/router';
|
|
3
|
-
import { SdNotifyService } from '@sd-angular/core/services/notify';
|
|
1
|
+
import { OnDestroy } from '@angular/core';
|
|
4
2
|
import { SdTab } from '../../models';
|
|
5
|
-
import { SdTabDecoratorService } from '../../services/tab-decorator.service';
|
|
6
|
-
import { SdTabRouterService } from '../../services/tab-router.service';
|
|
7
3
|
import { SdTabRouterNavComponent } from '../tab-router-nav/tab-router-nav.component';
|
|
8
4
|
import * as i0 from "@angular/core";
|
|
9
5
|
export declare class SdTabRouterOutletComponent implements OnDestroy {
|
|
10
6
|
#private;
|
|
11
|
-
private router;
|
|
12
|
-
private activatedRoute;
|
|
13
|
-
private cd;
|
|
14
|
-
private injector;
|
|
15
|
-
private tabDecoratorService;
|
|
16
|
-
private tabRouterService;
|
|
17
|
-
private sdNotifyService;
|
|
18
7
|
tabRouterNav?: SdTabRouterNavComponent;
|
|
19
|
-
tabs: SdTab[]
|
|
20
|
-
constructor(
|
|
21
|
-
tabRouterService: SdTabRouterService, sdNotifyService: SdNotifyService);
|
|
8
|
+
tabs: import("@angular/core").WritableSignal<SdTab[]>;
|
|
9
|
+
constructor();
|
|
22
10
|
ngOnDestroy(): void;
|
|
23
11
|
tabTrackBy: (index: number, tab: SdTab) => string;
|
|
24
12
|
static ɵfac: i0.ɵɵFactoryDeclaration<SdTabRouterOutletComponent, never>;
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, Pipe, Input, ChangeDetectionStrategy, Component, HostListener, ViewChild, createNgModule } from '@angular/core';
|
|
3
|
-
import * as
|
|
4
|
-
import { RouterEvent, RoutesRecognized, NavigationEnd
|
|
5
|
-
import * as
|
|
2
|
+
import { Injectable, Pipe, Input, ChangeDetectionStrategy, Component, HostListener, ViewChild, signal, inject, Injector, NgModuleFactory, createNgModule } from '@angular/core';
|
|
3
|
+
import * as i2 from '@angular/router';
|
|
4
|
+
import { Router, ActivatedRoute, RouterEvent, RoutesRecognized, NavigationEnd } from '@angular/router';
|
|
5
|
+
import * as i1 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, Subject } from 'rxjs';
|
|
10
|
+
import { BehaviorSubject, Subscription, isObservable, lastValueFrom, Subject } from 'rxjs';
|
|
11
11
|
import { debounceTime, startWith, map, filter, take } from 'rxjs/operators';
|
|
12
|
-
import
|
|
12
|
+
import { SdNotifyService } from '@sd-angular/core/services/notify';
|
|
13
|
+
import { SdUtilities } from '@sd-angular/core/utilities';
|
|
14
|
+
import * as i2$1 from '@angular/cdk/drag-drop';
|
|
13
15
|
import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
|
|
14
16
|
import { SdBadge } from '@sd-angular/core/components/badge';
|
|
15
|
-
import { SdUtilities } from '@sd-angular/core/utilities';
|
|
16
|
-
import * as i4 from '@sd-angular/core/services/notify';
|
|
17
17
|
|
|
18
18
|
class SdTabBase {
|
|
19
19
|
#tab;
|
|
@@ -114,6 +114,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
114
114
|
}]
|
|
115
115
|
}], ctorParameters: () => [] });
|
|
116
116
|
|
|
117
|
+
class SdTabDecoratorService {
|
|
118
|
+
static tabRouterService = new BehaviorSubject(undefined);
|
|
119
|
+
constructor(tabRouterService) {
|
|
120
|
+
SdTabDecoratorService.tabRouterService.next(tabRouterService);
|
|
121
|
+
}
|
|
122
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdTabDecoratorService, deps: [{ token: SdTabRouterService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
123
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdTabDecoratorService, providedIn: 'root' });
|
|
124
|
+
}
|
|
125
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdTabDecoratorService, decorators: [{
|
|
126
|
+
type: Injectable,
|
|
127
|
+
args: [{
|
|
128
|
+
providedIn: 'root',
|
|
129
|
+
}]
|
|
130
|
+
}], ctorParameters: () => [{ type: SdTabRouterService }] });
|
|
131
|
+
|
|
117
132
|
class SdTabInfoPipe {
|
|
118
133
|
tabRouterService;
|
|
119
134
|
constructor(tabRouterService) {
|
|
@@ -221,13 +236,13 @@ class SdTabRouterItemComponent {
|
|
|
221
236
|
this.tabRouterService.close(this.tab);
|
|
222
237
|
}
|
|
223
238
|
};
|
|
224
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdTabRouterItemComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: SdTabRouterService }, { token:
|
|
239
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdTabRouterItemComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: SdTabRouterService }, { token: i2.Router }], target: i0.ɵɵFactoryTarget.Component });
|
|
225
240
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: SdTabRouterItemComponent, isStandalone: true, selector: "sd-tab-router-item", inputs: { tab: "tab" }, ngImport: i0, template: "<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", styles: [":host{display:block;overflow:hidden;position:relative;flex:1 1 64px;max-width:240px}:host:after{content:\"\";position:absolute;right:0;top:0;bottom:0;height:16px;width:1px;background:#dde0e5;margin:auto}:host:last-child:after{content:none}:host::ng-deep .tab-router__item sd-badge .c-badge-title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;width:184px}.flex-1{flex:1}.tab-router__icon{background-color:#5c6bc0;width:16px;height:16px;line-height:16px;text-align:center;font-size:10px;color:#fff;border-radius:2px;text-transform:uppercase}.tab-router__icon .mat-icon{height:10px;width:10px;font-size:10px}.tab-router__close{color:#757575;outline:none;border:0;background:none;border-radius:50%;height:16px;width:16px}.tab-router__close:hover{background-color:#0000001f}.tab-router__close .mat-icon{font-size:12px;height:12px;width:12px}.tab-router__item{background:#f2f3f4;padding:8px;color:inherit;text-decoration:none;font-size:12px;line-height:16px;overflow:hidden}.tab-router__item:hover{background-color:#fff}.tab-router__name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tab-router__item--active{border-radius:8px 8px 0 0;background-color:#fff}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: SdBadge, selector: "sd-badge", inputs: ["type", "color", "primary", "secondary", "success", "info", "warning", "error", "fontSet", "title", "description", "tooltip", "icon", "size"], outputs: ["click"] }, { kind: "pipe", type: SdTabInfoPipe, name: "sdTabInfo" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
226
241
|
}
|
|
227
242
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdTabRouterItemComponent, decorators: [{
|
|
228
243
|
type: Component,
|
|
229
244
|
args: [{ selector: 'sd-tab-router-item', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, MatIconModule, SdBadge, SdTabInfoPipe], template: "<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", styles: [":host{display:block;overflow:hidden;position:relative;flex:1 1 64px;max-width:240px}:host:after{content:\"\";position:absolute;right:0;top:0;bottom:0;height:16px;width:1px;background:#dde0e5;margin:auto}:host:last-child:after{content:none}:host::ng-deep .tab-router__item sd-badge .c-badge-title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;width:184px}.flex-1{flex:1}.tab-router__icon{background-color:#5c6bc0;width:16px;height:16px;line-height:16px;text-align:center;font-size:10px;color:#fff;border-radius:2px;text-transform:uppercase}.tab-router__icon .mat-icon{height:10px;width:10px;font-size:10px}.tab-router__close{color:#757575;outline:none;border:0;background:none;border-radius:50%;height:16px;width:16px}.tab-router__close:hover{background-color:#0000001f}.tab-router__close .mat-icon{font-size:12px;height:12px;width:12px}.tab-router__item{background:#f2f3f4;padding:8px;color:inherit;text-decoration:none;font-size:12px;line-height:16px;overflow:hidden}.tab-router__item:hover{background-color:#fff}.tab-router__name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tab-router__item--active{border-radius:8px 8px 0 0;background-color:#fff}\n"] }]
|
|
230
|
-
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: SdTabRouterService }, { type:
|
|
245
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: SdTabRouterService }, { type: i2.Router }], propDecorators: { tab: [{
|
|
231
246
|
type: Input,
|
|
232
247
|
args: [{ required: true }]
|
|
233
248
|
}] } });
|
|
@@ -262,7 +277,7 @@ class SdTabRouterNavComponent {
|
|
|
262
277
|
moveItemInArray(this.tabs, event.previousIndex, event.currentIndex);
|
|
263
278
|
};
|
|
264
279
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdTabRouterNavComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
265
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: SdTabRouterNavComponent, isStandalone: true, selector: "sd-tab-router-nav", inputs: { tabs: "tabs" }, host: { listeners: { "window:resize": "onResize($event)" } }, viewQueries: [{ propertyName: "tabRouterNav", first: true, predicate: ["tabRouterNav"], descendants: 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 <ng-container *ngFor=\"let tab of tabs\">\n <sd-tab-router-item [tab]=\"tab\" cdkDrag [cdkDragBoundary]=\"elementRef?.nativeElement\"></sd-tab-router-item>\n </ng-container>\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: "directive", type:
|
|
280
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: SdTabRouterNavComponent, isStandalone: true, selector: "sd-tab-router-nav", inputs: { tabs: "tabs" }, host: { listeners: { "window:resize": "onResize($event)" } }, viewQueries: [{ propertyName: "tabRouterNav", first: true, predicate: ["tabRouterNav"], descendants: 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 <ng-container *ngFor=\"let tab of tabs\">\n <sd-tab-router-item [tab]=\"tab\" cdkDrag [cdkDragBoundary]=\"elementRef?.nativeElement\"></sd-tab-router-item>\n </ng-container>\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: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$1.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 });
|
|
266
281
|
}
|
|
267
282
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdTabRouterNavComponent, decorators: [{
|
|
268
283
|
type: Component,
|
|
@@ -277,64 +292,38 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
277
292
|
args: ['window:resize', ['$event']]
|
|
278
293
|
}] } });
|
|
279
294
|
|
|
280
|
-
class SdTabDecoratorService {
|
|
281
|
-
static tabRouterService = new BehaviorSubject(undefined);
|
|
282
|
-
constructor(tabRouterService) {
|
|
283
|
-
SdTabDecoratorService.tabRouterService.next(tabRouterService);
|
|
284
|
-
}
|
|
285
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdTabDecoratorService, deps: [{ token: SdTabRouterService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
286
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdTabDecoratorService, providedIn: 'root' });
|
|
287
|
-
}
|
|
288
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdTabDecoratorService, decorators: [{
|
|
289
|
-
type: Injectable,
|
|
290
|
-
args: [{
|
|
291
|
-
providedIn: 'root',
|
|
292
|
-
}]
|
|
293
|
-
}], ctorParameters: () => [{ type: SdTabRouterService }] });
|
|
294
|
-
|
|
295
295
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
296
296
|
class SdTabRouterOutletComponent {
|
|
297
|
-
router;
|
|
298
|
-
activatedRoute;
|
|
299
|
-
cd;
|
|
300
|
-
injector;
|
|
301
|
-
tabDecoratorService;
|
|
302
|
-
tabRouterService;
|
|
303
|
-
sdNotifyService;
|
|
304
297
|
tabRouterNav;
|
|
305
|
-
tabs = [];
|
|
298
|
+
tabs = signal([]);
|
|
299
|
+
#router = inject(Router);
|
|
300
|
+
#activatedRoute = inject(ActivatedRoute);
|
|
301
|
+
#injector = inject(Injector);
|
|
302
|
+
#tabRouterService = inject(SdTabRouterService);
|
|
303
|
+
#sdNotifyService = inject(SdNotifyService);
|
|
304
|
+
#tabDecoratorService = inject(SdTabDecoratorService);
|
|
306
305
|
#rootRoute;
|
|
307
306
|
#subscription = new Subscription();
|
|
308
307
|
#firstLoad = true;
|
|
309
|
-
constructor(
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
this.activatedRoute = activatedRoute;
|
|
313
|
-
this.cd = cd;
|
|
314
|
-
this.injector = injector;
|
|
315
|
-
this.tabDecoratorService = tabDecoratorService;
|
|
316
|
-
this.tabRouterService = tabRouterService;
|
|
317
|
-
this.sdNotifyService = sdNotifyService;
|
|
318
|
-
this.#subscription.add(router.events
|
|
319
|
-
.pipe(map((event) => (event instanceof RouterEvent ? event : event.routerEvent)), filter(event => {
|
|
320
|
-
return event instanceof RoutesRecognized || event instanceof NavigationEnd;
|
|
321
|
-
}))
|
|
308
|
+
constructor() {
|
|
309
|
+
this.#subscription.add(this.#router.events
|
|
310
|
+
.pipe(map((event) => (event instanceof RouterEvent ? event : event.routerEvent)), filter(event => event instanceof RoutesRecognized || event instanceof NavigationEnd))
|
|
322
311
|
.subscribe(async (event) => {
|
|
323
312
|
if (this.#firstLoad && event instanceof NavigationEnd) {
|
|
324
313
|
this.#firstLoad = false;
|
|
325
|
-
const route = this.#getActivatedRouteSnapshot(this
|
|
326
|
-
this.#rootRoute = this
|
|
314
|
+
const route = this.#getActivatedRouteSnapshot(this.#activatedRoute.snapshot);
|
|
315
|
+
this.#rootRoute = this.#router.routerState.root;
|
|
327
316
|
await this.#activeRoute(event.urlAfterRedirects || event.url, route);
|
|
328
317
|
return;
|
|
329
318
|
}
|
|
330
319
|
if (!this.#firstLoad && event instanceof RoutesRecognized) {
|
|
331
320
|
const route = this.#getActivatedRouteSnapshot(event.state.root);
|
|
332
|
-
this.#rootRoute = this
|
|
321
|
+
this.#rootRoute = this.#router.routerState.root;
|
|
333
322
|
await this.#activeRoute(event.urlAfterRedirects || event.url, route);
|
|
334
323
|
}
|
|
335
324
|
}));
|
|
336
|
-
this.#subscription.add(tabRouterService.actions.subscribe((event) => {
|
|
337
|
-
if (event
|
|
325
|
+
this.#subscription.add(this.#tabRouterService.actions.subscribe((event) => {
|
|
326
|
+
if (event?.type === 'close') {
|
|
338
327
|
this.#closeTab(event.tab);
|
|
339
328
|
}
|
|
340
329
|
}));
|
|
@@ -342,61 +331,42 @@ class SdTabRouterOutletComponent {
|
|
|
342
331
|
ngOnDestroy() {
|
|
343
332
|
this.#subscription.unsubscribe();
|
|
344
333
|
}
|
|
345
|
-
tabTrackBy = (index, tab) =>
|
|
346
|
-
return tab.key;
|
|
347
|
-
};
|
|
334
|
+
tabTrackBy = (index, tab) => tab.key;
|
|
348
335
|
#closeTab = (tab) => {
|
|
336
|
+
const currentTabs = this.tabs();
|
|
349
337
|
const { isActive, key: activeKey } = tab;
|
|
350
338
|
if (isActive) {
|
|
351
|
-
const activeIndex =
|
|
352
|
-
const nextTab =
|
|
339
|
+
const activeIndex = currentTabs.findIndex(({ key }) => key === activeKey);
|
|
340
|
+
const nextTab = currentTabs[activeIndex + 1] || currentTabs[activeIndex - 1];
|
|
341
|
+
this.tabs.set(currentTabs.filter(({ key }) => key !== activeKey));
|
|
353
342
|
if (nextTab) {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
};
|
|
358
|
-
this.tabs = this.tabs.filter(({ key }) => key !== activeKey);
|
|
359
|
-
this.router.navigate([nextUrl], {
|
|
360
|
-
queryParams: nextQueryParams,
|
|
361
|
-
state: {
|
|
362
|
-
switchTab: true,
|
|
363
|
-
},
|
|
343
|
+
this.#router.navigate([nextTab.url], {
|
|
344
|
+
queryParams: { ...(nextTab.queryParams || {}) },
|
|
345
|
+
state: { switchTab: true },
|
|
364
346
|
});
|
|
365
347
|
}
|
|
366
348
|
else {
|
|
367
|
-
this.
|
|
368
|
-
this.router.navigateByUrl('/', {
|
|
369
|
-
state: {
|
|
370
|
-
switchTab: true,
|
|
371
|
-
},
|
|
372
|
-
});
|
|
349
|
+
this.#router.navigateByUrl('/', { state: { switchTab: true } });
|
|
373
350
|
}
|
|
374
351
|
}
|
|
375
352
|
else {
|
|
376
|
-
this.tabs
|
|
353
|
+
this.tabs.set(currentTabs.filter(({ key }) => key !== tab.key));
|
|
377
354
|
this.tabRouterNav?.checkUI();
|
|
378
|
-
this.cd.markForCheck();
|
|
379
355
|
}
|
|
380
356
|
};
|
|
381
357
|
#activeRoute = async (fullUrl, route) => {
|
|
382
|
-
if (!route?.component)
|
|
358
|
+
if (!route?.component)
|
|
383
359
|
return;
|
|
384
|
-
}
|
|
385
360
|
const component = route.component;
|
|
386
|
-
const queryParams = {
|
|
387
|
-
|
|
388
|
-
};
|
|
389
|
-
const params = {
|
|
390
|
-
...(route.params || {}),
|
|
391
|
-
};
|
|
392
|
-
const data = {
|
|
393
|
-
...(route.data || {}),
|
|
394
|
-
};
|
|
361
|
+
const queryParams = { ...(route.queryParams || {}) };
|
|
362
|
+
const params = { ...(route.params || {}) };
|
|
363
|
+
const data = { ...(route.data || {}) };
|
|
395
364
|
const [url] = fullUrl.split('?');
|
|
396
365
|
const key = SdUtilities.hash({ url, queryParams });
|
|
397
366
|
let existedIndex = -1;
|
|
398
367
|
let activatedIndex = -1;
|
|
399
|
-
this.tabs
|
|
368
|
+
const currentTabs = this.tabs();
|
|
369
|
+
currentTabs.forEach((tab, index) => {
|
|
400
370
|
if (tab.key === key) {
|
|
401
371
|
tab.isActive = true;
|
|
402
372
|
existedIndex = index;
|
|
@@ -404,179 +374,126 @@ class SdTabRouterOutletComponent {
|
|
|
404
374
|
else {
|
|
405
375
|
if (tab.isActive) {
|
|
406
376
|
activatedIndex = index;
|
|
407
|
-
this
|
|
377
|
+
this.#tabRouterService.pushEvent(tab, SdTabDeactivated);
|
|
408
378
|
}
|
|
409
379
|
tab.isActive = false;
|
|
410
380
|
}
|
|
411
381
|
});
|
|
412
|
-
const currentNavigation = this
|
|
413
|
-
// Switch tab sẽ ko re-render lại trang
|
|
382
|
+
const currentNavigation = this.#router.getCurrentNavigation();
|
|
414
383
|
const switchTab = currentNavigation?.extras?.state?.['switchTab'];
|
|
415
|
-
// Replace tab sẽ close trang hiện tại
|
|
416
384
|
const replaceTab = currentNavigation?.extras?.state?.['replaceTab'];
|
|
385
|
+
// --- XỬ LÝ INJECTOR VÀ FIX LỖI TYPE TS(2345) ---
|
|
386
|
+
const getBestInjector = async (snapshot) => {
|
|
387
|
+
// 1. Nếu là Standalone Route, lấy injector từ chính route config (đã được router resolve)
|
|
388
|
+
const routeInjector = snapshot._resolvedGui || snapshot.routeConfig?._injector;
|
|
389
|
+
if (routeInjector)
|
|
390
|
+
return routeInjector;
|
|
391
|
+
// 2. Xử lý NgModule (Lazy load kiểu cũ)
|
|
392
|
+
const loadChildren = snapshot.parent?.routeConfig?.loadChildren;
|
|
393
|
+
if (typeof loadChildren === 'function') {
|
|
394
|
+
let loaded = await loadChildren();
|
|
395
|
+
// Unwrap Observable
|
|
396
|
+
if (isObservable(loaded)) {
|
|
397
|
+
loaded = await lastValueFrom(loaded);
|
|
398
|
+
}
|
|
399
|
+
// Unwrap Default Export (ES Module)
|
|
400
|
+
if (loaded && typeof loaded === 'object' && 'default' in loaded) {
|
|
401
|
+
loaded = loaded.default;
|
|
402
|
+
}
|
|
403
|
+
// Nếu là NgModuleFactory (Angular cũ hơn)
|
|
404
|
+
if (loaded instanceof NgModuleFactory) {
|
|
405
|
+
return loaded.create(this.#injector).injector;
|
|
406
|
+
}
|
|
407
|
+
// Nếu là Type (Class NgModule) - Đây là chỗ fix lỗi TS(2345)
|
|
408
|
+
if (typeof loaded === 'function' && !Array.isArray(loaded)) {
|
|
409
|
+
try {
|
|
410
|
+
return createNgModule(loaded, this.#injector).injector;
|
|
411
|
+
}
|
|
412
|
+
catch {
|
|
413
|
+
return this.#injector;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
return this.#injector;
|
|
418
|
+
};
|
|
419
|
+
const finalInjector = await getBestInjector(route);
|
|
420
|
+
const activatedRoute = this.#getActivatedRoute(this.#rootRoute, component);
|
|
421
|
+
const newTab = {
|
|
422
|
+
key,
|
|
423
|
+
component,
|
|
424
|
+
injector: new SdOutletInjector(activatedRoute, finalInjector),
|
|
425
|
+
isActive: true,
|
|
426
|
+
url,
|
|
427
|
+
params,
|
|
428
|
+
queryParams,
|
|
429
|
+
data,
|
|
430
|
+
tabInfoChanges: new Subject(),
|
|
431
|
+
};
|
|
417
432
|
if (existedIndex >= 0) {
|
|
418
|
-
const
|
|
433
|
+
const updatedTabs = [...currentTabs];
|
|
419
434
|
if (replaceTab && activatedIndex >= 0) {
|
|
420
|
-
|
|
421
|
-
this.tabs.splice(activatedIndex, 1);
|
|
422
|
-
}
|
|
435
|
+
updatedTabs.splice(activatedIndex, 1);
|
|
423
436
|
}
|
|
424
437
|
if (switchTab) {
|
|
425
|
-
this
|
|
426
|
-
this
|
|
438
|
+
this.#tabRouterService.setCurrentTab(updatedTabs[existedIndex]);
|
|
439
|
+
this.#tabRouterService.pushEvent(updatedTabs[existedIndex], SdTabActivated);
|
|
427
440
|
}
|
|
428
441
|
else {
|
|
429
|
-
|
|
430
|
-
const module = (await route.parent.routeConfig.loadChildren());
|
|
431
|
-
const moduleRef = createNgModule(module, this.injector);
|
|
432
|
-
const activatedRoute = this.#getActivatedRoute(this.#rootRoute, component);
|
|
433
|
-
const tab = {
|
|
434
|
-
key,
|
|
435
|
-
component,
|
|
436
|
-
injector: new SdOutletInjector(activatedRoute, moduleRef),
|
|
437
|
-
isActive: true,
|
|
438
|
-
url,
|
|
439
|
-
params,
|
|
440
|
-
queryParams,
|
|
441
|
-
data,
|
|
442
|
-
tabInfoChanges: new Subject(),
|
|
443
|
-
};
|
|
444
|
-
this.tabs[this.tabs.indexOf(existedTab)] = tab;
|
|
445
|
-
}
|
|
442
|
+
updatedTabs[existedIndex] = newTab;
|
|
446
443
|
}
|
|
444
|
+
this.tabs.set(updatedTabs);
|
|
447
445
|
}
|
|
448
446
|
else {
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
const tab = {
|
|
454
|
-
key,
|
|
455
|
-
component,
|
|
456
|
-
injector: new SdOutletInjector(activatedRoute, moduleRef),
|
|
457
|
-
isActive: true,
|
|
458
|
-
url,
|
|
459
|
-
params,
|
|
460
|
-
queryParams,
|
|
461
|
-
data,
|
|
462
|
-
tabInfoChanges: new Subject(),
|
|
463
|
-
};
|
|
464
|
-
this.tabRouterService.setCurrentTab(tab);
|
|
465
|
-
if (activatedIndex >= 0 && replaceTab) {
|
|
466
|
-
this.tabs.splice(activatedIndex, 1);
|
|
467
|
-
}
|
|
468
|
-
this.tabs.push(tab);
|
|
469
|
-
// if (existedIndex >= 0 && !switchTab) {
|
|
470
|
-
// this.tabs[existedIndex] = tab;
|
|
471
|
-
// } else {
|
|
472
|
-
// this.tabs.push(tab);
|
|
473
|
-
// }
|
|
447
|
+
const updatedTabs = [...currentTabs];
|
|
448
|
+
this.#tabRouterService.setCurrentTab(newTab);
|
|
449
|
+
if (activatedIndex >= 0 && replaceTab) {
|
|
450
|
+
updatedTabs.splice(activatedIndex, 1);
|
|
474
451
|
}
|
|
475
|
-
this.
|
|
476
|
-
if (this.tabs.length > 10) {
|
|
477
|
-
this
|
|
452
|
+
this.tabs.set([...updatedTabs, newTab]);
|
|
453
|
+
if (this.tabs().length > 10) {
|
|
454
|
+
this.#sdNotifyService.warning('Bạn đã mở quá nhiều tab.');
|
|
478
455
|
}
|
|
479
|
-
// if (this.tabs.length > 15) {
|
|
480
|
-
// this.tabs.splice(0, this.tabs.length - 10);
|
|
481
|
-
// }
|
|
482
456
|
}
|
|
483
|
-
|
|
484
|
-
// const existedTab = this.tabs[existedIndex];
|
|
485
|
-
// this.tabRouterService.setCurrentTab(existedTab);
|
|
486
|
-
// this.tabRouterService.pushEvent(existedTab, SdTabActivated);
|
|
487
|
-
// } else {
|
|
488
|
-
// if (typeof route?.parent?.routeConfig?.loadChildren === 'function') {
|
|
489
|
-
// const module = await route.parent.routeConfig.loadChildren();
|
|
490
|
-
// const factory = await this.compiler.compileModuleAsync(module);
|
|
491
|
-
// const injector = factory.create(this.injector);
|
|
492
|
-
// const activatedRoute = this.#getActivatedRoute(
|
|
493
|
-
// this.#rootRoute,
|
|
494
|
-
// component
|
|
495
|
-
// );
|
|
496
|
-
// const tab = {
|
|
497
|
-
// key,
|
|
498
|
-
// component,
|
|
499
|
-
// injector: new SdOutletInjector(activatedRoute, injector),
|
|
500
|
-
// isActive: true,
|
|
501
|
-
// name: url,
|
|
502
|
-
// url,
|
|
503
|
-
// params,
|
|
504
|
-
// queryParams,
|
|
505
|
-
// data
|
|
506
|
-
// };
|
|
507
|
-
// this.tabRouterService.setCurrentTab(tab);
|
|
508
|
-
// if (activatedIndex >= 0 && replaceTab) {
|
|
509
|
-
// this.tabs.splice(activatedIndex, 1);
|
|
510
|
-
// }
|
|
511
|
-
// if (existedIndex >= 0 && !switchTab) {
|
|
512
|
-
// this.tabs[existedIndex] = tab;
|
|
513
|
-
// } else {
|
|
514
|
-
// this.tabs.push(tab);
|
|
515
|
-
// }
|
|
516
|
-
// }
|
|
517
|
-
// this.tabRouterNav?.checkUI();
|
|
518
|
-
// if (this.tabs.length > 10) {
|
|
519
|
-
// this.sdNotifyService.notify.warning(
|
|
520
|
-
// 'Bạn đã mở quá nhiều tab. Vui lòng tắt các tab không dùng để hệ thống hoạt động tốt hơn.'
|
|
521
|
-
// );
|
|
522
|
-
// }
|
|
523
|
-
// if (this.tabs.length > 15) {
|
|
524
|
-
// this.tabs.splice(0, this.tabs.length - 10);
|
|
525
|
-
// }
|
|
526
|
-
// }
|
|
527
|
-
this.cd.markForCheck();
|
|
457
|
+
this.tabRouterNav?.checkUI();
|
|
528
458
|
};
|
|
529
|
-
#getActivatedRouteSnapshot = (
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
activatedRouteSnapshot = activatedRouteSnapshot.firstChild;
|
|
535
|
-
}
|
|
536
|
-
return activatedRouteSnapshot;
|
|
459
|
+
#getActivatedRouteSnapshot = (snapshot) => {
|
|
460
|
+
let node = snapshot;
|
|
461
|
+
while (node.firstChild)
|
|
462
|
+
node = node.firstChild;
|
|
463
|
+
return node;
|
|
537
464
|
};
|
|
538
465
|
#getActivatedRoute = (activatedRoute, component) => {
|
|
539
|
-
if (
|
|
540
|
-
return null;
|
|
541
|
-
}
|
|
542
|
-
if (activatedRoute.component && activatedRoute.component === component) {
|
|
466
|
+
if (activatedRoute.component === component)
|
|
543
467
|
return activatedRoute;
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
return activatedRoute;
|
|
549
|
-
}
|
|
468
|
+
for (const child of activatedRoute.children) {
|
|
469
|
+
const result = this.#getActivatedRoute(child, component);
|
|
470
|
+
if (result)
|
|
471
|
+
return result;
|
|
550
472
|
}
|
|
551
473
|
return null;
|
|
552
474
|
};
|
|
553
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdTabRouterOutletComponent, deps: [
|
|
554
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
475
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdTabRouterOutletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
476
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: SdTabRouterOutletComponent, isStandalone: true, selector: "sd-tab-router-outlet", viewQueries: [{ propertyName: "tabRouterNav", first: true, predicate: ["tabRouterNav"], descendants: true }], ngImport: i0, template: "<sd-tab-router-nav [tabs]=\"tabs()\" #tabRouterNav></sd-tab-router-nav>\n\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>", styles: [":host{display:flex;flex-direction:column;width:100%;height:calc(100vh - 64px)}:host ::ng-deep .sd-loading{max-width:100%;max-height:100%}.tab-router__list{flex:1}.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.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "component", type: SdTabRouterNavComponent, selector: "sd-tab-router-nav", inputs: ["tabs"] }] });
|
|
555
477
|
}
|
|
556
478
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdTabRouterOutletComponent, decorators: [{
|
|
557
479
|
type: Component,
|
|
558
|
-
args: [{ selector: 'sd-tab-router-outlet', standalone: true, imports: [CommonModule, MatIconModule, MatTooltipModule, SdTabRouterNavComponent], template: "<sd-tab-router-nav [tabs]=\"tabs\" #tabRouterNav></sd-tab-router-nav>\n\n<div class=\"tab-router__list\">\n
|
|
559
|
-
}], ctorParameters: () => [
|
|
480
|
+
args: [{ selector: 'sd-tab-router-outlet', standalone: true, imports: [CommonModule, MatIconModule, MatTooltipModule, SdTabRouterNavComponent], template: "<sd-tab-router-nav [tabs]=\"tabs()\" #tabRouterNav></sd-tab-router-nav>\n\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>", styles: [":host{display:flex;flex-direction:column;width:100%;height:calc(100vh - 64px)}:host ::ng-deep .sd-loading{max-width:100%;max-height:100%}.tab-router__list{flex:1}.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"] }]
|
|
481
|
+
}], ctorParameters: () => [], propDecorators: { tabRouterNav: [{
|
|
560
482
|
type: ViewChild,
|
|
561
483
|
args: ['tabRouterNav']
|
|
562
484
|
}] } });
|
|
563
485
|
class SdOutletInjector {
|
|
564
486
|
route;
|
|
565
|
-
|
|
566
|
-
constructor(route,
|
|
567
|
-
// private childContexts: ChildrenOutletContexts,
|
|
568
|
-
parent) {
|
|
487
|
+
parentInjector;
|
|
488
|
+
constructor(route, parentInjector) {
|
|
569
489
|
this.route = route;
|
|
570
|
-
this.
|
|
490
|
+
this.parentInjector = parentInjector;
|
|
571
491
|
}
|
|
572
492
|
get(token, notFoundValue) {
|
|
573
|
-
if (token === ActivatedRoute
|
|
574
|
-
return this.route;
|
|
493
|
+
if (token === ActivatedRoute) {
|
|
494
|
+
return this.route || notFoundValue;
|
|
575
495
|
}
|
|
576
|
-
|
|
577
|
-
// return this.childContexts;
|
|
578
|
-
// }
|
|
579
|
-
return this.parent.injector.get(token, notFoundValue);
|
|
496
|
+
return this.parentInjector.get(token, notFoundValue);
|
|
580
497
|
}
|
|
581
498
|
}
|
|
582
499
|
|