@acorex/platform 21.0.0-next.85 → 21.0.0-next.88
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/fesm2022/acorex-platform-auth.mjs +1 -1
- package/fesm2022/acorex-platform-auth.mjs.map +1 -1
- package/fesm2022/{acorex-platform-common-common-settings.provider-Ytey9uhY.mjs → acorex-platform-common-common-settings.provider-VfmZct9H.mjs} +43 -3
- package/fesm2022/acorex-platform-common-common-settings.provider-VfmZct9H.mjs.map +1 -0
- package/fesm2022/acorex-platform-common.mjs +1709 -870
- package/fesm2022/acorex-platform-common.mjs.map +1 -1
- package/fesm2022/acorex-platform-contracts.mjs +1160 -9
- package/fesm2022/acorex-platform-contracts.mjs.map +1 -1
- package/fesm2022/acorex-platform-core.mjs +210 -131
- package/fesm2022/acorex-platform-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-domain-contracts.mjs +58 -0
- package/fesm2022/acorex-platform-domain-contracts.mjs.map +1 -0
- package/fesm2022/acorex-platform-domain.mjs +2 -50
- package/fesm2022/acorex-platform-domain.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-components.mjs +59 -23
- package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-designer.mjs +3 -2
- package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity-attachments-page.component-CwG6n_Yb.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity-contracts.mjs +1114 -0
- package/fesm2022/acorex-platform-layout-entity-contracts.mjs.map +1 -0
- package/fesm2022/acorex-platform-layout-entity-file-list-popup.component--IeMZLIr.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity.mjs +661 -742
- package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-views.mjs +333 -119
- package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widget-core.mjs +11 -105
- package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-CFyfix31.mjs +513 -0
- package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-CFyfix31.mjs.map +1 -0
- package/fesm2022/{acorex-platform-layout-widgets-tabular-data-edit-popup.component-DjpZU6gz.mjs → acorex-platform-layout-widgets-tabular-data-edit-popup.component-D4MOHEpI.mjs} +4 -4
- package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-D4MOHEpI.mjs.map +1 -0
- package/fesm2022/acorex-platform-layout-widgets.mjs +868 -57
- package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
- package/fesm2022/acorex-platform-runtime.mjs.map +1 -1
- package/fesm2022/{acorex-platform-themes-default-entity-master-single-view.component-Br9p5aXT.mjs → acorex-platform-themes-default-entity-master-single-view.component-DrUwqKKA.mjs} +2 -3
- package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-DrUwqKKA.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-default.mjs +740 -96
- package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
- package/fesm2022/{acorex-platform-themes-shared-settings.provider-BjuzSe0T.mjs → acorex-platform-themes-shared-settings.provider-BUwPqwUS.mjs} +3 -3
- package/fesm2022/acorex-platform-themes-shared-settings.provider-BUwPqwUS.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-shared.mjs +4 -3
- package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
- package/fesm2022/acorex-platform-workflow.mjs +6 -8
- package/fesm2022/acorex-platform-workflow.mjs.map +1 -1
- package/package.json +9 -5
- package/types/acorex-platform-auth.d.ts +2 -1
- package/types/acorex-platform-common.d.ts +419 -1083
- package/types/acorex-platform-contracts.d.ts +1791 -260
- package/types/acorex-platform-core.d.ts +2153 -2806
- package/types/acorex-platform-domain-contracts.d.ts +416 -0
- package/types/acorex-platform-domain.d.ts +4 -415
- package/types/acorex-platform-layout-builder.d.ts +2 -1
- package/types/acorex-platform-layout-components.d.ts +15 -4
- package/types/acorex-platform-layout-designer.d.ts +2 -1
- package/types/acorex-platform-layout-entity-contracts.d.ts +864 -0
- package/types/acorex-platform-layout-entity.d.ts +88 -269
- package/types/acorex-platform-layout-views.d.ts +48 -14
- package/types/acorex-platform-layout-widget-core.d.ts +9 -5
- package/types/acorex-platform-layout-widgets.d.ts +89 -13
- package/types/acorex-platform-runtime.d.ts +1 -1
- package/types/acorex-platform-themes-default.d.ts +173 -70
- package/types/acorex-platform-workflow.d.ts +5 -18
- package/fesm2022/acorex-platform-common-common-settings.provider-Ytey9uhY.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-J0zcGKBX.mjs +0 -116
- package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-J0zcGKBX.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-DjpZU6gz.mjs.map +0 -1
- package/fesm2022/acorex-platform-native.mjs +0 -155
- package/fesm2022/acorex-platform-native.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-Br9p5aXT.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-shared-settings.provider-BjuzSe0T.mjs.map +0 -1
- package/native/README.md +0 -4
- package/types/acorex-platform-native.d.ts +0 -28
|
@@ -27,7 +27,7 @@ import { AXTranslationModule, AXTranslationService, translateSync } from '@acore
|
|
|
27
27
|
import * as i2 from '@acorex/core/utils';
|
|
28
28
|
import { AXUnsubscriber } from '@acorex/core/utils';
|
|
29
29
|
import { AXPAuthModule, AXPSessionService, AXPSessionStatus } from '@acorex/platform/auth';
|
|
30
|
-
import { AXPRefreshEvent, AXPSettingsService, AXPCommonSettings, axpIsEntityListRoute, axpReplaceEntityListRouteQueryParams, axpIsEntityListPath, AXP_PLATFORM_CONFIG_TOKEN, AXPMenuService, AXPMenuVisibilityService, AXP_PROTECTED_ROUTE_GUARDS, AXPCommonModule } from '@acorex/platform/common';
|
|
30
|
+
import { AXPRefreshEvent, AXPSettingsService, AXPCommonSettings, axpIsEntityListRoute, axpReplaceEntityListRouteQueryParams, axpIsEntityListPath, AXPTabNavigationService, AXPTabPreviewService, AXP_HOME_TAB_KEY, AXP_PLATFORM_CONFIG_TOKEN, AXPMenuService, AXPMenuVisibilityService, axpMenuPathsMatch, AXPTabRouteCacheRegistry, axpResolveTabKeyFromSnapshot, axpHasTabScope, axpPathFromSnapshot, axpIsTabEligibleUrl, axpResolveTabKeyFromRouteConfig, AXP_PROTECTED_ROUTE_GUARDS, AXPCommonModule } from '@acorex/platform/common';
|
|
31
31
|
import * as i1$5 from '@acorex/platform/core';
|
|
32
32
|
import { AXPDeviceService, AXHighlightService, AXPGridLayoutDirective, AXPComponentSlotModule, AXPKeyboardShortcutRegistry, AXPKeyboardShortcutPriority, AXPBroadcastEventService, AXPContextStore } from '@acorex/platform/core';
|
|
33
33
|
import { AXP_CATEGORY_TREE_ROOT_TITLE_I18N_KEY, AXPEntityDefinitionRegistryService, AXPCategoryTreeService, AXPEntityListViewColumnViewModel, AXPEntityMasterListCardSelectActionName, applyDataSourcePagingWithoutLoad, getDataSourcePageIndex, restoreEntityListExpandedRows, AXP_ENTITY_CONFIG_TOKEN } from '@acorex/platform/layout/entity';
|
|
@@ -39,14 +39,14 @@ import { AXPWorkflowService, ofType } from '@acorex/platform/workflow';
|
|
|
39
39
|
import * as i1$1 from '@angular/common';
|
|
40
40
|
import { CommonModule, AsyncPipe } from '@angular/common';
|
|
41
41
|
import * as i0 from '@angular/core';
|
|
42
|
-
import { inject, signal, computed, effect, ViewChild, Input, ChangeDetectionStrategy, ViewEncapsulation, Component, input, viewChild, afterNextRender, output, untracked, DestroyRef, NgModule } from '@angular/core';
|
|
42
|
+
import { inject, signal, computed, effect, ViewChild, Input, ChangeDetectionStrategy, ViewEncapsulation, Component, input, viewChild, afterNextRender, Injector, output, untracked, ElementRef, DestroyRef, NgModule } from '@angular/core';
|
|
43
43
|
import { FormsModule } from '@angular/forms';
|
|
44
44
|
import * as i1$6 from '@angular/router';
|
|
45
45
|
import { RouterModule, Router, ActivatedRoute, NavigationStart, NavigationEnd, RouteReuseStrategy, ROUTES } from '@angular/router';
|
|
46
46
|
import { Subject, takeUntil, filter, firstValueFrom } from 'rxjs';
|
|
47
47
|
import * as i1$4 from '@acorex/core/platform';
|
|
48
48
|
import { AXPThemeLayoutBlockComponent, AXPThemeLayoutHeaderComponent, AXPThemeLayoutToolbarComponent, AXPStateMessageComponent, AXPQueryFiltersComponent, AXPQuerySortsComponent, AXPQueryViewsComponent, AXPQueryColumnsComponent, AXPThemeLayoutStartSideComponent, AXPTaskBadgeService, AXPMenuBadgeHelper, AXPTaskBadgeDirective, AXPLogoComponent } from '@acorex/platform/layout/components';
|
|
49
|
-
import { DragDropModule } from '@angular/cdk/drag-drop';
|
|
49
|
+
import { DragDropModule, CdkDropList, CdkDrag, CdkDragHandle, CdkDragPreview } from '@angular/cdk/drag-drop';
|
|
50
50
|
import { AXDropdownButtonModule } from '@acorex/components/dropdown-button';
|
|
51
51
|
import { AXPPageLayoutBaseComponent, AXPPageLayoutComponent, AXPPageLayoutBase } from '@acorex/platform/layout/views';
|
|
52
52
|
import * as i2$2 from '@acorex/components/skeleton';
|
|
@@ -59,12 +59,12 @@ import * as i1$3 from '@acorex/components/data-pager';
|
|
|
59
59
|
import { AXDataPagerModule } from '@acorex/components/data-pager';
|
|
60
60
|
import * as i3$3 from '@acorex/components/check-box';
|
|
61
61
|
import { AXCheckBoxModule } from '@acorex/components/check-box';
|
|
62
|
+
import * as i4 from '@acorex/components/menu';
|
|
63
|
+
import { AXContextMenuComponent, AXMenuModule } from '@acorex/components/menu';
|
|
62
64
|
import * as i2$3 from '@acorex/components/side-menu';
|
|
63
65
|
import { AXSideMenuModule } from '@acorex/components/side-menu';
|
|
64
66
|
import { AXAvatarModule } from '@acorex/components/avatar';
|
|
65
67
|
import { AXImageModule } from '@acorex/components/image';
|
|
66
|
-
import * as i4 from '@acorex/components/menu';
|
|
67
|
-
import { AXMenuModule } from '@acorex/components/menu';
|
|
68
68
|
import sortBy$1 from 'lodash-es/sortBy';
|
|
69
69
|
import { AXResizableDirective } from '@acorex/cdk/resizable';
|
|
70
70
|
|
|
@@ -872,19 +872,23 @@ class AXPEntityCategoryComponent {
|
|
|
872
872
|
return children;
|
|
873
873
|
}
|
|
874
874
|
/**
|
|
875
|
-
*
|
|
875
|
+
* Reloads tree data from the server and optionally expands a parent node.
|
|
876
876
|
*/
|
|
877
|
-
|
|
877
|
+
async refreshAfterChange(parentId) {
|
|
878
878
|
const treeComponent = this.tree();
|
|
879
|
-
if (treeComponent) {
|
|
880
|
-
|
|
879
|
+
if (!treeComponent) {
|
|
880
|
+
return;
|
|
881
|
+
}
|
|
882
|
+
await treeComponent.reloadData();
|
|
883
|
+
const expandId = parentId ?? ROOT_NODE_ID;
|
|
884
|
+
try {
|
|
885
|
+
if (!treeComponent.isNodeExpanded(expandId)) {
|
|
886
|
+
await treeComponent.expandNode(expandId);
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
catch {
|
|
890
|
+
// Parent node may not exist yet after reload; ignore.
|
|
881
891
|
}
|
|
882
|
-
}
|
|
883
|
-
/**
|
|
884
|
-
* Refreshes tree after CRUD operations
|
|
885
|
-
*/
|
|
886
|
-
async refreshAfterChange(parentId) {
|
|
887
|
-
this.refreshTree();
|
|
888
892
|
}
|
|
889
893
|
/**
|
|
890
894
|
* Adds a new node to the tree after create operation
|
|
@@ -1236,8 +1240,8 @@ class AXPEntityMasterToolbarViewComponent {
|
|
|
1236
1240
|
this.router = inject(Router);
|
|
1237
1241
|
this.activeRoute = inject(ActivatedRoute);
|
|
1238
1242
|
this.settingsService = inject(AXPSettingsService);
|
|
1243
|
+
this.injector = inject(Injector);
|
|
1239
1244
|
this.isInitializing = false;
|
|
1240
|
-
this.pendingInitialFilters = true;
|
|
1241
1245
|
this.pendingInitialSorts = true;
|
|
1242
1246
|
this.filterTriggerMode = 'manual';
|
|
1243
1247
|
this.previousFilterQueries = signal([], ...(ngDevMode ? [{ debugName: "previousFilterQueries" }] : /* istanbul ignore next */ []));
|
|
@@ -1286,7 +1290,7 @@ class AXPEntityMasterToolbarViewComponent {
|
|
|
1286
1290
|
this.applyTimer = null;
|
|
1287
1291
|
this.#effect = effect(() => {
|
|
1288
1292
|
// Keep definitions up to date; initial filters are set explicitly from settings or view
|
|
1289
|
-
this.filtersDefinitions.set(this.vm.
|
|
1293
|
+
this.filtersDefinitions.set(this.vm.filterDefinitions());
|
|
1290
1294
|
}, ...(ngDevMode ? [{ debugName: "#effect" }] : /* istanbul ignore next */ []));
|
|
1291
1295
|
this.sortQueries = computed(() => this.vm
|
|
1292
1296
|
.sortedFields()
|
|
@@ -1315,20 +1319,34 @@ class AXPEntityMasterToolbarViewComponent {
|
|
|
1315
1319
|
}, ...(ngDevMode ? [{ debugName: "sortDefinitions" }] : /* istanbul ignore next */ []));
|
|
1316
1320
|
}
|
|
1317
1321
|
async ngOnInit() {
|
|
1318
|
-
// Prefer saved settings (view/columns/sorts/filters) if available, then apply
|
|
1322
|
+
// Prefer saved settings (view/columns/sorts/filters) if available, then apply once
|
|
1319
1323
|
await this.loadSettings();
|
|
1320
1324
|
await this.vm.setView();
|
|
1321
1325
|
await this.vm.ensureListPagingResolved();
|
|
1322
|
-
this.filtersDefinitions.set(this.vm.
|
|
1326
|
+
this.filtersDefinitions.set(this.vm.filterDefinitions());
|
|
1327
|
+
await this.runInitialListLoad();
|
|
1328
|
+
}
|
|
1329
|
+
/**
|
|
1330
|
+
* Applies persisted view/filters/sorts once after query-filters syncs `initialFilters`.
|
|
1331
|
+
* Avoids a second list query from `scheduleApply` plus a follow-up `onFiltersChanged` emit.
|
|
1332
|
+
*/
|
|
1333
|
+
async runInitialListLoad() {
|
|
1323
1334
|
this.isInitializing = true;
|
|
1324
|
-
|
|
1325
|
-
// this.pendingInitialSorts = true;
|
|
1335
|
+
this.pendingInitialSorts = true;
|
|
1326
1336
|
this.setInitialFiltersFromSettingsOrView();
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1337
|
+
await this.waitForQueryFiltersSync();
|
|
1338
|
+
await this.vm.applyFilterAndSort();
|
|
1339
|
+
this.previousFilterQueries.set(this.vm.filterQueries());
|
|
1340
|
+
this.isInitializing = false;
|
|
1341
|
+
this.pendingInitialSorts = false;
|
|
1342
|
+
}
|
|
1343
|
+
/** Waits until query-filters has rendered and synced converted `initialFilters`. */
|
|
1344
|
+
waitForQueryFiltersSync() {
|
|
1345
|
+
return new Promise((resolve) => {
|
|
1346
|
+
afterNextRender(() => {
|
|
1347
|
+
queueMicrotask(() => resolve());
|
|
1348
|
+
}, { injector: this.injector });
|
|
1349
|
+
});
|
|
1332
1350
|
}
|
|
1333
1351
|
async loadSettings() {
|
|
1334
1352
|
const filterTriggerMode = await this.settingsService.get(AXPCommonSettings.EntityFilterApplyMode);
|
|
@@ -1349,15 +1367,7 @@ class AXPEntityMasterToolbarViewComponent {
|
|
|
1349
1367
|
if (axpIsEntityListRoute(this.router)) {
|
|
1350
1368
|
axpReplaceEntityListRouteQueryParams(this.router, { view: view.name });
|
|
1351
1369
|
}
|
|
1352
|
-
this.
|
|
1353
|
-
this.pendingInitialFilters = true;
|
|
1354
|
-
this.pendingInitialSorts = true;
|
|
1355
|
-
this.setInitialFiltersFromSettingsOrView();
|
|
1356
|
-
// Ensure initial load after view change
|
|
1357
|
-
setTimeout(() => {
|
|
1358
|
-
this.isInitializing = false;
|
|
1359
|
-
this.scheduleApply();
|
|
1360
|
-
}, 0);
|
|
1370
|
+
await this.runInitialListLoad();
|
|
1361
1371
|
}
|
|
1362
1372
|
#effect;
|
|
1363
1373
|
setInitialFiltersFromSettingsOrView() {
|
|
@@ -1376,8 +1386,9 @@ class AXPEntityMasterToolbarViewComponent {
|
|
|
1376
1386
|
})));
|
|
1377
1387
|
}
|
|
1378
1388
|
onFiltersChanged(filters) {
|
|
1379
|
-
if (this.isInitializing
|
|
1380
|
-
this.
|
|
1389
|
+
if (this.isInitializing) {
|
|
1390
|
+
this.vm.filterQueries.set(filters);
|
|
1391
|
+
this.previousFilterQueries.set(filters);
|
|
1381
1392
|
return;
|
|
1382
1393
|
}
|
|
1383
1394
|
this.vm.filterQueries.set(filters);
|
|
@@ -1388,7 +1399,7 @@ class AXPEntityMasterToolbarViewComponent {
|
|
|
1388
1399
|
applyFilters() {
|
|
1389
1400
|
this.previousFilterQueries.set(this.vm.filterQueries());
|
|
1390
1401
|
this.vm.saveSettings('filters', this.vm.filterQueries());
|
|
1391
|
-
this.
|
|
1402
|
+
void this.vm.applyFilterAndSort();
|
|
1392
1403
|
}
|
|
1393
1404
|
onSortQueriesChange(e) {
|
|
1394
1405
|
if (this.isInitializing || this.pendingInitialSorts) {
|
|
@@ -1774,10 +1785,15 @@ class AXPEntityMasterListCardListComponent {
|
|
|
1774
1785
|
await this.vm().executeCommand(name, row);
|
|
1775
1786
|
}
|
|
1776
1787
|
onPageChanged(event) {
|
|
1777
|
-
|
|
1788
|
+
applyDataSourcePagingWithoutLoad(this.vm().dataSource, { take: event.take, skip: event.skip });
|
|
1789
|
+
this.pageIndex.set(getDataSourcePageIndex(this.vm().dataSource));
|
|
1790
|
+
this.pageSize.set(event.take);
|
|
1791
|
+
if (!event.isUserInteraction) {
|
|
1792
|
+
return;
|
|
1793
|
+
}
|
|
1794
|
+
if (!this.vm().skipListPagingPersistence) {
|
|
1778
1795
|
this.vm().saveListPaging(event.take, event.skip);
|
|
1779
1796
|
}
|
|
1780
|
-
applyDataSourcePagingWithoutLoad(this.vm().dataSource, { take: event.take, skip: event.skip });
|
|
1781
1797
|
this.pageChanged.emit(event);
|
|
1782
1798
|
void this.reload(false);
|
|
1783
1799
|
}
|
|
@@ -1946,7 +1962,6 @@ class AXPEntityMasterListViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
1946
1962
|
this.platform = platform;
|
|
1947
1963
|
//#region ---- Services & Dependencies ----
|
|
1948
1964
|
this.activeRoute = inject(ActivatedRoute);
|
|
1949
|
-
this.router = inject(Router);
|
|
1950
1965
|
//#endregion
|
|
1951
1966
|
//#region ---- View State ----
|
|
1952
1967
|
this.vm = this.activeRoute.snapshot.data['vm'];
|
|
@@ -1957,6 +1972,7 @@ class AXPEntityMasterListViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
1957
1972
|
//#endregion
|
|
1958
1973
|
//#region ---- View References ----
|
|
1959
1974
|
this.dataTable = viewChild(AXPEntityMasterListDataTableComponent, ...(ngDevMode ? [{ debugName: "dataTable" }] : /* istanbul ignore next */ []));
|
|
1975
|
+
this.cardList = viewChild(AXPEntityMasterListCardListComponent, ...(ngDevMode ? [{ debugName: "cardList" }] : /* istanbul ignore next */ []));
|
|
1960
1976
|
this.initializedFromRoute = false;
|
|
1961
1977
|
this.lastEvaluatedViewName = null;
|
|
1962
1978
|
this.componentDestroyed = new Subject();
|
|
@@ -2173,6 +2189,10 @@ class AXPEntityMasterListViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
2173
2189
|
await this.vm.ensureListPagingResolved();
|
|
2174
2190
|
this.vm.applyPagingToDataSourceWithoutLoad();
|
|
2175
2191
|
}
|
|
2192
|
+
if (this.vm.activeListLayout() === 'card') {
|
|
2193
|
+
await this.cardList()?.reload(resetPagination);
|
|
2194
|
+
return;
|
|
2195
|
+
}
|
|
2176
2196
|
const grid = this.grid();
|
|
2177
2197
|
if (grid) {
|
|
2178
2198
|
await grid.refresh({ reset: resetPagination });
|
|
@@ -2310,7 +2330,7 @@ class AXPEntityMasterListViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
2310
2330
|
provide: AXPPageLayoutBase,
|
|
2311
2331
|
useExisting: AXPEntityMasterListViewComponent,
|
|
2312
2332
|
},
|
|
2313
|
-
], viewQueries: [{ propertyName: "dataTable", first: true, predicate: AXPEntityMasterListDataTableComponent, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<axp-page-layout *translate=\"let t\">\n @if (vm.entityDef.category) {\n <axp-layout-start-side id=\"axp-entity-category-drawer\">\n <axp-entity-category\n id=\"axp-entity-category\"\n class=\"ax-w-80\"\n [vm]=\"vm\"\n [searchValue]=\"categorySearchValue()\"\n ></axp-entity-category>\n </axp-layout-start-side>\n }\n <axp-page-toolbar id=\"axp-entity-toolbar\">\n <axp-entity-master-toolbar-view [viewModel]=\"vm\"></axp-entity-master-toolbar-view>\n </axp-page-toolbar>\n <axp-page-content class=\"ax-overflow-auto ax-pt-0\">\n <div\n class=\"ax-flex ax-items-center ax-justify-between ax-gap-1 ax-pb-1 ax-text-muted ax-text-sm\"\n [class.ax-invisible]=\"!vm.selectedItems().length\"\n >\n <span\n >{{ vm.selectedItems().length }}\n <span>{{ '@general:terms.interface.items-selected' | translate | async }}</span>\n </span>\n <ax-button text=\"@general:terms.interface.unselect-all\" class=\"ax-xs\" (onClick)=\"handleUnselectAll()\"></ax-button>\n </div>\n @if (vm.enabledListLayouts().includes('table')) {\n <axp-entity-master-list-data-table\n class=\"axp-entity-list-host\"\n [class.axp-entity-list-host--hidden]=\"vm.activeListLayout() !== 'table'\"\n [vm]=\"vm\"\n (pageChanged)=\"onListPageChanged()\"\n ></axp-entity-master-list-data-table>\n }\n @if (vm.enabledListLayouts().includes('card')) {\n <axp-entity-master-list-card-list\n class=\"axp-entity-list-host\"\n [class.axp-entity-list-host--hidden]=\"vm.activeListLayout() !== 'card'\"\n [vm]=\"vm\"\n (pageChanged)=\"onListPageChanged()\"\n ></axp-entity-master-list-card-list>\n }\n </axp-page-content>\n</axp-page-layout>\n", styles: ["axp-entity-master-list axp-layout-start-side{min-width:20rem!important;border-inline-end-width:1px}axp-entity-master-list axp-layout-header{padding-bottom:.25rem!important}axp-entity-master-list .axp-entity-list-host{display:flex;height:100%;min-height:0px;flex-direction:column}axp-entity-master-list axp-page-content{display:flex;min-height:0px;flex-direction:column}axp-entity-master-list .axp-entity-list-host--hidden{display:none!important}.cdk-drag-preview{border-radius:.375rem;border-width:1px;--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);background:rgba(var(--ax-color-on-surface));padding:.5rem;height:max-content!important}.collapsed-search-box{margin-top:0;height:0px;opacity:0}.view-drawer{width:85vw}@media(min-width:768px){.view-drawer{width:45vw}}@media(min-width:1024px){.view-drawer{width:35vw}}@media(min-width:1536px){.view-drawer{width:20vw}}.view-drawer{--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lightest-surface),var(--tw-bg-opacity, 1));border-inline-start-width:1px;border-inline-start-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));border-top-width:1px;--tw-border-opacity: 1;border-top-color:rgba(var(--ax-sys-color-primary-600),var(--tw-border-opacity, 1))}.view-drawer ax-header{display:flex;align-items:center;border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lighter-surface),var(--tw-bg-opacity, 1));padding:.5rem 1rem}.view-drawer ax-header h2{font-size:1.25rem;line-height:1.75rem;font-weight:700;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lighter-surface),var(--tw-text-opacity, 1))}.view-drawer ax-footer{position:absolute!important;bottom:0!important;width:100%!important;justify-content:flex-start!important;border-top-width:1px!important;--tw-border-opacity: 1 !important;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1))!important;padding:.5rem 1rem!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "ngmodule", type: AXFormModule }, { kind: "ngmodule", type: AXActionSheetModule }, { kind: "ngmodule", type: AXDrawerModule }, { kind: "ngmodule", type: AXDialogModule }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "ngmodule", type: AXTabsModule }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "ngmodule", type: AXBreadcrumbsModule }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i3$1.AXTranslatorDirective, selector: "[translate]" }, { kind: "ngmodule", type: DragDropModule }, { kind: "ngmodule", type: AXPAuthModule }, { kind: "component", type: AXPEntityMasterToolbarViewComponent, selector: "axp-entity-master-toolbar-view", inputs: ["viewModel"] }, { kind: "component", type: AXPPageLayoutComponent, selector: "axp-page-layout" }, { kind: "component", type: AXPThemeLayoutBlockComponent, selector: " axp-page-content, axp-page-footer-container, axp-page-footer, axp-page-header, axp-page-header-container, axp-page-toolbar, axp-layout-content, axp-layout-page-content, axp-layout-sections, axp-layout-body, axp-layout-page-body, axp-layout-prefix, axp-layout-suffix, axp-layout-title-bar, axp-layout-title, axp-layout-title-actions, axp-layout-nav-button, axp-layout-description, axp-layout-breadcrumbs, axp-layout-list-action, " }, { kind: "component", type: AXPThemeLayoutStartSideComponent, selector: "axp-layout-page-start-side, axp-layout-start-side" }, { kind: "component", type: AXPEntityCategoryComponent, selector: "axp-entity-category", inputs: ["vm", "searchValue", "selectMode", "selectionBehavior", "dragArea", "dragBehavior", "showIcons", "showChildrenBadge", "expandedIcon", "collapsedIcon", "indentSize", "look", "searchWithChildren"] }, { kind: "component", type: AXPEntityMasterListDataTableComponent, selector: "axp-entity-master-list-data-table", inputs: ["vm"], outputs: ["pageChanged"] }, { kind: "component", type: AXPEntityMasterListCardListComponent, selector: "axp-entity-master-list-card-list", inputs: ["vm"], outputs: ["pageChanged"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2333
|
+
], viewQueries: [{ propertyName: "dataTable", first: true, predicate: AXPEntityMasterListDataTableComponent, descendants: true, isSignal: true }, { propertyName: "cardList", first: true, predicate: AXPEntityMasterListCardListComponent, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<axp-page-layout *translate=\"let t\">\n @if (vm.entityDef.category) {\n <axp-layout-start-side id=\"axp-entity-category-drawer\">\n <axp-entity-category\n id=\"axp-entity-category\"\n class=\"ax-w-80\"\n [vm]=\"vm\"\n [searchValue]=\"categorySearchValue()\"\n ></axp-entity-category>\n </axp-layout-start-side>\n }\n <axp-page-toolbar id=\"axp-entity-toolbar\">\n <axp-entity-master-toolbar-view [viewModel]=\"vm\"></axp-entity-master-toolbar-view>\n </axp-page-toolbar>\n <axp-page-content class=\"ax-overflow-auto ax-pt-0\">\n <div\n class=\"ax-flex ax-items-center ax-justify-between ax-gap-1 ax-pb-1 ax-text-muted ax-text-sm\"\n [class.ax-invisible]=\"!vm.selectedItems().length\"\n >\n <span\n >{{ vm.selectedItems().length }}\n <span>{{ '@general:terms.interface.items-selected' | translate | async }}</span>\n </span>\n <ax-button text=\"@general:terms.interface.unselect-all\" class=\"ax-xs\" (onClick)=\"handleUnselectAll()\"></ax-button>\n </div>\n @if (vm.enabledListLayouts().includes('table')) {\n <axp-entity-master-list-data-table\n class=\"axp-entity-list-host\"\n [class.axp-entity-list-host--hidden]=\"vm.activeListLayout() !== 'table'\"\n [vm]=\"vm\"\n (pageChanged)=\"onListPageChanged()\"\n ></axp-entity-master-list-data-table>\n }\n @if (vm.enabledListLayouts().includes('card')) {\n <axp-entity-master-list-card-list\n class=\"axp-entity-list-host\"\n [class.axp-entity-list-host--hidden]=\"vm.activeListLayout() !== 'card'\"\n [vm]=\"vm\"\n (pageChanged)=\"onListPageChanged()\"\n ></axp-entity-master-list-card-list>\n }\n </axp-page-content>\n</axp-page-layout>\n", styles: ["axp-entity-master-list axp-layout-start-side{min-width:20rem!important;border-inline-end-width:1px}axp-entity-master-list axp-layout-header{padding-bottom:.25rem!important}axp-entity-master-list .axp-entity-list-host{display:flex;height:100%;min-height:0px;flex-direction:column}axp-entity-master-list axp-page-content{display:flex;min-height:0px;flex-direction:column}axp-entity-master-list .axp-entity-list-host--hidden{display:none!important}.cdk-drag-preview{border-radius:.375rem;border-width:1px;--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);background:rgba(var(--ax-color-on-surface));padding:.5rem;height:max-content!important}.collapsed-search-box{margin-top:0;height:0px;opacity:0}.view-drawer{width:85vw}@media(min-width:768px){.view-drawer{width:45vw}}@media(min-width:1024px){.view-drawer{width:35vw}}@media(min-width:1536px){.view-drawer{width:20vw}}.view-drawer{--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lightest-surface),var(--tw-bg-opacity, 1));border-inline-start-width:1px;border-inline-start-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));border-top-width:1px;--tw-border-opacity: 1;border-top-color:rgba(var(--ax-sys-color-primary-600),var(--tw-border-opacity, 1))}.view-drawer ax-header{display:flex;align-items:center;border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lighter-surface),var(--tw-bg-opacity, 1));padding:.5rem 1rem}.view-drawer ax-header h2{font-size:1.25rem;line-height:1.75rem;font-weight:700;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lighter-surface),var(--tw-text-opacity, 1))}.view-drawer ax-footer{position:absolute!important;bottom:0!important;width:100%!important;justify-content:flex-start!important;border-top-width:1px!important;--tw-border-opacity: 1 !important;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1))!important;padding:.5rem 1rem!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "ngmodule", type: AXFormModule }, { kind: "ngmodule", type: AXActionSheetModule }, { kind: "ngmodule", type: AXDrawerModule }, { kind: "ngmodule", type: AXDialogModule }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "ngmodule", type: AXTabsModule }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "ngmodule", type: AXBreadcrumbsModule }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i3$1.AXTranslatorDirective, selector: "[translate]" }, { kind: "ngmodule", type: DragDropModule }, { kind: "ngmodule", type: AXPAuthModule }, { kind: "component", type: AXPEntityMasterToolbarViewComponent, selector: "axp-entity-master-toolbar-view", inputs: ["viewModel"] }, { kind: "component", type: AXPPageLayoutComponent, selector: "axp-page-layout" }, { kind: "component", type: AXPThemeLayoutBlockComponent, selector: " axp-page-content, axp-page-footer-container, axp-page-footer, axp-page-header, axp-page-header-container, axp-page-toolbar, axp-layout-content, axp-layout-page-content, axp-layout-sections, axp-layout-body, axp-layout-page-body, axp-layout-prefix, axp-layout-suffix, axp-layout-title-bar, axp-layout-title, axp-layout-title-actions, axp-layout-nav-button, axp-layout-description, axp-layout-breadcrumbs, axp-layout-list-action, " }, { kind: "component", type: AXPThemeLayoutStartSideComponent, selector: "axp-layout-page-start-side, axp-layout-start-side" }, { kind: "component", type: AXPEntityCategoryComponent, selector: "axp-entity-category", inputs: ["vm", "searchValue", "selectMode", "selectionBehavior", "dragArea", "dragBehavior", "showIcons", "showChildrenBadge", "expandedIcon", "collapsedIcon", "indentSize", "look", "searchWithChildren"] }, { kind: "component", type: AXPEntityMasterListDataTableComponent, selector: "axp-entity-master-list-data-table", inputs: ["vm"], outputs: ["pageChanged"] }, { kind: "component", type: AXPEntityMasterListCardListComponent, selector: "axp-entity-master-list-card-list", inputs: ["vm"], outputs: ["pageChanged"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2314
2334
|
}
|
|
2315
2335
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityMasterListViewComponent, decorators: [{
|
|
2316
2336
|
type: Component,
|
|
@@ -2349,7 +2369,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
2349
2369
|
useExisting: AXPEntityMasterListViewComponent,
|
|
2350
2370
|
},
|
|
2351
2371
|
], template: "<axp-page-layout *translate=\"let t\">\n @if (vm.entityDef.category) {\n <axp-layout-start-side id=\"axp-entity-category-drawer\">\n <axp-entity-category\n id=\"axp-entity-category\"\n class=\"ax-w-80\"\n [vm]=\"vm\"\n [searchValue]=\"categorySearchValue()\"\n ></axp-entity-category>\n </axp-layout-start-side>\n }\n <axp-page-toolbar id=\"axp-entity-toolbar\">\n <axp-entity-master-toolbar-view [viewModel]=\"vm\"></axp-entity-master-toolbar-view>\n </axp-page-toolbar>\n <axp-page-content class=\"ax-overflow-auto ax-pt-0\">\n <div\n class=\"ax-flex ax-items-center ax-justify-between ax-gap-1 ax-pb-1 ax-text-muted ax-text-sm\"\n [class.ax-invisible]=\"!vm.selectedItems().length\"\n >\n <span\n >{{ vm.selectedItems().length }}\n <span>{{ '@general:terms.interface.items-selected' | translate | async }}</span>\n </span>\n <ax-button text=\"@general:terms.interface.unselect-all\" class=\"ax-xs\" (onClick)=\"handleUnselectAll()\"></ax-button>\n </div>\n @if (vm.enabledListLayouts().includes('table')) {\n <axp-entity-master-list-data-table\n class=\"axp-entity-list-host\"\n [class.axp-entity-list-host--hidden]=\"vm.activeListLayout() !== 'table'\"\n [vm]=\"vm\"\n (pageChanged)=\"onListPageChanged()\"\n ></axp-entity-master-list-data-table>\n }\n @if (vm.enabledListLayouts().includes('card')) {\n <axp-entity-master-list-card-list\n class=\"axp-entity-list-host\"\n [class.axp-entity-list-host--hidden]=\"vm.activeListLayout() !== 'card'\"\n [vm]=\"vm\"\n (pageChanged)=\"onListPageChanged()\"\n ></axp-entity-master-list-card-list>\n }\n </axp-page-content>\n</axp-page-layout>\n", styles: ["axp-entity-master-list axp-layout-start-side{min-width:20rem!important;border-inline-end-width:1px}axp-entity-master-list axp-layout-header{padding-bottom:.25rem!important}axp-entity-master-list .axp-entity-list-host{display:flex;height:100%;min-height:0px;flex-direction:column}axp-entity-master-list axp-page-content{display:flex;min-height:0px;flex-direction:column}axp-entity-master-list .axp-entity-list-host--hidden{display:none!important}.cdk-drag-preview{border-radius:.375rem;border-width:1px;--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);background:rgba(var(--ax-color-on-surface));padding:.5rem;height:max-content!important}.collapsed-search-box{margin-top:0;height:0px;opacity:0}.view-drawer{width:85vw}@media(min-width:768px){.view-drawer{width:45vw}}@media(min-width:1024px){.view-drawer{width:35vw}}@media(min-width:1536px){.view-drawer{width:20vw}}.view-drawer{--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lightest-surface),var(--tw-bg-opacity, 1));border-inline-start-width:1px;border-inline-start-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));border-top-width:1px;--tw-border-opacity: 1;border-top-color:rgba(var(--ax-sys-color-primary-600),var(--tw-border-opacity, 1))}.view-drawer ax-header{display:flex;align-items:center;border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lighter-surface),var(--tw-bg-opacity, 1));padding:.5rem 1rem}.view-drawer ax-header h2{font-size:1.25rem;line-height:1.75rem;font-weight:700;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lighter-surface),var(--tw-text-opacity, 1))}.view-drawer ax-footer{position:absolute!important;bottom:0!important;width:100%!important;justify-content:flex-start!important;border-top-width:1px!important;--tw-border-opacity: 1 !important;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1))!important;padding:.5rem 1rem!important}\n"] }]
|
|
2352
|
-
}], ctorParameters: () => [{ type: i1$4.AXPlatform }], propDecorators: { dataTable: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXPEntityMasterListDataTableComponent), { isSignal: true }] }] } });
|
|
2372
|
+
}], ctorParameters: () => [{ type: i1$4.AXPlatform }], propDecorators: { dataTable: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXPEntityMasterListDataTableComponent), { isSignal: true }] }], cardList: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXPEntityMasterListCardListComponent), { isSignal: true }] }] } });
|
|
2353
2373
|
|
|
2354
2374
|
var entityMasterListView_component = /*#__PURE__*/Object.freeze({
|
|
2355
2375
|
__proto__: null,
|
|
@@ -2369,6 +2389,433 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
2369
2389
|
], template: "<div class=\"ax-flex ax-items-center ax-justify-start ax-gap-1\">\n <axp-component-slot name=\"root-footer-start\"></axp-component-slot>\n</div>\n<div class=\"ax-flex ax-items-center ax-justify-end ax-gap-1\">\n <axp-component-slot name=\"root-footer-end\"></axp-component-slot>\n</div>\n" }]
|
|
2370
2390
|
}] });
|
|
2371
2391
|
|
|
2392
|
+
//#region ---- Types ----
|
|
2393
|
+
//#endregion
|
|
2394
|
+
//#region ---- Layout ----
|
|
2395
|
+
const DEFAULT_MIN_WIDTH_PX = 88;
|
|
2396
|
+
const DEFAULT_MAX_WIDTH_PX = 192;
|
|
2397
|
+
const DEFAULT_TAB_GAP_PX = 8;
|
|
2398
|
+
/**
|
|
2399
|
+
* Chrome-like tab strip layout: equal flexible widths between min/max; horizontal scroll when needed.
|
|
2400
|
+
*/
|
|
2401
|
+
function computeRouteTabBarLayout(stripWidthPx, tabs, _activeKey, options = {}) {
|
|
2402
|
+
const minWidthPx = options.minWidthPx ?? DEFAULT_MIN_WIDTH_PX;
|
|
2403
|
+
const maxWidthPx = options.maxWidthPx ?? DEFAULT_MAX_WIDTH_PX;
|
|
2404
|
+
const tabGapPx = options.tabGapPx ?? DEFAULT_TAB_GAP_PX;
|
|
2405
|
+
if (stripWidthPx <= 0 || !tabs.length) {
|
|
2406
|
+
return {
|
|
2407
|
+
tabWidthPx: minWidthPx,
|
|
2408
|
+
isScrollable: false,
|
|
2409
|
+
};
|
|
2410
|
+
}
|
|
2411
|
+
const count = tabs.length;
|
|
2412
|
+
const gapsForAll = Math.max(0, count - 1) * tabGapPx;
|
|
2413
|
+
const rawWidth = (stripWidthPx - gapsForAll) / count;
|
|
2414
|
+
const fittedWidth = Math.min(maxWidthPx, Math.max(minWidthPx, rawWidth));
|
|
2415
|
+
const needsScroll = count * fittedWidth + gapsForAll > stripWidthPx;
|
|
2416
|
+
const tabWidthPx = needsScroll ? minWidthPx : Math.floor(fittedWidth);
|
|
2417
|
+
return {
|
|
2418
|
+
tabWidthPx,
|
|
2419
|
+
isScrollable: needsScroll,
|
|
2420
|
+
};
|
|
2421
|
+
}
|
|
2422
|
+
//#endregion
|
|
2423
|
+
|
|
2424
|
+
class AXPRouteTabBarComponent {
|
|
2425
|
+
constructor() {
|
|
2426
|
+
//#region ---- Services & Dependencies ----
|
|
2427
|
+
this.tabNavigation = inject(AXPTabNavigationService);
|
|
2428
|
+
this.tabPreviewService = inject(AXPTabPreviewService);
|
|
2429
|
+
this.translateService = inject(AXTranslationService);
|
|
2430
|
+
this.host = inject((ElementRef));
|
|
2431
|
+
this.tabStrip = viewChild('tabStrip', ...(ngDevMode ? [{ debugName: "tabStrip" }] : /* istanbul ignore next */ []));
|
|
2432
|
+
this.tabsScroll = viewChild('tabsScroll', ...(ngDevMode ? [{ debugName: "tabsScroll" }] : /* istanbul ignore next */ []));
|
|
2433
|
+
this.contextMenu = viewChild('tabContextMenu', ...(ngDevMode ? [{ debugName: "contextMenu" }] : /* istanbul ignore next */ []));
|
|
2434
|
+
this.suppressTabChange = signal(false, ...(ngDevMode ? [{ debugName: "suppressTabChange" }] : /* istanbul ignore next */ []));
|
|
2435
|
+
this.contextTabKey = signal(null, ...(ngDevMode ? [{ debugName: "contextTabKey" }] : /* istanbul ignore next */ []));
|
|
2436
|
+
this.stripWidthPx = signal(0, ...(ngDevMode ? [{ debugName: "stripWidthPx" }] : /* istanbul ignore next */ []));
|
|
2437
|
+
this.isTabDragging = signal(false, ...(ngDevMode ? [{ debugName: "isTabDragging" }] : /* istanbul ignore next */ []));
|
|
2438
|
+
this.inHeader = signal(false, ...(ngDevMode ? [{ debugName: "inHeader" }] : /* istanbul ignore next */ []));
|
|
2439
|
+
//#endregion
|
|
2440
|
+
//#region ---- Layout State ----
|
|
2441
|
+
this.layout = computed(() => computeRouteTabBarLayout(this.stripWidthPx(), this.tabNavigation.tabList(), this.tabNavigation.activeKey()), ...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
|
|
2442
|
+
this.tabWidthPx = computed(() => this.layout().tabWidthPx, ...(ngDevMode ? [{ debugName: "tabWidthPx" }] : /* istanbul ignore next */ []));
|
|
2443
|
+
this.hasHorizontalOverflow = signal(false, ...(ngDevMode ? [{ debugName: "hasHorizontalOverflow" }] : /* istanbul ignore next */ []));
|
|
2444
|
+
this.canScrollForward = signal(false, ...(ngDevMode ? [{ debugName: "canScrollForward" }] : /* istanbul ignore next */ []));
|
|
2445
|
+
this.canScrollBackward = signal(false, ...(ngDevMode ? [{ debugName: "canScrollBackward" }] : /* istanbul ignore next */ []));
|
|
2446
|
+
this.scrollForwardIcon = computed(() => this.#isTabsRtl() ? 'fa-solid fa-chevron-left' : 'fa-solid fa-chevron-right', ...(ngDevMode ? [{ debugName: "scrollForwardIcon" }] : /* istanbul ignore next */ []));
|
|
2447
|
+
this.scrollBackwardIcon = computed(() => this.#isTabsRtl() ? 'fa-solid fa-chevron-right' : 'fa-solid fa-chevron-left', ...(ngDevMode ? [{ debugName: "scrollBackwardIcon" }] : /* istanbul ignore next */ []));
|
|
2448
|
+
this.isMiddlePanning = signal(false, ...(ngDevMode ? [{ debugName: "isMiddlePanning" }] : /* istanbul ignore next */ []));
|
|
2449
|
+
this.middlePanSession = null;
|
|
2450
|
+
this.middlePanMoved = false;
|
|
2451
|
+
//#endregion
|
|
2452
|
+
//#region ---- Layout Helpers ----
|
|
2453
|
+
this.#onTabsScroll = () => {
|
|
2454
|
+
this.#updateScrollState();
|
|
2455
|
+
};
|
|
2456
|
+
this.#onMiddlePanMove = (event) => {
|
|
2457
|
+
const session = this.middlePanSession;
|
|
2458
|
+
if (!session) {
|
|
2459
|
+
return;
|
|
2460
|
+
}
|
|
2461
|
+
const deltaX = event.clientX - session.lastX;
|
|
2462
|
+
session.lastX = event.clientX;
|
|
2463
|
+
if (Math.abs(event.clientX - session.startX) > 2) {
|
|
2464
|
+
session.moved = true;
|
|
2465
|
+
}
|
|
2466
|
+
session.container.scrollBy({ left: -deltaX });
|
|
2467
|
+
this.#updateScrollState();
|
|
2468
|
+
};
|
|
2469
|
+
this.#onMiddlePanUp = (event) => {
|
|
2470
|
+
if (event.button !== 1 && event.buttons !== 0) {
|
|
2471
|
+
return;
|
|
2472
|
+
}
|
|
2473
|
+
this.#endMiddlePan();
|
|
2474
|
+
};
|
|
2475
|
+
//#endregion
|
|
2476
|
+
//#region ---- Tab Strip Sync ----
|
|
2477
|
+
/** Scrolls the active tab into view when the strip overflows horizontally. */
|
|
2478
|
+
this.#scrollActiveTabIntoView = effect(() => {
|
|
2479
|
+
const activeKey = this.tabNavigation.activeKey();
|
|
2480
|
+
const tabs = this.tabNavigation.tabList();
|
|
2481
|
+
this.tabWidthPx();
|
|
2482
|
+
this.stripWidthPx();
|
|
2483
|
+
if (!activeKey || !tabs.length) {
|
|
2484
|
+
return;
|
|
2485
|
+
}
|
|
2486
|
+
untracked(() => {
|
|
2487
|
+
queueMicrotask(() => {
|
|
2488
|
+
this.#updateScrollState();
|
|
2489
|
+
this.#scrollTabIntoView(activeKey);
|
|
2490
|
+
});
|
|
2491
|
+
});
|
|
2492
|
+
}, ...(ngDevMode ? [{ debugName: "#scrollActiveTabIntoView" }] : /* istanbul ignore next */ []));
|
|
2493
|
+
}
|
|
2494
|
+
//#endregion
|
|
2495
|
+
//#region ---- Lifecycle Methods ----
|
|
2496
|
+
ngAfterViewInit() {
|
|
2497
|
+
this.inHeader.set(this.host.nativeElement.classList.contains('axp-route-tab-bar--in-header'));
|
|
2498
|
+
const strip = this.tabStrip()?.nativeElement;
|
|
2499
|
+
if (!strip) {
|
|
2500
|
+
return;
|
|
2501
|
+
}
|
|
2502
|
+
this.stripWidthPx.set(strip.clientWidth);
|
|
2503
|
+
this.stripResizeObserver = new ResizeObserver(() => {
|
|
2504
|
+
this.stripWidthPx.set(strip.clientWidth);
|
|
2505
|
+
this.#updateScrollState();
|
|
2506
|
+
});
|
|
2507
|
+
this.stripResizeObserver.observe(strip);
|
|
2508
|
+
const scrollElement = this.tabsScroll()?.nativeElement;
|
|
2509
|
+
if (scrollElement) {
|
|
2510
|
+
this.tabsScrollElement = scrollElement;
|
|
2511
|
+
scrollElement.addEventListener('scroll', this.#onTabsScroll, { passive: true });
|
|
2512
|
+
this.tabsScrollObserver = new ResizeObserver(() => {
|
|
2513
|
+
this.#updateScrollState();
|
|
2514
|
+
});
|
|
2515
|
+
this.tabsScrollObserver.observe(scrollElement);
|
|
2516
|
+
const tabList = scrollElement.querySelector('.axp-route-tab-bar__tab-list');
|
|
2517
|
+
if (tabList) {
|
|
2518
|
+
this.tabsScrollObserver.observe(tabList);
|
|
2519
|
+
}
|
|
2520
|
+
}
|
|
2521
|
+
this.#updateScrollState();
|
|
2522
|
+
}
|
|
2523
|
+
ngOnDestroy() {
|
|
2524
|
+
this.#endMiddlePan();
|
|
2525
|
+
this.tabsScrollElement?.removeEventListener('scroll', this.#onTabsScroll);
|
|
2526
|
+
this.stripResizeObserver?.disconnect();
|
|
2527
|
+
this.tabsScrollObserver?.disconnect();
|
|
2528
|
+
}
|
|
2529
|
+
//#endregion
|
|
2530
|
+
//#region ---- Layout Helpers ----
|
|
2531
|
+
#onTabsScroll;
|
|
2532
|
+
/** Updates overflow and edge scroll affordances from the live tab strip. */
|
|
2533
|
+
#updateScrollState() {
|
|
2534
|
+
const tabsElement = this.#getTabsScrollElement();
|
|
2535
|
+
if (!tabsElement) {
|
|
2536
|
+
this.hasHorizontalOverflow.set(false);
|
|
2537
|
+
this.canScrollForward.set(false);
|
|
2538
|
+
this.canScrollBackward.set(false);
|
|
2539
|
+
return;
|
|
2540
|
+
}
|
|
2541
|
+
const hasOverflow = tabsElement.scrollWidth - tabsElement.clientWidth > 1;
|
|
2542
|
+
this.hasHorizontalOverflow.set(hasOverflow);
|
|
2543
|
+
if (!hasOverflow) {
|
|
2544
|
+
this.canScrollForward.set(false);
|
|
2545
|
+
this.canScrollBackward.set(false);
|
|
2546
|
+
return;
|
|
2547
|
+
}
|
|
2548
|
+
this.canScrollForward.set(!!this.#findScrollTarget(tabsElement, 'forward'));
|
|
2549
|
+
this.canScrollBackward.set(!!this.#findScrollTarget(tabsElement, 'backward'));
|
|
2550
|
+
}
|
|
2551
|
+
#getTabsScrollElement() {
|
|
2552
|
+
return this.tabsScrollElement ?? this.tabsScroll()?.nativeElement ?? null;
|
|
2553
|
+
}
|
|
2554
|
+
#isTabsRtl() {
|
|
2555
|
+
const tabsElement = this.#getTabsScrollElement();
|
|
2556
|
+
if (!tabsElement) {
|
|
2557
|
+
return false;
|
|
2558
|
+
}
|
|
2559
|
+
return getComputedStyle(tabsElement).direction === 'rtl';
|
|
2560
|
+
}
|
|
2561
|
+
#findScrollTarget(container, direction) {
|
|
2562
|
+
const tabs = Array.from(container.querySelectorAll('[data-tab-key]'));
|
|
2563
|
+
if (!tabs.length) {
|
|
2564
|
+
return null;
|
|
2565
|
+
}
|
|
2566
|
+
const bounds = container.getBoundingClientRect();
|
|
2567
|
+
const epsilon = 2;
|
|
2568
|
+
const isRtl = this.#isTabsRtl();
|
|
2569
|
+
if (direction === 'forward') {
|
|
2570
|
+
if (!isRtl) {
|
|
2571
|
+
return tabs.find((tab) => tab.getBoundingClientRect().right > bounds.right + epsilon) ?? null;
|
|
2572
|
+
}
|
|
2573
|
+
return [...tabs].reverse().find((tab) => tab.getBoundingClientRect().left < bounds.left - epsilon) ?? null;
|
|
2574
|
+
}
|
|
2575
|
+
if (!isRtl) {
|
|
2576
|
+
return [...tabs].reverse().find((tab) => tab.getBoundingClientRect().left < bounds.left - epsilon) ?? null;
|
|
2577
|
+
}
|
|
2578
|
+
return tabs.find((tab) => tab.getBoundingClientRect().right > bounds.right + epsilon) ?? null;
|
|
2579
|
+
}
|
|
2580
|
+
/** Scrolls the strip toward hidden tabs on the requested edge. */
|
|
2581
|
+
scrollTabs(direction) {
|
|
2582
|
+
const container = this.#getTabsScrollElement();
|
|
2583
|
+
if (!container) {
|
|
2584
|
+
return;
|
|
2585
|
+
}
|
|
2586
|
+
const target = this.#findScrollTarget(container, direction);
|
|
2587
|
+
target?.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'center' });
|
|
2588
|
+
}
|
|
2589
|
+
/** Smoothly brings a tab header into view inside the scrollable strip. */
|
|
2590
|
+
#scrollTabIntoView(key) {
|
|
2591
|
+
const scrollElement = this.#getTabsScrollElement();
|
|
2592
|
+
const activeTab = scrollElement?.querySelector(`[data-tab-key="${key}"]`);
|
|
2593
|
+
activeTab?.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'center' });
|
|
2594
|
+
}
|
|
2595
|
+
/** Starts middle-mouse drag scrolling on the tab strip. */
|
|
2596
|
+
onTabsScrollMouseDown(event) {
|
|
2597
|
+
if (event.button !== 1) {
|
|
2598
|
+
return;
|
|
2599
|
+
}
|
|
2600
|
+
if (event.target.closest('.axp-route-tab-bar__close')) {
|
|
2601
|
+
return;
|
|
2602
|
+
}
|
|
2603
|
+
const container = this.#getTabsScrollElement();
|
|
2604
|
+
if (!container) {
|
|
2605
|
+
return;
|
|
2606
|
+
}
|
|
2607
|
+
event.preventDefault();
|
|
2608
|
+
this.middlePanSession = {
|
|
2609
|
+
container,
|
|
2610
|
+
startX: event.clientX,
|
|
2611
|
+
lastX: event.clientX,
|
|
2612
|
+
moved: false,
|
|
2613
|
+
};
|
|
2614
|
+
this.isMiddlePanning.set(true);
|
|
2615
|
+
document.body.style.cursor = 'grabbing';
|
|
2616
|
+
window.addEventListener('mousemove', this.#onMiddlePanMove);
|
|
2617
|
+
window.addEventListener('mouseup', this.#onMiddlePanUp);
|
|
2618
|
+
}
|
|
2619
|
+
#onMiddlePanMove;
|
|
2620
|
+
#onMiddlePanUp;
|
|
2621
|
+
#endMiddlePan() {
|
|
2622
|
+
window.removeEventListener('mousemove', this.#onMiddlePanMove);
|
|
2623
|
+
window.removeEventListener('mouseup', this.#onMiddlePanUp);
|
|
2624
|
+
document.body.style.cursor = '';
|
|
2625
|
+
this.isMiddlePanning.set(false);
|
|
2626
|
+
this.middlePanMoved = this.middlePanSession?.moved ?? false;
|
|
2627
|
+
this.middlePanSession = null;
|
|
2628
|
+
}
|
|
2629
|
+
//#endregion
|
|
2630
|
+
//#region ---- UI Handlers ----
|
|
2631
|
+
/** Whether a tab can be dragged (home tab stays fixed at the start). */
|
|
2632
|
+
isTabDragDisabled(tab) {
|
|
2633
|
+
return tab.key === AXP_HOME_TAB_KEY;
|
|
2634
|
+
}
|
|
2635
|
+
onTabDragStarted() {
|
|
2636
|
+
this.isTabDragging.set(true);
|
|
2637
|
+
}
|
|
2638
|
+
onTabDragEnded() {
|
|
2639
|
+
queueMicrotask(() => {
|
|
2640
|
+
this.isTabDragging.set(false);
|
|
2641
|
+
});
|
|
2642
|
+
}
|
|
2643
|
+
onTabDropped(event) {
|
|
2644
|
+
this.tabNavigation.reorderTabs(event.previousIndex, event.currentIndex);
|
|
2645
|
+
}
|
|
2646
|
+
async onTabActivate(tab, event) {
|
|
2647
|
+
if (this.isTabDragging() || this.suppressTabChange()) {
|
|
2648
|
+
return;
|
|
2649
|
+
}
|
|
2650
|
+
if (event.defaultPrevented) {
|
|
2651
|
+
return;
|
|
2652
|
+
}
|
|
2653
|
+
this.#scrollTabIntoView(tab.key);
|
|
2654
|
+
if (tab.key === this.tabNavigation.activeKey()) {
|
|
2655
|
+
return;
|
|
2656
|
+
}
|
|
2657
|
+
await this.tabNavigation.activateTabKey(tab.key);
|
|
2658
|
+
}
|
|
2659
|
+
/** Resolves tab metadata for context menu actions. */
|
|
2660
|
+
findTab(key) {
|
|
2661
|
+
return this.tabNavigation.tabList().find((item) => item.key === key);
|
|
2662
|
+
}
|
|
2663
|
+
/** Normalizes menu/page icon classes for `ax-icon`. */
|
|
2664
|
+
resolveTabIcon(tab) {
|
|
2665
|
+
const icon = tab.icon?.trim();
|
|
2666
|
+
if (!icon) {
|
|
2667
|
+
return 'fa-light fa-window';
|
|
2668
|
+
}
|
|
2669
|
+
if (icon.includes(' ')) {
|
|
2670
|
+
return icon;
|
|
2671
|
+
}
|
|
2672
|
+
return `fa-light ${icon}`;
|
|
2673
|
+
}
|
|
2674
|
+
/** Closes a tab when the close button is clicked. */
|
|
2675
|
+
async onTabCloseClick(tab, event) {
|
|
2676
|
+
if (!tab.closable || tab.pinned) {
|
|
2677
|
+
return;
|
|
2678
|
+
}
|
|
2679
|
+
event.preventDefault();
|
|
2680
|
+
event.stopPropagation();
|
|
2681
|
+
this.suppressTabChange.set(true);
|
|
2682
|
+
try {
|
|
2683
|
+
await this.tabNavigation.closeTab(tab.key);
|
|
2684
|
+
}
|
|
2685
|
+
finally {
|
|
2686
|
+
this.suppressTabChange.set(false);
|
|
2687
|
+
}
|
|
2688
|
+
}
|
|
2689
|
+
/** Closes a tab on middle mouse button click (browser-style). */
|
|
2690
|
+
async onTabMiddleClick(tab, event) {
|
|
2691
|
+
if (this.middlePanMoved) {
|
|
2692
|
+
this.middlePanMoved = false;
|
|
2693
|
+
event.preventDefault();
|
|
2694
|
+
event.stopPropagation();
|
|
2695
|
+
return;
|
|
2696
|
+
}
|
|
2697
|
+
if (event.button !== 1 || !tab.closable || tab.pinned) {
|
|
2698
|
+
return;
|
|
2699
|
+
}
|
|
2700
|
+
event.preventDefault();
|
|
2701
|
+
event.stopPropagation();
|
|
2702
|
+
this.suppressTabChange.set(true);
|
|
2703
|
+
try {
|
|
2704
|
+
await this.tabNavigation.closeTab(tab.key);
|
|
2705
|
+
}
|
|
2706
|
+
finally {
|
|
2707
|
+
this.suppressTabChange.set(false);
|
|
2708
|
+
}
|
|
2709
|
+
}
|
|
2710
|
+
async openTabContextMenu(event, key) {
|
|
2711
|
+
event.preventDefault();
|
|
2712
|
+
event.stopPropagation();
|
|
2713
|
+
this.contextTabKey.set(key);
|
|
2714
|
+
const tab = this.findTab(key);
|
|
2715
|
+
const isHomeTab = key === AXP_HOME_TAB_KEY;
|
|
2716
|
+
const closableTabs = this.tabNavigation.tabList().filter((item) => item.closable && !item.pinned);
|
|
2717
|
+
const otherClosableCount = closableTabs.filter((item) => item.key !== key).length;
|
|
2718
|
+
const canCloseTab = !!tab?.closable && !tab.pinned;
|
|
2719
|
+
const [pinText, unpinText, closeText, closeOthersText, closeAllText] = await Promise.all([
|
|
2720
|
+
this.translateService.translateAsync('@general:actions.pin-tab.title'),
|
|
2721
|
+
this.translateService.translateAsync('@general:actions.unpin-tab.title'),
|
|
2722
|
+
this.translateService.translateAsync('@general:actions.close-tab.title'),
|
|
2723
|
+
this.translateService.translateAsync('@general:actions.close-other-tabs.title'),
|
|
2724
|
+
this.translateService.translateAsync('@general:actions.close-all-tabs.title'),
|
|
2725
|
+
]);
|
|
2726
|
+
const items = [
|
|
2727
|
+
{
|
|
2728
|
+
name: 'toggle-pin',
|
|
2729
|
+
text: tab?.pinned ? unpinText : pinText,
|
|
2730
|
+
icon: tab?.pinned ? 'fa-light fa-thumbtack-slash' : 'fa-light fa-thumbtack',
|
|
2731
|
+
disabled: isHomeTab,
|
|
2732
|
+
},
|
|
2733
|
+
{
|
|
2734
|
+
name: 'close',
|
|
2735
|
+
text: closeText,
|
|
2736
|
+
icon: 'fa-light fa-xmark',
|
|
2737
|
+
disabled: !canCloseTab,
|
|
2738
|
+
break: true,
|
|
2739
|
+
},
|
|
2740
|
+
{
|
|
2741
|
+
name: 'close-others',
|
|
2742
|
+
text: closeOthersText,
|
|
2743
|
+
icon: 'fa-light fa-clone',
|
|
2744
|
+
disabled: otherClosableCount === 0,
|
|
2745
|
+
break: true,
|
|
2746
|
+
},
|
|
2747
|
+
{
|
|
2748
|
+
name: 'close-all',
|
|
2749
|
+
text: closeAllText,
|
|
2750
|
+
icon: 'fa-light fa-table-columns',
|
|
2751
|
+
disabled: closableTabs.length === 0,
|
|
2752
|
+
},
|
|
2753
|
+
];
|
|
2754
|
+
const menu = this.contextMenu();
|
|
2755
|
+
const targetElement = event.currentTarget;
|
|
2756
|
+
if (!menu) {
|
|
2757
|
+
return;
|
|
2758
|
+
}
|
|
2759
|
+
const openingEvent = {
|
|
2760
|
+
sender: menu,
|
|
2761
|
+
canceled: false,
|
|
2762
|
+
targetElement,
|
|
2763
|
+
items,
|
|
2764
|
+
};
|
|
2765
|
+
menu.showAt({ x: event.clientX, y: event.clientY }, targetElement, openingEvent);
|
|
2766
|
+
}
|
|
2767
|
+
async handleTabContextMenuItemClick(event) {
|
|
2768
|
+
const key = this.contextTabKey();
|
|
2769
|
+
if (!key) {
|
|
2770
|
+
return;
|
|
2771
|
+
}
|
|
2772
|
+
const action = event.item.name;
|
|
2773
|
+
this.suppressTabChange.set(true);
|
|
2774
|
+
try {
|
|
2775
|
+
switch (action) {
|
|
2776
|
+
case 'toggle-pin':
|
|
2777
|
+
this.tabNavigation.toggleTabPinned(key);
|
|
2778
|
+
break;
|
|
2779
|
+
case 'close':
|
|
2780
|
+
await this.tabNavigation.closeTab(key);
|
|
2781
|
+
break;
|
|
2782
|
+
case 'close-others':
|
|
2783
|
+
await this.tabNavigation.closeOtherTabs(key);
|
|
2784
|
+
break;
|
|
2785
|
+
case 'close-all':
|
|
2786
|
+
await this.tabNavigation.closeAllTabs();
|
|
2787
|
+
break;
|
|
2788
|
+
}
|
|
2789
|
+
}
|
|
2790
|
+
finally {
|
|
2791
|
+
this.suppressTabChange.set(false);
|
|
2792
|
+
this.contextTabKey.set(null);
|
|
2793
|
+
}
|
|
2794
|
+
}
|
|
2795
|
+
//#endregion
|
|
2796
|
+
//#region ---- Tab Strip Sync ----
|
|
2797
|
+
/** Scrolls the active tab into view when the strip overflows horizontally. */
|
|
2798
|
+
#scrollActiveTabIntoView;
|
|
2799
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRouteTabBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2800
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPRouteTabBarComponent, isStandalone: true, selector: "axp-route-tab-bar", host: { properties: { "class.axp-route-tab-bar--scrollable": "hasHorizontalOverflow()" }, classAttribute: "axp-route-tab-bar" }, viewQueries: [{ propertyName: "tabStrip", first: true, predicate: ["tabStrip"], descendants: true, isSignal: true }, { propertyName: "tabsScroll", first: true, predicate: ["tabsScroll"], descendants: true, isSignal: true }, { propertyName: "contextMenu", first: true, predicate: ["tabContextMenu"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (tabNavigation.isTabBarVisible()) {\n <div class=\"axp-route-tab-bar__strip\" #tabStrip [style.--axp-tab-width.px]=\"tabWidthPx()\">\n <div class=\"axp-route-tab-bar__viewport\">\n @if (canScrollBackward()) {\n <div class=\"axp-route-tab-bar__scroll-rail axp-route-tab-bar__scroll-rail--start\">\n <button\n type=\"button\"\n class=\"axp-route-tab-bar__scroll-btn\"\n [title]=\"'@general:actions.scroll-tabs-back.title' | translate | async\"\n [attr.aria-label]=\"'@general:actions.scroll-tabs-back.title' | translate | async\"\n (click)=\"scrollTabs('backward')\"\n >\n <ax-icon [icon]=\"scrollBackwardIcon()\"></ax-icon>\n </button>\n </div>\n }\n\n <div\n class=\"axp-route-tab-bar__scroll-wrap\"\n [class.axp-route-tab-bar__scroll-wrap--overflow-start]=\"canScrollBackward()\"\n [class.axp-route-tab-bar__scroll-wrap--overflow-end]=\"canScrollForward()\"\n >\n <div\n #tabsScroll\n class=\"axp-route-tab-bar__scroll\"\n [class.axp-route-tab-bar__scroll--panning]=\"isMiddlePanning()\"\n (mousedown)=\"onTabsScrollMouseDown($event)\"\n >\n <div\n class=\"axp-route-tab-bar__tab-list\"\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListData]=\"tabNavigation.tabList()\"\n (cdkDropListDropped)=\"onTabDropped($event)\"\n >\n @for (tab of tabNavigation.tabList(); track tab.key) {\n @let tabTitle = (tab.title | translate | async) || '';\n <div\n class=\"axp-route-tab-bar__tab\"\n [class.axp-route-tab-bar__tab--active]=\"tabNavigation.activeKey() === tab.key\"\n [class.axp-route-tab-bar__tab--dragging]=\"isTabDragging()\"\n [attr.data-tab-key]=\"tab.key\"\n role=\"tab\"\n [attr.aria-selected]=\"tabNavigation.activeKey() === tab.key\"\n cdkDrag\n cdkDragLockAxis=\"x\"\n [cdkDragData]=\"tab\"\n [cdkDragDisabled]=\"isTabDragDisabled(tab)\"\n (cdkDragStarted)=\"onTabDragStarted()\"\n (cdkDragEnded)=\"onTabDragEnded()\"\n (click)=\"onTabActivate(tab, $event)\"\n >\n <div\n class=\"axp-route-tab-bar__tab-inner\"\n cdkDragHandle\n [title]=\"tabTitle\"\n (contextmenu)=\"openTabContextMenu($event, tab.key)\"\n (auxclick)=\"onTabMiddleClick(tab, $event)\"\n >\n @if (tabPreviewService.previews()[tab.key]?.isDirty) {\n <span\n class=\"axp-route-tab-bar__dirty-badge\"\n [attr.aria-label]=\"'@general:terms.interface.save-status.not-saved.title' | translate | async\"\n ></span>\n }\n\n <span class=\"axp-route-tab-bar__tab-icon\" aria-hidden=\"true\">\n <ax-icon [icon]=\"resolveTabIcon(tab)\"></ax-icon>\n </span>\n\n <span class=\"axp-route-tab-bar__tab-title-fade\" axpRouteTabTitleOverflow>\n <span class=\"axp-route-tab-bar__tab-title\">{{ tabTitle }}</span>\n </span>\n\n @if (tab.pinned) {\n <span class=\"axp-route-tab-bar__pin\" aria-hidden=\"true\">\n <ax-icon icon=\"fa-solid fa-thumbtack\"></ax-icon>\n </span>\n } @else if (tab.closable) {\n <button\n type=\"button\"\n class=\"axp-route-tab-bar__close\"\n [title]=\"'@general:actions.close-tab.title' | translate | async\"\n (click)=\"onTabCloseClick(tab, $event)\"\n >\n <ax-icon icon=\"far fa-xmark\"></ax-icon>\n </button>\n }\n </div>\n\n <ng-template cdkDragPreview>\n <div\n class=\"axp-route-tab-bar__drag-preview\"\n [class.axp-route-tab-bar__drag-preview--in-header]=\"inHeader()\"\n [class.axp-route-tab-bar__drag-preview--active]=\"tabNavigation.activeKey() === tab.key\"\n [style.width.px]=\"tabWidthPx()\"\n >\n <div class=\"axp-route-tab-bar__drag-preview-inner\">\n <span class=\"axp-route-tab-bar__tab-icon\" aria-hidden=\"true\">\n <ax-icon [icon]=\"resolveTabIcon(tab)\"></ax-icon>\n </span>\n <span class=\"axp-route-tab-bar__tab-title\">{{ tabTitle }}</span>\n </div>\n </div>\n </ng-template>\n </div>\n }\n </div>\n </div>\n </div>\n\n @if (canScrollForward()) {\n <div class=\"axp-route-tab-bar__scroll-rail axp-route-tab-bar__scroll-rail--end\">\n <button\n type=\"button\"\n class=\"axp-route-tab-bar__scroll-btn\"\n [title]=\"'@general:actions.scroll-tabs-forward.title' | translate | async\"\n [attr.aria-label]=\"'@general:actions.scroll-tabs-forward.title' | translate | async\"\n (click)=\"scrollTabs('forward')\"\n >\n <ax-icon [icon]=\"scrollForwardIcon()\"></ax-icon>\n </button>\n </div>\n }\n </div>\n </div>\n}\n\n<ax-context-menu\n #tabContextMenu\n [closeOn]=\"'click'\"\n [orientation]=\"'vertical'\"\n (onItemClick)=\"handleTabContextMenuItemClick($event)\"\n></ax-context-menu>\n", styles: ["axp-route-tab-bar{display:block;min-width:0;--axp-route-tab-bar-fade: var(--ax-sys-color-lightest-surface);--axp-route-tab-bar-chevron-size: 2rem}axp-route-tab-bar .axp-route-tab-bar__strip{display:flex;align-items:stretch;gap:.5rem;min-width:0}axp-route-tab-bar .axp-route-tab-bar__viewport{display:flex;flex-direction:row;align-items:center;flex:1 1 auto;min-width:0;height:100%;gap:.25rem}axp-route-tab-bar .axp-route-tab-bar__viewport ax-tabs,axp-route-tab-bar .axp-route-tab-bar__viewport ax-tabs .ax-tabs-scroll-area,axp-route-tab-bar .axp-route-tab-bar__viewport .axp-route-tab-bar__tab-list{overflow:visible!important;scrollbar-width:none!important;-ms-overflow-style:none!important}axp-route-tab-bar .axp-route-tab-bar__viewport ax-tabs::-webkit-scrollbar,axp-route-tab-bar .axp-route-tab-bar__viewport ax-tabs .ax-tabs-scroll-area::-webkit-scrollbar,axp-route-tab-bar .axp-route-tab-bar__viewport .axp-route-tab-bar__tab-list::-webkit-scrollbar{display:none!important;width:0!important;height:0!important}axp-route-tab-bar .axp-route-tab-bar__scroll-rail{display:flex;flex:0 0 var(--axp-route-tab-bar-chevron-size);align-items:center;justify-content:center;align-self:center;width:var(--axp-route-tab-bar-chevron-size);min-width:var(--axp-route-tab-bar-chevron-size);height:var(--axp-route-tab-bar-tab-row-height, 100%)}axp-route-tab-bar .axp-route-tab-bar__scroll-wrap{position:relative;flex:1 1 auto;min-width:0;height:100%;overflow:hidden}axp-route-tab-bar .axp-route-tab-bar__scroll-wrap--overflow-start:before,axp-route-tab-bar .axp-route-tab-bar__scroll-wrap--overflow-end:after{content:\"\";position:absolute;inset-block:0;width:1.5rem;z-index:1;pointer-events:none}axp-route-tab-bar .axp-route-tab-bar__scroll-wrap--overflow-start:before{inset-inline-start:0;background:linear-gradient(to right,rgb(var(--axp-route-tab-bar-fade)) 0%,rgb(var(--axp-route-tab-bar-fade)/.72) 35%,transparent 100%)}axp-route-tab-bar .axp-route-tab-bar__scroll-wrap--overflow-end:after{inset-inline-end:0;background:linear-gradient(to left,rgb(var(--axp-route-tab-bar-fade)) 0%,rgb(var(--axp-route-tab-bar-fade)/.72) 35%,transparent 100%)}[dir=rtl] axp-route-tab-bar .axp-route-tab-bar__scroll-wrap--overflow-start:before{background:linear-gradient(to left,rgb(var(--axp-route-tab-bar-fade)) 0%,rgb(var(--axp-route-tab-bar-fade)/.72) 35%,transparent 100%)}[dir=rtl] axp-route-tab-bar .axp-route-tab-bar__scroll-wrap--overflow-end:after{background:linear-gradient(to right,rgb(var(--axp-route-tab-bar-fade)) 0%,rgb(var(--axp-route-tab-bar-fade)/.72) 35%,transparent 100%)}axp-route-tab-bar .axp-route-tab-bar__scroll{width:100%;min-width:0;height:100%;overflow-x:auto;overflow-y:hidden;scroll-behavior:smooth;cursor:default;scrollbar-width:none!important;-ms-overflow-style:none!important}axp-route-tab-bar .axp-route-tab-bar__scroll::-webkit-scrollbar{display:none!important;width:0!important;height:0!important;background:transparent!important}axp-route-tab-bar .axp-route-tab-bar__scroll.axp-route-tab-bar__scroll--panning,axp-route-tab-bar .axp-route-tab-bar__scroll.axp-route-tab-bar__scroll--panning *{cursor:grabbing!important;-webkit-user-select:none;user-select:none}axp-route-tab-bar .axp-route-tab-bar__tabs-host{height:100%;min-width:0;width:max-content}axp-route-tab-bar .axp-route-tab-bar__tab-list{display:flex;flex:none;flex-wrap:nowrap;align-items:stretch;width:max-content;min-width:max-content;height:100%;gap:.5rem}axp-route-tab-bar .axp-route-tab-bar__tab{cursor:pointer;flex:0 0 var(--axp-tab-width, 5.5rem);width:var(--axp-tab-width, 5.5rem);min-width:var(--axp-tab-width, 5.5rem);max-width:var(--axp-tab-width, 5.5rem);height:100%;transform:translateY(0);transition:background-color .15s ease,color .15s ease,border-color .15s ease,transform .22s cubic-bezier(.4,0,.2,1)}axp-route-tab-bar .axp-route-tab-bar__tab.cdk-drag-disabled{cursor:pointer}axp-route-tab-bar .axp-route-tab-bar__tab.cdk-drag-dragging,axp-route-tab-bar .axp-route-tab-bar__tab.cdk-drag-dragging .axp-route-tab-bar__tab-inner{cursor:grabbing}axp-route-tab-bar .axp-route-tab-bar__tab.cdk-drag-placeholder{opacity:.35}axp-route-tab-bar .axp-route-tab-bar__tab.cdk-drag-animating{transition:transform .22s cubic-bezier(.4,0,.2,1)}axp-route-tab-bar .axp-route-tab-bar__tab-list.cdk-drop-list-dragging .axp-route-tab-bar__tab:not(.cdk-drag-placeholder){transition:transform .22s cubic-bezier(.4,0,.2,1)}axp-route-tab-bar .axp-route-tab-bar__scroll-btn{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;margin:0;padding:0;border:none;background:transparent;color:inherit;cursor:pointer;opacity:.88;border-radius:var(--ax-sys-border-radius);transition:opacity .15s ease}axp-route-tab-bar .axp-route-tab-bar__scroll-btn ax-icon{font-size:.75rem}axp-route-tab-bar .axp-route-tab-bar__scroll-btn:hover{opacity:1}axp-route-tab-bar .axp-route-tab-bar__scroll-btn:focus-visible{opacity:1;outline:2px solid rgb(var(--ax-sys-color-primary-500));outline-offset:1px}axp-route-tab-bar .axp-route-tab-bar__tab-inner{position:relative;display:flex;justify-content:space-between;width:100%;align-items:center;gap:.375rem;min-width:0;max-width:100%;height:100%;padding-inline:.625rem;cursor:pointer}axp-route-tab-bar .axp-route-tab-bar__tab-inner.cdk-drag-handle{cursor:pointer}axp-route-tab-bar .axp-route-tab-bar__dirty-badge{position:absolute;top:.25rem;inset-inline-end:.25rem;width:.4375rem;height:.4375rem;border-radius:50%;background:rgb(var(--ax-sys-color-warning-500));border:1px solid rgb(var(--ax-sys-color-lightest-surface));pointer-events:none;z-index:1}axp-route-tab-bar .axp-route-tab-bar__tab-icon{display:inline-flex;flex-shrink:0}axp-route-tab-bar .axp-route-tab-bar__tab-icon ax-icon{font-size:.875rem}axp-route-tab-bar .axp-route-tab-bar__tab-title-fade{position:relative;flex:1 1 auto;min-width:0;max-width:100%;overflow:hidden}axp-route-tab-bar .axp-route-tab-bar__tab-title{display:block;width:100%;white-space:nowrap;overflow:hidden;font-size:.875rem;line-height:1.25rem}axp-route-tab-bar .axp-route-tab-bar__tab-title-fade--overflowing .axp-route-tab-bar__tab-title{-webkit-mask-image:linear-gradient(to right,#000 0,#000 calc(100% - 1.25rem),transparent 100%);mask-image:linear-gradient(to right,#000 0,#000 calc(100% - 1.25rem),transparent 100%)}[dir=rtl] axp-route-tab-bar .axp-route-tab-bar__tab-title-fade--overflowing .axp-route-tab-bar__tab-title{-webkit-mask-image:linear-gradient(to left,#000 0,#000 calc(100% - 1.25rem),transparent 100%);mask-image:linear-gradient(to left,#000 0,#000 calc(100% - 1.25rem),transparent 100%)}axp-route-tab-bar .axp-route-tab-bar__pin{display:inline-flex;flex-shrink:0;color:inherit}axp-route-tab-bar .axp-route-tab-bar__pin ax-icon{font-size:.6875rem}axp-route-tab-bar .axp-route-tab-bar__close{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:0;height:1.25rem;margin:0;padding:0;overflow:hidden;border:none;background:transparent;color:inherit;border-radius:var(--ax-sys-border-radius);opacity:0;pointer-events:none;cursor:pointer;transition:opacity .15s ease,width .15s ease,background-color .15s ease}axp-route-tab-bar .axp-route-tab-bar__close ax-icon{font-size:.75rem}axp-route-tab-bar .axp-route-tab-bar__tab:hover .axp-route-tab-bar__close,axp-route-tab-bar .axp-route-tab-bar__close:focus-visible{width:1.25rem;opacity:.72;pointer-events:auto}axp-route-tab-bar .axp-route-tab-bar__close:hover{background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}axp-route-tab-bar:not(.axp-route-tab-bar--in-header){border-bottom:1px solid rgb(var(--ax-sys-color-border-light-surface))}axp-route-tab-bar:not(.axp-route-tab-bar--in-header) .axp-route-tab-bar__strip{background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface));padding-inline:.5rem}axp-route-tab-bar:not(.axp-route-tab-bar--in-header) .axp-route-tab-bar__tab{background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}axp-route-tab-bar:not(.axp-route-tab-bar--in-header) .axp-route-tab-bar__tab:hover:not(.axp-route-tab-bar__tab--active){background-color:rgb(var(--ax-sys-color-light-surface));color:rgb(var(--ax-sys-color-on-light-surface));border-color:rgb(var(--ax-sys-color-border-light-surface))}axp-route-tab-bar:not(.axp-route-tab-bar--in-header) .axp-route-tab-bar__tab.axp-route-tab-bar__tab--active{background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}axp-route-tab-bar.axp-route-tab-bar--in-header{align-self:stretch;height:100%;--axp-route-tab-bar-fade: var(--ax-sys-color-primary-surface);--axp-route-tab-bar-tab-row-height: 2.25rem}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__strip{display:flex;align-self:stretch;height:100%;align-items:stretch;background:transparent;color:rgb(var(--ax-sys-color-on-primary-surface))}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__viewport{align-items:flex-end}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__scroll-rail{align-self:flex-end;margin-bottom:0}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__scroll-wrap--overflow-start:before,axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__scroll-wrap--overflow-end:after{inset-block-end:0;inset-block-start:auto;height:var(--axp-route-tab-bar-tab-row-height)}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__scroll{cursor:default}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__tab-list{align-self:stretch;align-items:flex-end;min-height:0;padding-top:1rem}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__tab{align-self:center;padding:0;border-top-left-radius:.5rem;border-top-right-radius:.5rem;border-bottom-right-radius:0;border-bottom-left-radius:0;background-color:rgb(var(--ax-sys-color-primary-dark-surface));color:rgb(var(--ax-sys-color-on-primary-dark-surface));border-color:rgb(var(--ax-sys-color-border-primary-dark-surface))}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__tab ax-icon{color:inherit}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__tab:hover:not(.axp-route-tab-bar__tab--active){background-color:rgb(var(--ax-sys-color-primary-light-surface));color:rgb(var(--ax-sys-color-on-primary-light-surface));border-color:rgb(var(--ax-sys-color-border-primary-light-surface))}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__tab.axp-route-tab-bar__tab--active{background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__tab.axp-route-tab-bar__tab--active:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-primary-darkest-surface));color:rgb(var(--ax-sys-color-on-primary-darkest-surface));border-color:rgb(var(--ax-sys-color-border-primary-darkest-surface))}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__tab .axp-route-tab-bar__close:hover{background-color:rgb(var(--ax-sys-color-primary-light-surface));color:rgb(var(--ax-sys-color-on-primary-light-surface));border-color:rgb(var(--ax-sys-color-border-primary-light-surface))}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__tab.axp-route-tab-bar__tab--active .axp-route-tab-bar__close:hover{background-color:rgb(var(--ax-sys-color-primary-light-surface));color:rgb(var(--ax-sys-color-on-primary-light-surface));border-color:rgb(var(--ax-sys-color-border-primary-light-surface))}.cdk-drag-preview.axp-route-tab-bar__drag-preview{display:flex;align-items:center;box-sizing:border-box;height:var(--axp-route-tab-bar-tab-row-height, 2.25rem);opacity:.96;cursor:grabbing;box-shadow:0 4px 12px rgb(var(--ax-sys-color-dark)/.16),0 1px 3px rgb(var(--ax-sys-color-dark)/.12)}.cdk-drag-preview.axp-route-tab-bar__drag-preview .axp-route-tab-bar__drag-preview-inner{display:flex;align-items:center;gap:.5rem;width:100%;min-width:0;height:100%;padding-inline:.625rem}.cdk-drag-preview.axp-route-tab-bar__drag-preview .axp-route-tab-bar__tab-icon{display:inline-flex;flex-shrink:0}.cdk-drag-preview.axp-route-tab-bar__drag-preview .axp-route-tab-bar__tab-icon ax-icon{font-size:.875rem}.cdk-drag-preview.axp-route-tab-bar__drag-preview .axp-route-tab-bar__tab-title{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem}.cdk-drag-preview.axp-route-tab-bar__drag-preview.axp-route-tab-bar__drag-preview--in-header{border-top-left-radius:.5rem;border-top-right-radius:.5rem;border-bottom-right-radius:0;border-bottom-left-radius:0;background-color:rgb(var(--ax-sys-color-primary-dark-surface));color:rgb(var(--ax-sys-color-on-primary-dark-surface));border-color:rgb(var(--ax-sys-color-border-primary-dark-surface))}.cdk-drag-preview.axp-route-tab-bar__drag-preview.axp-route-tab-bar__drag-preview--in-header.axp-route-tab-bar__drag-preview--active{background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}.cdk-drag-preview.axp-route-tab-bar__drag-preview.axp-route-tab-bar__drag-preview--in-header.axp-route-tab-bar__drag-preview--active:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-primary-darkest-surface));color:rgb(var(--ax-sys-color-on-primary-darkest-surface));border-color:rgb(var(--ax-sys-color-border-primary-darkest-surface))}.cdk-drag-preview.axp-route-tab-bar__drag-preview:not(.axp-route-tab-bar__drag-preview--in-header){border-radius:.375rem;background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}.cdk-drag-preview.axp-route-tab-bar__drag-preview:not(.axp-route-tab-bar__drag-preview--in-header).axp-route-tab-bar__drag-preview--active{background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}\n"], dependencies: [{ kind: "directive", type: 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: 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: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXContextMenuComponent, selector: "ax-context-menu", inputs: ["orientation", "openOn", "closeOn", "closeOnRouteChange", "items", "target"], outputs: ["onItemClick", "onOpening", "onClose"] }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2801
|
+
}
|
|
2802
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRouteTabBarComponent, decorators: [{
|
|
2803
|
+
type: Component,
|
|
2804
|
+
args: [{ selector: 'axp-route-tab-bar', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
2805
|
+
class: 'axp-route-tab-bar',
|
|
2806
|
+
'[class.axp-route-tab-bar--scrollable]': 'hasHorizontalOverflow()',
|
|
2807
|
+
}, imports: [
|
|
2808
|
+
CdkDropList,
|
|
2809
|
+
CdkDrag,
|
|
2810
|
+
CdkDragHandle,
|
|
2811
|
+
CdkDragPreview,
|
|
2812
|
+
AXDecoratorModule,
|
|
2813
|
+
AXTranslationModule,
|
|
2814
|
+
AXContextMenuComponent,
|
|
2815
|
+
AsyncPipe,
|
|
2816
|
+
], template: "@if (tabNavigation.isTabBarVisible()) {\n <div class=\"axp-route-tab-bar__strip\" #tabStrip [style.--axp-tab-width.px]=\"tabWidthPx()\">\n <div class=\"axp-route-tab-bar__viewport\">\n @if (canScrollBackward()) {\n <div class=\"axp-route-tab-bar__scroll-rail axp-route-tab-bar__scroll-rail--start\">\n <button\n type=\"button\"\n class=\"axp-route-tab-bar__scroll-btn\"\n [title]=\"'@general:actions.scroll-tabs-back.title' | translate | async\"\n [attr.aria-label]=\"'@general:actions.scroll-tabs-back.title' | translate | async\"\n (click)=\"scrollTabs('backward')\"\n >\n <ax-icon [icon]=\"scrollBackwardIcon()\"></ax-icon>\n </button>\n </div>\n }\n\n <div\n class=\"axp-route-tab-bar__scroll-wrap\"\n [class.axp-route-tab-bar__scroll-wrap--overflow-start]=\"canScrollBackward()\"\n [class.axp-route-tab-bar__scroll-wrap--overflow-end]=\"canScrollForward()\"\n >\n <div\n #tabsScroll\n class=\"axp-route-tab-bar__scroll\"\n [class.axp-route-tab-bar__scroll--panning]=\"isMiddlePanning()\"\n (mousedown)=\"onTabsScrollMouseDown($event)\"\n >\n <div\n class=\"axp-route-tab-bar__tab-list\"\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListData]=\"tabNavigation.tabList()\"\n (cdkDropListDropped)=\"onTabDropped($event)\"\n >\n @for (tab of tabNavigation.tabList(); track tab.key) {\n @let tabTitle = (tab.title | translate | async) || '';\n <div\n class=\"axp-route-tab-bar__tab\"\n [class.axp-route-tab-bar__tab--active]=\"tabNavigation.activeKey() === tab.key\"\n [class.axp-route-tab-bar__tab--dragging]=\"isTabDragging()\"\n [attr.data-tab-key]=\"tab.key\"\n role=\"tab\"\n [attr.aria-selected]=\"tabNavigation.activeKey() === tab.key\"\n cdkDrag\n cdkDragLockAxis=\"x\"\n [cdkDragData]=\"tab\"\n [cdkDragDisabled]=\"isTabDragDisabled(tab)\"\n (cdkDragStarted)=\"onTabDragStarted()\"\n (cdkDragEnded)=\"onTabDragEnded()\"\n (click)=\"onTabActivate(tab, $event)\"\n >\n <div\n class=\"axp-route-tab-bar__tab-inner\"\n cdkDragHandle\n [title]=\"tabTitle\"\n (contextmenu)=\"openTabContextMenu($event, tab.key)\"\n (auxclick)=\"onTabMiddleClick(tab, $event)\"\n >\n @if (tabPreviewService.previews()[tab.key]?.isDirty) {\n <span\n class=\"axp-route-tab-bar__dirty-badge\"\n [attr.aria-label]=\"'@general:terms.interface.save-status.not-saved.title' | translate | async\"\n ></span>\n }\n\n <span class=\"axp-route-tab-bar__tab-icon\" aria-hidden=\"true\">\n <ax-icon [icon]=\"resolveTabIcon(tab)\"></ax-icon>\n </span>\n\n <span class=\"axp-route-tab-bar__tab-title-fade\" axpRouteTabTitleOverflow>\n <span class=\"axp-route-tab-bar__tab-title\">{{ tabTitle }}</span>\n </span>\n\n @if (tab.pinned) {\n <span class=\"axp-route-tab-bar__pin\" aria-hidden=\"true\">\n <ax-icon icon=\"fa-solid fa-thumbtack\"></ax-icon>\n </span>\n } @else if (tab.closable) {\n <button\n type=\"button\"\n class=\"axp-route-tab-bar__close\"\n [title]=\"'@general:actions.close-tab.title' | translate | async\"\n (click)=\"onTabCloseClick(tab, $event)\"\n >\n <ax-icon icon=\"far fa-xmark\"></ax-icon>\n </button>\n }\n </div>\n\n <ng-template cdkDragPreview>\n <div\n class=\"axp-route-tab-bar__drag-preview\"\n [class.axp-route-tab-bar__drag-preview--in-header]=\"inHeader()\"\n [class.axp-route-tab-bar__drag-preview--active]=\"tabNavigation.activeKey() === tab.key\"\n [style.width.px]=\"tabWidthPx()\"\n >\n <div class=\"axp-route-tab-bar__drag-preview-inner\">\n <span class=\"axp-route-tab-bar__tab-icon\" aria-hidden=\"true\">\n <ax-icon [icon]=\"resolveTabIcon(tab)\"></ax-icon>\n </span>\n <span class=\"axp-route-tab-bar__tab-title\">{{ tabTitle }}</span>\n </div>\n </div>\n </ng-template>\n </div>\n }\n </div>\n </div>\n </div>\n\n @if (canScrollForward()) {\n <div class=\"axp-route-tab-bar__scroll-rail axp-route-tab-bar__scroll-rail--end\">\n <button\n type=\"button\"\n class=\"axp-route-tab-bar__scroll-btn\"\n [title]=\"'@general:actions.scroll-tabs-forward.title' | translate | async\"\n [attr.aria-label]=\"'@general:actions.scroll-tabs-forward.title' | translate | async\"\n (click)=\"scrollTabs('forward')\"\n >\n <ax-icon [icon]=\"scrollForwardIcon()\"></ax-icon>\n </button>\n </div>\n }\n </div>\n </div>\n}\n\n<ax-context-menu\n #tabContextMenu\n [closeOn]=\"'click'\"\n [orientation]=\"'vertical'\"\n (onItemClick)=\"handleTabContextMenuItemClick($event)\"\n></ax-context-menu>\n", styles: ["axp-route-tab-bar{display:block;min-width:0;--axp-route-tab-bar-fade: var(--ax-sys-color-lightest-surface);--axp-route-tab-bar-chevron-size: 2rem}axp-route-tab-bar .axp-route-tab-bar__strip{display:flex;align-items:stretch;gap:.5rem;min-width:0}axp-route-tab-bar .axp-route-tab-bar__viewport{display:flex;flex-direction:row;align-items:center;flex:1 1 auto;min-width:0;height:100%;gap:.25rem}axp-route-tab-bar .axp-route-tab-bar__viewport ax-tabs,axp-route-tab-bar .axp-route-tab-bar__viewport ax-tabs .ax-tabs-scroll-area,axp-route-tab-bar .axp-route-tab-bar__viewport .axp-route-tab-bar__tab-list{overflow:visible!important;scrollbar-width:none!important;-ms-overflow-style:none!important}axp-route-tab-bar .axp-route-tab-bar__viewport ax-tabs::-webkit-scrollbar,axp-route-tab-bar .axp-route-tab-bar__viewport ax-tabs .ax-tabs-scroll-area::-webkit-scrollbar,axp-route-tab-bar .axp-route-tab-bar__viewport .axp-route-tab-bar__tab-list::-webkit-scrollbar{display:none!important;width:0!important;height:0!important}axp-route-tab-bar .axp-route-tab-bar__scroll-rail{display:flex;flex:0 0 var(--axp-route-tab-bar-chevron-size);align-items:center;justify-content:center;align-self:center;width:var(--axp-route-tab-bar-chevron-size);min-width:var(--axp-route-tab-bar-chevron-size);height:var(--axp-route-tab-bar-tab-row-height, 100%)}axp-route-tab-bar .axp-route-tab-bar__scroll-wrap{position:relative;flex:1 1 auto;min-width:0;height:100%;overflow:hidden}axp-route-tab-bar .axp-route-tab-bar__scroll-wrap--overflow-start:before,axp-route-tab-bar .axp-route-tab-bar__scroll-wrap--overflow-end:after{content:\"\";position:absolute;inset-block:0;width:1.5rem;z-index:1;pointer-events:none}axp-route-tab-bar .axp-route-tab-bar__scroll-wrap--overflow-start:before{inset-inline-start:0;background:linear-gradient(to right,rgb(var(--axp-route-tab-bar-fade)) 0%,rgb(var(--axp-route-tab-bar-fade)/.72) 35%,transparent 100%)}axp-route-tab-bar .axp-route-tab-bar__scroll-wrap--overflow-end:after{inset-inline-end:0;background:linear-gradient(to left,rgb(var(--axp-route-tab-bar-fade)) 0%,rgb(var(--axp-route-tab-bar-fade)/.72) 35%,transparent 100%)}[dir=rtl] axp-route-tab-bar .axp-route-tab-bar__scroll-wrap--overflow-start:before{background:linear-gradient(to left,rgb(var(--axp-route-tab-bar-fade)) 0%,rgb(var(--axp-route-tab-bar-fade)/.72) 35%,transparent 100%)}[dir=rtl] axp-route-tab-bar .axp-route-tab-bar__scroll-wrap--overflow-end:after{background:linear-gradient(to right,rgb(var(--axp-route-tab-bar-fade)) 0%,rgb(var(--axp-route-tab-bar-fade)/.72) 35%,transparent 100%)}axp-route-tab-bar .axp-route-tab-bar__scroll{width:100%;min-width:0;height:100%;overflow-x:auto;overflow-y:hidden;scroll-behavior:smooth;cursor:default;scrollbar-width:none!important;-ms-overflow-style:none!important}axp-route-tab-bar .axp-route-tab-bar__scroll::-webkit-scrollbar{display:none!important;width:0!important;height:0!important;background:transparent!important}axp-route-tab-bar .axp-route-tab-bar__scroll.axp-route-tab-bar__scroll--panning,axp-route-tab-bar .axp-route-tab-bar__scroll.axp-route-tab-bar__scroll--panning *{cursor:grabbing!important;-webkit-user-select:none;user-select:none}axp-route-tab-bar .axp-route-tab-bar__tabs-host{height:100%;min-width:0;width:max-content}axp-route-tab-bar .axp-route-tab-bar__tab-list{display:flex;flex:none;flex-wrap:nowrap;align-items:stretch;width:max-content;min-width:max-content;height:100%;gap:.5rem}axp-route-tab-bar .axp-route-tab-bar__tab{cursor:pointer;flex:0 0 var(--axp-tab-width, 5.5rem);width:var(--axp-tab-width, 5.5rem);min-width:var(--axp-tab-width, 5.5rem);max-width:var(--axp-tab-width, 5.5rem);height:100%;transform:translateY(0);transition:background-color .15s ease,color .15s ease,border-color .15s ease,transform .22s cubic-bezier(.4,0,.2,1)}axp-route-tab-bar .axp-route-tab-bar__tab.cdk-drag-disabled{cursor:pointer}axp-route-tab-bar .axp-route-tab-bar__tab.cdk-drag-dragging,axp-route-tab-bar .axp-route-tab-bar__tab.cdk-drag-dragging .axp-route-tab-bar__tab-inner{cursor:grabbing}axp-route-tab-bar .axp-route-tab-bar__tab.cdk-drag-placeholder{opacity:.35}axp-route-tab-bar .axp-route-tab-bar__tab.cdk-drag-animating{transition:transform .22s cubic-bezier(.4,0,.2,1)}axp-route-tab-bar .axp-route-tab-bar__tab-list.cdk-drop-list-dragging .axp-route-tab-bar__tab:not(.cdk-drag-placeholder){transition:transform .22s cubic-bezier(.4,0,.2,1)}axp-route-tab-bar .axp-route-tab-bar__scroll-btn{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;margin:0;padding:0;border:none;background:transparent;color:inherit;cursor:pointer;opacity:.88;border-radius:var(--ax-sys-border-radius);transition:opacity .15s ease}axp-route-tab-bar .axp-route-tab-bar__scroll-btn ax-icon{font-size:.75rem}axp-route-tab-bar .axp-route-tab-bar__scroll-btn:hover{opacity:1}axp-route-tab-bar .axp-route-tab-bar__scroll-btn:focus-visible{opacity:1;outline:2px solid rgb(var(--ax-sys-color-primary-500));outline-offset:1px}axp-route-tab-bar .axp-route-tab-bar__tab-inner{position:relative;display:flex;justify-content:space-between;width:100%;align-items:center;gap:.375rem;min-width:0;max-width:100%;height:100%;padding-inline:.625rem;cursor:pointer}axp-route-tab-bar .axp-route-tab-bar__tab-inner.cdk-drag-handle{cursor:pointer}axp-route-tab-bar .axp-route-tab-bar__dirty-badge{position:absolute;top:.25rem;inset-inline-end:.25rem;width:.4375rem;height:.4375rem;border-radius:50%;background:rgb(var(--ax-sys-color-warning-500));border:1px solid rgb(var(--ax-sys-color-lightest-surface));pointer-events:none;z-index:1}axp-route-tab-bar .axp-route-tab-bar__tab-icon{display:inline-flex;flex-shrink:0}axp-route-tab-bar .axp-route-tab-bar__tab-icon ax-icon{font-size:.875rem}axp-route-tab-bar .axp-route-tab-bar__tab-title-fade{position:relative;flex:1 1 auto;min-width:0;max-width:100%;overflow:hidden}axp-route-tab-bar .axp-route-tab-bar__tab-title{display:block;width:100%;white-space:nowrap;overflow:hidden;font-size:.875rem;line-height:1.25rem}axp-route-tab-bar .axp-route-tab-bar__tab-title-fade--overflowing .axp-route-tab-bar__tab-title{-webkit-mask-image:linear-gradient(to right,#000 0,#000 calc(100% - 1.25rem),transparent 100%);mask-image:linear-gradient(to right,#000 0,#000 calc(100% - 1.25rem),transparent 100%)}[dir=rtl] axp-route-tab-bar .axp-route-tab-bar__tab-title-fade--overflowing .axp-route-tab-bar__tab-title{-webkit-mask-image:linear-gradient(to left,#000 0,#000 calc(100% - 1.25rem),transparent 100%);mask-image:linear-gradient(to left,#000 0,#000 calc(100% - 1.25rem),transparent 100%)}axp-route-tab-bar .axp-route-tab-bar__pin{display:inline-flex;flex-shrink:0;color:inherit}axp-route-tab-bar .axp-route-tab-bar__pin ax-icon{font-size:.6875rem}axp-route-tab-bar .axp-route-tab-bar__close{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:0;height:1.25rem;margin:0;padding:0;overflow:hidden;border:none;background:transparent;color:inherit;border-radius:var(--ax-sys-border-radius);opacity:0;pointer-events:none;cursor:pointer;transition:opacity .15s ease,width .15s ease,background-color .15s ease}axp-route-tab-bar .axp-route-tab-bar__close ax-icon{font-size:.75rem}axp-route-tab-bar .axp-route-tab-bar__tab:hover .axp-route-tab-bar__close,axp-route-tab-bar .axp-route-tab-bar__close:focus-visible{width:1.25rem;opacity:.72;pointer-events:auto}axp-route-tab-bar .axp-route-tab-bar__close:hover{background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}axp-route-tab-bar:not(.axp-route-tab-bar--in-header){border-bottom:1px solid rgb(var(--ax-sys-color-border-light-surface))}axp-route-tab-bar:not(.axp-route-tab-bar--in-header) .axp-route-tab-bar__strip{background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface));padding-inline:.5rem}axp-route-tab-bar:not(.axp-route-tab-bar--in-header) .axp-route-tab-bar__tab{background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}axp-route-tab-bar:not(.axp-route-tab-bar--in-header) .axp-route-tab-bar__tab:hover:not(.axp-route-tab-bar__tab--active){background-color:rgb(var(--ax-sys-color-light-surface));color:rgb(var(--ax-sys-color-on-light-surface));border-color:rgb(var(--ax-sys-color-border-light-surface))}axp-route-tab-bar:not(.axp-route-tab-bar--in-header) .axp-route-tab-bar__tab.axp-route-tab-bar__tab--active{background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}axp-route-tab-bar.axp-route-tab-bar--in-header{align-self:stretch;height:100%;--axp-route-tab-bar-fade: var(--ax-sys-color-primary-surface);--axp-route-tab-bar-tab-row-height: 2.25rem}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__strip{display:flex;align-self:stretch;height:100%;align-items:stretch;background:transparent;color:rgb(var(--ax-sys-color-on-primary-surface))}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__viewport{align-items:flex-end}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__scroll-rail{align-self:flex-end;margin-bottom:0}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__scroll-wrap--overflow-start:before,axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__scroll-wrap--overflow-end:after{inset-block-end:0;inset-block-start:auto;height:var(--axp-route-tab-bar-tab-row-height)}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__scroll{cursor:default}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__tab-list{align-self:stretch;align-items:flex-end;min-height:0;padding-top:1rem}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__tab{align-self:center;padding:0;border-top-left-radius:.5rem;border-top-right-radius:.5rem;border-bottom-right-radius:0;border-bottom-left-radius:0;background-color:rgb(var(--ax-sys-color-primary-dark-surface));color:rgb(var(--ax-sys-color-on-primary-dark-surface));border-color:rgb(var(--ax-sys-color-border-primary-dark-surface))}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__tab ax-icon{color:inherit}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__tab:hover:not(.axp-route-tab-bar__tab--active){background-color:rgb(var(--ax-sys-color-primary-light-surface));color:rgb(var(--ax-sys-color-on-primary-light-surface));border-color:rgb(var(--ax-sys-color-border-primary-light-surface))}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__tab.axp-route-tab-bar__tab--active{background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__tab.axp-route-tab-bar__tab--active:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-primary-darkest-surface));color:rgb(var(--ax-sys-color-on-primary-darkest-surface));border-color:rgb(var(--ax-sys-color-border-primary-darkest-surface))}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__tab .axp-route-tab-bar__close:hover{background-color:rgb(var(--ax-sys-color-primary-light-surface));color:rgb(var(--ax-sys-color-on-primary-light-surface));border-color:rgb(var(--ax-sys-color-border-primary-light-surface))}axp-route-tab-bar.axp-route-tab-bar--in-header .axp-route-tab-bar__tab.axp-route-tab-bar__tab--active .axp-route-tab-bar__close:hover{background-color:rgb(var(--ax-sys-color-primary-light-surface));color:rgb(var(--ax-sys-color-on-primary-light-surface));border-color:rgb(var(--ax-sys-color-border-primary-light-surface))}.cdk-drag-preview.axp-route-tab-bar__drag-preview{display:flex;align-items:center;box-sizing:border-box;height:var(--axp-route-tab-bar-tab-row-height, 2.25rem);opacity:.96;cursor:grabbing;box-shadow:0 4px 12px rgb(var(--ax-sys-color-dark)/.16),0 1px 3px rgb(var(--ax-sys-color-dark)/.12)}.cdk-drag-preview.axp-route-tab-bar__drag-preview .axp-route-tab-bar__drag-preview-inner{display:flex;align-items:center;gap:.5rem;width:100%;min-width:0;height:100%;padding-inline:.625rem}.cdk-drag-preview.axp-route-tab-bar__drag-preview .axp-route-tab-bar__tab-icon{display:inline-flex;flex-shrink:0}.cdk-drag-preview.axp-route-tab-bar__drag-preview .axp-route-tab-bar__tab-icon ax-icon{font-size:.875rem}.cdk-drag-preview.axp-route-tab-bar__drag-preview .axp-route-tab-bar__tab-title{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem}.cdk-drag-preview.axp-route-tab-bar__drag-preview.axp-route-tab-bar__drag-preview--in-header{border-top-left-radius:.5rem;border-top-right-radius:.5rem;border-bottom-right-radius:0;border-bottom-left-radius:0;background-color:rgb(var(--ax-sys-color-primary-dark-surface));color:rgb(var(--ax-sys-color-on-primary-dark-surface));border-color:rgb(var(--ax-sys-color-border-primary-dark-surface))}.cdk-drag-preview.axp-route-tab-bar__drag-preview.axp-route-tab-bar__drag-preview--in-header.axp-route-tab-bar__drag-preview--active{background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}.cdk-drag-preview.axp-route-tab-bar__drag-preview.axp-route-tab-bar__drag-preview--in-header.axp-route-tab-bar__drag-preview--active:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-primary-darkest-surface));color:rgb(var(--ax-sys-color-on-primary-darkest-surface));border-color:rgb(var(--ax-sys-color-border-primary-darkest-surface))}.cdk-drag-preview.axp-route-tab-bar__drag-preview:not(.axp-route-tab-bar__drag-preview--in-header){border-radius:.375rem;background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}.cdk-drag-preview.axp-route-tab-bar__drag-preview:not(.axp-route-tab-bar__drag-preview--in-header).axp-route-tab-bar__drag-preview--active{background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}\n"] }]
|
|
2817
|
+
}], propDecorators: { tabStrip: [{ type: i0.ViewChild, args: ['tabStrip', { isSignal: true }] }], tabsScroll: [{ type: i0.ViewChild, args: ['tabsScroll', { isSignal: true }] }], contextMenu: [{ type: i0.ViewChild, args: ['tabContextMenu', { isSignal: true }] }] } });
|
|
2818
|
+
|
|
2372
2819
|
class AXPRootLayoutHeaderComponent {
|
|
2373
2820
|
//#endregion
|
|
2374
2821
|
//#region ---- Lifecycle Methods ----
|
|
@@ -2379,6 +2826,7 @@ class AXPRootLayoutHeaderComponent {
|
|
|
2379
2826
|
this.destroyRef = inject(DestroyRef);
|
|
2380
2827
|
this.shortcutRegistry = inject(AXPKeyboardShortcutRegistry);
|
|
2381
2828
|
this.store = inject(AXPLayoutThemeService);
|
|
2829
|
+
this.tabNavigation = inject(AXPTabNavigationService);
|
|
2382
2830
|
this.logo = this.config.logo;
|
|
2383
2831
|
this.shortcutRegistry.register({
|
|
2384
2832
|
owner: this.destroyRef,
|
|
@@ -2406,15 +2854,13 @@ class AXPRootLayoutHeaderComponent {
|
|
|
2406
2854
|
this.router.navigate(['/']);
|
|
2407
2855
|
}
|
|
2408
2856
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootLayoutHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2409
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPRootLayoutHeaderComponent, isStandalone: true, selector: "axp-dashboard-admin-header", host: { classAttribute: "ax-w-full ax-flex ax-items-center ax-
|
|
2857
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPRootLayoutHeaderComponent, isStandalone: true, selector: "axp-dashboard-admin-header", host: { classAttribute: "ax-w-full ax-flex ax-min-w-0 ax-items-center ax-gap-2 ax-bg-primary-surface ax-text-primary-on-surface ax-h-14 ax-px-2 ax-light" }, ngImport: i0, template: "<ax-button id=\"axp-menu-toggle\" (onClick)=\"toggleSideMenu()\" color=\"primary\">\n <ax-icon class=\"rtl:ax-rotate-180\">\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 30 30\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n @if (store.isSideMenuOpen()) {\n <defs>\n <clipPath id=\"clip1382_20239\">\n <rect width=\"30.000000\" height=\"30.000000\" fill=\"white\" fill-opacity=\"0\"></rect>\n </clipPath>\n </defs>\n <rect width=\"30.000000\" height=\"30.000000\" fill=\"#FFFFFF\" fill-opacity=\"0\"></rect>\n <g clip-path=\"url(#clip1382_20239)\">\n <rect\n id=\"rect\"\n x=\"17.420410\"\n y=\"12.316406\"\n rx=\"1.000947\"\n width=\"5.995172\"\n height=\"2.001895\"\n transform=\"rotate(137.159 17.420410 12.316406)\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n ></rect>\n <rect\n id=\"rect\"\n x=\"12.959473\"\n y=\"13.728516\"\n rx=\"0.995190\"\n width=\"6.002943\"\n height=\"1.990380\"\n transform=\"rotate(40.853 12.959473 13.728516)\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n ></rect>\n <path\n id=\"path\"\n d=\"M20.1 25.5L9.9 25.51C9.48 25.51 9.06 25.47 8.65 25.39C8.24 25.3 7.84 25.18 7.45 25.02C7.06 24.86 6.69 24.66 6.34 24.43C5.99 24.19 5.67 23.92 5.37 23.63C5.07 23.33 4.81 23 4.58 22.65C4.34 22.3 4.15 21.93 3.98 21.54C3.82 21.15 3.7 20.75 3.62 20.34C3.54 19.93 3.5 19.51 3.5 19.09L3.5 10.93C3.5 10.51 3.54 10.1 3.62 9.68C3.7 9.27 3.82 8.87 3.98 8.48C4.15 8.09 4.34 7.72 4.58 7.37C4.81 7.02 5.07 6.69 5.37 6.39C5.67 6.1 5.99 5.83 6.34 5.6C6.69 5.36 7.06 5.16 7.45 5C7.84 4.84 8.24 4.72 8.65 4.64C9.06 4.55 9.48 4.51 9.9 4.51L20.1 4.5C20.52 4.5 20.94 4.54 21.35 4.62C21.76 4.7 22.16 4.83 22.55 4.99C22.94 5.15 23.31 5.35 23.66 5.58C24 5.82 24.33 6.08 24.62 6.38C24.92 6.68 25.19 7 25.42 7.35C25.65 7.7 25.85 8.07 26.01 8.46C26.17 8.85 26.3 9.25 26.38 9.67C26.46 10.08 26.5 10.5 26.5 10.92L26.5 19.07C26.5 19.5 26.46 19.91 26.38 20.32C26.3 20.74 26.17 21.14 26.01 21.53C25.85 21.92 25.65 22.29 25.42 22.64C25.19 22.99 24.92 23.31 24.62 23.61C24.33 23.91 24 24.17 23.66 24.41C23.31 24.64 22.94 24.84 22.55 25C22.16 25.16 21.76 25.29 21.35 25.37C20.94 25.45 20.52 25.5 20.1 25.5ZM9.9 6.6C9.61 6.6 9.33 6.63 9.05 6.69C8.78 6.74 8.51 6.82 8.24 6.93C7.98 7.04 7.73 7.18 7.5 7.33C7.26 7.49 7.04 7.67 6.84 7.87C6.64 8.07 6.46 8.29 6.31 8.53C6.15 8.77 6.02 9.01 5.91 9.28C5.8 9.54 5.72 9.81 5.66 10.09C5.61 10.37 5.58 10.65 5.58 10.93L5.58 19.09C5.58 19.37 5.61 19.65 5.66 19.93C5.72 20.21 5.8 20.48 5.91 20.74C6.02 21.01 6.15 21.26 6.31 21.49C6.46 21.73 6.64 21.95 6.84 22.15C7.04 22.35 7.26 22.53 7.5 22.69C7.73 22.85 7.98 22.98 8.24 23.09C8.51 23.2 8.78 23.28 9.05 23.33C9.33 23.39 9.61 23.42 9.9 23.42L20.1 23.41C20.38 23.41 20.67 23.37 20.94 23.32C21.22 23.26 21.49 23.18 21.75 23.07C22.01 22.96 22.26 22.83 22.5 22.67C22.73 22.51 22.95 22.33 23.15 22.13C23.35 21.93 23.53 21.71 23.69 21.48C23.85 21.24 23.98 20.99 24.09 20.73C24.2 20.47 24.28 20.2 24.33 19.92C24.39 19.64 24.42 19.36 24.42 19.07L24.42 10.92C24.42 10.64 24.39 10.35 24.33 10.07C24.28 9.79 24.2 9.52 24.09 9.26C23.98 9 23.85 8.75 23.69 8.51C23.53 8.28 23.35 8.06 23.15 7.86C22.95 7.66 22.73 7.48 22.5 7.32C22.26 7.16 22.01 7.03 21.75 6.92C21.49 6.81 21.22 6.73 20.94 6.67C20.67 6.62 20.38 6.59 20.1 6.59L9.9 6.6Z\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n fill-rule=\"nonzero\"\n ></path>\n <path\n id=\"rect\"\n d=\"M8.5 5.51L10.54 5.51L10.6 24.43L8.55 24.43L8.5 5.51Z\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n fill-rule=\"evenodd\"\n ></path>\n </g>\n } @else {\n <defs>\n <clipPath id=\"clip1381_20236\">\n <rect id=\"\u6253\u5F00\u8FB9\u680F0730\" width=\"30.000000\" height=\"30.000000\" fill=\"white\" fill-opacity=\"0\"></rect>\n </clipPath>\n </defs>\n <rect id=\"\u6253\u5F00\u8FB9\u680F0730\" width=\"30.000000\" height=\"30.000000\" fill=\"#FFFFFF\" fill-opacity=\"0\"></rect>\n <g clip-path=\"url(#clip1381_20236)\">\n <rect\n id=\"rect\"\n x=\"11.572754\"\n y=\"17.683594\"\n rx=\"1.000947\"\n width=\"5.995172\"\n height=\"2.001895\"\n transform=\"rotate(-42.841 11.572754 17.683594)\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n ></rect>\n <rect\n id=\"rect\"\n x=\"16.033691\"\n y=\"16.271484\"\n rx=\"0.995190\"\n width=\"6.002943\"\n height=\"1.990380\"\n transform=\"rotate(-139.147 16.033691 16.271484)\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n ></rect>\n <path\n id=\"path\"\n d=\"M20.09 25.48L9.89 25.5C9.47 25.5 9.05 25.45 8.64 25.37C8.23 25.29 7.83 25.17 7.44 25C7.05 24.84 6.68 24.64 6.33 24.41C5.98 24.18 5.66 23.91 5.36 23.61C5.07 23.31 4.8 22.99 4.57 22.64C4.34 22.29 4.14 21.92 3.98 21.53C3.82 21.14 3.69 20.74 3.61 20.32C3.53 19.91 3.49 19.49 3.49 19.07L3.49 10.92C3.49 10.5 3.53 10.08 3.61 9.67C3.69 9.25 3.82 8.85 3.98 8.46C4.14 8.07 4.34 7.7 4.57 7.35C4.8 7 5.07 6.68 5.36 6.38C5.66 6.08 5.98 5.81 6.33 5.58C6.68 5.35 7.05 5.15 7.44 4.99C7.83 4.82 8.23 4.7 8.64 4.62C9.05 4.54 9.47 4.5 9.89 4.5L20.09 4.48C20.51 4.48 20.93 4.52 21.34 4.6C21.75 4.69 22.15 4.81 22.54 4.97C22.93 5.13 23.3 5.33 23.65 5.57C24 5.8 24.32 6.06 24.62 6.36C24.92 6.66 25.18 6.98 25.41 7.33C25.65 7.69 25.84 8.06 26.01 8.45C26.17 8.84 26.29 9.24 26.37 9.65C26.45 10.06 26.49 10.48 26.5 10.91L26.5 19.06C26.49 19.48 26.45 19.89 26.37 20.31C26.29 20.72 26.17 21.12 26.01 21.51C25.84 21.9 25.65 22.27 25.41 22.62C25.18 22.97 24.92 23.3 24.62 23.6C24.32 23.89 24 24.16 23.65 24.39C23.3 24.63 22.93 24.83 22.54 24.99C22.15 25.15 21.75 25.27 21.34 25.35C20.93 25.44 20.51 25.48 20.09 25.48ZM9.89 6.59C9.61 6.59 9.32 6.62 9.05 6.67C8.77 6.73 8.5 6.81 8.24 6.92C7.98 7.03 7.73 7.16 7.49 7.32C7.26 7.48 7.04 7.66 6.84 7.86C6.64 8.06 6.46 8.28 6.3 8.51C6.14 8.75 6.01 9 5.9 9.26C5.79 9.52 5.71 9.8 5.66 10.07C5.6 10.35 5.57 10.63 5.57 10.92L5.57 19.07C5.57 19.36 5.6 19.64 5.66 19.92C5.71 20.19 5.79 20.47 5.9 20.73C6.01 20.99 6.14 21.24 6.3 21.48C6.46 21.71 6.64 21.93 6.84 22.13C7.04 22.33 7.26 22.51 7.49 22.67C7.73 22.83 7.98 22.96 8.24 23.07C8.5 23.18 8.77 23.26 9.05 23.32C9.32 23.37 9.61 23.4 9.89 23.4L20.09 23.39C20.38 23.39 20.66 23.36 20.94 23.3C21.21 23.25 21.48 23.17 21.75 23.06C22.01 22.95 22.26 22.81 22.49 22.66C22.73 22.5 22.95 22.32 23.15 22.12C23.35 21.91 23.52 21.7 23.68 21.46C23.84 21.22 23.97 20.98 24.08 20.71C24.19 20.45 24.27 20.18 24.33 19.9C24.38 19.62 24.41 19.34 24.41 19.06L24.41 10.91C24.41 10.62 24.38 10.34 24.33 10.06C24.27 9.78 24.19 9.51 24.08 9.25C23.97 8.98 23.84 8.74 23.68 8.5C23.52 8.26 23.35 8.04 23.15 7.84C22.95 7.64 22.73 7.46 22.49 7.3C22.26 7.15 22.01 7.01 21.75 6.9C21.48 6.79 21.21 6.71 20.94 6.66C20.66 6.6 20.38 6.57 20.09 6.57L9.89 6.59Z\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n fill-rule=\"nonzero\"\n ></path>\n <path\n id=\"rect\"\n d=\"M8.49 5.5L10.53 5.5L10.59 24.41L8.54 24.41L8.49 5.5Z\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n fill-rule=\"evenodd\"\n ></path>\n </g>\n }\n </svg>\n </ax-icon>\n</ax-button>\n\n<div class=\"axp-root-header__main ax-h-full ax-flex ax-min-w-0 ax-flex-1 ax-items-center ax-gap-2\">\n @if (tabNavigation.isTabBarVisible()) {\n <axp-route-tab-bar class=\"axp-route-tab-bar--in-header ax-min-w-0 ax-flex-1 ax-self-stretch\"></axp-route-tab-bar>\n }\n <div class=\"ax-flex ax-min-w-0 ax-items-center ax-gap-1\" [class.ax-flex-1]=\"!tabNavigation.isTabBarVisible()\">\n <axp-component-slot name=\"root-header-start\"></axp-component-slot>\n </div>\n</div>\n\n<div class=\"ax-flex ax-shrink-0 ax-items-center ax-gap-1\">\n <axp-component-slot name=\"root-header-end\"></axp-component-slot>\n</div>\n", dependencies: [{ kind: "ngmodule", type: AXPComponentSlotModule }, { kind: "directive", type: i1$5.AXPComponentSlotDirective, selector: "axp-component-slot", inputs: ["name", "host", "context"], exportAs: ["slot"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: AXPRouteTabBarComponent, selector: "axp-route-tab-bar" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2410
2858
|
}
|
|
2411
2859
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootLayoutHeaderComponent, decorators: [{
|
|
2412
2860
|
type: Component,
|
|
2413
|
-
args: [{ selector: 'axp-dashboard-admin-header', encapsulation: ViewEncapsulation.None, host: {
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
AXDecoratorModule
|
|
2417
|
-
], template: "<ax-button id=\"axp-menu-toggle\" (onClick)=\"toggleSideMenu()\" color=\"primary\">\n <ax-icon class=\"rtl:ax-rotate-180\">\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 30 30\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n @if (store.isSideMenuOpen()) {\n <defs>\n <clipPath id=\"clip1382_20239\">\n <rect width=\"30.000000\" height=\"30.000000\" fill=\"white\" fill-opacity=\"0\"></rect>\n </clipPath>\n </defs>\n <rect width=\"30.000000\" height=\"30.000000\" fill=\"#FFFFFF\" fill-opacity=\"0\"></rect>\n <g clip-path=\"url(#clip1382_20239)\">\n <rect\n id=\"rect\"\n x=\"17.420410\"\n y=\"12.316406\"\n rx=\"1.000947\"\n width=\"5.995172\"\n height=\"2.001895\"\n transform=\"rotate(137.159 17.420410 12.316406)\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n ></rect>\n <rect\n id=\"rect\"\n x=\"12.959473\"\n y=\"13.728516\"\n rx=\"0.995190\"\n width=\"6.002943\"\n height=\"1.990380\"\n transform=\"rotate(40.853 12.959473 13.728516)\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n ></rect>\n <path\n id=\"path\"\n d=\"M20.1 25.5L9.9 25.51C9.48 25.51 9.06 25.47 8.65 25.39C8.24 25.3 7.84 25.18 7.45 25.02C7.06 24.86 6.69 24.66 6.34 24.43C5.99 24.19 5.67 23.92 5.37 23.63C5.07 23.33 4.81 23 4.58 22.65C4.34 22.3 4.15 21.93 3.98 21.54C3.82 21.15 3.7 20.75 3.62 20.34C3.54 19.93 3.5 19.51 3.5 19.09L3.5 10.93C3.5 10.51 3.54 10.1 3.62 9.68C3.7 9.27 3.82 8.87 3.98 8.48C4.15 8.09 4.34 7.72 4.58 7.37C4.81 7.02 5.07 6.69 5.37 6.39C5.67 6.1 5.99 5.83 6.34 5.6C6.69 5.36 7.06 5.16 7.45 5C7.84 4.84 8.24 4.72 8.65 4.64C9.06 4.55 9.48 4.51 9.9 4.51L20.1 4.5C20.52 4.5 20.94 4.54 21.35 4.62C21.76 4.7 22.16 4.83 22.55 4.99C22.94 5.15 23.31 5.35 23.66 5.58C24 5.82 24.33 6.08 24.62 6.38C24.92 6.68 25.19 7 25.42 7.35C25.65 7.7 25.85 8.07 26.01 8.46C26.17 8.85 26.3 9.25 26.38 9.67C26.46 10.08 26.5 10.5 26.5 10.92L26.5 19.07C26.5 19.5 26.46 19.91 26.38 20.32C26.3 20.74 26.17 21.14 26.01 21.53C25.85 21.92 25.65 22.29 25.42 22.64C25.19 22.99 24.92 23.31 24.62 23.61C24.33 23.91 24 24.17 23.66 24.41C23.31 24.64 22.94 24.84 22.55 25C22.16 25.16 21.76 25.29 21.35 25.37C20.94 25.45 20.52 25.5 20.1 25.5ZM9.9 6.6C9.61 6.6 9.33 6.63 9.05 6.69C8.78 6.74 8.51 6.82 8.24 6.93C7.98 7.04 7.73 7.18 7.5 7.33C7.26 7.49 7.04 7.67 6.84 7.87C6.64 8.07 6.46 8.29 6.31 8.53C6.15 8.77 6.02 9.01 5.91 9.28C5.8 9.54 5.72 9.81 5.66 10.09C5.61 10.37 5.58 10.65 5.58 10.93L5.58 19.09C5.58 19.37 5.61 19.65 5.66 19.93C5.72 20.21 5.8 20.48 5.91 20.74C6.02 21.01 6.15 21.26 6.31 21.49C6.46 21.73 6.64 21.95 6.84 22.15C7.04 22.35 7.26 22.53 7.5 22.69C7.73 22.85 7.98 22.98 8.24 23.09C8.51 23.2 8.78 23.28 9.05 23.33C9.33 23.39 9.61 23.42 9.9 23.42L20.1 23.41C20.38 23.41 20.67 23.37 20.94 23.32C21.22 23.26 21.49 23.18 21.75 23.07C22.01 22.96 22.26 22.83 22.5 22.67C22.73 22.51 22.95 22.33 23.15 22.13C23.35 21.93 23.53 21.71 23.69 21.48C23.85 21.24 23.98 20.99 24.09 20.73C24.2 20.47 24.28 20.2 24.33 19.92C24.39 19.64 24.42 19.36 24.42 19.07L24.42 10.92C24.42 10.64 24.39 10.35 24.33 10.07C24.28 9.79 24.2 9.52 24.09 9.26C23.98 9 23.85 8.75 23.69 8.51C23.53 8.28 23.35 8.06 23.15 7.86C22.95 7.66 22.73 7.48 22.5 7.32C22.26 7.16 22.01 7.03 21.75 6.92C21.49 6.81 21.22 6.73 20.94 6.67C20.67 6.62 20.38 6.59 20.1 6.59L9.9 6.6Z\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n fill-rule=\"nonzero\"\n ></path>\n <path\n id=\"rect\"\n d=\"M8.5 5.51L10.54 5.51L10.6 24.43L8.55 24.43L8.5 5.51Z\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n fill-rule=\"evenodd\"\n ></path>\n </g>\n } @else {\n <defs>\n <clipPath id=\"clip1381_20236\">\n <rect id=\"\u6253\u5F00\u8FB9\u680F0730\" width=\"30.000000\" height=\"30.000000\" fill=\"white\" fill-opacity=\"0\"></rect>\n </clipPath>\n </defs>\n <rect id=\"\u6253\u5F00\u8FB9\u680F0730\" width=\"30.000000\" height=\"30.000000\" fill=\"#FFFFFF\" fill-opacity=\"0\"></rect>\n <g clip-path=\"url(#clip1381_20236)\">\n <rect\n id=\"rect\"\n x=\"11.572754\"\n y=\"17.683594\"\n rx=\"1.000947\"\n width=\"5.995172\"\n height=\"2.001895\"\n transform=\"rotate(-42.841 11.572754 17.683594)\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n ></rect>\n <rect\n id=\"rect\"\n x=\"16.033691\"\n y=\"16.271484\"\n rx=\"0.995190\"\n width=\"6.002943\"\n height=\"1.990380\"\n transform=\"rotate(-139.147 16.033691 16.271484)\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n ></rect>\n <path\n id=\"path\"\n d=\"M20.09 25.48L9.89 25.5C9.47 25.5 9.05 25.45 8.64 25.37C8.23 25.29 7.83 25.17 7.44 25C7.05 24.84 6.68 24.64 6.33 24.41C5.98 24.18 5.66 23.91 5.36 23.61C5.07 23.31 4.8 22.99 4.57 22.64C4.34 22.29 4.14 21.92 3.98 21.53C3.82 21.14 3.69 20.74 3.61 20.32C3.53 19.91 3.49 19.49 3.49 19.07L3.49 10.92C3.49 10.5 3.53 10.08 3.61 9.67C3.69 9.25 3.82 8.85 3.98 8.46C4.14 8.07 4.34 7.7 4.57 7.35C4.8 7 5.07 6.68 5.36 6.38C5.66 6.08 5.98 5.81 6.33 5.58C6.68 5.35 7.05 5.15 7.44 4.99C7.83 4.82 8.23 4.7 8.64 4.62C9.05 4.54 9.47 4.5 9.89 4.5L20.09 4.48C20.51 4.48 20.93 4.52 21.34 4.6C21.75 4.69 22.15 4.81 22.54 4.97C22.93 5.13 23.3 5.33 23.65 5.57C24 5.8 24.32 6.06 24.62 6.36C24.92 6.66 25.18 6.98 25.41 7.33C25.65 7.69 25.84 8.06 26.01 8.45C26.17 8.84 26.29 9.24 26.37 9.65C26.45 10.06 26.49 10.48 26.5 10.91L26.5 19.06C26.49 19.48 26.45 19.89 26.37 20.31C26.29 20.72 26.17 21.12 26.01 21.51C25.84 21.9 25.65 22.27 25.41 22.62C25.18 22.97 24.92 23.3 24.62 23.6C24.32 23.89 24 24.16 23.65 24.39C23.3 24.63 22.93 24.83 22.54 24.99C22.15 25.15 21.75 25.27 21.34 25.35C20.93 25.44 20.51 25.48 20.09 25.48ZM9.89 6.59C9.61 6.59 9.32 6.62 9.05 6.67C8.77 6.73 8.5 6.81 8.24 6.92C7.98 7.03 7.73 7.16 7.49 7.32C7.26 7.48 7.04 7.66 6.84 7.86C6.64 8.06 6.46 8.28 6.3 8.51C6.14 8.75 6.01 9 5.9 9.26C5.79 9.52 5.71 9.8 5.66 10.07C5.6 10.35 5.57 10.63 5.57 10.92L5.57 19.07C5.57 19.36 5.6 19.64 5.66 19.92C5.71 20.19 5.79 20.47 5.9 20.73C6.01 20.99 6.14 21.24 6.3 21.48C6.46 21.71 6.64 21.93 6.84 22.13C7.04 22.33 7.26 22.51 7.49 22.67C7.73 22.83 7.98 22.96 8.24 23.07C8.5 23.18 8.77 23.26 9.05 23.32C9.32 23.37 9.61 23.4 9.89 23.4L20.09 23.39C20.38 23.39 20.66 23.36 20.94 23.3C21.21 23.25 21.48 23.17 21.75 23.06C22.01 22.95 22.26 22.81 22.49 22.66C22.73 22.5 22.95 22.32 23.15 22.12C23.35 21.91 23.52 21.7 23.68 21.46C23.84 21.22 23.97 20.98 24.08 20.71C24.19 20.45 24.27 20.18 24.33 19.9C24.38 19.62 24.41 19.34 24.41 19.06L24.41 10.91C24.41 10.62 24.38 10.34 24.33 10.06C24.27 9.78 24.19 9.51 24.08 9.25C23.97 8.98 23.84 8.74 23.68 8.5C23.52 8.26 23.35 8.04 23.15 7.84C22.95 7.64 22.73 7.46 22.49 7.3C22.26 7.15 22.01 7.01 21.75 6.9C21.48 6.79 21.21 6.71 20.94 6.66C20.66 6.6 20.38 6.57 20.09 6.57L9.89 6.59Z\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n fill-rule=\"nonzero\"\n ></path>\n <path\n id=\"rect\"\n d=\"M8.49 5.5L10.53 5.5L10.59 24.41L8.54 24.41L8.49 5.5Z\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n fill-rule=\"evenodd\"\n ></path>\n </g>\n }\n </svg>\n </ax-icon>\n</ax-button>\n<div class=\"ax-flex ax-items-center ax-gap-1 ax-justify-between ax-w-full\">\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <axp-component-slot name=\"root-header-start\"></axp-component-slot>\n </div>\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <axp-component-slot name=\"root-header-end\"></axp-component-slot>\n </div>\n</div>\n" }]
|
|
2861
|
+
args: [{ selector: 'axp-dashboard-admin-header', encapsulation: ViewEncapsulation.None, host: {
|
|
2862
|
+
class: 'ax-w-full ax-flex ax-min-w-0 ax-items-center ax-gap-2 ax-bg-primary-surface ax-text-primary-on-surface ax-h-14 ax-px-2 ax-light',
|
|
2863
|
+
}, standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [AXPComponentSlotModule, AXButtonModule, AXDecoratorModule, AXPRouteTabBarComponent], template: "<ax-button id=\"axp-menu-toggle\" (onClick)=\"toggleSideMenu()\" color=\"primary\">\n <ax-icon class=\"rtl:ax-rotate-180\">\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 30 30\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n @if (store.isSideMenuOpen()) {\n <defs>\n <clipPath id=\"clip1382_20239\">\n <rect width=\"30.000000\" height=\"30.000000\" fill=\"white\" fill-opacity=\"0\"></rect>\n </clipPath>\n </defs>\n <rect width=\"30.000000\" height=\"30.000000\" fill=\"#FFFFFF\" fill-opacity=\"0\"></rect>\n <g clip-path=\"url(#clip1382_20239)\">\n <rect\n id=\"rect\"\n x=\"17.420410\"\n y=\"12.316406\"\n rx=\"1.000947\"\n width=\"5.995172\"\n height=\"2.001895\"\n transform=\"rotate(137.159 17.420410 12.316406)\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n ></rect>\n <rect\n id=\"rect\"\n x=\"12.959473\"\n y=\"13.728516\"\n rx=\"0.995190\"\n width=\"6.002943\"\n height=\"1.990380\"\n transform=\"rotate(40.853 12.959473 13.728516)\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n ></rect>\n <path\n id=\"path\"\n d=\"M20.1 25.5L9.9 25.51C9.48 25.51 9.06 25.47 8.65 25.39C8.24 25.3 7.84 25.18 7.45 25.02C7.06 24.86 6.69 24.66 6.34 24.43C5.99 24.19 5.67 23.92 5.37 23.63C5.07 23.33 4.81 23 4.58 22.65C4.34 22.3 4.15 21.93 3.98 21.54C3.82 21.15 3.7 20.75 3.62 20.34C3.54 19.93 3.5 19.51 3.5 19.09L3.5 10.93C3.5 10.51 3.54 10.1 3.62 9.68C3.7 9.27 3.82 8.87 3.98 8.48C4.15 8.09 4.34 7.72 4.58 7.37C4.81 7.02 5.07 6.69 5.37 6.39C5.67 6.1 5.99 5.83 6.34 5.6C6.69 5.36 7.06 5.16 7.45 5C7.84 4.84 8.24 4.72 8.65 4.64C9.06 4.55 9.48 4.51 9.9 4.51L20.1 4.5C20.52 4.5 20.94 4.54 21.35 4.62C21.76 4.7 22.16 4.83 22.55 4.99C22.94 5.15 23.31 5.35 23.66 5.58C24 5.82 24.33 6.08 24.62 6.38C24.92 6.68 25.19 7 25.42 7.35C25.65 7.7 25.85 8.07 26.01 8.46C26.17 8.85 26.3 9.25 26.38 9.67C26.46 10.08 26.5 10.5 26.5 10.92L26.5 19.07C26.5 19.5 26.46 19.91 26.38 20.32C26.3 20.74 26.17 21.14 26.01 21.53C25.85 21.92 25.65 22.29 25.42 22.64C25.19 22.99 24.92 23.31 24.62 23.61C24.33 23.91 24 24.17 23.66 24.41C23.31 24.64 22.94 24.84 22.55 25C22.16 25.16 21.76 25.29 21.35 25.37C20.94 25.45 20.52 25.5 20.1 25.5ZM9.9 6.6C9.61 6.6 9.33 6.63 9.05 6.69C8.78 6.74 8.51 6.82 8.24 6.93C7.98 7.04 7.73 7.18 7.5 7.33C7.26 7.49 7.04 7.67 6.84 7.87C6.64 8.07 6.46 8.29 6.31 8.53C6.15 8.77 6.02 9.01 5.91 9.28C5.8 9.54 5.72 9.81 5.66 10.09C5.61 10.37 5.58 10.65 5.58 10.93L5.58 19.09C5.58 19.37 5.61 19.65 5.66 19.93C5.72 20.21 5.8 20.48 5.91 20.74C6.02 21.01 6.15 21.26 6.31 21.49C6.46 21.73 6.64 21.95 6.84 22.15C7.04 22.35 7.26 22.53 7.5 22.69C7.73 22.85 7.98 22.98 8.24 23.09C8.51 23.2 8.78 23.28 9.05 23.33C9.33 23.39 9.61 23.42 9.9 23.42L20.1 23.41C20.38 23.41 20.67 23.37 20.94 23.32C21.22 23.26 21.49 23.18 21.75 23.07C22.01 22.96 22.26 22.83 22.5 22.67C22.73 22.51 22.95 22.33 23.15 22.13C23.35 21.93 23.53 21.71 23.69 21.48C23.85 21.24 23.98 20.99 24.09 20.73C24.2 20.47 24.28 20.2 24.33 19.92C24.39 19.64 24.42 19.36 24.42 19.07L24.42 10.92C24.42 10.64 24.39 10.35 24.33 10.07C24.28 9.79 24.2 9.52 24.09 9.26C23.98 9 23.85 8.75 23.69 8.51C23.53 8.28 23.35 8.06 23.15 7.86C22.95 7.66 22.73 7.48 22.5 7.32C22.26 7.16 22.01 7.03 21.75 6.92C21.49 6.81 21.22 6.73 20.94 6.67C20.67 6.62 20.38 6.59 20.1 6.59L9.9 6.6Z\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n fill-rule=\"nonzero\"\n ></path>\n <path\n id=\"rect\"\n d=\"M8.5 5.51L10.54 5.51L10.6 24.43L8.55 24.43L8.5 5.51Z\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n fill-rule=\"evenodd\"\n ></path>\n </g>\n } @else {\n <defs>\n <clipPath id=\"clip1381_20236\">\n <rect id=\"\u6253\u5F00\u8FB9\u680F0730\" width=\"30.000000\" height=\"30.000000\" fill=\"white\" fill-opacity=\"0\"></rect>\n </clipPath>\n </defs>\n <rect id=\"\u6253\u5F00\u8FB9\u680F0730\" width=\"30.000000\" height=\"30.000000\" fill=\"#FFFFFF\" fill-opacity=\"0\"></rect>\n <g clip-path=\"url(#clip1381_20236)\">\n <rect\n id=\"rect\"\n x=\"11.572754\"\n y=\"17.683594\"\n rx=\"1.000947\"\n width=\"5.995172\"\n height=\"2.001895\"\n transform=\"rotate(-42.841 11.572754 17.683594)\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n ></rect>\n <rect\n id=\"rect\"\n x=\"16.033691\"\n y=\"16.271484\"\n rx=\"0.995190\"\n width=\"6.002943\"\n height=\"1.990380\"\n transform=\"rotate(-139.147 16.033691 16.271484)\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n ></rect>\n <path\n id=\"path\"\n d=\"M20.09 25.48L9.89 25.5C9.47 25.5 9.05 25.45 8.64 25.37C8.23 25.29 7.83 25.17 7.44 25C7.05 24.84 6.68 24.64 6.33 24.41C5.98 24.18 5.66 23.91 5.36 23.61C5.07 23.31 4.8 22.99 4.57 22.64C4.34 22.29 4.14 21.92 3.98 21.53C3.82 21.14 3.69 20.74 3.61 20.32C3.53 19.91 3.49 19.49 3.49 19.07L3.49 10.92C3.49 10.5 3.53 10.08 3.61 9.67C3.69 9.25 3.82 8.85 3.98 8.46C4.14 8.07 4.34 7.7 4.57 7.35C4.8 7 5.07 6.68 5.36 6.38C5.66 6.08 5.98 5.81 6.33 5.58C6.68 5.35 7.05 5.15 7.44 4.99C7.83 4.82 8.23 4.7 8.64 4.62C9.05 4.54 9.47 4.5 9.89 4.5L20.09 4.48C20.51 4.48 20.93 4.52 21.34 4.6C21.75 4.69 22.15 4.81 22.54 4.97C22.93 5.13 23.3 5.33 23.65 5.57C24 5.8 24.32 6.06 24.62 6.36C24.92 6.66 25.18 6.98 25.41 7.33C25.65 7.69 25.84 8.06 26.01 8.45C26.17 8.84 26.29 9.24 26.37 9.65C26.45 10.06 26.49 10.48 26.5 10.91L26.5 19.06C26.49 19.48 26.45 19.89 26.37 20.31C26.29 20.72 26.17 21.12 26.01 21.51C25.84 21.9 25.65 22.27 25.41 22.62C25.18 22.97 24.92 23.3 24.62 23.6C24.32 23.89 24 24.16 23.65 24.39C23.3 24.63 22.93 24.83 22.54 24.99C22.15 25.15 21.75 25.27 21.34 25.35C20.93 25.44 20.51 25.48 20.09 25.48ZM9.89 6.59C9.61 6.59 9.32 6.62 9.05 6.67C8.77 6.73 8.5 6.81 8.24 6.92C7.98 7.03 7.73 7.16 7.49 7.32C7.26 7.48 7.04 7.66 6.84 7.86C6.64 8.06 6.46 8.28 6.3 8.51C6.14 8.75 6.01 9 5.9 9.26C5.79 9.52 5.71 9.8 5.66 10.07C5.6 10.35 5.57 10.63 5.57 10.92L5.57 19.07C5.57 19.36 5.6 19.64 5.66 19.92C5.71 20.19 5.79 20.47 5.9 20.73C6.01 20.99 6.14 21.24 6.3 21.48C6.46 21.71 6.64 21.93 6.84 22.13C7.04 22.33 7.26 22.51 7.49 22.67C7.73 22.83 7.98 22.96 8.24 23.07C8.5 23.18 8.77 23.26 9.05 23.32C9.32 23.37 9.61 23.4 9.89 23.4L20.09 23.39C20.38 23.39 20.66 23.36 20.94 23.3C21.21 23.25 21.48 23.17 21.75 23.06C22.01 22.95 22.26 22.81 22.49 22.66C22.73 22.5 22.95 22.32 23.15 22.12C23.35 21.91 23.52 21.7 23.68 21.46C23.84 21.22 23.97 20.98 24.08 20.71C24.19 20.45 24.27 20.18 24.33 19.9C24.38 19.62 24.41 19.34 24.41 19.06L24.41 10.91C24.41 10.62 24.38 10.34 24.33 10.06C24.27 9.78 24.19 9.51 24.08 9.25C23.97 8.98 23.84 8.74 23.68 8.5C23.52 8.26 23.35 8.04 23.15 7.84C22.95 7.64 22.73 7.46 22.49 7.3C22.26 7.15 22.01 7.01 21.75 6.9C21.48 6.79 21.21 6.71 20.94 6.66C20.66 6.6 20.38 6.57 20.09 6.57L9.89 6.59Z\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n fill-rule=\"nonzero\"\n ></path>\n <path\n id=\"rect\"\n d=\"M8.49 5.5L10.53 5.5L10.59 24.41L8.54 24.41L8.49 5.5Z\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n fill-rule=\"evenodd\"\n ></path>\n </g>\n }\n </svg>\n </ax-icon>\n</ax-button>\n\n<div class=\"axp-root-header__main ax-h-full ax-flex ax-min-w-0 ax-flex-1 ax-items-center ax-gap-2\">\n @if (tabNavigation.isTabBarVisible()) {\n <axp-route-tab-bar class=\"axp-route-tab-bar--in-header ax-min-w-0 ax-flex-1 ax-self-stretch\"></axp-route-tab-bar>\n }\n <div class=\"ax-flex ax-min-w-0 ax-items-center ax-gap-1\" [class.ax-flex-1]=\"!tabNavigation.isTabBarVisible()\">\n <axp-component-slot name=\"root-header-start\"></axp-component-slot>\n </div>\n</div>\n\n<div class=\"ax-flex ax-shrink-0 ax-items-center ax-gap-1\">\n <axp-component-slot name=\"root-header-end\"></axp-component-slot>\n</div>\n" }]
|
|
2418
2864
|
}], ctorParameters: () => [] });
|
|
2419
2865
|
|
|
2420
2866
|
class AXPRootLayoutMenuComponent {
|
|
@@ -2440,12 +2886,41 @@ class AXPRootLayoutMenuComponent {
|
|
|
2440
2886
|
}
|
|
2441
2887
|
});
|
|
2442
2888
|
}
|
|
2443
|
-
onMenuItemClick(item
|
|
2444
|
-
if (
|
|
2889
|
+
onMenuItemClick(item) {
|
|
2890
|
+
if (item.children?.length) {
|
|
2445
2891
|
return;
|
|
2446
2892
|
}
|
|
2447
2893
|
this.menuStore.executeCommand(item);
|
|
2448
2894
|
}
|
|
2895
|
+
/**
|
|
2896
|
+
* Determines whether a menu item should render as active.
|
|
2897
|
+
* Do not bind `routerLink` on `ax-side-menu-item`: that component ignores the `active` input
|
|
2898
|
+
* and only uses `RouterLinkActive`, which cannot match entity detail routes to list menu paths.
|
|
2899
|
+
*/
|
|
2900
|
+
isMenuItemActive(item) {
|
|
2901
|
+
const selected = this.menuStore.selectedMenuItem().item;
|
|
2902
|
+
if (selected && this.isSameMenuItem(selected, item)) {
|
|
2903
|
+
return true;
|
|
2904
|
+
}
|
|
2905
|
+
const routePath = this.getMenuItemRoutePath(item);
|
|
2906
|
+
if (!routePath) {
|
|
2907
|
+
return false;
|
|
2908
|
+
}
|
|
2909
|
+
return axpMenuPathsMatch(routePath, this.router.url).isMatch;
|
|
2910
|
+
}
|
|
2911
|
+
isSameMenuItem(left, right) {
|
|
2912
|
+
if (left === right) {
|
|
2913
|
+
return true;
|
|
2914
|
+
}
|
|
2915
|
+
return !!left.name && left.name === right.name;
|
|
2916
|
+
}
|
|
2917
|
+
getMenuItemRoutePath(item) {
|
|
2918
|
+
const navigation = this.extractRouterNavigation(item);
|
|
2919
|
+
if (!navigation?.path) {
|
|
2920
|
+
return null;
|
|
2921
|
+
}
|
|
2922
|
+
return this.normalizeRouterPath(navigation.path);
|
|
2923
|
+
}
|
|
2449
2924
|
sort(items) {
|
|
2450
2925
|
return sortBy(items, [(c) => c.priority ?? 0, (c) => c.text]);
|
|
2451
2926
|
}
|
|
@@ -2501,16 +2976,16 @@ class AXPRootLayoutMenuComponent {
|
|
|
2501
2976
|
* command execution pipeline remains responsible for navigation.
|
|
2502
2977
|
*/
|
|
2503
2978
|
getRouterLink(item) {
|
|
2504
|
-
const
|
|
2505
|
-
if (!
|
|
2979
|
+
const routePath = this.getMenuItemRoutePath(item);
|
|
2980
|
+
if (!routePath) {
|
|
2506
2981
|
return null;
|
|
2507
2982
|
}
|
|
2508
|
-
|
|
2983
|
+
const navigation = this.extractRouterNavigation(item);
|
|
2984
|
+
if (!navigation || !this.isRouterLinkCompatible(navigation)) {
|
|
2509
2985
|
return null;
|
|
2510
2986
|
}
|
|
2511
|
-
const normalizedPath = this.normalizeRouterPath(navigation.path);
|
|
2512
2987
|
try {
|
|
2513
|
-
return this.router.parseUrl(
|
|
2988
|
+
return this.router.parseUrl(routePath);
|
|
2514
2989
|
}
|
|
2515
2990
|
catch (error) {
|
|
2516
2991
|
console.warn('Failed to create router link for menu item.', { item, error });
|
|
@@ -2595,7 +3070,7 @@ class AXPRootLayoutMenuComponent {
|
|
|
2595
3070
|
return lowerPath.startsWith('http://') || lowerPath.startsWith('https://');
|
|
2596
3071
|
}
|
|
2597
3072
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootLayoutMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2598
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPRootLayoutMenuComponent, isStandalone: true, selector: "axp-side-menu", ngImport: i0, template: "<ax-side-menu look=\"pills\" [mode]=\"menuMode()\">\n @let sortedItems = sort(menuStore.items());\n @for (item of sortedItems; track item; let i = $index) {\n <ng-container\n [ngTemplateOutlet]=\"recursiveMenu\"\n [ngTemplateOutletContext]=\"{ item: item, items: sortedItems, index: i }\"\n >\n </ng-container>\n }\n</ax-side-menu>\n<ng-template #recursiveMenu let-item=\"item\" let-items=\"items\" let-index=\"index\">\n @if (item.type == 'group' && menuMode() === 'full') {\n @if (isItemVisible(item)) {\n <ax-title>{{ item.text | translate | async }}</ax-title>\n }\n } @else if (item.type == 'break') {\n @if (shouldShowDivider(item, items, index)) {\n <ax-divider></ax-divider>\n }\n } @else {\n @if (shouldRenderMenuItem(item)) {\n
|
|
3073
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPRootLayoutMenuComponent, isStandalone: true, selector: "axp-side-menu", ngImport: i0, template: "<ax-side-menu look=\"pills\" [mode]=\"menuMode()\">\n @let sortedItems = sort(menuStore.items());\n @for (item of sortedItems; track item; let i = $index) {\n <ng-container\n [ngTemplateOutlet]=\"recursiveMenu\"\n [ngTemplateOutletContext]=\"{ item: item, items: sortedItems, index: i }\"\n >\n </ng-container>\n }\n</ax-side-menu>\n<ng-template #recursiveMenu let-item=\"item\" let-items=\"items\" let-index=\"index\">\n @if (item.type == 'group' && menuMode() === 'full') {\n @if (isItemVisible(item)) {\n <ax-title>{{ item.text | translate | async }}</ax-title>\n }\n } @else if (item.type == 'break') {\n @if (shouldShowDivider(item, items, index)) {\n <ax-divider></ax-divider>\n }\n } @else {\n @if (shouldRenderMenuItem(item)) {\n <ax-side-menu-item\n [attr.id]=\"'axp-menu-item-' + (item.name || item.text)\"\n (onClick)=\"onMenuItemClick(item)\"\n [active]=\"isMenuItemActive(item)\"\n [isCollapsed]=\"!menuStore.isItemOpen(item)\"\n >\n <ax-prefix>\n <ax-icon [class]=\"item.icon\" class=\"fa-fw\"></ax-icon>\n </ax-prefix>\n <span>{{ item.text | translate | async }}</span>\n @if (item.children?.length) {\n <ng-container>\n @let sortedChildren = sort(item.children);\n @for (child of sortedChildren; track child; let childIndex = $index) {\n <ng-container\n [ngTemplateOutlet]=\"recursiveMenu\"\n [ngTemplateOutletContext]=\"{ item: child, items: sortedChildren, index: childIndex }\"\n >\n </ng-container>\n }\n </ng-container>\n }\n <ax-suffix>\n @if (badgeVisible()) {\n <ax-badge [axp-task-badge]=\"getMenuBadge(item)()\" color=\"secondary\"></ax-badge>\n }\n </ax-suffix>\n </ax-side-menu-item>\n }\n }\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: AXSideMenuModule }, { kind: "component", type: i2$3.AXSideMenuComponent, selector: "ax-side-menu", inputs: ["items", "look", "location", "mode"], outputs: ["itemsChange"] }, { kind: "component", type: i2$3.AXSideMenuItemComponent, selector: "ax-side-menu-item", inputs: ["disabled", "text", "active", "isLoading", "isCollapsed", "toggleOnClick", "href", "routerLink", "routerLinkActive", "routerLinkActiveOptions", "target"], outputs: ["textChange", "activeChange", "isLoadingChange", "isCollapsedChange", "onClick"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: AXPTaskBadgeDirective, selector: "[axp-task-badge]", inputs: ["badgeKey", "axp-task-badge"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i1$2.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2599
3074
|
}
|
|
2600
3075
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootLayoutMenuComponent, decorators: [{
|
|
2601
3076
|
type: Component,
|
|
@@ -2606,7 +3081,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
2606
3081
|
AXPTaskBadgeDirective,
|
|
2607
3082
|
AXDecoratorModule,
|
|
2608
3083
|
AXBadgeModule,
|
|
2609
|
-
], template: "<ax-side-menu look=\"pills\" [mode]=\"menuMode()\">\n @let sortedItems = sort(menuStore.items());\n @for (item of sortedItems; track item; let i = $index) {\n <ng-container\n [ngTemplateOutlet]=\"recursiveMenu\"\n [ngTemplateOutletContext]=\"{ item: item, items: sortedItems, index: i }\"\n >\n </ng-container>\n }\n</ax-side-menu>\n<ng-template #recursiveMenu let-item=\"item\" let-items=\"items\" let-index=\"index\">\n @if (item.type == 'group' && menuMode() === 'full') {\n @if (isItemVisible(item)) {\n <ax-title>{{ item.text | translate | async }}</ax-title>\n }\n } @else if (item.type == 'break') {\n @if (shouldShowDivider(item, items, index)) {\n <ax-divider></ax-divider>\n }\n } @else {\n @if (shouldRenderMenuItem(item)) {\n
|
|
3084
|
+
], template: "<ax-side-menu look=\"pills\" [mode]=\"menuMode()\">\n @let sortedItems = sort(menuStore.items());\n @for (item of sortedItems; track item; let i = $index) {\n <ng-container\n [ngTemplateOutlet]=\"recursiveMenu\"\n [ngTemplateOutletContext]=\"{ item: item, items: sortedItems, index: i }\"\n >\n </ng-container>\n }\n</ax-side-menu>\n<ng-template #recursiveMenu let-item=\"item\" let-items=\"items\" let-index=\"index\">\n @if (item.type == 'group' && menuMode() === 'full') {\n @if (isItemVisible(item)) {\n <ax-title>{{ item.text | translate | async }}</ax-title>\n }\n } @else if (item.type == 'break') {\n @if (shouldShowDivider(item, items, index)) {\n <ax-divider></ax-divider>\n }\n } @else {\n @if (shouldRenderMenuItem(item)) {\n <ax-side-menu-item\n [attr.id]=\"'axp-menu-item-' + (item.name || item.text)\"\n (onClick)=\"onMenuItemClick(item)\"\n [active]=\"isMenuItemActive(item)\"\n [isCollapsed]=\"!menuStore.isItemOpen(item)\"\n >\n <ax-prefix>\n <ax-icon [class]=\"item.icon\" class=\"fa-fw\"></ax-icon>\n </ax-prefix>\n <span>{{ item.text | translate | async }}</span>\n @if (item.children?.length) {\n <ng-container>\n @let sortedChildren = sort(item.children);\n @for (child of sortedChildren; track child; let childIndex = $index) {\n <ng-container\n [ngTemplateOutlet]=\"recursiveMenu\"\n [ngTemplateOutletContext]=\"{ item: child, items: sortedChildren, index: childIndex }\"\n >\n </ng-container>\n }\n </ng-container>\n }\n <ax-suffix>\n @if (badgeVisible()) {\n <ax-badge [axp-task-badge]=\"getMenuBadge(item)()\" color=\"secondary\"></ax-badge>\n }\n </ax-suffix>\n </ax-side-menu-item>\n }\n }\n</ng-template>\n" }]
|
|
2610
3085
|
}] });
|
|
2611
3086
|
|
|
2612
3087
|
class AXPHorizontalMenuComponent {
|
|
@@ -2907,12 +3382,11 @@ class AXPRootLayoutComponent {
|
|
|
2907
3382
|
this.contextStore = inject(AXPContextStore);
|
|
2908
3383
|
}
|
|
2909
3384
|
ngOnInit() {
|
|
2910
|
-
|
|
2911
|
-
this.
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
this
|
|
2915
|
-
// Reset the context store
|
|
3385
|
+
this.#syncMenuSelectionByRoute(this.router.url);
|
|
3386
|
+
this.router.events
|
|
3387
|
+
.pipe(filter((event) => event instanceof NavigationEnd), this.unsubscriber.takeUntilDestroy)
|
|
3388
|
+
.subscribe((event) => {
|
|
3389
|
+
this.#syncMenuSelectionByRoute(event.urlAfterRedirects);
|
|
2916
3390
|
this.contextStore.reset();
|
|
2917
3391
|
});
|
|
2918
3392
|
this.eventService.listen(AXPSessionStatus.SignedOut).subscribe(() => {
|
|
@@ -2934,12 +3408,15 @@ class AXPRootLayoutComponent {
|
|
|
2934
3408
|
}
|
|
2935
3409
|
});
|
|
2936
3410
|
}
|
|
3411
|
+
#syncMenuSelectionByRoute(url) {
|
|
3412
|
+
this.menuStore.selectMenuItemByRoute(url);
|
|
3413
|
+
}
|
|
2937
3414
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2938
3415
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPRootLayoutComponent, isStandalone: true, selector: "ng-component", providers: [AXUnsubscriber, AXPContextStore], ngImport: i0, template: `
|
|
2939
|
-
@if(layout.isMenuHorizontal()){
|
|
2940
|
-
|
|
2941
|
-
}@else{
|
|
2942
|
-
|
|
3416
|
+
@if (layout.isMenuHorizontal()) {
|
|
3417
|
+
<axp-root-horizontal-layout></axp-root-horizontal-layout>
|
|
3418
|
+
} @else {
|
|
3419
|
+
<axp-root-vertical-layout></axp-root-vertical-layout>
|
|
2943
3420
|
}
|
|
2944
3421
|
`, isInline: true, dependencies: [{ kind: "component", type: AXPRootHorizontalLayoutComponent, selector: "axp-root-horizontal-layout" }, { kind: "component", type: AXPRootVerticalLayoutComponent, selector: "axp-root-vertical-layout" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2945
3422
|
}
|
|
@@ -2947,10 +3424,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
2947
3424
|
type: Component,
|
|
2948
3425
|
args: [{
|
|
2949
3426
|
template: `
|
|
2950
|
-
@if(layout.isMenuHorizontal()){
|
|
2951
|
-
|
|
2952
|
-
}@else{
|
|
2953
|
-
|
|
3427
|
+
@if (layout.isMenuHorizontal()) {
|
|
3428
|
+
<axp-root-horizontal-layout></axp-root-horizontal-layout>
|
|
3429
|
+
} @else {
|
|
3430
|
+
<axp-root-vertical-layout></axp-root-vertical-layout>
|
|
2954
3431
|
}
|
|
2955
3432
|
`,
|
|
2956
3433
|
encapsulation: ViewEncapsulation.None,
|
|
@@ -2966,57 +3443,226 @@ var rootLayout_component = /*#__PURE__*/Object.freeze({
|
|
|
2966
3443
|
AXPRootLayoutComponent: AXPRootLayoutComponent
|
|
2967
3444
|
});
|
|
2968
3445
|
|
|
3446
|
+
/**
|
|
3447
|
+
* Route reuse strategy that powers both same-route reuse (`reuse` route data) and tabular
|
|
3448
|
+
* navigation. In tabular mode it detaches the leaf page component of an open tab when the user
|
|
3449
|
+
* switches away, caches the live component instance, and reattaches it on return so state such as
|
|
3450
|
+
* data-table selection, scroll position, and unsaved form values is preserved — like browser tabs.
|
|
3451
|
+
*/
|
|
2969
3452
|
class AXPEntityReuseStrategy {
|
|
3453
|
+
constructor() {
|
|
3454
|
+
//#region ---- Services & Dependencies ----
|
|
3455
|
+
this.routeCache = inject(AXPTabRouteCacheRegistry);
|
|
3456
|
+
/** Lazy lookup avoids Router ↔ RouteReuseStrategy construction cycle (NG0200). */
|
|
3457
|
+
this.injector = inject(Injector);
|
|
3458
|
+
//#endregion
|
|
3459
|
+
}
|
|
3460
|
+
//#endregion
|
|
3461
|
+
//#region ---- Detach / Attach ----
|
|
2970
3462
|
shouldDetach(route) {
|
|
2971
|
-
|
|
3463
|
+
if (!this.routeCache.isEnabled() || !this.isTabCacheRoute(route)) {
|
|
3464
|
+
return false;
|
|
3465
|
+
}
|
|
3466
|
+
const scopedKey = this.scopedTabKeyFor(route);
|
|
3467
|
+
const cacheKey = this.routeCacheKeyFor(route);
|
|
3468
|
+
if (!scopedKey || !cacheKey || !this.routeCache.isOpen(scopedKey)) {
|
|
3469
|
+
return false;
|
|
3470
|
+
}
|
|
3471
|
+
// Keep the live component when navigating within the same scoped tab (e.g. chat → chat/:id).
|
|
3472
|
+
return this.isLeavingScopedTab(route);
|
|
3473
|
+
}
|
|
3474
|
+
store(route, handle) {
|
|
3475
|
+
if (!this.routeCache.isEnabled()) {
|
|
3476
|
+
return;
|
|
3477
|
+
}
|
|
3478
|
+
const key = this.routeCacheKeyFor(route);
|
|
3479
|
+
if (!key) {
|
|
3480
|
+
return;
|
|
3481
|
+
}
|
|
3482
|
+
// A null handle is Angular releasing a just-reattached view; drop it without destroying.
|
|
3483
|
+
if (handle) {
|
|
3484
|
+
this.routeCache.store(key, handle);
|
|
3485
|
+
}
|
|
3486
|
+
else {
|
|
3487
|
+
this.routeCache.release(key);
|
|
3488
|
+
}
|
|
2972
3489
|
}
|
|
2973
|
-
store(route, detachedTree) { }
|
|
2974
3490
|
shouldAttach(route) {
|
|
2975
|
-
|
|
3491
|
+
if (!this.routeCache.isEnabled() || !this.isTabCacheRoute(route)) {
|
|
3492
|
+
return false;
|
|
3493
|
+
}
|
|
3494
|
+
const key = this.routeCacheKeyFor(route);
|
|
3495
|
+
return !!key && this.routeCache.has(key);
|
|
2976
3496
|
}
|
|
2977
3497
|
retrieve(route) {
|
|
2978
|
-
|
|
3498
|
+
if (!this.routeCache.isEnabled() || !this.isTabCacheRoute(route)) {
|
|
3499
|
+
return null;
|
|
3500
|
+
}
|
|
3501
|
+
const key = this.routeCacheKeyFor(route);
|
|
3502
|
+
return key ? this.routeCache.retrieve(key) : null;
|
|
2979
3503
|
}
|
|
3504
|
+
//#endregion
|
|
3505
|
+
//#region ---- Reuse Decision ----
|
|
2980
3506
|
shouldReuseRoute(future, curr) {
|
|
2981
|
-
//
|
|
2982
|
-
|
|
2983
|
-
|
|
3507
|
+
// Reuse the single root-layout shell across module navigations so the heavy shell (menus,
|
|
3508
|
+
// header, session subscriptions, theme) is not destroyed and recreated on every route switch.
|
|
3509
|
+
// Uses `routeConfig.data` (the node's own data) so inherited child data does not leak this flag.
|
|
3510
|
+
if (future.routeConfig?.data?.['rootLayout'] === true && curr.routeConfig?.data?.['rootLayout'] === true) {
|
|
3511
|
+
return true;
|
|
2984
3512
|
}
|
|
2985
3513
|
const reuseConfig = future.data?.['reuse'];
|
|
2986
|
-
// If reuse is explicitly false, don't reuse
|
|
2987
3514
|
if (reuseConfig === false) {
|
|
2988
3515
|
return false;
|
|
2989
3516
|
}
|
|
2990
|
-
//
|
|
3517
|
+
// `reuse: true` on sibling routes under the same scoped tab (e.g. chat '' ↔ :id).
|
|
2991
3518
|
if (reuseConfig === true) {
|
|
2992
|
-
|
|
3519
|
+
// Same route node re-activated (e.g. settings `:scope` change reusing its `setting-page`).
|
|
3520
|
+
// Use config reference equality, not path strings: different tabs can share a path (e.g. the
|
|
3521
|
+
// empty-path child of both settings and chat), and once the root-layout shell is reused those
|
|
3522
|
+
// siblings get compared directly — a path-only match would wrongly keep the previous content.
|
|
3523
|
+
if (future.routeConfig && future.routeConfig === curr.routeConfig) {
|
|
3524
|
+
return true;
|
|
3525
|
+
}
|
|
3526
|
+
if (curr.data?.['reuse'] === true) {
|
|
3527
|
+
return axpResolveTabKeyFromSnapshot(future) === axpResolveTabKeyFromSnapshot(curr);
|
|
3528
|
+
}
|
|
3529
|
+
return false;
|
|
3530
|
+
}
|
|
3531
|
+
// Baseline "same route node" check. Reference equality (not path strings) so same-path children
|
|
3532
|
+
// of different reused shells (e.g. the empty-path child of notifications vs comments) are treated
|
|
3533
|
+
// as distinct and their content swaps correctly.
|
|
3534
|
+
if (future.routeConfig !== curr.routeConfig) {
|
|
3535
|
+
return false;
|
|
2993
3536
|
}
|
|
2994
|
-
// Handle string-based reuse strategies
|
|
2995
3537
|
if (typeof reuseConfig === 'string') {
|
|
2996
3538
|
const paramsChanged = this.haveParamsChanged(future, curr);
|
|
2997
3539
|
const queryParamsChanged = this.haveQueryParamsChanged(future, curr);
|
|
2998
3540
|
switch (reuseConfig) {
|
|
2999
3541
|
case 'paramsChange':
|
|
3000
|
-
// Reuse when params change, but destroy if queryParams change
|
|
3001
3542
|
return !queryParamsChanged;
|
|
3002
3543
|
case 'queryParamsChange':
|
|
3003
|
-
// Reuse when queryParams change, but destroy if params change
|
|
3004
3544
|
return !paramsChanged;
|
|
3005
3545
|
case 'paramsOrQueryParamsChange':
|
|
3006
|
-
// Reuse when either params or queryParams change
|
|
3007
3546
|
return true;
|
|
3008
3547
|
default:
|
|
3009
|
-
// Unknown strategy, use default behavior
|
|
3010
3548
|
return true;
|
|
3011
3549
|
}
|
|
3012
3550
|
}
|
|
3013
|
-
// Default behavior: reuse if paths are the same
|
|
3014
3551
|
return true;
|
|
3015
3552
|
}
|
|
3016
|
-
//#
|
|
3553
|
+
//#endregion
|
|
3554
|
+
//#region ---- Helper Methods ----
|
|
3555
|
+
/**
|
|
3556
|
+
* True when this route is the detach/attach target: a routable leaf, or a scoped tab shell
|
|
3557
|
+
* (`data.tab = true`) that owns a nested outlet (e.g. settings page).
|
|
3558
|
+
*/
|
|
3559
|
+
isTabCacheRoute(route) {
|
|
3560
|
+
return this.resolveTabCacheTarget(route) === route;
|
|
3561
|
+
}
|
|
3017
3562
|
/**
|
|
3018
|
-
*
|
|
3563
|
+
* Under a scoped tab, cache the `reuse: true` page shell (settings page) instead of nested outlet
|
|
3564
|
+
* children (setting-view). Otherwise cache the routable leaf (entity pages, chat).
|
|
3019
3565
|
*/
|
|
3566
|
+
resolveTabCacheTarget(route) {
|
|
3567
|
+
const shell = this.findScopedShellRoute(route);
|
|
3568
|
+
if (shell) {
|
|
3569
|
+
// A scoped shell that owns a nested routed outlet (e.g. the settings page, whose `:group`
|
|
3570
|
+
// child renders `setting-view`) cannot be safely detached and reattached: Angular does not
|
|
3571
|
+
// resume the nested child's `effect()`s / change detection after reattach, so dirty tracking
|
|
3572
|
+
// and child content swaps silently stop working. Skip caching these shells — they recreate
|
|
3573
|
+
// fresh on tab return (the active child is preserved via the URL). Flat leaf shells (e.g. the
|
|
3574
|
+
// chat component) have no nested outlet and reattach correctly, so they stay cached.
|
|
3575
|
+
if (this.shellOwnsNestedOutlet(shell)) {
|
|
3576
|
+
return null;
|
|
3577
|
+
}
|
|
3578
|
+
return shell;
|
|
3579
|
+
}
|
|
3580
|
+
if (this.isRoutableLeaf(route)) {
|
|
3581
|
+
return route;
|
|
3582
|
+
}
|
|
3583
|
+
return null;
|
|
3584
|
+
}
|
|
3585
|
+
/** True when the scoped shell route declares child routes (i.e. it hosts a nested outlet). */
|
|
3586
|
+
shellOwnsNestedOutlet(shell) {
|
|
3587
|
+
const config = shell.routeConfig;
|
|
3588
|
+
return !!(config?.children?.length || config?.loadChildren);
|
|
3589
|
+
}
|
|
3590
|
+
/** Nearest ancestor route that declares `data.tab = true`. */
|
|
3591
|
+
findScopedAncestor(route) {
|
|
3592
|
+
for (let index = route.pathFromRoot.length - 1; index >= 0; index--) {
|
|
3593
|
+
const snapshot = route.pathFromRoot[index];
|
|
3594
|
+
if (axpHasTabScope(snapshot.data)) {
|
|
3595
|
+
return snapshot;
|
|
3596
|
+
}
|
|
3597
|
+
}
|
|
3598
|
+
return null;
|
|
3599
|
+
}
|
|
3600
|
+
/**
|
|
3601
|
+
* The innermost `reuse: true` component route between a scoped ancestor and the active route.
|
|
3602
|
+
* Settings: `setting-page` (not `setting-view`). Chat: the active chat child route.
|
|
3603
|
+
*/
|
|
3604
|
+
findScopedShellRoute(route) {
|
|
3605
|
+
const scope = this.findScopedAncestor(route);
|
|
3606
|
+
if (!scope) {
|
|
3607
|
+
return null;
|
|
3608
|
+
}
|
|
3609
|
+
const chain = route.pathFromRoot;
|
|
3610
|
+
const scopeIndex = chain.indexOf(scope);
|
|
3611
|
+
if (scopeIndex < 0) {
|
|
3612
|
+
return null;
|
|
3613
|
+
}
|
|
3614
|
+
let shell = null;
|
|
3615
|
+
for (let index = scopeIndex + 1; index < chain.length; index++) {
|
|
3616
|
+
const snapshot = chain[index];
|
|
3617
|
+
if (snapshot.data?.['reuse'] === true && this.hasRoutableComponent(snapshot)) {
|
|
3618
|
+
shell = snapshot;
|
|
3619
|
+
}
|
|
3620
|
+
}
|
|
3621
|
+
return shell;
|
|
3622
|
+
}
|
|
3623
|
+
isRoutableLeaf(route) {
|
|
3624
|
+
if (route.firstChild) {
|
|
3625
|
+
return false;
|
|
3626
|
+
}
|
|
3627
|
+
return this.hasRoutableComponent(route);
|
|
3628
|
+
}
|
|
3629
|
+
hasRoutableComponent(route) {
|
|
3630
|
+
const config = route.routeConfig;
|
|
3631
|
+
return !!(route.component || config?.component || config?.loadComponent);
|
|
3632
|
+
}
|
|
3633
|
+
/** Cache key — scoped tab path for shells, full leaf path otherwise. */
|
|
3634
|
+
routeCacheKeyFor(route) {
|
|
3635
|
+
if (!this.isTabCacheRoute(route)) {
|
|
3636
|
+
return null;
|
|
3637
|
+
}
|
|
3638
|
+
const path = this.findScopedShellRoute(route) ? axpResolveTabKeyFromSnapshot(route) : axpPathFromSnapshot(route);
|
|
3639
|
+
return axpIsTabEligibleUrl(path) ? path : null;
|
|
3640
|
+
}
|
|
3641
|
+
/** Scoped tab key — matches open tab descriptors (`data.tab = true`). */
|
|
3642
|
+
scopedTabKeyFor(route) {
|
|
3643
|
+
const target = this.resolveTabCacheTarget(route);
|
|
3644
|
+
if (!target) {
|
|
3645
|
+
return null;
|
|
3646
|
+
}
|
|
3647
|
+
const path = axpResolveTabKeyFromSnapshot(target);
|
|
3648
|
+
return axpIsTabEligibleUrl(path) ? path : null;
|
|
3649
|
+
}
|
|
3650
|
+
/** True when the in-flight navigation leaves the scoped tab that owns this route. */
|
|
3651
|
+
isLeavingScopedTab(route) {
|
|
3652
|
+
const currentScoped = axpResolveTabKeyFromSnapshot(route);
|
|
3653
|
+
const router = this.injector.get(Router, null);
|
|
3654
|
+
if (!router) {
|
|
3655
|
+
return true;
|
|
3656
|
+
}
|
|
3657
|
+
const navigation = router.getCurrentNavigation();
|
|
3658
|
+
if (!navigation?.finalUrl) {
|
|
3659
|
+
return true;
|
|
3660
|
+
}
|
|
3661
|
+
const targetPath = router.serializeUrl(navigation.finalUrl).split('?')[0].split('#')[0];
|
|
3662
|
+
const futureScoped = axpResolveTabKeyFromRouteConfig(router.config, targetPath) ??
|
|
3663
|
+
(targetPath.startsWith('/') ? targetPath : `/${targetPath}`);
|
|
3664
|
+
return currentScoped !== futureScoped;
|
|
3665
|
+
}
|
|
3020
3666
|
haveParamsChanged(future, curr) {
|
|
3021
3667
|
const futureParams = future.params;
|
|
3022
3668
|
const currParams = curr.params;
|
|
@@ -3032,9 +3678,6 @@ class AXPEntityReuseStrategy {
|
|
|
3032
3678
|
}
|
|
3033
3679
|
return false;
|
|
3034
3680
|
}
|
|
3035
|
-
/**
|
|
3036
|
-
* Check if query params have changed between current and future routes
|
|
3037
|
-
*/
|
|
3038
3681
|
haveQueryParamsChanged(future, curr) {
|
|
3039
3682
|
const futureQueryParams = future.queryParams;
|
|
3040
3683
|
const currQueryParams = curr.queryParams;
|
|
@@ -3058,6 +3701,7 @@ function routesFacory() {
|
|
|
3058
3701
|
{
|
|
3059
3702
|
path: ':app/modules/:module/:entity',
|
|
3060
3703
|
canActivate: [...AXP_PROTECTED_ROUTE_GUARDS],
|
|
3704
|
+
data: { rootLayout: true },
|
|
3061
3705
|
loadComponent: () => {
|
|
3062
3706
|
return config.viewers.root();
|
|
3063
3707
|
},
|
|
@@ -3113,7 +3757,7 @@ class AXPDefaultThemeModule {
|
|
|
3113
3757
|
viewers: {
|
|
3114
3758
|
root: () => Promise.resolve().then(function () { return rootLayout_component; }).then((c) => c.AXPRootLayoutComponent),
|
|
3115
3759
|
master: {
|
|
3116
|
-
single: () => import('./acorex-platform-themes-default-entity-master-single-view.component-
|
|
3760
|
+
single: () => import('./acorex-platform-themes-default-entity-master-single-view.component-DrUwqKKA.mjs').then((c) => c.AXPEntityMasterSingleViewComponent),
|
|
3117
3761
|
details: () => import('@acorex/platform/layout/views').then((c) => c.AXPLayoutDetailsViewComponent),
|
|
3118
3762
|
///
|
|
3119
3763
|
create: () => import('./acorex-platform-themes-default-entity-master-create-view.component-CWLfNqV0.mjs').then((c) => c.AXPEntityMasterCreateViewComponent),
|
|
@@ -3149,7 +3793,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
3149
3793
|
viewers: {
|
|
3150
3794
|
root: () => Promise.resolve().then(function () { return rootLayout_component; }).then((c) => c.AXPRootLayoutComponent),
|
|
3151
3795
|
master: {
|
|
3152
|
-
single: () => import('./acorex-platform-themes-default-entity-master-single-view.component-
|
|
3796
|
+
single: () => import('./acorex-platform-themes-default-entity-master-single-view.component-DrUwqKKA.mjs').then((c) => c.AXPEntityMasterSingleViewComponent),
|
|
3153
3797
|
details: () => import('@acorex/platform/layout/views').then((c) => c.AXPLayoutDetailsViewComponent),
|
|
3154
3798
|
///
|
|
3155
3799
|
create: () => import('./acorex-platform-themes-default-entity-master-create-view.component-CWLfNqV0.mjs').then((c) => c.AXPEntityMasterCreateViewComponent),
|
|
@@ -3177,5 +3821,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
3177
3821
|
* Generated bundle index. Do not edit.
|
|
3178
3822
|
*/
|
|
3179
3823
|
|
|
3180
|
-
export { AXPDefaultThemeModule, AXPEntityDetailListViewComponent, AXPEntityMasterListViewComponent, AXPRootHorizontalLayoutComponent, AXPRootLayoutComponent, AXPRootLayoutFooterComponent, AXPRootLayoutHeaderComponent, AXPRootLayoutMenuComponent, AXPRootVerticalLayoutComponent };
|
|
3824
|
+
export { AXPDefaultThemeModule, AXPEntityDetailListViewComponent, AXPEntityMasterListViewComponent, AXPRootHorizontalLayoutComponent, AXPRootLayoutComponent, AXPRootLayoutFooterComponent, AXPRootLayoutHeaderComponent, AXPRootLayoutMenuComponent, AXPRootVerticalLayoutComponent, AXPRouteTabBarComponent };
|
|
3181
3825
|
//# sourceMappingURL=acorex-platform-themes-default.mjs.map
|