@acorex-platform/framework-client 2.0.0-next.3 → 2.0.0-next.31
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-framework-client-auth.mjs +8 -9
- package/fesm2022/acorex-platform-framework-client-auth.mjs.map +1 -1
- package/fesm2022/{acorex-platform-framework-client-common-common-settings.provider-ChU2tvyt.mjs → acorex-platform-framework-client-common-common-settings.provider-Biu0_ryw.mjs} +35 -2
- package/fesm2022/acorex-platform-framework-client-common-common-settings.provider-Biu0_ryw.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-common.mjs +1387 -538
- package/fesm2022/acorex-platform-framework-client-common.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-core.mjs +7 -2
- package/fesm2022/acorex-platform-framework-client-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-builder.mjs +20 -0
- package/fesm2022/acorex-platform-framework-client-layout-builder.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-components.mjs +520 -142
- package/fesm2022/acorex-platform-framework-client-layout-components.mjs.map +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-DaOvPoNI.mjs → acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-DmkFxSuJ.mjs} +1084 -223
- package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-DmkFxSuJ.mjs.map +1 -0
- package/fesm2022/{acorex-platform-framework-client-layout-entity-attachments-page.component-BU7KEfyF.mjs → acorex-platform-framework-client-layout-entity-attachments-page.component-BV5WLQVo.mjs} +2 -2
- package/fesm2022/{acorex-platform-framework-client-layout-entity-attachments-page.component-BU7KEfyF.mjs.map → acorex-platform-framework-client-layout-entity-attachments-page.component-BV5WLQVo.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-entity-bulk-entity.command-Boq0MUFK.mjs → acorex-platform-framework-client-layout-entity-bulk-entity.command-O8zdiHRH.mjs} +2 -2
- package/fesm2022/{acorex-platform-framework-client-layout-entity-bulk-entity.command-Boq0MUFK.mjs.map → acorex-platform-framework-client-layout-entity-bulk-entity.command-O8zdiHRH.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-entity-file-list-popup.component-CMoFkzhf.mjs → acorex-platform-framework-client-layout-entity-file-list-popup.component-B3-0gJTQ.mjs} +4 -4
- package/fesm2022/{acorex-platform-framework-client-layout-entity-file-list-popup.component-CMoFkzhf.mjs.map → acorex-platform-framework-client-layout-entity-file-list-popup.component-B3-0gJTQ.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-entity-gallery-page.component-Bre8friL.mjs → acorex-platform-framework-client-layout-entity-gallery-page.component-CjfLUBPZ.mjs} +2 -2
- package/fesm2022/{acorex-platform-framework-client-layout-entity-gallery-page.component-Bre8friL.mjs.map → acorex-platform-framework-client-layout-entity-gallery-page.component-CjfLUBPZ.mjs.map} +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-entity.mjs +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-views.mjs +94 -17
- package/fesm2022/acorex-platform-framework-client-layout-views.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-widget-core.mjs +285 -184
- package/fesm2022/acorex-platform-framework-client-layout-widget-core.mjs.map +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-1UJh0Qj4.mjs → acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-CpmGqDUE.mjs} +1167 -265
- package/fesm2022/acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-CpmGqDUE.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-layout-widgets-filter-default-operators-widget-edit.component-DOEn58--.mjs +103 -0
- package/fesm2022/acorex-platform-framework-client-layout-widgets-filter-default-operators-widget-edit.component-DOEn58--.mjs.map +1 -0
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-SHCgo4UC.mjs → acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-XgjDH9Oc.mjs} +3 -3
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-SHCgo4UC.mjs.map → acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-XgjDH9Oc.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-BYsrp8LT.mjs → acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-DDczHmAA.mjs} +2 -2
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-BYsrp8LT.mjs.map → acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-DDczHmAA.mjs.map} +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-widgets.mjs +1 -1
- package/fesm2022/acorex-platform-framework-client-realtime.mjs +49 -7
- package/fesm2022/acorex-platform-framework-client-realtime.mjs.map +1 -1
- package/fesm2022/{acorex-platform-framework-client-themes-default-entity-master-create-view.component-DwCoz2Du.mjs → acorex-platform-framework-client-themes-default-entity-master-create-view.component-DPU6jTDk.mjs} +8 -2
- package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-create-view.component-DPU6jTDk.mjs.map +1 -0
- package/fesm2022/{acorex-platform-framework-client-themes-default-entity-master-modify-view.component-BCyFK60f.mjs → acorex-platform-framework-client-themes-default-entity-master-modify-view.component-CLdQJ8e8.mjs} +8 -2
- package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-modify-view.component-CLdQJ8e8.mjs.map +1 -0
- package/fesm2022/{acorex-platform-framework-client-themes-default-error-401.component-1lfBpY_d.mjs → acorex-platform-framework-client-themes-default-error-401.component-DszlyIaw.mjs} +5 -11
- package/fesm2022/acorex-platform-framework-client-themes-default-error-401.component-DszlyIaw.mjs.map +1 -0
- package/fesm2022/{acorex-platform-framework-client-themes-default-error-404.component-BeWyRCJr.mjs → acorex-platform-framework-client-themes-default-error-404.component-BusKNAit.mjs} +5 -11
- package/fesm2022/acorex-platform-framework-client-themes-default-error-404.component-BusKNAit.mjs.map +1 -0
- package/fesm2022/{acorex-platform-framework-client-themes-default-error-offline.component-PvveUj5c.mjs → acorex-platform-framework-client-themes-default-error-offline.component-Abf14p44.mjs} +15 -4
- package/fesm2022/acorex-platform-framework-client-themes-default-error-offline.component-Abf14p44.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-themes-default-error-page-go-home-B9VmB9Vt.mjs +19 -0
- package/fesm2022/acorex-platform-framework-client-themes-default-error-page-go-home-B9VmB9Vt.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-themes-default.mjs +306 -129
- package/fesm2022/acorex-platform-framework-client-themes-default.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-themes-shared.mjs +11 -5
- package/fesm2022/acorex-platform-framework-client-themes-shared.mjs.map +1 -1
- package/i18n/en-AU/general.json +32 -4
- package/i18n/en-AU/layout.json +2 -1
- package/i18n/en-AU/platform-layout-widgets.json +7 -1
- package/i18n/en-US/general.json +32 -4
- package/i18n/en-US/layout.json +2 -1
- package/i18n/en-US/platform-layout-widgets.json +7 -1
- package/i18n/fa-IR/general.json +32 -4
- package/i18n/fa-IR/layout.json +2 -1
- package/i18n/fa-IR/platform-layout-widgets.json +7 -1
- package/package.json +6 -6
- package/types/acorex-platform-framework-client-auth.d.ts +21 -11
- package/types/acorex-platform-framework-client-common.d.ts +230 -14
- package/types/acorex-platform-framework-client-layout-components.d.ts +47 -6
- package/types/acorex-platform-framework-client-layout-entity.d.ts +187 -35
- package/types/acorex-platform-framework-client-layout-views.d.ts +15 -0
- package/types/acorex-platform-framework-client-layout-widget-core.d.ts +64 -14
- package/types/acorex-platform-framework-client-layout-widgets.d.ts +145 -9
- package/types/acorex-platform-framework-client-realtime.d.ts +5 -0
- package/types/acorex-platform-framework-client-themes-default.d.ts +16 -5
- package/fesm2022/acorex-platform-framework-client-common-common-settings.provider-ChU2tvyt.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-DaOvPoNI.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-1UJh0Qj4.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-create-view.component-DwCoz2Du.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-modify-view.component-BCyFK60f.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-themes-default-error-401.component-1lfBpY_d.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-themes-default-error-404.component-BeWyRCJr.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-themes-default-error-offline.component-PvveUj5c.mjs.map +0 -1
|
@@ -14,7 +14,7 @@ import { AXDecoratorModule } from '@acorex/components/decorators';
|
|
|
14
14
|
import * as i6 from '@acorex/components/dropdown';
|
|
15
15
|
import { AXDropdownModule } from '@acorex/components/dropdown';
|
|
16
16
|
import { AXDropdownButtonModule } from '@acorex/components/dropdown-button';
|
|
17
|
-
import { AXPTabNavigationService, axpSplitCollapsedBreadcrumbs, AXPStickyDirective, AXPCommonSettings, AXPHomePageService, AXPSettingsService, AXPTabPreviewService, AXPUnsavedChangesConfirmService, AXPBrowserTitleService, AXPEntityDetailsNavTrailService, axpJoinTabTitleSegments, normalizeRouterUrl, AXP_HOME_TAB_KEY, axpResolveTabKey, axpIsEntityListPath, axpParseEntityListRoute, axpGetEntityListReturnUrl, axpIsEntityDetailsPath, axpParseEntityDetailsRoute, axpSetEntityDetailsPageQuery, axpIsEntityDetailsViewRoute, AXPNotFoundError,
|
|
17
|
+
import { AXPTabNavigationService, axpSplitCollapsedBreadcrumbs, AXPStickyDirective, AXPCommonSettings, AXPHomePageService, AXPSettingsService, AXPTabPreviewService, AXPUnsavedChangesConfirmService, AXPBrowserTitleService, AXPEntityDetailsNavTrailService, axpJoinTabTitleSegments, axpGetLeafRouteSnapshot, normalizeRouterUrl, AXP_HOME_TAB_KEY, axpResolveTabKey, axpIsEntityListPath, axpParseEntityListRoute, axpGetEntityListReturnUrl, axpIsEntityDetailsPath, axpParseEntityDetailsRoute, axpSetEntityDetailsPageQuery, axpIsEntityDetailsViewRoute, AXPNotFoundError, axpInTabErrorLocation, AXPUnsavedChangesPopstateService, createUnsavedChangesCanDeactivateGuard } from '@acorex-platform/framework-client/common';
|
|
18
18
|
import * as i9 from '@acorex-platform/framework-client/core';
|
|
19
19
|
import { AXPDeviceService, AXPComponentSlotModule, AXPDebugService, OVERLAY_DETAILS_VIEW_TRACE_NS, AXPExpressionEvaluatorService, AXPContextEvalFactory, normalizeKeyboardShortcuts, AXPContextStore, AXPEntityBroadcastService, AXPKeyboardShortcutRegistry } from '@acorex-platform/framework-client/core';
|
|
20
20
|
import * as i1 from '@acorex/cdk/drawer';
|
|
@@ -30,7 +30,7 @@ import { AXToastService } from '@acorex/components/toast';
|
|
|
30
30
|
import { AXFormatService, AXFormatModule } from '@acorex/core/format';
|
|
31
31
|
import { AXPSessionService } from '@acorex-platform/framework-client/auth';
|
|
32
32
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
33
|
-
import { Router,
|
|
33
|
+
import { Router, ActivatedRoute, NavigationEnd } from '@angular/router';
|
|
34
34
|
import { isEmpty, cloneDeep, get } from 'lodash-es';
|
|
35
35
|
import { filter } from 'rxjs/operators';
|
|
36
36
|
import { AXBasePageComponent } from '@acorex/components/page';
|
|
@@ -263,6 +263,7 @@ class AXPPageLayoutBaseComponent {
|
|
|
263
263
|
this.unsavedChangesConfirm = inject(AXPUnsavedChangesConfirmService);
|
|
264
264
|
this.browserTitleService = inject(AXPBrowserTitleService);
|
|
265
265
|
this.router = inject(Router);
|
|
266
|
+
this.pageLayoutRoute = inject(ActivatedRoute);
|
|
266
267
|
this.navTrailService = inject(AXPEntityDetailsNavTrailService);
|
|
267
268
|
this.pageLayoutDestroyRef = inject(DestroyRef);
|
|
268
269
|
//#endregion
|
|
@@ -324,7 +325,7 @@ class AXPPageLayoutBaseComponent {
|
|
|
324
325
|
this.title.set(await this.getPageTitle());
|
|
325
326
|
const icon = await this.getPageIcon();
|
|
326
327
|
this.titleIcon.set(icon);
|
|
327
|
-
if (this.tabNavigation.effectiveMode() === 'tabular') {
|
|
328
|
+
if (this.tabNavigation.effectiveMode() === 'tabular' && this.canPublishActiveTabChrome()) {
|
|
328
329
|
const tabKey = this.pageTabKey();
|
|
329
330
|
if (tabKey && icon) {
|
|
330
331
|
this.tabNavigation.syncTabIcon(tabKey, icon);
|
|
@@ -410,15 +411,30 @@ class AXPPageLayoutBaseComponent {
|
|
|
410
411
|
if (isActiveForNavTrail && this.isActivePageForNavTrail()) {
|
|
411
412
|
this.navTrailService.setActiveTrail(breadCrumbs);
|
|
412
413
|
}
|
|
413
|
-
if (this.tabNavigation.effectiveMode() === 'tabular') {
|
|
414
|
+
if (this.tabNavigation.effectiveMode() === 'tabular' && this.canPublishActiveTabChrome()) {
|
|
414
415
|
const tabKey = this.pageTabKey();
|
|
415
|
-
const
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
416
|
+
const routeTabTitle = await Promise.resolve(this.getRouteTabTitle());
|
|
417
|
+
if (!tabKey || this.pageTabKey() !== tabKey || this.tabNavigation.activeKey() !== tabKey) {
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
if (typeof routeTabTitle === 'string' && routeTabTitle.trim()) {
|
|
421
|
+
this.tabNavigation.syncTabTitle(tabKey, routeTabTitle.trim());
|
|
419
422
|
}
|
|
420
|
-
if (
|
|
421
|
-
this.tabNavigation.syncTabTitle(tabKey,
|
|
423
|
+
else if (Array.isArray(routeTabTitle) && routeTabTitle.length) {
|
|
424
|
+
this.tabNavigation.syncTabTitle(tabKey, routeTabTitle);
|
|
425
|
+
}
|
|
426
|
+
else {
|
|
427
|
+
const tabTitleSegments = await this.resolveBreadcrumbTabTitleSegments(breadCrumbs);
|
|
428
|
+
let tabTitle = tabTitleSegments.length ? axpJoinTabTitleSegments(tabTitleSegments) : null;
|
|
429
|
+
if (!tabTitle) {
|
|
430
|
+
tabTitle = await this.resolvePageTitleForTab();
|
|
431
|
+
}
|
|
432
|
+
if (this.pageTabKey() !== tabKey || this.tabNavigation.activeKey() !== tabKey) {
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
if (tabTitle) {
|
|
436
|
+
this.tabNavigation.syncTabTitle(tabKey, tabTitleSegments.length ? tabTitleSegments : tabTitle);
|
|
437
|
+
}
|
|
422
438
|
}
|
|
423
439
|
}
|
|
424
440
|
}, /* @ts-ignore */
|
|
@@ -507,9 +523,35 @@ class AXPPageLayoutBaseComponent {
|
|
|
507
523
|
this.router.events
|
|
508
524
|
.pipe(filter((event) => event instanceof NavigationEnd), takeUntilDestroyed(this.pageLayoutDestroyRef))
|
|
509
525
|
.subscribe(() => {
|
|
526
|
+
this.syncOwnedPageTabKey();
|
|
510
527
|
void this.publishBrowserTitleIfActive();
|
|
511
528
|
});
|
|
512
529
|
}
|
|
530
|
+
/**
|
|
531
|
+
* Follows the scoped tab when this instance is the active route (settings scope changes).
|
|
532
|
+
* Cached background pages keep the key captured at init.
|
|
533
|
+
*/
|
|
534
|
+
syncOwnedPageTabKey() {
|
|
535
|
+
if (this.tabNavigation.effectiveMode() !== 'tabular' || !this.isOwningActiveRoute()) {
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
const nextKey = this.resolvePageTabKey();
|
|
539
|
+
if (nextKey !== this.pageTabKey()) {
|
|
540
|
+
this.pageTabKey.set(nextKey);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
/** True when this page's route snapshot is in the active router tree. */
|
|
544
|
+
isOwningActiveRoute() {
|
|
545
|
+
const own = this.pageLayoutRoute.snapshot;
|
|
546
|
+
const leaf = axpGetLeafRouteSnapshot(this.router.routerState.snapshot.root);
|
|
547
|
+
return leaf.pathFromRoot.includes(own);
|
|
548
|
+
}
|
|
549
|
+
/** True when this page may publish chrome onto its route tab. */
|
|
550
|
+
canPublishActiveTabChrome() {
|
|
551
|
+
const pageKey = this.pageTabKey();
|
|
552
|
+
const activeKey = this.tabNavigation.activeKey();
|
|
553
|
+
return !!pageKey && !!activeKey && pageKey === activeKey;
|
|
554
|
+
}
|
|
513
555
|
/** Maps the home-page route to the pinned home tab key instead of a path-based key. */
|
|
514
556
|
resolvePageTabKey() {
|
|
515
557
|
const homePath = this.homePageService.getCurrent().path;
|
|
@@ -632,6 +674,13 @@ class AXPPageLayoutBaseComponent {
|
|
|
632
674
|
getPageBreadcrumbs() {
|
|
633
675
|
return [];
|
|
634
676
|
}
|
|
677
|
+
/**
|
|
678
|
+
* Route-tab label for this page. Return a scope title when child routes are internal
|
|
679
|
+
* (settings groups). Null keeps the breadcrumb / page-title fallback.
|
|
680
|
+
*/
|
|
681
|
+
getRouteTabTitle() {
|
|
682
|
+
return null;
|
|
683
|
+
}
|
|
635
684
|
/** Collects resolved breadcrumb labels (Home excluded upstream) for tab chrome. */
|
|
636
685
|
async resolveBreadcrumbTabTitleSegments(pageBreadcrumbs) {
|
|
637
686
|
const segments = [];
|
|
@@ -1118,11 +1167,25 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
|
|
|
1118
1167
|
let pageActivationChain = Promise.resolve();
|
|
1119
1168
|
/** Serializes route-driven adapter loads (initial navigation and layout refresh). */
|
|
1120
1169
|
let routeLoadChain = Promise.resolve();
|
|
1170
|
+
/** Invalidates a queued load once this component's route changes or a newer load starts. */
|
|
1171
|
+
let routeLoadGeneration = 0;
|
|
1172
|
+
const routePath = () => {
|
|
1173
|
+
const tree = router.createUrlTree([], { relativeTo: route });
|
|
1174
|
+
return router.serializeUrl(tree).split('?')[0]?.split('#')[0] ?? '';
|
|
1175
|
+
};
|
|
1121
1176
|
/** `page` query param from the browser URL (reliable on hard refresh). */
|
|
1122
1177
|
const readPageQueryParam = () => {
|
|
1123
1178
|
const page = router.parseUrl(router.url).queryParams['page'];
|
|
1124
1179
|
return typeof page === 'string' && page.length > 0 ? page : null;
|
|
1125
1180
|
};
|
|
1181
|
+
/** Keep caller history state (for example related-list field hides) across in-page navigations. */
|
|
1182
|
+
const callerNavigationState = () => {
|
|
1183
|
+
if (typeof history === 'undefined' || history.state == null || typeof history.state !== 'object') {
|
|
1184
|
+
return undefined;
|
|
1185
|
+
}
|
|
1186
|
+
const { navigationId: _navigationId, ...rest } = history.state;
|
|
1187
|
+
return Object.keys(rest).length > 0 ? rest : undefined;
|
|
1188
|
+
};
|
|
1126
1189
|
/** Loads page data, context, and evaluated widgets for the target sidebar page. */
|
|
1127
1190
|
const activatePageById = async (pageId, forceRefresh) => {
|
|
1128
1191
|
const activation = pageActivationChain.then(() => runPageActivation(pageId, forceRefresh));
|
|
@@ -1391,16 +1454,24 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
|
|
|
1391
1454
|
queryParams: { page: resolvedPage.id },
|
|
1392
1455
|
queryParamsHandling: 'merge',
|
|
1393
1456
|
replaceUrl: true,
|
|
1457
|
+
...(callerNavigationState() ? { state: callerNavigationState() } : {}),
|
|
1394
1458
|
});
|
|
1395
1459
|
}
|
|
1396
1460
|
await this.loadPage(pageId, forceRefresh);
|
|
1397
1461
|
},
|
|
1398
1462
|
async loadFromRoute(forceRefresh, reason = 'unspecified') {
|
|
1463
|
+
const generation = ++routeLoadGeneration;
|
|
1464
|
+
const moduleName = route.parent?.snapshot.paramMap.get('module');
|
|
1465
|
+
const entityName = route.snapshot.paramMap.get('entity');
|
|
1466
|
+
const id = route.snapshot.paramMap.get('id');
|
|
1467
|
+
const requestUrl = router.serializeUrl(router.createUrlTree([], { relativeTo: route }));
|
|
1468
|
+
const requestPath = requestUrl.split('?')[0]?.split('#')[0] ?? '';
|
|
1469
|
+
const requestStillOwnsThisPage = () => generation === routeLoadGeneration &&
|
|
1470
|
+
route.parent?.snapshot.paramMap.get('module') === moduleName &&
|
|
1471
|
+
route.snapshot.paramMap.get('entity') === entityName &&
|
|
1472
|
+
route.snapshot.paramMap.get('id') === id;
|
|
1399
1473
|
const run = async () => {
|
|
1400
1474
|
const pageIdFromUrl = readPageQueryParam() ?? undefined;
|
|
1401
|
-
const moduleName = route.parent?.snapshot.paramMap.get('module');
|
|
1402
|
-
const entityName = route.snapshot.paramMap.get('entity');
|
|
1403
|
-
const id = route.snapshot.paramMap.get('id');
|
|
1404
1475
|
AXPDebugService.instance?.trace(DETAILS_VIEW_PAGE_TRACE_NS, 'viewmodel', 'loadFromRoute start', () => ({
|
|
1405
1476
|
moduleName,
|
|
1406
1477
|
entityName,
|
|
@@ -1410,7 +1481,7 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
|
|
|
1410
1481
|
reason,
|
|
1411
1482
|
note: 'Entity/route load started',
|
|
1412
1483
|
}));
|
|
1413
|
-
if (!moduleName || !entityName || !id) {
|
|
1484
|
+
if (!moduleName || !entityName || !id || !requestStillOwnsThisPage()) {
|
|
1414
1485
|
return;
|
|
1415
1486
|
}
|
|
1416
1487
|
layout.setNavigationLoading(true);
|
|
@@ -1436,7 +1507,10 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
|
|
|
1436
1507
|
}));
|
|
1437
1508
|
layout.setOverlayLoading(false);
|
|
1438
1509
|
if (error instanceof AXPNotFoundError) {
|
|
1439
|
-
|
|
1510
|
+
const currentPath = router.url.split('?')[0]?.split('#')[0] ?? '';
|
|
1511
|
+
if (requestStillOwnsThisPage() && currentPath === requestPath && routePath() === requestPath) {
|
|
1512
|
+
void router.navigateByUrl(axpInTabErrorLocation('404', requestUrl));
|
|
1513
|
+
}
|
|
1440
1514
|
return;
|
|
1441
1515
|
}
|
|
1442
1516
|
throw error;
|
|
@@ -1531,6 +1605,7 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
|
|
|
1531
1605
|
queryParams: { page: page.id, filters: null },
|
|
1532
1606
|
queryParamsHandling: 'merge',
|
|
1533
1607
|
replaceUrl: false,
|
|
1608
|
+
...(callerNavigationState() ? { state: callerNavigationState() } : {}),
|
|
1534
1609
|
});
|
|
1535
1610
|
}
|
|
1536
1611
|
void activatePageById(page.id);
|
|
@@ -1549,6 +1624,7 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
|
|
|
1549
1624
|
queryParamsHandling: 'merge',
|
|
1550
1625
|
// Push history for desktop sidebar switches and mobile page-list picks.
|
|
1551
1626
|
replaceUrl: false,
|
|
1627
|
+
...(callerNavigationState() ? { state: callerNavigationState() } : {}),
|
|
1552
1628
|
});
|
|
1553
1629
|
return;
|
|
1554
1630
|
}
|
|
@@ -1568,6 +1644,7 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
|
|
|
1568
1644
|
relativeTo: route,
|
|
1569
1645
|
queryParams: currentParams,
|
|
1570
1646
|
replaceUrl: true,
|
|
1647
|
+
...(callerNavigationState() ? { state: callerNavigationState() } : {}),
|
|
1571
1648
|
});
|
|
1572
1649
|
}
|
|
1573
1650
|
}
|
|
@@ -3302,7 +3379,7 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
3302
3379
|
useExisting: AXPLayoutDetailsViewComponent,
|
|
3303
3380
|
},
|
|
3304
3381
|
AXPLayoutDetailsViewViewModel,
|
|
3305
|
-
], viewQueries: [{ propertyName: "form", first: true, predicate: ["form"], descendants: true, isSignal: true }, { propertyName: "widgetContainer", first: true, predicate: AXPWidgetContainerComponent, descendants: true, isSignal: true }, { propertyName: "sidebarTabs", first: true, predicate: ["sidebarTabs"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<axp-page-layout *translate=\"let t\">\n @if (vm.adapter()?.pages?.length! > 1 && vm.isLarge()) {\n <axp-layout-start-side>\n <axp-layout-header>\n <axp-layout-title>{{\n formatPageLabel(\n vm.showPages()\n ? (vm.adapter()?.title ?? '')\n : (vm.adapter()?.label ?? '')\n )\n | translate\n | async\n }}</axp-layout-title>\n <axp-layout-description>{{\n formatPageLabel(vm.adapter()?.description ?? '')\n | translate\n | async\n }}</axp-layout-description>\n </axp-layout-header>\n <axp-layout-content>\n <ax-tabs\n #sidebarTabs\n class=\"axp-vertical-tabs\"\n [look]=\"'with-line-color'\"\n [location]=\"'end'\"\n [fitParent]=\"true\"\n (onActiveTabChanged)=\"handleSidebarTabChanged($event)\"\n >\n @for (item of vm.adapter()?.pages; track item.id) {\n <ax-tab-item\n [key]=\"item.id\"\n [text]=\"(formatPageLabel(item.label) | translate | async)!\"\n [active]=\"vm.currentPage()?.id === item.id\"\n >\n <ax-prefix>\n <ax-icon icon=\"far ${{ item.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n }\n </ax-tabs>\n </axp-layout-content>\n </axp-layout-start-side>\n }\n <!-- Content Section -->\n <axp-page-content\n class=\"flex flex-row gap-4\"\n [class.axp-details-page-list]=\"isEntityListPage()\"\n >\n @if (vm.showPages()) {\n <axp-layout-list class=\"w-full\">\n @for (item of vm.adapter()?.pages; track $index) {\n <axp-layout-list-item (click)=\"handleSelectPage(item)\">\n <axp-layout-prefix>\n <ax-icon\n icon=\"far ${{ item.icon }}\"\n class=\"text-gray-500\"\n ></ax-icon>\n </axp-layout-prefix>\n <axp-layout-content>\n <a class=\"font-semibold\">{{\n formatPageLabel(item.label) | translate | async\n }}</a>\n </axp-layout-content>\n <axp-layout-suffix>\n <ax-icon\n icon=\" far fa-chevron-right\"\n class=\"text-gray-400\"\n ></ax-icon>\n </axp-layout-suffix>\n </axp-layout-list-item>\n }\n </axp-layout-list>\n } @else {\n <ax-form class=\"h-full w-full\" #form>\n <axp-widgets-container\n #widgetsContainerRef\n [context]=\"vm.context()\"\n (onContextChanged)=\"handleOnContextChanged($event)\"\n >\n <div class=\"flex h-full min-h-0 w-full flex-col\">\n @for (\n item of vm.currentPageContent();\n track pageContentTrackKey($any(item), $index)\n ) {\n @if ('type' in item && item.type === 'component') {\n <!-- Component-based content -->\n <div\n axp-page-component-renderer\n [componentKey]=\"$any(item).componentKey\"\n [rootContext]=\"vm.rootContext()\"\n [pageConfig]=\"$any(item).pageConfig\"\n [options]=\"$any(item).options\"\n (componentReady)=\"recompute()\"\n ></div>\n } @else {\n <!-- Widget-based content -->\n <ng-container\n axp-widget-renderer\n [node]=\"$any(item)\"\n [mode]=\"$any(item).mode ?? 'view'\"\n ></ng-container>\n }\n }\n @if (vm.currentPage()?.tabs?.length) {\n <div class=\"axp-horizontal-tabs\">\n <ax-tabs\n [location]=\"'bottom'\"\n [fitParent]=\"false\"\n look=\"classic\"\n >\n @for (tab of vm.currentPageTabs(); track $index) {\n <ax-tab-item\n (onClick)=\"vm.setCurrentTab(tab)\"\n [text]=\"(tab.title | translate | async)!\"\n [active]=\"vm.currentTab()?.id === tab.id\"\n >\n <ax-prefix>\n <ax-icon icon=\"far ${{ tab.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n }\n </ax-tabs>\n <div class=\"content\">\n @if (vm.currentTab()) {\n @for (\n content of vm.activeTabContent();\n track content.name\n ) {\n <ng-container\n axp-widget-renderer\n [node]=\"content\"\n [mode]=\"content.mode ?? 'view'\"\n >\n </ng-container>\n }\n }\n </div>\n </div>\n }\n </div>\n </axp-widgets-container>\n <ax-validation-summary\n [displayMode]=\"'toast'\"\n [autoHide]=\"true\"\n ></ax-validation-summary>\n </ax-form>\n }\n </axp-page-content>\n\n <!-- Footer Section -->\n @if (hasFooter()) {\n <axp-page-footer class=\"--animated\">\n <axp-layout-suffix>\n <!-- secondary footer actions -->\n @if (hasVisibleFooterSecondaryActions()) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [iconOnly]=\"deviceService.isSmall()\"\n [text]=\"'@general:terms.interface.actions' | translate | async\"\n [look]=\"deviceService.isSmall() ? 'blank' : 'solid'\"\n [color]=\"'default'\"\n >\n <ax-prefix>\n <i class=\"fa-solid fa-ellipsis-vertical\"></i>\n </ax-prefix>\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (action of footerSecondaryActions(); track $index) {\n @if (isFooterActionVisible(action)) {\n <ax-button-item\n [text]=\"(t(action.title) | async)!\"\n [color]=\"action.color\"\n [disabled]=\"isFooterActionDisabled(action)\"\n (onClick)=\"execute(action.command!)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light {{ action.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n @if (action.break) {\n <ax-divider></ax-divider>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n\n @if (hasVisibleFooterPrimaryActions()) {\n @if (showSaveDiscardFooter()) {\n @if (rejectFooterCommand(); as reject) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [disabled]=\"vm.isOverlayBusy()\"\n [text]=\"(t(reject.title) | async)!\"\n [look]=\"'solid'\"\n [color]=\"reject.color\"\n (onClick)=\"execute(reject.command)\"\n >\n <ax-prefix>\n <i class=\"{{ reject.icon }}\"></i>\n </ax-prefix>\n </ax-button>\n }\n @if (acceptFooterCommand(); as accept) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [disabled]=\"vm.isOverlayBusy()\"\n [text]=\"(t(accept.title) | async)!\"\n [look]=\"'solid'\"\n [color]=\"accept.color\"\n (onClick)=\"execute(accept.command)\"\n >\n <ax-prefix>\n <i class=\"{{ accept.icon }}\"></i>\n </ax-prefix>\n </ax-button>\n }\n }\n @for (action of footerPrimaryActions(); track $index) {\n @if (isFooterActionVisible(action)) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [disabled]=\"isFooterActionDisabled(action)\"\n [text]=\"(t(action.title) | async)!\"\n [look]=\"'solid'\"\n [color]=\"action.color\"\n (onClick)=\"execute(action.command!)\"\n >\n <ax-prefix>\n <i class=\"{{ action.icon }}\"></i>\n </ax-prefix>\n @if (action?.items) {\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (sub of action?.items; track $index) {\n @if (isFooterActionVisible(sub)) {\n <ax-button-item\n [text]=\"(t(sub.title) | async)!\"\n [color]=\"sub.color\"\n [disabled]=\"isFooterActionDisabled(sub)\"\n (onClick)=\"execute(sub.command!)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light {{ sub.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n @if (sub.break) {\n <ax-divider></ax-divider>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n }\n </ax-button>\n }\n }\n }\n </axp-layout-suffix>\n </axp-page-footer>\n }\n</axp-page-layout>\n", styles: ["@layer properties;axp-layout-details-view .axp-vertical-tabs ax-tab-item{margin-block:0px;border-radius:0!important;padding-block:calc(var(--spacing, .25rem) * 3);--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}axp-layout-details-view .axp-vertical-tabs ax-tab-item>div{display:flex;align-items:center}axp-layout-details-view .axp-vertical-tabs ax-tab-item>div .tab-item-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}axp-layout-details-view .axp-horizontal-tabs{display:flex;width:100%;flex-direction:column}axp-layout-details-view .axp-horizontal-tabs .content{margin-block:calc(var(--spacing, .25rem) * 4);display:block;width:100%}axp-layout-details-view axp-layout-section axp-layout-content{display:flex;width:100%;flex-direction:column}:where(axp-layout-details-view axp-layout-section axp-layout-content>:not(:last-child)){--tw-divide-y-reverse: 0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(axp-layout-details-view axp-layout-section axp-layout-content>:not(:last-child)){--tw-border-style: dashed;border-style:dashed}:where(axp-layout-details-view axp-layout-section axp-layout-content>:not(:last-child)){border-color:var(--color-gray-200, oklch(92.8% .006 264.531))}axp-layout-details-view axp-layout-section axp-layout-content .--item-container{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));align-items:center;gap:calc(var(--spacing, .25rem) * 4);padding-inline:calc(var(--spacing, .25rem) * 4);padding-block:calc(var(--spacing, .25rem) * 4)}@media(width>=64rem){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-inline:calc(var(--spacing, .25rem) * 6)}}@media(width>=80rem){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-inline:calc(var(--spacing, .25rem) * 8)}}@media(width>=96rem){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-inline:calc(var(--spacing, .25rem) * 10)}}axp-layout-details-view axp-layout-section axp-layout-content .--item-container axp-layout-description{margin-top:calc(var(--spacing, .25rem) * 2);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)))}axp-layout-details-view axp-page-content ax-form form{height:100%}axp-layout-details-view:has(axp-page-content.axp-details-page-list) axp-page-layout>axp-layout-container{overflow:hidden}axp-layout-details-view axp-page-content.axp-details-page-list{display:flex;min-height:0px;flex-direction:column;overflow:hidden}axp-layout-details-view axp-page-content.axp-details-page-list>ax-form,axp-layout-details-view axp-page-content.axp-details-page-list ax-form form,axp-layout-details-view axp-page-content.axp-details-page-list ax-form form>div,axp-layout-details-view axp-page-content.axp-details-page-list .axp-entity-list,axp-layout-details-view axp-page-content.axp-details-page-list .axp-entity-list-body,axp-layout-details-view axp-page-content.axp-details-page-list axp-data-list-widget-view{display:flex;min-height:0px;flex:1;flex-direction:column;height:100%}axp-layout-details-view axp-page-content.axp-details-page-list axp-data-list-widget-view{min-height:0!important}axp-layout-details-view axp-page-content.axp-details-page-list ax-data-table{min-height:0px;flex:1;height:100%}axp-layout-details-view .axp-entity-list ax-data-table .ax-data-table-wrapper:has(tfoot) table{height:100%}axp-layout-details-view .axp-entity-list ax-data-table .ax-data-table-wrapper:has(tfoot) table tbody tr.empty-row{height:100%!important}axp-layout-details-view axp-layout-start-side{border-inline-end-style:var(--tw-border-style);border-inline-end-width:1px}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-divide-y-reverse{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-divide-y-reverse: 0;--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type:
|
|
3382
|
+
], viewQueries: [{ propertyName: "form", first: true, predicate: ["form"], descendants: true, isSignal: true }, { propertyName: "widgetContainer", first: true, predicate: AXPWidgetContainerComponent, descendants: true, isSignal: true }, { propertyName: "sidebarTabs", first: true, predicate: ["sidebarTabs"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<axp-page-layout *translate=\"let t\">\n @if (vm.adapter()?.pages?.length! > 1 && vm.isLarge()) {\n <axp-layout-start-side>\n <axp-layout-header>\n <axp-layout-title>{{\n formatPageLabel(\n vm.showPages()\n ? (vm.adapter()?.title ?? '')\n : (vm.adapter()?.label ?? '')\n )\n | translate\n | async\n }}</axp-layout-title>\n <axp-layout-description>{{\n formatPageLabel(vm.adapter()?.description ?? '')\n | translate\n | async\n }}</axp-layout-description>\n </axp-layout-header>\n <axp-layout-content>\n <ax-tabs\n #sidebarTabs\n class=\"axp-vertical-tabs\"\n [look]=\"'with-line-color'\"\n [location]=\"'end'\"\n [fitParent]=\"true\"\n (onActiveTabChanged)=\"handleSidebarTabChanged($event)\"\n >\n @for (item of vm.adapter()?.pages; track item.id) {\n <ax-tab-item\n [key]=\"item.id\"\n [text]=\"(formatPageLabel(item.label) | translate | async)!\"\n [active]=\"vm.currentPage()?.id === item.id\"\n >\n <ax-prefix>\n <ax-icon icon=\"far ${{ item.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n }\n </ax-tabs>\n </axp-layout-content>\n </axp-layout-start-side>\n }\n <!-- Content Section -->\n <axp-page-content\n class=\"flex flex-row gap-4\"\n [class.axp-details-page-list]=\"isEntityListPage()\"\n >\n @if (vm.showPages()) {\n <axp-layout-list class=\"w-full\">\n @for (item of vm.adapter()?.pages; track $index) {\n <axp-layout-list-item (click)=\"handleSelectPage(item)\">\n <axp-layout-prefix>\n <ax-icon\n icon=\"far ${{ item.icon }}\"\n class=\"text-gray-500\"\n ></ax-icon>\n </axp-layout-prefix>\n <axp-layout-content>\n <a class=\"font-semibold\">{{\n formatPageLabel(item.label) | translate | async\n }}</a>\n </axp-layout-content>\n <axp-layout-suffix>\n <ax-icon\n icon=\" far fa-chevron-right\"\n class=\"text-gray-400\"\n ></ax-icon>\n </axp-layout-suffix>\n </axp-layout-list-item>\n }\n </axp-layout-list>\n } @else {\n <ax-form class=\"h-full w-full\" #form>\n <axp-widgets-container\n #widgetsContainerRef\n [context]=\"vm.context()\"\n (onContextChanged)=\"handleOnContextChanged($event)\"\n >\n <div class=\"flex h-full min-h-0 w-full flex-col\">\n @for (\n item of vm.currentPageContent();\n track pageContentTrackKey($any(item), $index)\n ) {\n @if ('type' in item && item.type === 'component') {\n <!-- Component-based content -->\n <div\n axp-page-component-renderer\n [componentKey]=\"$any(item).componentKey\"\n [rootContext]=\"vm.rootContext()\"\n [pageConfig]=\"$any(item).pageConfig\"\n [options]=\"$any(item).options\"\n (componentReady)=\"recompute()\"\n ></div>\n } @else {\n <!-- Widget-based content -->\n <ng-container\n axp-widget-renderer\n [node]=\"$any(item)\"\n [mode]=\"$any(item).mode ?? 'view'\"\n ></ng-container>\n }\n }\n @if (vm.currentPage()?.tabs?.length) {\n <div class=\"axp-horizontal-tabs\">\n <ax-tabs\n [location]=\"'bottom'\"\n [fitParent]=\"false\"\n look=\"classic\"\n >\n @for (tab of vm.currentPageTabs(); track $index) {\n <ax-tab-item\n (onClick)=\"vm.setCurrentTab(tab)\"\n [text]=\"(tab.title | translate | async)!\"\n [active]=\"vm.currentTab()?.id === tab.id\"\n >\n <ax-prefix>\n <ax-icon icon=\"far ${{ tab.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n }\n </ax-tabs>\n <div class=\"content\">\n @if (vm.currentTab()) {\n @for (\n content of vm.activeTabContent();\n track content.name\n ) {\n <ng-container\n axp-widget-renderer\n [node]=\"content\"\n [mode]=\"content.mode ?? 'view'\"\n >\n </ng-container>\n }\n }\n </div>\n </div>\n }\n </div>\n </axp-widgets-container>\n <ax-validation-summary\n [displayMode]=\"'toast'\"\n [autoHide]=\"true\"\n ></ax-validation-summary>\n </ax-form>\n }\n </axp-page-content>\n\n <!-- Footer Section -->\n @if (hasFooter()) {\n <axp-page-footer class=\"--animated\">\n <axp-layout-suffix>\n <!-- secondary footer actions -->\n @if (hasVisibleFooterSecondaryActions()) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [iconOnly]=\"deviceService.isSmall()\"\n [text]=\"'@general:terms.interface.actions' | translate | async\"\n [look]=\"deviceService.isSmall() ? 'blank' : 'solid'\"\n [color]=\"'default'\"\n >\n <ax-prefix>\n <i class=\"fa-solid fa-ellipsis-vertical\"></i>\n </ax-prefix>\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (action of footerSecondaryActions(); track $index) {\n @if (isFooterActionVisible(action)) {\n <ax-button-item\n [text]=\"(t(action.title) | async)!\"\n [color]=\"action.color\"\n [disabled]=\"isFooterActionDisabled(action)\"\n (onClick)=\"execute(action.command!)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light {{ action.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n @if (action.break) {\n <ax-divider></ax-divider>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n\n @if (hasVisibleFooterPrimaryActions()) {\n @if (showSaveDiscardFooter()) {\n @if (rejectFooterCommand(); as reject) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [disabled]=\"vm.isOverlayBusy()\"\n [text]=\"(t(reject.title) | async)!\"\n [look]=\"'solid'\"\n [color]=\"reject.color\"\n (onClick)=\"execute(reject.command)\"\n >\n <ax-prefix>\n <i class=\"{{ reject.icon }}\"></i>\n </ax-prefix>\n </ax-button>\n }\n @if (acceptFooterCommand(); as accept) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [disabled]=\"vm.isOverlayBusy()\"\n [text]=\"(t(accept.title) | async)!\"\n [look]=\"'solid'\"\n [color]=\"accept.color\"\n (onClick)=\"execute(accept.command)\"\n >\n <ax-prefix>\n <i class=\"{{ accept.icon }}\"></i>\n </ax-prefix>\n </ax-button>\n }\n }\n @for (action of footerPrimaryActions(); track $index) {\n @if (isFooterActionVisible(action)) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [disabled]=\"isFooterActionDisabled(action)\"\n [text]=\"(t(action.title) | async)!\"\n [look]=\"'solid'\"\n [color]=\"action.color\"\n (onClick)=\"execute(action.command!)\"\n >\n <ax-prefix>\n <i class=\"{{ action.icon }}\"></i>\n </ax-prefix>\n @if (action?.items) {\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (sub of action?.items; track $index) {\n @if (isFooterActionVisible(sub)) {\n <ax-button-item\n [text]=\"(t(sub.title) | async)!\"\n [color]=\"sub.color\"\n [disabled]=\"isFooterActionDisabled(sub)\"\n (onClick)=\"execute(sub.command!)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light {{ sub.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n @if (sub.break) {\n <ax-divider></ax-divider>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n }\n </ax-button>\n }\n }\n }\n </axp-layout-suffix>\n </axp-page-footer>\n }\n</axp-page-layout>\n", styles: ["@layer properties;axp-layout-details-view .axp-vertical-tabs ax-tab-item{margin-block:0px;border-radius:0!important;padding-block:calc(var(--spacing, .25rem) * 3);--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}axp-layout-details-view .axp-vertical-tabs ax-tab-item>div{display:flex;align-items:center}axp-layout-details-view .axp-vertical-tabs ax-tab-item>div .tab-item-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}axp-layout-details-view .axp-horizontal-tabs{margin-top:calc(var(--spacing, .25rem) * 6);display:flex;width:100%;flex-shrink:0;flex-direction:column}axp-layout-details-view .axp-horizontal-tabs .content{margin-top:calc(var(--spacing, .25rem) * 2);display:block;width:100%}axp-layout-details-view .axp-horizontal-tabs .content .axp-entity-list{height:auto;min-height:0;flex:none}axp-layout-details-view axp-layout-section axp-layout-content{display:flex;width:100%;flex-direction:column}:where(axp-layout-details-view axp-layout-section axp-layout-content>:not(:last-child)){--tw-divide-y-reverse: 0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(axp-layout-details-view axp-layout-section axp-layout-content>:not(:last-child)){--tw-border-style: dashed;border-style:dashed}:where(axp-layout-details-view axp-layout-section axp-layout-content>:not(:last-child)){border-color:var(--color-gray-200, oklch(92.8% .006 264.531))}axp-layout-details-view axp-layout-section axp-layout-content .--item-container{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));align-items:center;gap:calc(var(--spacing, .25rem) * 4);padding-inline:calc(var(--spacing, .25rem) * 4);padding-block:calc(var(--spacing, .25rem) * 4)}@media(width>=64rem){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-inline:calc(var(--spacing, .25rem) * 6)}}@media(width>=80rem){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-inline:calc(var(--spacing, .25rem) * 8)}}@media(width>=96rem){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-inline:calc(var(--spacing, .25rem) * 10)}}axp-layout-details-view axp-layout-section axp-layout-content .--item-container axp-layout-description{margin-top:calc(var(--spacing, .25rem) * 2);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)))}axp-layout-details-view axp-page-content ax-form form{height:100%}axp-layout-details-view:has(axp-page-content.axp-details-page-list) axp-page-layout>axp-layout-container{overflow:hidden}axp-layout-details-view axp-page-content.axp-details-page-list{display:flex;min-height:0px;flex-direction:column;overflow:hidden}axp-layout-details-view axp-page-content.axp-details-page-list>ax-form,axp-layout-details-view axp-page-content.axp-details-page-list ax-form form,axp-layout-details-view axp-page-content.axp-details-page-list ax-form form>div,axp-layout-details-view axp-page-content.axp-details-page-list .axp-entity-list,axp-layout-details-view axp-page-content.axp-details-page-list .axp-entity-list-body,axp-layout-details-view axp-page-content.axp-details-page-list axp-data-list-widget-view{display:flex;min-height:0px;flex:1;flex-direction:column;height:100%}axp-layout-details-view axp-page-content.axp-details-page-list axp-data-list-widget-view{min-height:0!important}axp-layout-details-view axp-page-content.axp-details-page-list ax-data-table{min-height:0px;flex:1;height:100%}axp-layout-details-view .axp-entity-list ax-data-table .ax-data-table-wrapper:has(tfoot) table{height:100%}axp-layout-details-view .axp-entity-list ax-data-table .ax-data-table-wrapper:has(tfoot) table tbody tr.empty-row{height:100%!important}axp-layout-details-view axp-layout-start-side{border-inline-end-style:var(--tw-border-style);border-inline-end-width:1px}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-divide-y-reverse{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-divide-y-reverse: 0;--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type:
|
|
3306
3383
|
// Angular
|
|
3307
3384
|
CommonModule }, { kind: "ngmodule", type:
|
|
3308
3385
|
// ACoreX
|
|
@@ -3347,7 +3424,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
3347
3424
|
useExisting: AXPLayoutDetailsViewComponent,
|
|
3348
3425
|
},
|
|
3349
3426
|
AXPLayoutDetailsViewViewModel,
|
|
3350
|
-
], template: "<axp-page-layout *translate=\"let t\">\n @if (vm.adapter()?.pages?.length! > 1 && vm.isLarge()) {\n <axp-layout-start-side>\n <axp-layout-header>\n <axp-layout-title>{{\n formatPageLabel(\n vm.showPages()\n ? (vm.adapter()?.title ?? '')\n : (vm.adapter()?.label ?? '')\n )\n | translate\n | async\n }}</axp-layout-title>\n <axp-layout-description>{{\n formatPageLabel(vm.adapter()?.description ?? '')\n | translate\n | async\n }}</axp-layout-description>\n </axp-layout-header>\n <axp-layout-content>\n <ax-tabs\n #sidebarTabs\n class=\"axp-vertical-tabs\"\n [look]=\"'with-line-color'\"\n [location]=\"'end'\"\n [fitParent]=\"true\"\n (onActiveTabChanged)=\"handleSidebarTabChanged($event)\"\n >\n @for (item of vm.adapter()?.pages; track item.id) {\n <ax-tab-item\n [key]=\"item.id\"\n [text]=\"(formatPageLabel(item.label) | translate | async)!\"\n [active]=\"vm.currentPage()?.id === item.id\"\n >\n <ax-prefix>\n <ax-icon icon=\"far ${{ item.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n }\n </ax-tabs>\n </axp-layout-content>\n </axp-layout-start-side>\n }\n <!-- Content Section -->\n <axp-page-content\n class=\"flex flex-row gap-4\"\n [class.axp-details-page-list]=\"isEntityListPage()\"\n >\n @if (vm.showPages()) {\n <axp-layout-list class=\"w-full\">\n @for (item of vm.adapter()?.pages; track $index) {\n <axp-layout-list-item (click)=\"handleSelectPage(item)\">\n <axp-layout-prefix>\n <ax-icon\n icon=\"far ${{ item.icon }}\"\n class=\"text-gray-500\"\n ></ax-icon>\n </axp-layout-prefix>\n <axp-layout-content>\n <a class=\"font-semibold\">{{\n formatPageLabel(item.label) | translate | async\n }}</a>\n </axp-layout-content>\n <axp-layout-suffix>\n <ax-icon\n icon=\" far fa-chevron-right\"\n class=\"text-gray-400\"\n ></ax-icon>\n </axp-layout-suffix>\n </axp-layout-list-item>\n }\n </axp-layout-list>\n } @else {\n <ax-form class=\"h-full w-full\" #form>\n <axp-widgets-container\n #widgetsContainerRef\n [context]=\"vm.context()\"\n (onContextChanged)=\"handleOnContextChanged($event)\"\n >\n <div class=\"flex h-full min-h-0 w-full flex-col\">\n @for (\n item of vm.currentPageContent();\n track pageContentTrackKey($any(item), $index)\n ) {\n @if ('type' in item && item.type === 'component') {\n <!-- Component-based content -->\n <div\n axp-page-component-renderer\n [componentKey]=\"$any(item).componentKey\"\n [rootContext]=\"vm.rootContext()\"\n [pageConfig]=\"$any(item).pageConfig\"\n [options]=\"$any(item).options\"\n (componentReady)=\"recompute()\"\n ></div>\n } @else {\n <!-- Widget-based content -->\n <ng-container\n axp-widget-renderer\n [node]=\"$any(item)\"\n [mode]=\"$any(item).mode ?? 'view'\"\n ></ng-container>\n }\n }\n @if (vm.currentPage()?.tabs?.length) {\n <div class=\"axp-horizontal-tabs\">\n <ax-tabs\n [location]=\"'bottom'\"\n [fitParent]=\"false\"\n look=\"classic\"\n >\n @for (tab of vm.currentPageTabs(); track $index) {\n <ax-tab-item\n (onClick)=\"vm.setCurrentTab(tab)\"\n [text]=\"(tab.title | translate | async)!\"\n [active]=\"vm.currentTab()?.id === tab.id\"\n >\n <ax-prefix>\n <ax-icon icon=\"far ${{ tab.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n }\n </ax-tabs>\n <div class=\"content\">\n @if (vm.currentTab()) {\n @for (\n content of vm.activeTabContent();\n track content.name\n ) {\n <ng-container\n axp-widget-renderer\n [node]=\"content\"\n [mode]=\"content.mode ?? 'view'\"\n >\n </ng-container>\n }\n }\n </div>\n </div>\n }\n </div>\n </axp-widgets-container>\n <ax-validation-summary\n [displayMode]=\"'toast'\"\n [autoHide]=\"true\"\n ></ax-validation-summary>\n </ax-form>\n }\n </axp-page-content>\n\n <!-- Footer Section -->\n @if (hasFooter()) {\n <axp-page-footer class=\"--animated\">\n <axp-layout-suffix>\n <!-- secondary footer actions -->\n @if (hasVisibleFooterSecondaryActions()) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [iconOnly]=\"deviceService.isSmall()\"\n [text]=\"'@general:terms.interface.actions' | translate | async\"\n [look]=\"deviceService.isSmall() ? 'blank' : 'solid'\"\n [color]=\"'default'\"\n >\n <ax-prefix>\n <i class=\"fa-solid fa-ellipsis-vertical\"></i>\n </ax-prefix>\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (action of footerSecondaryActions(); track $index) {\n @if (isFooterActionVisible(action)) {\n <ax-button-item\n [text]=\"(t(action.title) | async)!\"\n [color]=\"action.color\"\n [disabled]=\"isFooterActionDisabled(action)\"\n (onClick)=\"execute(action.command!)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light {{ action.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n @if (action.break) {\n <ax-divider></ax-divider>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n\n @if (hasVisibleFooterPrimaryActions()) {\n @if (showSaveDiscardFooter()) {\n @if (rejectFooterCommand(); as reject) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [disabled]=\"vm.isOverlayBusy()\"\n [text]=\"(t(reject.title) | async)!\"\n [look]=\"'solid'\"\n [color]=\"reject.color\"\n (onClick)=\"execute(reject.command)\"\n >\n <ax-prefix>\n <i class=\"{{ reject.icon }}\"></i>\n </ax-prefix>\n </ax-button>\n }\n @if (acceptFooterCommand(); as accept) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [disabled]=\"vm.isOverlayBusy()\"\n [text]=\"(t(accept.title) | async)!\"\n [look]=\"'solid'\"\n [color]=\"accept.color\"\n (onClick)=\"execute(accept.command)\"\n >\n <ax-prefix>\n <i class=\"{{ accept.icon }}\"></i>\n </ax-prefix>\n </ax-button>\n }\n }\n @for (action of footerPrimaryActions(); track $index) {\n @if (isFooterActionVisible(action)) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [disabled]=\"isFooterActionDisabled(action)\"\n [text]=\"(t(action.title) | async)!\"\n [look]=\"'solid'\"\n [color]=\"action.color\"\n (onClick)=\"execute(action.command!)\"\n >\n <ax-prefix>\n <i class=\"{{ action.icon }}\"></i>\n </ax-prefix>\n @if (action?.items) {\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (sub of action?.items; track $index) {\n @if (isFooterActionVisible(sub)) {\n <ax-button-item\n [text]=\"(t(sub.title) | async)!\"\n [color]=\"sub.color\"\n [disabled]=\"isFooterActionDisabled(sub)\"\n (onClick)=\"execute(sub.command!)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light {{ sub.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n @if (sub.break) {\n <ax-divider></ax-divider>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n }\n </ax-button>\n }\n }\n }\n </axp-layout-suffix>\n </axp-page-footer>\n }\n</axp-page-layout>\n", styles: ["@layer properties;axp-layout-details-view .axp-vertical-tabs ax-tab-item{margin-block:0px;border-radius:0!important;padding-block:calc(var(--spacing, .25rem) * 3);--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}axp-layout-details-view .axp-vertical-tabs ax-tab-item>div{display:flex;align-items:center}axp-layout-details-view .axp-vertical-tabs ax-tab-item>div .tab-item-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}axp-layout-details-view .axp-horizontal-tabs{display:flex;width:100%;flex-direction:column}axp-layout-details-view .axp-horizontal-tabs .content{margin-block:calc(var(--spacing, .25rem) * 4);display:block;width:100%}axp-layout-details-view axp-layout-section axp-layout-content{display:flex;width:100%;flex-direction:column}:where(axp-layout-details-view axp-layout-section axp-layout-content>:not(:last-child)){--tw-divide-y-reverse: 0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(axp-layout-details-view axp-layout-section axp-layout-content>:not(:last-child)){--tw-border-style: dashed;border-style:dashed}:where(axp-layout-details-view axp-layout-section axp-layout-content>:not(:last-child)){border-color:var(--color-gray-200, oklch(92.8% .006 264.531))}axp-layout-details-view axp-layout-section axp-layout-content .--item-container{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));align-items:center;gap:calc(var(--spacing, .25rem) * 4);padding-inline:calc(var(--spacing, .25rem) * 4);padding-block:calc(var(--spacing, .25rem) * 4)}@media(width>=64rem){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-inline:calc(var(--spacing, .25rem) * 6)}}@media(width>=80rem){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-inline:calc(var(--spacing, .25rem) * 8)}}@media(width>=96rem){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-inline:calc(var(--spacing, .25rem) * 10)}}axp-layout-details-view axp-layout-section axp-layout-content .--item-container axp-layout-description{margin-top:calc(var(--spacing, .25rem) * 2);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)))}axp-layout-details-view axp-page-content ax-form form{height:100%}axp-layout-details-view:has(axp-page-content.axp-details-page-list) axp-page-layout>axp-layout-container{overflow:hidden}axp-layout-details-view axp-page-content.axp-details-page-list{display:flex;min-height:0px;flex-direction:column;overflow:hidden}axp-layout-details-view axp-page-content.axp-details-page-list>ax-form,axp-layout-details-view axp-page-content.axp-details-page-list ax-form form,axp-layout-details-view axp-page-content.axp-details-page-list ax-form form>div,axp-layout-details-view axp-page-content.axp-details-page-list .axp-entity-list,axp-layout-details-view axp-page-content.axp-details-page-list .axp-entity-list-body,axp-layout-details-view axp-page-content.axp-details-page-list axp-data-list-widget-view{display:flex;min-height:0px;flex:1;flex-direction:column;height:100%}axp-layout-details-view axp-page-content.axp-details-page-list axp-data-list-widget-view{min-height:0!important}axp-layout-details-view axp-page-content.axp-details-page-list ax-data-table{min-height:0px;flex:1;height:100%}axp-layout-details-view .axp-entity-list ax-data-table .ax-data-table-wrapper:has(tfoot) table{height:100%}axp-layout-details-view .axp-entity-list ax-data-table .ax-data-table-wrapper:has(tfoot) table tbody tr.empty-row{height:100%!important}axp-layout-details-view axp-layout-start-side{border-inline-end-style:var(--tw-border-style);border-inline-end-width:1px}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-divide-y-reverse{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-divide-y-reverse: 0;--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
|
|
3427
|
+
], template: "<axp-page-layout *translate=\"let t\">\n @if (vm.adapter()?.pages?.length! > 1 && vm.isLarge()) {\n <axp-layout-start-side>\n <axp-layout-header>\n <axp-layout-title>{{\n formatPageLabel(\n vm.showPages()\n ? (vm.adapter()?.title ?? '')\n : (vm.adapter()?.label ?? '')\n )\n | translate\n | async\n }}</axp-layout-title>\n <axp-layout-description>{{\n formatPageLabel(vm.adapter()?.description ?? '')\n | translate\n | async\n }}</axp-layout-description>\n </axp-layout-header>\n <axp-layout-content>\n <ax-tabs\n #sidebarTabs\n class=\"axp-vertical-tabs\"\n [look]=\"'with-line-color'\"\n [location]=\"'end'\"\n [fitParent]=\"true\"\n (onActiveTabChanged)=\"handleSidebarTabChanged($event)\"\n >\n @for (item of vm.adapter()?.pages; track item.id) {\n <ax-tab-item\n [key]=\"item.id\"\n [text]=\"(formatPageLabel(item.label) | translate | async)!\"\n [active]=\"vm.currentPage()?.id === item.id\"\n >\n <ax-prefix>\n <ax-icon icon=\"far ${{ item.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n }\n </ax-tabs>\n </axp-layout-content>\n </axp-layout-start-side>\n }\n <!-- Content Section -->\n <axp-page-content\n class=\"flex flex-row gap-4\"\n [class.axp-details-page-list]=\"isEntityListPage()\"\n >\n @if (vm.showPages()) {\n <axp-layout-list class=\"w-full\">\n @for (item of vm.adapter()?.pages; track $index) {\n <axp-layout-list-item (click)=\"handleSelectPage(item)\">\n <axp-layout-prefix>\n <ax-icon\n icon=\"far ${{ item.icon }}\"\n class=\"text-gray-500\"\n ></ax-icon>\n </axp-layout-prefix>\n <axp-layout-content>\n <a class=\"font-semibold\">{{\n formatPageLabel(item.label) | translate | async\n }}</a>\n </axp-layout-content>\n <axp-layout-suffix>\n <ax-icon\n icon=\" far fa-chevron-right\"\n class=\"text-gray-400\"\n ></ax-icon>\n </axp-layout-suffix>\n </axp-layout-list-item>\n }\n </axp-layout-list>\n } @else {\n <ax-form class=\"h-full w-full\" #form>\n <axp-widgets-container\n #widgetsContainerRef\n [context]=\"vm.context()\"\n (onContextChanged)=\"handleOnContextChanged($event)\"\n >\n <div class=\"flex h-full min-h-0 w-full flex-col\">\n @for (\n item of vm.currentPageContent();\n track pageContentTrackKey($any(item), $index)\n ) {\n @if ('type' in item && item.type === 'component') {\n <!-- Component-based content -->\n <div\n axp-page-component-renderer\n [componentKey]=\"$any(item).componentKey\"\n [rootContext]=\"vm.rootContext()\"\n [pageConfig]=\"$any(item).pageConfig\"\n [options]=\"$any(item).options\"\n (componentReady)=\"recompute()\"\n ></div>\n } @else {\n <!-- Widget-based content -->\n <ng-container\n axp-widget-renderer\n [node]=\"$any(item)\"\n [mode]=\"$any(item).mode ?? 'view'\"\n ></ng-container>\n }\n }\n @if (vm.currentPage()?.tabs?.length) {\n <div class=\"axp-horizontal-tabs\">\n <ax-tabs\n [location]=\"'bottom'\"\n [fitParent]=\"false\"\n look=\"classic\"\n >\n @for (tab of vm.currentPageTabs(); track $index) {\n <ax-tab-item\n (onClick)=\"vm.setCurrentTab(tab)\"\n [text]=\"(tab.title | translate | async)!\"\n [active]=\"vm.currentTab()?.id === tab.id\"\n >\n <ax-prefix>\n <ax-icon icon=\"far ${{ tab.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n }\n </ax-tabs>\n <div class=\"content\">\n @if (vm.currentTab()) {\n @for (\n content of vm.activeTabContent();\n track content.name\n ) {\n <ng-container\n axp-widget-renderer\n [node]=\"content\"\n [mode]=\"content.mode ?? 'view'\"\n >\n </ng-container>\n }\n }\n </div>\n </div>\n }\n </div>\n </axp-widgets-container>\n <ax-validation-summary\n [displayMode]=\"'toast'\"\n [autoHide]=\"true\"\n ></ax-validation-summary>\n </ax-form>\n }\n </axp-page-content>\n\n <!-- Footer Section -->\n @if (hasFooter()) {\n <axp-page-footer class=\"--animated\">\n <axp-layout-suffix>\n <!-- secondary footer actions -->\n @if (hasVisibleFooterSecondaryActions()) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [iconOnly]=\"deviceService.isSmall()\"\n [text]=\"'@general:terms.interface.actions' | translate | async\"\n [look]=\"deviceService.isSmall() ? 'blank' : 'solid'\"\n [color]=\"'default'\"\n >\n <ax-prefix>\n <i class=\"fa-solid fa-ellipsis-vertical\"></i>\n </ax-prefix>\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (action of footerSecondaryActions(); track $index) {\n @if (isFooterActionVisible(action)) {\n <ax-button-item\n [text]=\"(t(action.title) | async)!\"\n [color]=\"action.color\"\n [disabled]=\"isFooterActionDisabled(action)\"\n (onClick)=\"execute(action.command!)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light {{ action.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n @if (action.break) {\n <ax-divider></ax-divider>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n\n @if (hasVisibleFooterPrimaryActions()) {\n @if (showSaveDiscardFooter()) {\n @if (rejectFooterCommand(); as reject) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [disabled]=\"vm.isOverlayBusy()\"\n [text]=\"(t(reject.title) | async)!\"\n [look]=\"'solid'\"\n [color]=\"reject.color\"\n (onClick)=\"execute(reject.command)\"\n >\n <ax-prefix>\n <i class=\"{{ reject.icon }}\"></i>\n </ax-prefix>\n </ax-button>\n }\n @if (acceptFooterCommand(); as accept) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [disabled]=\"vm.isOverlayBusy()\"\n [text]=\"(t(accept.title) | async)!\"\n [look]=\"'solid'\"\n [color]=\"accept.color\"\n (onClick)=\"execute(accept.command)\"\n >\n <ax-prefix>\n <i class=\"{{ accept.icon }}\"></i>\n </ax-prefix>\n </ax-button>\n }\n }\n @for (action of footerPrimaryActions(); track $index) {\n @if (isFooterActionVisible(action)) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [disabled]=\"isFooterActionDisabled(action)\"\n [text]=\"(t(action.title) | async)!\"\n [look]=\"'solid'\"\n [color]=\"action.color\"\n (onClick)=\"execute(action.command!)\"\n >\n <ax-prefix>\n <i class=\"{{ action.icon }}\"></i>\n </ax-prefix>\n @if (action?.items) {\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (sub of action?.items; track $index) {\n @if (isFooterActionVisible(sub)) {\n <ax-button-item\n [text]=\"(t(sub.title) | async)!\"\n [color]=\"sub.color\"\n [disabled]=\"isFooterActionDisabled(sub)\"\n (onClick)=\"execute(sub.command!)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light {{ sub.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n @if (sub.break) {\n <ax-divider></ax-divider>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n }\n </ax-button>\n }\n }\n }\n </axp-layout-suffix>\n </axp-page-footer>\n }\n</axp-page-layout>\n", styles: ["@layer properties;axp-layout-details-view .axp-vertical-tabs ax-tab-item{margin-block:0px;border-radius:0!important;padding-block:calc(var(--spacing, .25rem) * 3);--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}axp-layout-details-view .axp-vertical-tabs ax-tab-item>div{display:flex;align-items:center}axp-layout-details-view .axp-vertical-tabs ax-tab-item>div .tab-item-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}axp-layout-details-view .axp-horizontal-tabs{margin-top:calc(var(--spacing, .25rem) * 6);display:flex;width:100%;flex-shrink:0;flex-direction:column}axp-layout-details-view .axp-horizontal-tabs .content{margin-top:calc(var(--spacing, .25rem) * 2);display:block;width:100%}axp-layout-details-view .axp-horizontal-tabs .content .axp-entity-list{height:auto;min-height:0;flex:none}axp-layout-details-view axp-layout-section axp-layout-content{display:flex;width:100%;flex-direction:column}:where(axp-layout-details-view axp-layout-section axp-layout-content>:not(:last-child)){--tw-divide-y-reverse: 0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(axp-layout-details-view axp-layout-section axp-layout-content>:not(:last-child)){--tw-border-style: dashed;border-style:dashed}:where(axp-layout-details-view axp-layout-section axp-layout-content>:not(:last-child)){border-color:var(--color-gray-200, oklch(92.8% .006 264.531))}axp-layout-details-view axp-layout-section axp-layout-content .--item-container{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));align-items:center;gap:calc(var(--spacing, .25rem) * 4);padding-inline:calc(var(--spacing, .25rem) * 4);padding-block:calc(var(--spacing, .25rem) * 4)}@media(width>=64rem){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-inline:calc(var(--spacing, .25rem) * 6)}}@media(width>=80rem){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-inline:calc(var(--spacing, .25rem) * 8)}}@media(width>=96rem){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-inline:calc(var(--spacing, .25rem) * 10)}}axp-layout-details-view axp-layout-section axp-layout-content .--item-container axp-layout-description{margin-top:calc(var(--spacing, .25rem) * 2);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)))}axp-layout-details-view axp-page-content ax-form form{height:100%}axp-layout-details-view:has(axp-page-content.axp-details-page-list) axp-page-layout>axp-layout-container{overflow:hidden}axp-layout-details-view axp-page-content.axp-details-page-list{display:flex;min-height:0px;flex-direction:column;overflow:hidden}axp-layout-details-view axp-page-content.axp-details-page-list>ax-form,axp-layout-details-view axp-page-content.axp-details-page-list ax-form form,axp-layout-details-view axp-page-content.axp-details-page-list ax-form form>div,axp-layout-details-view axp-page-content.axp-details-page-list .axp-entity-list,axp-layout-details-view axp-page-content.axp-details-page-list .axp-entity-list-body,axp-layout-details-view axp-page-content.axp-details-page-list axp-data-list-widget-view{display:flex;min-height:0px;flex:1;flex-direction:column;height:100%}axp-layout-details-view axp-page-content.axp-details-page-list axp-data-list-widget-view{min-height:0!important}axp-layout-details-view axp-page-content.axp-details-page-list ax-data-table{min-height:0px;flex:1;height:100%}axp-layout-details-view .axp-entity-list ax-data-table .ax-data-table-wrapper:has(tfoot) table{height:100%}axp-layout-details-view .axp-entity-list ax-data-table .ax-data-table-wrapper:has(tfoot) table tbody tr.empty-row{height:100%!important}axp-layout-details-view axp-layout-start-side{border-inline-end-style:var(--tw-border-style);border-inline-end-width:1px}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-divide-y-reverse{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-divide-y-reverse: 0;--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
|
|
3351
3428
|
}], propDecorators: { form: [{ type: i0.ViewChild, args: ['form', { isSignal: true }] }], widgetContainer: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXPWidgetContainerComponent), { isSignal: true }] }], sidebarTabs: [{ type: i0.ViewChild, args: ['sidebarTabs', { isSignal: true }] }] } });
|
|
3352
3429
|
|
|
3353
3430
|
//#region ---- Details View Can Deactivate Guard ----
|