@acorex/platform 21.0.0-next.88 → 21.0.0-next.90
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 +8 -2
- package/fesm2022/acorex-platform-auth.mjs.map +1 -1
- package/fesm2022/{acorex-platform-common-common-settings.provider-VfmZct9H.mjs → acorex-platform-common-common-settings.provider-DilV4dql.mjs} +15 -42
- package/fesm2022/acorex-platform-common-common-settings.provider-DilV4dql.mjs.map +1 -0
- package/fesm2022/acorex-platform-common.mjs +3299 -3200
- package/fesm2022/acorex-platform-common.mjs.map +1 -1
- package/fesm2022/acorex-platform-contracts.mjs +1 -0
- package/fesm2022/acorex-platform-contracts.mjs.map +1 -1
- package/fesm2022/acorex-platform-core.mjs +643 -30
- package/fesm2022/acorex-platform-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-builder.mjs +98 -189
- package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
- package/fesm2022/{acorex-platform-layout-components-binding-expression-editor-popup.component-CXEdvDTf.mjs → acorex-platform-layout-components-binding-expression-editor-popup.component-RttFwaw9.mjs} +17 -4
- package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-RttFwaw9.mjs.map +1 -0
- package/fesm2022/acorex-platform-layout-components.mjs +125 -26
- package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-designer.mjs +4 -4
- package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity-contracts.mjs +106 -12
- package/fesm2022/acorex-platform-layout-entity-contracts.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity.mjs +512 -155
- package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-views.mjs +921 -173
- package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widget-core.mjs +380 -103
- package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -1
- package/fesm2022/{acorex-platform-layout-widgets-tabular-data-edit-popup.component-D4MOHEpI.mjs → acorex-platform-layout-widgets-tabular-data-edit-popup.component-BvFykMTH.mjs} +2 -2
- package/fesm2022/{acorex-platform-layout-widgets-tabular-data-edit-popup.component-D4MOHEpI.mjs.map → acorex-platform-layout-widgets-tabular-data-edit-popup.component-BvFykMTH.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-layout-widgets-tabular-data-view-popup.component-gX-3Kx9I.mjs → acorex-platform-layout-widgets-tabular-data-view-popup.component-CntopmDS.mjs} +2 -2
- package/fesm2022/{acorex-platform-layout-widgets-tabular-data-view-popup.component-gX-3Kx9I.mjs.map → acorex-platform-layout-widgets-tabular-data-view-popup.component-CntopmDS.mjs.map} +1 -1
- package/fesm2022/acorex-platform-layout-widgets.mjs +575 -239
- package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
- package/fesm2022/acorex-platform-themes-default.mjs +232 -25
- package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
- package/fesm2022/{acorex-platform-themes-shared-settings.provider-BUwPqwUS.mjs → acorex-platform-themes-shared-settings.provider-UyKdkeyk.mjs} +48 -1
- package/fesm2022/acorex-platform-themes-shared-settings.provider-UyKdkeyk.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-shared.mjs +103 -24
- package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
- package/package.json +1 -1
- package/types/acorex-platform-auth.d.ts +1 -0
- package/types/acorex-platform-common.d.ts +202 -151
- package/types/acorex-platform-contracts.d.ts +1 -0
- package/types/acorex-platform-core.d.ts +162 -7
- package/types/acorex-platform-layout-builder.d.ts +10 -20
- package/types/acorex-platform-layout-components.d.ts +14 -1
- package/types/acorex-platform-layout-entity-contracts.d.ts +31 -2
- package/types/acorex-platform-layout-entity.d.ts +91 -16
- package/types/acorex-platform-layout-views.d.ts +107 -20
- package/types/acorex-platform-layout-widget-core.d.ts +71 -9
- package/types/acorex-platform-layout-widgets.d.ts +48 -26
- package/types/acorex-platform-themes-default.d.ts +60 -6
- package/types/acorex-platform-themes-shared.d.ts +4 -0
- package/fesm2022/acorex-platform-common-common-settings.provider-VfmZct9H.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-CXEdvDTf.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-shared-settings.provider-BUwPqwUS.mjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as i2 from '@angular/common';
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { inject, viewChild, afterNextRender, effect, ChangeDetectionStrategy, ViewEncapsulation, Component, signal, untracked, computed, Injectable, input, output, ViewContainerRef, Directive,
|
|
4
|
+
import { inject, viewChild, afterNextRender, effect, ChangeDetectionStrategy, ViewEncapsulation, Component, DestroyRef, signal, untracked, computed, InjectionToken, Injectable, input, output, ViewContainerRef, Directive, ElementRef } from '@angular/core';
|
|
5
5
|
import { AXCommonModule } from '@acorex/cdk/common';
|
|
6
6
|
import * as i4 from '@acorex/components/breadcrumbs';
|
|
7
7
|
import { AXBreadcrumbsModule } from '@acorex/components/breadcrumbs';
|
|
@@ -12,9 +12,9 @@ import { AXDecoratorModule } from '@acorex/components/decorators';
|
|
|
12
12
|
import * as i5 from '@acorex/components/dropdown';
|
|
13
13
|
import { AXDropdownModule } from '@acorex/components/dropdown';
|
|
14
14
|
import { AXDropdownButtonModule } from '@acorex/components/dropdown-button';
|
|
15
|
-
import { AXPTabNavigationService, AXPStickyDirective, AXPCommonSettings, AXPHomePageService, AXPSettingsService, AXPTabPreviewService, AXPUnsavedChangesConfirmService, normalizeRouterUrl, AXP_HOME_TAB_KEY, axpResolveTabKey, axpIsEntityDetailsViewRoute, axpNavigateAppPath, AXPEntityCommandScope, AXPUnsavedChangesPopstateService, createUnsavedChangesCanDeactivateGuard } from '@acorex/platform/common';
|
|
15
|
+
import { AXPTabNavigationService, AXPStickyDirective, AXPCommonSettings, AXPHomePageService, AXPSettingsService, AXPTabPreviewService, AXPUnsavedChangesConfirmService, AXPBrowserTitleService, axpJoinTabTitleSegments, normalizeRouterUrl, AXP_HOME_TAB_KEY, axpResolveTabKey, axpIsEntityDetailsViewRoute, axpNavigateAppPath, AXPEntityCommandScope, AXPNotFoundError, AXP_NOT_FOUND_ROUTE, AXPUnsavedChangesPopstateService, AXP_ENTITY_DELETED_WORKFLOW_EVENT_TYPE, createUnsavedChangesCanDeactivateGuard } from '@acorex/platform/common';
|
|
16
16
|
import * as i8 from '@acorex/platform/core';
|
|
17
|
-
import { AXPDeviceService, AXPComponentSlotModule, getSmart, AXPExpressionEvaluatorService, AXPContextEvalFactory, normalizeKeyboardShortcuts, AXPContextStore, AXPBroadcastEventService, AXPKeyboardShortcutRegistry, AXPKeyboardShortcutPriority } from '@acorex/platform/core';
|
|
17
|
+
import { AXPDeviceService, AXPComponentSlotModule, getSmart, AXPDebugService, OVERLAY_DETAILS_VIEW_TRACE_NS, AXPExpressionEvaluatorService, AXPContextEvalFactory, normalizeKeyboardShortcuts, AXPContextStore, AXPBroadcastEventService, AXPKeyboardShortcutRegistry, FORM_DIRTY_TRACE_NS, summarizeFormContextDirtyDiff, AXPKeyboardShortcutPriority } from '@acorex/platform/core';
|
|
18
18
|
import * as i1 from '@acorex/cdk/drawer';
|
|
19
19
|
import { AXDrawerDirectiveModule, AXDrawerContainerDirective } from '@acorex/cdk/drawer';
|
|
20
20
|
import { AXDrawerModule } from '@acorex/components/drawer';
|
|
@@ -28,25 +28,25 @@ import { AXPWorkflowService } from '@acorex/platform/workflow';
|
|
|
28
28
|
import { AXToastService } from '@acorex/components/toast';
|
|
29
29
|
import { AXFormatService, AXFormatModule } from '@acorex/core/format';
|
|
30
30
|
import { AXPSessionService } from '@acorex/platform/auth';
|
|
31
|
-
import {
|
|
31
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
32
|
+
import { Router, NavigationEnd, ActivatedRoute } from '@angular/router';
|
|
32
33
|
import { isEmpty, cloneDeep, get } from 'lodash-es';
|
|
34
|
+
import { filter } from 'rxjs/operators';
|
|
33
35
|
import { AXBasePageComponent } from '@acorex/components/page';
|
|
34
|
-
import * as
|
|
36
|
+
import * as i6$1 from '@acorex/platform/layout/widget-core';
|
|
35
37
|
import { AXPPageStatus, AXPWidgetContainerComponent, AXPWidgetCoreModule } from '@acorex/platform/layout/widget-core';
|
|
36
38
|
import { signalStore, withState, withComputed, withMethods, patchState } from '@ngrx/signals';
|
|
37
39
|
import { AXBadgeModule } from '@acorex/components/badge';
|
|
38
40
|
import { AXButtonGroupModule } from '@acorex/components/button-group';
|
|
39
|
-
import * as i5$1 from '@acorex/components/loading';
|
|
40
|
-
import { AXLoadingModule } from '@acorex/components/loading';
|
|
41
41
|
import { AXMenuModule } from '@acorex/components/menu';
|
|
42
42
|
import { AXSearchBoxModule } from '@acorex/components/search-box';
|
|
43
43
|
import { AXDateTimeModule } from '@acorex/core/date-time';
|
|
44
44
|
import { AXFileModule } from '@acorex/core/file';
|
|
45
|
-
import * as
|
|
45
|
+
import * as i7 from '@acorex/components/form';
|
|
46
46
|
import { AXFormModule } from '@acorex/components/form';
|
|
47
|
-
import * as
|
|
47
|
+
import * as i5$1 from '@acorex/components/tabs';
|
|
48
48
|
import { AXTabsModule } from '@acorex/components/tabs';
|
|
49
|
-
import { Subject, takeUntil } from 'rxjs';
|
|
49
|
+
import { Subject, takeUntil, filter as filter$1 } from 'rxjs';
|
|
50
50
|
|
|
51
51
|
class AXPPageLayoutBase {
|
|
52
52
|
}
|
|
@@ -146,7 +146,7 @@ class AXPPageLayoutComponent {
|
|
|
146
146
|
});
|
|
147
147
|
}
|
|
148
148
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPPageLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
149
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPPageLayoutComponent, isStandalone: true, selector: "axp-page-layout", providers: [], viewQueries: [{ propertyName: "startSideDrawer", first: true, predicate: ["startSideDrawer"], descendants: true, isSignal: true }], hostDirectives: [{ directive: i1.AXDrawerContainerDirective }], ngImport: i0, template: "<!-------- Begin Start Side Drawer -------->\n<div id=\"axp-drawer-start\" [mode]=\"deviceService.isSmall() ? 'overlay' : 'push'\" [transition]=\"250\" axDrawerItem\n [backDrop]=\"true\" (onBackdropClick)=\"handleBackdropClick($event)\" #startSideDrawer=\"axDrawerItem\"\n [backdropClass]=\"'ax-bg-darkest/75'\" [collapsed]=\"deviceService.isSmall()\" drawerLocation=\"start\"\n class=\"ax-z-50 ax-h-full\">\n <ng-content select=\"axp-layout-start-side\"></ng-content>\n</div>\n<!-------- Finish Start Side Drawer -------->\n<!--------------------------------------------------------------->\n<!-------- Begin Main Layout Container -------->\n<axp-layout-container id=\"axp-page-layout\" #container>\n <!-------- Begin Page Header -------->\n <axp-layout-header id=\"axp-page-header\" *translate=\"let t\" #sticky=\"axpSticky\" [axpSticky]=\"'axp-is-sticky'\"\n [stickyOffset]=\"50\" [stickyParent]=\"container.hostElement\">\n <!-------- Begin Back Button (Mobile Only) -------->\n @if (page?.hasBackButton() && deviceService.isSmall()) {\n <ax-button id=\"axp-btn-back\" [look]=\"'blank'\" class=\"ax-sm ax-w-fit ax-ms-1\" color=\"secondary\"\n (click)=\"page?.onBackButtonClick()\" [text]=\"(page?.backButton()?.title | translate | async) ?? ''\">\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-chevron-left rtl:ax-rotate-180\"></ax-icon>\n </ax-prefix>\n </ax-button>\n }\n <!-------- Finish Back Button -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Title Bar -------->\n <axp-layout-title-bar id=\"axp-title-bar\">\n <!-------- Begin Title Section -------->\n <div class=\"ax-flex ax-flex-col ax-transition ax-shrink-1 ax-min-w-0\">\n <!-------- Begin Breadcrumbs -------->\n @if (page?.hasBreadcrumbs() && !deviceService.isSmall()) {\n <ax-breadcrumbs id=\"axp-breadcrumb\" class=\"ax-mb-1\">\n @for (item of page?.breadcrumbs(); track $index) {\n <ax-breadcrumbs-item [attr.id]=\"'axp-breadcrumb-item-' + $index\" [active]=\"$last\"\n (click)=\"!$last && item.command ? execute(item.command) : null\">\n @if (item.icon) {\n <i [class]=\"item.icon\"></i>\n }\n {{ t(item.title) | async }}\n </ax-breadcrumbs-item>\n }\n <ng-template #divider>\n <i class=\"fa-regular fa-chevron-right rtl:ax-rotate-180 fa-sm\"></i>\n </ng-template>\n </ax-breadcrumbs>\n }\n <!-------- Finish Breadcrumbs -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Title Container -------->\n <div class=\"__title-container\">\n <!-------- Begin Page Title -------->\n @if (page?.hasTitle()) {\n <axp-layout-title id=\"axp-page-title\">\n @if (page?.hasTitleIcon()) {\n <ax-icon [icon]=\"page?.titleIcon()!\" class=\"ax-me-2\"></ax-icon>\n }\n {{ page?.title() | translate | async }}\n </axp-layout-title>\n }\n <!-------- Finish Page Title -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Title Actions -------->\n @if (page?.hasTitleActions()) {\n <ax-button id=\"axp-btn-title-actions\" [look]=\"'blank'\" class=\"ax-sm -ax-mx-2\">\n <ax-prefix>\n <i class=\"fa-solid fa-caret-down fa-fw\"></i>\n </ax-prefix>\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (sub of page?.titleActions(); track $index) {\n <ng-container>\n <ax-button-item [attr.id]=\"'axp-btn-title-action-' + (sub.name || $index)\"\n [text]=\"(t(sub.title) | async)!\" [color]=\"sub.color\" [disabled]=\"sub.disabled\"\n [selected]=\"sub.command?.metadata?.['isSelected']\" (onClick)=\"handleActionClick(sub)\">\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 </ng-container>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n <!-------- Finish Title Actions -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Page Status -------->\n\n @if (page?.hasStatus()) {\n <axp-status-chip [value]=\"page?.status()?.value ?? null\" [readonly]=\"page?.status()?.readonly || false\"\n [definitionKey]=\"page?.status()?.definitionKey ?? null\" [entityData]=\"getEntityData()\"\n (transitionExecuted)=\"handleStatusTransition($event)\" class=\"__title-status\"></axp-status-chip>\n }\n <!-------- Finish Page Status -------->\n\n <!-------- Begin Title Badge -------->\n @if (page?.hasBadge()) {\n <div\n id=\"axp-page-badge\"\n class=\"__title-badge --{{ page?.badge()?.color }}\"\n [attr.title]=\"page?.badge()?.description ?? page?.badge()?.title\"\n [attr.aria-label]=\"page?.badge()?.title\"\n >\n <i class=\"fa-solid fa-circle\" aria-hidden=\"true\"></i>\n <span class=\"__title-badge-label\">{{ page?.badge()?.title }}</span>\n </div>\n }\n <!-------- Finish Title Badge -------->\n\n </div>\n <!-------- Finish Title Container -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Page Description -------->\n @if (page?.hasDescription()) {\n <axp-layout-description id=\"axp-page-description\">\n {{ page?.description() | translate | async }}</axp-layout-description>\n }\n <!-------- Finish Page Description -------->\n </div>\n <!-------- Finish Title Section -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Page Actions -------->\n <axp-layout-actions id=\"axp-page-actions\" class=\"ax-shrink-0\">\n <axp-component-slot name=\"page-header-actions\"></axp-component-slot>\n <!-------- Begin Primary Actions -------->\n @if (page?.hasPrimaryActions()) {\n @for (item of page?.primaryMenuItems(); track $index) {\n @if (item.visible != false) {\n <ax-button [attr.id]=\"'axp-btn-primary-' + (item.name || item.title)\" [class.ax-sm]=\"deviceService.isSmall()\"\n [iconOnly]=\"deviceService.isSmall()\" [disabled]=\"item.disabled\" [text]=\"(t(item.title) | async)!\"\n [look]=\"'solid'\" [color]=\"item.color\" (onClick)=\"handleActionClick(item)\">\n <ax-prefix>\n <i class=\"{{ item.icon }}\"></i>\n </ax-prefix>\n @if (item?.items) {\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (sub of item?.items; track $index) {\n @if (sub.visible != false) {\n <ax-button-item [attr.id]=\"'axp-btn-primary-' + (item.name || item.title) + '-' + (sub.name || sub.title)\"\n [text]=\"(t(sub.title) | async)!\" [color]=\"sub.color\" [disabled]=\"sub.disabled\"\n (onClick)=\"handleActionClick(sub)\">\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 <!-------- Finish Primary Actions -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Secondary Actions -------->\n @if (page?.hasSecondaryActions()) {\n <ax-button id=\"axp-btn-secondary\" [class.ax-sm]=\"deviceService.isSmall()\" [iconOnly]=\"deviceService.isSmall()\"\n [text]=\"'@general:terms.interface.actions' | translate | async\"\n [look]=\"deviceService.isSmall() ? 'blank' : 'solid'\" [color]=\"'default'\">\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 (item of page?.secondaryMenuItems(); track $index) {\n @if (item.visible != false) {\n <ax-button-item [attr.id]=\"'axp-btn-secondary-' + (item.name || item.title)\"\n [text]=\"(item.title | translate | async)!\" [color]=\"item.color\" [disabled]=\"item.disabled\"\n (onClick)=\"handleSecondaryActionClick(item)\">\n <ax-prefix>\n <ax-icon icon=\"fa-light {{ item.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n @if (item.break) {\n <ax-divider></ax-divider>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n <!-------- Finish Secondary Actions -------->\n </axp-layout-actions>\n <!-------- Finish Page Actions -------->\n </axp-layout-title-bar>\n <!-------- Finish Title Bar -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Page Toolbar / Navbar -------->\n @if (!sticky.isSticky) {}\n <ng-content select=\"axp-page-toolbar\"></ng-content>\n <!-------- Finish Page Toolbar / Navbar -------->\n </axp-layout-header>\n <!-------- Finish Page Header -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Page Content -------->\n <ng-content select=\"axp-page-content\"></ng-content>\n <!-------- Finish Page Content -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Page Footer -------->\n <axp-page-footer-container id=\"axp-page-footer-container\"\n [ngStyle]=\"{ display: tt.isEmpty() && prefixSlot.isEmpty() && suffixSlot.isEmpty() ? 'none' : 'block' }\">\n <axp-layout-container #tt>\n <ng-content select=\"axp-page-footer\"></ng-content>\n </axp-layout-container>\n <axp-page-footer id=\"axp-page-footer\">\n <axp-layout-prefix>\n <axp-component-slot name=\"page-footer-start\" #prefixSlot=\"slot\"></axp-component-slot>\n </axp-layout-prefix>\n <axp-layout-suffix>\n <axp-component-slot name=\"page-footer-end\" #suffixSlot=\"slot\"></axp-component-slot>\n </axp-layout-suffix>\n </axp-page-footer>\n </axp-page-footer-container>\n <!-------- Finish Page Footer -------->\n</axp-layout-container>\n<!-------- Finish Main Layout Container -------->", styles: ["@charset \"UTF-8\";.axp-status-icon{font-size:.875rem;line-height:1}.axp-status-chip{display:inline-flex}.axp-status-chip--primary{background-color:rgb(var(--ax-sys-color-primary-lighter-surface));color:rgb(var(--ax-sys-color-on-primary-lighter-surface))}.axp-status-icon--primary{color:rgb(var(--ax-sys-color-primary-dark-surface))}.axp-status-chip--secondary{background-color:rgb(var(--ax-sys-color-secondary-lighter-surface));color:rgb(var(--ax-sys-color-on-secondary-lighter-surface))}.axp-status-icon--secondary{color:rgb(var(--ax-sys-color-secondary-dark-surface))}.axp-status-chip--success{background-color:rgb(var(--ax-sys-color-success-lighter-surface));color:rgb(var(--ax-sys-color-on-success-lighter-surface))}.axp-status-icon--success{color:rgb(var(--ax-sys-color-success-dark-surface))}.axp-status-chip--warning{background-color:rgb(var(--ax-sys-color-warning-lighter-surface));color:rgb(var(--ax-sys-color-on-warning-lighter-surface))}.axp-status-icon--warning{color:rgb(var(--ax-sys-color-warning-dark-surface))}.axp-status-chip--danger{background-color:rgb(var(--ax-sys-color-danger-lighter-surface));color:rgb(var(--ax-sys-color-on-danger-lighter-surface))}.axp-status-icon--danger{color:rgb(var(--ax-sys-color-danger-dark-surface))}.axp-status-chip--info{background-color:rgb(var(--ax-sys-color-accent3-lighter-surface));color:rgb(var(--ax-sys-color-on-accent3-lighter-surface))}.axp-status-icon--info{color:rgb(var(--ax-sys-color-accent3-dark-surface))}.axp-status-chip--accent1{background-color:rgb(var(--ax-sys-color-accent1-lighter-surface));color:rgb(var(--ax-sys-color-on-accent1-lighter-surface))}.axp-status-icon--accent1{color:rgb(var(--ax-sys-color-accent1-dark-surface))}.axp-status-chip--accent2{background-color:rgb(var(--ax-sys-color-accent2-lighter-surface));color:rgb(var(--ax-sys-color-on-accent2-lighter-surface))}.axp-status-icon--accent2{color:rgb(var(--ax-sys-color-accent2-dark-surface))}.axp-status-chip--accent3{background-color:rgb(var(--ax-sys-color-accent3-lighter-surface));color:rgb(var(--ax-sys-color-on-accent3-lighter-surface))}.axp-status-icon--accent3{color:rgb(var(--ax-sys-color-accent3-dark-surface))}.axp-status-chip--neutral{background-color:rgb(var(--ax-sys-color-neutral-lighter-surface));color:rgb(var(--ax-sys-color-on-neutral-lighter-surface))}.axp-status-icon--neutral{color:rgb(var(--ax-sys-color-neutral-dark-surface))}axp-layout-title{display:block;width:100%;font-weight:600}axp-layout-description{display:block;width:100%;font-size:.875rem;line-height:1.25rem;opacity:.65}axp-layout-actions{display:flex;align-items:center;gap:.75rem}axp-layout-actions axp-layout-actions-primary{display:flex;align-items:center;gap:.75rem}axp-layout-footer,axp-layout-toolbar,axp-layout-header,axp-page-header,axp-page-footer,axp-page-toolbar{display:flex;width:100%;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.5rem}axp-layout-footer>axp-layout-prefix,axp-layout-footer>axp-layout-suffix,axp-layout-toolbar>axp-layout-prefix,axp-layout-toolbar>axp-layout-suffix,axp-layout-header>axp-layout-prefix,axp-layout-header>axp-layout-suffix,axp-page-header>axp-layout-prefix,axp-page-header>axp-layout-suffix,axp-page-footer>axp-layout-prefix,axp-page-footer>axp-layout-suffix,axp-page-toolbar>axp-layout-prefix,axp-page-toolbar>axp-layout-suffix{display:flex;flex-direction:row;align-items:center;gap:.5rem}axp-layout-footer>axp-layout-prefix,axp-layout-toolbar>axp-layout-prefix,axp-layout-header>axp-layout-prefix,axp-page-header>axp-layout-prefix,axp-page-footer>axp-layout-prefix,axp-page-toolbar>axp-layout-prefix{order:-9999}axp-layout-footer>axp-layout-suffix,axp-layout-toolbar>axp-layout-suffix,axp-layout-header>axp-layout-suffix,axp-page-header>axp-layout-suffix,axp-page-footer>axp-layout-suffix,axp-page-toolbar>axp-layout-suffix{order:9999;margin-inline-start:auto}axp-layout-list{display:flex;flex-direction:column}axp-layout-list>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse));border-style:dashed}axp-layout-list:focus{outline:none}axp-layout-list-group{display:flex;flex-direction:column;padding-top:.5rem;padding-bottom:.5rem}axp-layout-list-group>axp-layout-title{padding-bottom:.5rem;font-size:.875rem;line-height:1.25rem;font-weight:600}axp-layout-list-group>axp-layout-header{display:flex;justify-content:space-between;padding-top:.5rem;padding-bottom:.5rem}axp-layout-list-item{margin-top:.25rem;display:flex;flex-direction:row;align-items:center;justify-content:space-between;gap:.75rem;padding:.5rem;font-size:.875rem;line-height:1.25rem}axp-layout-list-item:focus{outline:none}axp-layout-list-item.axp-state-focused,axp-layout-list-item:hover{cursor:pointer;border-radius:.25rem;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-light-surface),var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lightest-surface),var(--tw-text-opacity, 1))}axp-layout-list-item>axp-layout-prefix{margin-inline-end:auto;display:flex;flex-direction:row;gap:.5rem}axp-layout-list-item>axp-layout-content{flex:1 1 0%}axp-layout-list-item>axp-layout-content axp-layout-description{margin-top:.25rem!important;font-size:.75rem!important;line-height:1rem!important}axp-layout-list-item>axp-layout-suffix{margin-inline-start:auto;display:flex;flex-direction:row;gap:.5rem}axp-layout-sections{display:flex;flex-direction:column;gap:1rem}axp-layout-sections axp-layout-section{display:block;border-radius:.375rem;border-width:1px;--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}axp-layout-sections axp-layout-section>axp-layout-footer,axp-layout-sections axp-layout-section>axp-layout-header{padding:.5rem 1rem}@media(min-width:1280px){axp-layout-sections axp-layout-section>axp-layout-footer,axp-layout-sections axp-layout-section>axp-layout-header{padding-top:1rem;padding-bottom:1rem}}axp-layout-sections axp-layout-section>axp-layout-header{display:flex;flex-direction:column;gap:0px;border-top-left-radius:.375rem;border-top-right-radius:.375rem;border-bottom-width:1px}axp-layout-sections axp-layout-section>axp-layout-header axp-layout-title{font-weight:700;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lightest-surface),var(--tw-text-opacity, 1))}axp-layout-sections axp-layout-section>axp-layout-header axp-layout-description{margin-top:.25rem;font-size:.875rem;line-height:1.25rem}axp-layout-sections axp-layout-section>axp-layout-footer{display:flex;align-items:center;justify-content:space-between;border-bottom-right-radius:.375rem;border-bottom-left-radius:.375rem;border-top-width:1px;padding:1rem}axp-layout-sections axp-layout-section>axp-layout-footer>axp-layout-suffix{margin-inline-start:auto;display:flex;gap:.5rem}axp-layout-sections axp-layout-section>axp-layout-footer{opacity:0;animation:fadeInDown .5s ease-out forwards}@keyframes fadeInDown{0%{opacity:0}to{opacity:1}}axp-page-layout{display:flex;width:100%;height:100%;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-page-layout:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-dark-surface));color:rgb(var(--ax-sys-color-on-dark-surface));border-color:rgb(var(--ax-sys-color-border-dark-surface))}axp-page-layout axp-layout-start-side,axp-page-layout axp-layout-end-side{display:flex;min-height:100%;min-width:16rem;flex-direction:column;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-page-layout axp-layout-start-side:is(.ax-dark *),axp-page-layout axp-layout-end-side:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-darker-surface));color:rgb(var(--ax-sys-color-on-darker-surface));border-color:rgb(var(--ax-sys-color-border-darker-surface))}axp-page-layout axp-layout-start-side axp-layout-header,axp-page-layout axp-layout-end-side axp-layout-header{display:flex;flex-direction:column;gap:.5rem;padding:1rem}axp-page-layout axp-layout-start-side axp-layout-header>axp-layout-title,axp-page-layout axp-layout-end-side axp-layout-header>axp-layout-title{font-size:1.125rem;line-height:1.75rem;font-weight:500}axp-page-layout axp-layout-start-side>axp-layout-content,axp-page-layout axp-layout-end-side>axp-layout-content{flex:1 1 0%}axp-page-layout>axp-layout-container{position:relative;display:flex;width:100%;height:100%;flex-direction:column;overflow:auto}axp-page-layout>axp-layout-container>axp-layout-header{position:sticky;top:0;z-index:20;display:flex;flex-direction:column;align-items:flex-start;gap:0px;padding-top:.5rem;padding-bottom:.5rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;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-page-layout>axp-layout-container>axp-layout-header:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-dark-surface));color:rgb(var(--ax-sys-color-on-dark-surface));border-color:rgb(var(--ax-sys-color-border-dark-surface))}@media(min-width:768px){axp-page-layout>axp-layout-container>axp-layout-header{padding-top:1rem;padding-bottom:1rem}}axp-page-layout>axp-layout-container>axp-layout-header.axp-is-sticky{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}axp-page-layout>axp-layout-container>axp-layout-header ax-breadcrumbs ax-breadcrumbs-item{font-size:.75rem;line-height:1rem}axp-page-layout>axp-layout-container>axp-layout-header ax-breadcrumbs ax-breadcrumbs-item.ax-state-active .ax-breadcrumb-item-content{cursor:default;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lightest-surface),var(--tw-text-opacity, 1));opacity:.75}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar{display:flex;width:100%;align-items:center;justify-content:space-between;padding-left:1rem;padding-right:1rem}@media(min-width:1280px){axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar{border-width:0px}}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar ax-layout-nav-button{display:flex;align-items:center;justify-content:space-between}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container{display:flex;align-items:baseline;gap:.75rem}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container axp-layout-title{display:inline-block;width:fit-content;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:1.25rem;line-height:1.75rem;font-weight:500;line-height:1}@media(min-width:1024px){axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container axp-layout-title{font-size:1.5rem;line-height:2rem}}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge{display:inline-flex;--tw-translate-y: -3px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));align-items:center;align-self:baseline;border-radius:.375rem;padding:.25rem .5rem;font-size:.75rem;line-height:1rem;font-weight:600;line-height:1}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge i{margin-inline-end:.25rem;line-height:1;font-size:.5rem}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--warning{background-color:rgb(var(--ax-sys-color-warning-lightest-surface));color:rgb(var(--ax-sys-color-on-warning-lightest-surface));border-color:rgb(var(--ax-sys-color-border-warning-lightest-surface))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--warning i{color:rgb(var(--ax-sys-color-warning-500))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--danger{background-color:rgb(var(--ax-sys-color-danger-lightest-surface));color:rgb(var(--ax-sys-color-on-danger-lightest-surface));border-color:rgb(var(--ax-sys-color-border-danger-lightest-surface))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--danger i{color:rgb(var(--ax-sys-color-danger-500))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--success{background-color:rgb(var(--ax-sys-color-success-lightest-surface));color:rgb(var(--ax-sys-color-on-success-lightest-surface));border-color:rgb(var(--ax-sys-color-border-success-lightest-surface))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--success i{color:rgb(var(--ax-sys-color-success-500))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--primary{background-color:rgb(var(--ax-sys-color-primary-lightest-surface));color:rgb(var(--ax-sys-color-on-primary-lightest-surface));border-color:rgb(var(--ax-sys-color-border-primary-lightest-surface))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--primary i{color:rgb(var(--ax-sys-color-primary-500))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--secondary i{color:rgb(var(--ax-sys-color-secondary-500))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--default i{color:rgb(var(--ax-sys-color-on-surface)/.45)}@media(max-width:600px){axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge{--tw-translate-y: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));background-color:transparent;padding:0;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge .__title-badge-label{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge i{margin:0;font-size:.625rem}}axp-page-layout>axp-layout-container>axp-layout-header axp-page-toolbar{margin-top:.5rem;padding-left:1rem;padding-right:1rem}axp-page-layout>axp-layout-container>axp-page-content{display:flex;width:100%;flex:1 1 0%;flex-direction:column;padding:.75rem 1rem}axp-page-layout>axp-layout-container>axp-page-content.--scrollable{padding-bottom:1rem}axp-page-layout>axp-layout-container>axp-page-footer-container{border-top-width:1px;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-page-layout>axp-layout-container>axp-page-footer-container:is(.ax-dark *){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-page-layout>axp-layout-container>axp-page-footer-container{position:sticky;bottom:0;z-index:20;padding:.75rem;--tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / .05);--tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}@keyframes ax-fadeInUp{0%{transform:translate3d(0,100%,0);opacity:0}}axp-page-layout>axp-layout-container>axp-page-footer-container.--animated{animation:1s both ax-fadeInUp;transition-duration:.3s;transition-timing-function:cubic-bezier(0,0,.2,1);animation-duration:.3s;animation-timing-function:cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type:
|
|
149
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPPageLayoutComponent, isStandalone: true, selector: "axp-page-layout", providers: [], viewQueries: [{ propertyName: "startSideDrawer", first: true, predicate: ["startSideDrawer"], descendants: true, isSignal: true }], hostDirectives: [{ directive: i1.AXDrawerContainerDirective }], ngImport: i0, template: "<!-------- Begin Start Side Drawer -------->\n<div id=\"axp-drawer-start\" [mode]=\"deviceService.isSmall() ? 'overlay' : 'push'\" [transition]=\"250\" axDrawerItem\n [backDrop]=\"true\" (onBackdropClick)=\"handleBackdropClick($event)\" #startSideDrawer=\"axDrawerItem\"\n [backdropClass]=\"'ax-bg-darkest/75'\" [collapsed]=\"deviceService.isSmall()\" drawerLocation=\"start\" class=\"ax-h-full\">\n <ng-content select=\"axp-layout-start-side\"></ng-content>\n</div>\n<!-------- Finish Start Side Drawer -------->\n<!--------------------------------------------------------------->\n<!-------- Begin Main Layout Container -------->\n<axp-layout-container id=\"axp-page-layout\" #container>\n <!-------- Begin Page Header -------->\n <axp-layout-header id=\"axp-page-header\" *translate=\"let t\" #sticky=\"axpSticky\" [axpSticky]=\"'axp-is-sticky'\"\n [stickyOffset]=\"50\" [stickyParent]=\"container.hostElement\">\n <!-------- Begin Back Button (Mobile Only) -------->\n @if (page?.hasBackButton() && deviceService.isSmall()) {\n <ax-button id=\"axp-btn-back\" [look]=\"'blank'\" class=\"ax-sm ax-w-fit ax-ms-1\" color=\"secondary\"\n (click)=\"page?.onBackButtonClick()\" [text]=\"(page?.backButton()?.title | translate | async) ?? ''\">\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-chevron-left rtl:ax-rotate-180\"></ax-icon>\n </ax-prefix>\n </ax-button>\n }\n <!-------- Finish Back Button -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Title Bar -------->\n <axp-layout-title-bar id=\"axp-title-bar\">\n <!-------- Begin Title Section -------->\n <div class=\"ax-flex ax-flex-col ax-transition ax-shrink-1 ax-min-w-0\">\n <!-------- Begin Breadcrumbs -------->\n @if (page?.hasBreadcrumbs() && !deviceService.isSmall()) {\n <ax-breadcrumbs id=\"axp-breadcrumb\" class=\"ax-mb-1\">\n @for (item of page?.breadcrumbs(); track $index) {\n <ax-breadcrumbs-item [attr.id]=\"'axp-breadcrumb-item-' + $index\" [active]=\"$last\"\n (click)=\"!$last && item.command ? execute(item.command) : null\">\n @if (item.icon) {\n <i [class]=\"item.icon\"></i>\n }\n {{ t(item.title) | async }}\n </ax-breadcrumbs-item>\n }\n <ng-template #divider>\n <i class=\"fa-regular fa-chevron-right rtl:ax-rotate-180 fa-sm\"></i>\n </ng-template>\n </ax-breadcrumbs>\n }\n <!-------- Finish Breadcrumbs -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Title Container -------->\n <div class=\"__title-container\">\n <!-------- Begin Page Title -------->\n @if (page?.hasTitle()) {\n <axp-layout-title id=\"axp-page-title\">\n @if (page?.hasTitleIcon()) {\n <ax-icon [icon]=\"page?.titleIcon()!\" class=\"ax-me-2\"></ax-icon>\n }\n {{ page?.title() | translate | async }}\n </axp-layout-title>\n }\n <!-------- Finish Page Title -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Title Actions -------->\n @if (page?.hasTitleActions()) {\n <ax-button id=\"axp-btn-title-actions\" [look]=\"'blank'\" class=\"ax-sm -ax-mx-2\">\n <ax-prefix>\n <i class=\"fa-solid fa-caret-down fa-fw\"></i>\n </ax-prefix>\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (sub of page?.titleActions(); track $index) {\n <ng-container>\n <ax-button-item [attr.id]=\"'axp-btn-title-action-' + (sub.name || $index)\"\n [text]=\"(t(sub.title) | async)!\" [color]=\"sub.color\" [disabled]=\"sub.disabled\"\n [selected]=\"sub.command?.metadata?.['isSelected']\" (onClick)=\"handleActionClick(sub)\">\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 </ng-container>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n <!-------- Finish Title Actions -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Page Status -------->\n\n @if (page?.hasStatus()) {\n <axp-status-chip [value]=\"page?.status()?.value ?? null\" [readonly]=\"page?.status()?.readonly || false\"\n [definitionKey]=\"page?.status()?.definitionKey ?? null\" [entityData]=\"getEntityData()\"\n (transitionExecuted)=\"handleStatusTransition($event)\" class=\"__title-status\"></axp-status-chip>\n }\n <!-------- Finish Page Status -------->\n\n <!-------- Begin Title Badge -------->\n @if (page?.hasBadge()) {\n <div id=\"axp-page-badge\" class=\"__title-badge --{{ page?.badge()?.color }}\"\n [attr.title]=\"page?.badge()?.description ?? page?.badge()?.title\" [attr.aria-label]=\"page?.badge()?.title\">\n <i class=\"fa-solid fa-circle\" aria-hidden=\"true\"></i>\n <span class=\"__title-badge-label\">{{ page?.badge()?.title }}</span>\n </div>\n }\n <!-------- Finish Title Badge -------->\n\n </div>\n <!-------- Finish Title Container -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Page Description -------->\n @if (page?.hasDescription()) {\n <axp-layout-description id=\"axp-page-description\">\n {{ page?.description() | translate | async }}</axp-layout-description>\n }\n <!-------- Finish Page Description -------->\n </div>\n <!-------- Finish Title Section -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Page Actions -------->\n <axp-layout-actions id=\"axp-page-actions\" class=\"ax-shrink-0\">\n <axp-component-slot name=\"page-header-actions\"></axp-component-slot>\n <!-------- Begin Primary Actions -------->\n @if (page?.hasPrimaryActions()) {\n @for (item of page?.primaryMenuItems(); track $index) {\n @if (item.visible != false) {\n <ax-button [attr.id]=\"'axp-btn-primary-' + (item.name || item.title)\" [class.ax-sm]=\"deviceService.isSmall()\"\n [iconOnly]=\"deviceService.isSmall()\" [disabled]=\"item.disabled\" [text]=\"(t(item.title) | async)!\"\n [look]=\"'solid'\" [color]=\"item.color\" (onClick)=\"handleActionClick(item)\">\n <ax-prefix>\n <i class=\"{{ item.icon }}\"></i>\n </ax-prefix>\n @if (item?.items) {\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (sub of item?.items; track $index) {\n @if (sub.visible != false) {\n <ax-button-item [attr.id]=\"'axp-btn-primary-' + (item.name || item.title) + '-' + (sub.name || sub.title)\"\n [text]=\"(t(sub.title) | async)!\" [color]=\"sub.color\" [disabled]=\"sub.disabled\"\n (onClick)=\"handleActionClick(sub)\">\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 <!-------- Finish Primary Actions -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Secondary Actions -------->\n @if (page?.hasSecondaryActions()) {\n <ax-button id=\"axp-btn-secondary\" [class.ax-sm]=\"deviceService.isSmall()\" [iconOnly]=\"deviceService.isSmall()\"\n [text]=\"'@general:terms.interface.actions' | translate | async\"\n [look]=\"deviceService.isSmall() ? 'blank' : 'solid'\" [color]=\"'default'\">\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 (item of page?.secondaryMenuItems(); track $index) {\n @if (item.visible != false) {\n <ax-button-item [attr.id]=\"'axp-btn-secondary-' + (item.name || item.title)\"\n [text]=\"(item.title | translate | async)!\" [color]=\"item.color\" [disabled]=\"item.disabled\"\n (onClick)=\"handleSecondaryActionClick(item)\">\n <ax-prefix>\n <ax-icon icon=\"fa-light {{ item.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n @if (item.break) {\n <ax-divider></ax-divider>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n <!-------- Finish Secondary Actions -------->\n </axp-layout-actions>\n <!-------- Finish Page Actions -------->\n </axp-layout-title-bar>\n <!-------- Finish Title Bar -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Page Toolbar / Navbar -------->\n @if (!sticky.isSticky) {}\n <ng-content select=\"axp-page-toolbar\"></ng-content>\n <!-------- Finish Page Toolbar / Navbar -------->\n </axp-layout-header>\n <!-------- Finish Page Header -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Page Content -------->\n <ng-content select=\"axp-page-content\"></ng-content>\n <!-------- Finish Page Content -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Page Footer -------->\n <axp-page-footer-container id=\"axp-page-footer-container\"\n [ngStyle]=\"{ display: tt.isEmpty() && prefixSlot.isEmpty() && suffixSlot.isEmpty() ? 'none' : 'block' }\">\n <axp-layout-container #tt>\n <ng-content select=\"axp-page-footer\"></ng-content>\n </axp-layout-container>\n <axp-page-footer id=\"axp-page-footer\">\n <axp-layout-prefix>\n <axp-component-slot name=\"page-footer-start\" #prefixSlot=\"slot\"></axp-component-slot>\n </axp-layout-prefix>\n <axp-layout-suffix>\n <axp-component-slot name=\"page-footer-end\" #suffixSlot=\"slot\"></axp-component-slot>\n </axp-layout-suffix>\n </axp-page-footer>\n </axp-page-footer-container>\n <!-------- Finish Page Footer -------->\n</axp-layout-container>\n<!-------- Finish Main Layout Container -------->", styles: ["@charset \"UTF-8\";.axp-status-icon{font-size:.875rem;line-height:1}.axp-status-chip{display:inline-flex}.axp-status-chip--primary{background-color:rgb(var(--ax-sys-color-primary-lighter-surface));color:rgb(var(--ax-sys-color-on-primary-lighter-surface))}.axp-status-icon--primary{color:rgb(var(--ax-sys-color-primary-dark-surface))}.axp-status-chip--secondary{background-color:rgb(var(--ax-sys-color-secondary-lighter-surface));color:rgb(var(--ax-sys-color-on-secondary-lighter-surface))}.axp-status-icon--secondary{color:rgb(var(--ax-sys-color-secondary-dark-surface))}.axp-status-chip--success{background-color:rgb(var(--ax-sys-color-success-lighter-surface));color:rgb(var(--ax-sys-color-on-success-lighter-surface))}.axp-status-icon--success{color:rgb(var(--ax-sys-color-success-dark-surface))}.axp-status-chip--warning{background-color:rgb(var(--ax-sys-color-warning-lighter-surface));color:rgb(var(--ax-sys-color-on-warning-lighter-surface))}.axp-status-icon--warning{color:rgb(var(--ax-sys-color-warning-dark-surface))}.axp-status-chip--danger{background-color:rgb(var(--ax-sys-color-danger-lighter-surface));color:rgb(var(--ax-sys-color-on-danger-lighter-surface))}.axp-status-icon--danger{color:rgb(var(--ax-sys-color-danger-dark-surface))}.axp-status-chip--info{background-color:rgb(var(--ax-sys-color-accent3-lighter-surface));color:rgb(var(--ax-sys-color-on-accent3-lighter-surface))}.axp-status-icon--info{color:rgb(var(--ax-sys-color-accent3-dark-surface))}.axp-status-chip--accent1{background-color:rgb(var(--ax-sys-color-accent1-lighter-surface));color:rgb(var(--ax-sys-color-on-accent1-lighter-surface))}.axp-status-icon--accent1{color:rgb(var(--ax-sys-color-accent1-dark-surface))}.axp-status-chip--accent2{background-color:rgb(var(--ax-sys-color-accent2-lighter-surface));color:rgb(var(--ax-sys-color-on-accent2-lighter-surface))}.axp-status-icon--accent2{color:rgb(var(--ax-sys-color-accent2-dark-surface))}.axp-status-chip--accent3{background-color:rgb(var(--ax-sys-color-accent3-lighter-surface));color:rgb(var(--ax-sys-color-on-accent3-lighter-surface))}.axp-status-icon--accent3{color:rgb(var(--ax-sys-color-accent3-dark-surface))}.axp-status-chip--neutral{background-color:rgb(var(--ax-sys-color-neutral-lighter-surface));color:rgb(var(--ax-sys-color-on-neutral-lighter-surface))}.axp-status-icon--neutral{color:rgb(var(--ax-sys-color-neutral-dark-surface))}axp-layout-title{display:block;width:100%;font-weight:600}axp-layout-description{display:block;width:100%;font-size:.875rem;line-height:1.25rem;opacity:.65}axp-layout-actions{display:flex;align-items:center;gap:.75rem}axp-layout-actions axp-layout-actions-primary{display:flex;align-items:center;gap:.75rem}axp-layout-footer,axp-layout-toolbar,axp-layout-header,axp-page-header,axp-page-footer,axp-page-toolbar{display:flex;width:100%;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.5rem}axp-layout-footer>axp-layout-prefix,axp-layout-footer>axp-layout-suffix,axp-layout-toolbar>axp-layout-prefix,axp-layout-toolbar>axp-layout-suffix,axp-layout-header>axp-layout-prefix,axp-layout-header>axp-layout-suffix,axp-page-header>axp-layout-prefix,axp-page-header>axp-layout-suffix,axp-page-footer>axp-layout-prefix,axp-page-footer>axp-layout-suffix,axp-page-toolbar>axp-layout-prefix,axp-page-toolbar>axp-layout-suffix{display:flex;flex-direction:row;align-items:center;gap:.5rem}axp-layout-footer>axp-layout-prefix,axp-layout-toolbar>axp-layout-prefix,axp-layout-header>axp-layout-prefix,axp-page-header>axp-layout-prefix,axp-page-footer>axp-layout-prefix,axp-page-toolbar>axp-layout-prefix{order:-9999}axp-layout-footer>axp-layout-suffix,axp-layout-toolbar>axp-layout-suffix,axp-layout-header>axp-layout-suffix,axp-page-header>axp-layout-suffix,axp-page-footer>axp-layout-suffix,axp-page-toolbar>axp-layout-suffix{order:9999;margin-inline-start:auto}axp-layout-list{display:flex;flex-direction:column}axp-layout-list>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse));border-style:dashed}axp-layout-list:focus{outline:none}axp-layout-list-group{display:flex;flex-direction:column;padding-top:.5rem;padding-bottom:.5rem}axp-layout-list-group>axp-layout-title{padding-bottom:.5rem;font-size:.875rem;line-height:1.25rem;font-weight:600}axp-layout-list-group>axp-layout-header{display:flex;justify-content:space-between;padding-top:.5rem;padding-bottom:.5rem}axp-layout-list-item{margin-top:.25rem;display:flex;flex-direction:row;align-items:center;justify-content:space-between;gap:.75rem;padding:.5rem;font-size:.875rem;line-height:1.25rem}axp-layout-list-item:focus{outline:none}axp-layout-list-item.axp-state-focused,axp-layout-list-item:hover{cursor:pointer;border-radius:.25rem;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-light-surface),var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lightest-surface),var(--tw-text-opacity, 1))}axp-layout-list-item>axp-layout-prefix{margin-inline-end:auto;display:flex;flex-direction:row;gap:.5rem}axp-layout-list-item>axp-layout-content{flex:1 1 0%}axp-layout-list-item>axp-layout-content axp-layout-description{margin-top:.25rem!important;font-size:.75rem!important;line-height:1rem!important}axp-layout-list-item>axp-layout-suffix{margin-inline-start:auto;display:flex;flex-direction:row;gap:.5rem}axp-layout-sections{display:flex;flex-direction:column;gap:1rem}axp-layout-sections axp-layout-section{display:block;border-radius:.375rem;border-width:1px;--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}axp-layout-sections axp-layout-section>axp-layout-footer,axp-layout-sections axp-layout-section>axp-layout-header{padding:.5rem 1rem}@media(min-width:1280px){axp-layout-sections axp-layout-section>axp-layout-footer,axp-layout-sections axp-layout-section>axp-layout-header{padding-top:1rem;padding-bottom:1rem}}axp-layout-sections axp-layout-section>axp-layout-header{display:flex;flex-direction:column;gap:0px;border-top-left-radius:.375rem;border-top-right-radius:.375rem;border-bottom-width:1px}axp-layout-sections axp-layout-section>axp-layout-header axp-layout-title{font-weight:700;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lightest-surface),var(--tw-text-opacity, 1))}axp-layout-sections axp-layout-section>axp-layout-header axp-layout-description{margin-top:.25rem;font-size:.875rem;line-height:1.25rem}axp-layout-sections axp-layout-section>axp-layout-footer{display:flex;align-items:center;justify-content:space-between;border-bottom-right-radius:.375rem;border-bottom-left-radius:.375rem;border-top-width:1px;padding:1rem}axp-layout-sections axp-layout-section>axp-layout-footer>axp-layout-suffix{margin-inline-start:auto;display:flex;gap:.5rem}axp-layout-sections axp-layout-section>axp-layout-footer{opacity:0;animation:fadeInDown .5s ease-out forwards}@keyframes fadeInDown{0%{opacity:0}to{opacity:1}}axp-page-layout{display:flex;width:100%;height:100%;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-page-layout:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-dark-surface));color:rgb(var(--ax-sys-color-on-dark-surface));border-color:rgb(var(--ax-sys-color-border-dark-surface))}axp-page-layout axp-layout-start-side,axp-page-layout axp-layout-end-side{display:flex;min-height:100%;min-width:16rem;flex-direction:column;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-page-layout axp-layout-start-side:is(.ax-dark *),axp-page-layout axp-layout-end-side:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-darker-surface));color:rgb(var(--ax-sys-color-on-darker-surface));border-color:rgb(var(--ax-sys-color-border-darker-surface))}axp-page-layout axp-layout-start-side axp-layout-header,axp-page-layout axp-layout-end-side axp-layout-header{display:flex;flex-direction:column;gap:.5rem;padding:1rem}axp-page-layout axp-layout-start-side axp-layout-header>axp-layout-title,axp-page-layout axp-layout-end-side axp-layout-header>axp-layout-title{font-size:1.125rem;line-height:1.75rem;font-weight:500}axp-page-layout axp-layout-start-side>axp-layout-content,axp-page-layout axp-layout-end-side>axp-layout-content{flex:1 1 0%}axp-page-layout>axp-layout-container{position:relative;display:flex;width:100%;height:100%;flex-direction:column;overflow:auto}axp-page-layout>axp-layout-container>axp-layout-header{position:sticky;top:0;z-index:20;display:flex;flex-direction:column;align-items:flex-start;gap:0px;padding-top:.5rem;padding-bottom:.5rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;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-page-layout>axp-layout-container>axp-layout-header:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-dark-surface));color:rgb(var(--ax-sys-color-on-dark-surface));border-color:rgb(var(--ax-sys-color-border-dark-surface))}@media(min-width:768px){axp-page-layout>axp-layout-container>axp-layout-header{padding-top:1rem;padding-bottom:1rem}}axp-page-layout>axp-layout-container>axp-layout-header.axp-is-sticky{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}axp-page-layout>axp-layout-container>axp-layout-header ax-breadcrumbs ax-breadcrumbs-item{font-size:.75rem;line-height:1rem}axp-page-layout>axp-layout-container>axp-layout-header ax-breadcrumbs ax-breadcrumbs-item.ax-state-active .ax-breadcrumb-item-content{cursor:default;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lightest-surface),var(--tw-text-opacity, 1));opacity:.75}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar{display:flex;width:100%;align-items:center;justify-content:space-between;padding-left:1rem;padding-right:1rem}@media(min-width:1280px){axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar{border-width:0px}}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar ax-layout-nav-button{display:flex;align-items:center;justify-content:space-between}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container{display:flex;align-items:baseline;gap:.75rem}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container axp-layout-title{display:inline-block;width:fit-content;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:1.25rem;line-height:1.75rem;font-weight:500;line-height:1}@media(min-width:1024px){axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container axp-layout-title{font-size:1.5rem;line-height:2rem}}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge{display:inline-flex;--tw-translate-y: -3px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));align-items:center;align-self:baseline;border-radius:.375rem;padding:.25rem .5rem;font-size:.75rem;line-height:1rem;font-weight:600;line-height:1}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge i{margin-inline-end:.25rem;line-height:1;font-size:.5rem}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--warning{background-color:rgb(var(--ax-sys-color-warning-lightest-surface));color:rgb(var(--ax-sys-color-on-warning-lightest-surface));border-color:rgb(var(--ax-sys-color-border-warning-lightest-surface))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--warning i{color:rgb(var(--ax-sys-color-warning-500))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--danger{background-color:rgb(var(--ax-sys-color-danger-lightest-surface));color:rgb(var(--ax-sys-color-on-danger-lightest-surface));border-color:rgb(var(--ax-sys-color-border-danger-lightest-surface))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--danger i{color:rgb(var(--ax-sys-color-danger-500))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--success{background-color:rgb(var(--ax-sys-color-success-lightest-surface));color:rgb(var(--ax-sys-color-on-success-lightest-surface));border-color:rgb(var(--ax-sys-color-border-success-lightest-surface))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--success i{color:rgb(var(--ax-sys-color-success-500))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--primary{background-color:rgb(var(--ax-sys-color-primary-lightest-surface));color:rgb(var(--ax-sys-color-on-primary-lightest-surface));border-color:rgb(var(--ax-sys-color-border-primary-lightest-surface))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--primary i{color:rgb(var(--ax-sys-color-primary-500))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--secondary i{color:rgb(var(--ax-sys-color-secondary-500))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--default i{color:rgb(var(--ax-sys-color-on-surface)/.45)}@media(max-width:600px){axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge{--tw-translate-y: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));background-color:transparent;padding:0;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge .__title-badge-label{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge i{margin:0;font-size:.625rem}}axp-page-layout>axp-layout-container>axp-layout-header axp-page-toolbar{margin-top:.5rem;padding-left:1rem;padding-right:1rem}axp-page-layout>axp-layout-container>axp-page-content{display:flex;width:100%;flex:1 1 0%;flex-direction:column;padding:.75rem 1rem}axp-page-layout>axp-layout-container>axp-page-content.--scrollable{padding-bottom:1rem}axp-page-layout>axp-layout-container>axp-page-footer-container{border-top-width:1px;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-page-layout>axp-layout-container>axp-page-footer-container:is(.ax-dark *){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-page-layout>axp-layout-container>axp-page-footer-container{position:sticky;bottom:0;z-index:20;padding:.75rem;--tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / .05);--tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}@keyframes ax-fadeInUp{0%{transform:translate3d(0,100%,0);opacity:0}}axp-page-layout>axp-layout-container>axp-page-footer-container.--animated{animation:1s both ax-fadeInUp;transition-duration:.3s;transition-timing-function:cubic-bezier(0,0,.2,1);animation-duration:.3s;animation-timing-function:cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type:
|
|
150
150
|
//
|
|
151
151
|
AXCommonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3.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: AXBreadcrumbsModule }, { kind: "component", type: i4.AXBreadCrumbsComponent, selector: "ax-breadcrumbs" }, { kind: "component", type: i4.AXBreadCrumbsItemComponent, selector: "ax-breadcrumbs-item", inputs: ["disabled", "active"] }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i5.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i6.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: "component", type: i6.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i6.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i3$1.AXTranslatorDirective, selector: "[translate]" }, { kind: "ngmodule", type: AXDrawerModule }, { kind: "ngmodule", type: AXDrawerDirectiveModule }, { kind: "directive", type: i1.AXDrawerItemDirective, selector: "[axDrawerItem]", inputs: ["location", "collapsed", "backDrop", "mode", "transition", "closeOnBackdropClick", "backdropClass", "singleOpenMode"], outputs: ["collapseStateChanged", "locationChange", "collapsedChange", "backDropChange", "modeChange", "transitionChange", "closeOnBackdropClickChange", "backdropClassChange", "onBackdropClick", "singleOpenModeChange"], exportAs: ["axDrawerItem"] }, { kind: "ngmodule", type:
|
|
152
152
|
//
|
|
@@ -174,7 +174,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
174
174
|
AXPStickyDirective,
|
|
175
175
|
AXPThemeLayoutContainerComponent,
|
|
176
176
|
AXPStatusChipComponent,
|
|
177
|
-
], selector: 'axp-page-layout', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, hostDirectives: [AXDrawerContainerDirective], providers: [], template: "<!-------- Begin Start Side Drawer -------->\n<div id=\"axp-drawer-start\" [mode]=\"deviceService.isSmall() ? 'overlay' : 'push'\" [transition]=\"250\" axDrawerItem\n [backDrop]=\"true\" (onBackdropClick)=\"handleBackdropClick($event)\" #startSideDrawer=\"axDrawerItem\"\n [backdropClass]=\"'ax-bg-darkest/75'\" [collapsed]=\"deviceService.isSmall()\" drawerLocation=\"start\"\n class=\"ax-z-50 ax-h-full\">\n <ng-content select=\"axp-layout-start-side\"></ng-content>\n</div>\n<!-------- Finish Start Side Drawer -------->\n<!--------------------------------------------------------------->\n<!-------- Begin Main Layout Container -------->\n<axp-layout-container id=\"axp-page-layout\" #container>\n <!-------- Begin Page Header -------->\n <axp-layout-header id=\"axp-page-header\" *translate=\"let t\" #sticky=\"axpSticky\" [axpSticky]=\"'axp-is-sticky'\"\n [stickyOffset]=\"50\" [stickyParent]=\"container.hostElement\">\n <!-------- Begin Back Button (Mobile Only) -------->\n @if (page?.hasBackButton() && deviceService.isSmall()) {\n <ax-button id=\"axp-btn-back\" [look]=\"'blank'\" class=\"ax-sm ax-w-fit ax-ms-1\" color=\"secondary\"\n (click)=\"page?.onBackButtonClick()\" [text]=\"(page?.backButton()?.title | translate | async) ?? ''\">\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-chevron-left rtl:ax-rotate-180\"></ax-icon>\n </ax-prefix>\n </ax-button>\n }\n <!-------- Finish Back Button -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Title Bar -------->\n <axp-layout-title-bar id=\"axp-title-bar\">\n <!-------- Begin Title Section -------->\n <div class=\"ax-flex ax-flex-col ax-transition ax-shrink-1 ax-min-w-0\">\n <!-------- Begin Breadcrumbs -------->\n @if (page?.hasBreadcrumbs() && !deviceService.isSmall()) {\n <ax-breadcrumbs id=\"axp-breadcrumb\" class=\"ax-mb-1\">\n @for (item of page?.breadcrumbs(); track $index) {\n <ax-breadcrumbs-item [attr.id]=\"'axp-breadcrumb-item-' + $index\" [active]=\"$last\"\n (click)=\"!$last && item.command ? execute(item.command) : null\">\n @if (item.icon) {\n <i [class]=\"item.icon\"></i>\n }\n {{ t(item.title) | async }}\n </ax-breadcrumbs-item>\n }\n <ng-template #divider>\n <i class=\"fa-regular fa-chevron-right rtl:ax-rotate-180 fa-sm\"></i>\n </ng-template>\n </ax-breadcrumbs>\n }\n <!-------- Finish Breadcrumbs -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Title Container -------->\n <div class=\"__title-container\">\n <!-------- Begin Page Title -------->\n @if (page?.hasTitle()) {\n <axp-layout-title id=\"axp-page-title\">\n @if (page?.hasTitleIcon()) {\n <ax-icon [icon]=\"page?.titleIcon()!\" class=\"ax-me-2\"></ax-icon>\n }\n {{ page?.title() | translate | async }}\n </axp-layout-title>\n }\n <!-------- Finish Page Title -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Title Actions -------->\n @if (page?.hasTitleActions()) {\n <ax-button id=\"axp-btn-title-actions\" [look]=\"'blank'\" class=\"ax-sm -ax-mx-2\">\n <ax-prefix>\n <i class=\"fa-solid fa-caret-down fa-fw\"></i>\n </ax-prefix>\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (sub of page?.titleActions(); track $index) {\n <ng-container>\n <ax-button-item [attr.id]=\"'axp-btn-title-action-' + (sub.name || $index)\"\n [text]=\"(t(sub.title) | async)!\" [color]=\"sub.color\" [disabled]=\"sub.disabled\"\n [selected]=\"sub.command?.metadata?.['isSelected']\" (onClick)=\"handleActionClick(sub)\">\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 </ng-container>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n <!-------- Finish Title Actions -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Page Status -------->\n\n @if (page?.hasStatus()) {\n <axp-status-chip [value]=\"page?.status()?.value ?? null\" [readonly]=\"page?.status()?.readonly || false\"\n [definitionKey]=\"page?.status()?.definitionKey ?? null\" [entityData]=\"getEntityData()\"\n (transitionExecuted)=\"handleStatusTransition($event)\" class=\"__title-status\"></axp-status-chip>\n }\n <!-------- Finish Page Status -------->\n\n <!-------- Begin Title Badge -------->\n @if (page?.hasBadge()) {\n <div\n id=\"axp-page-badge\"\n class=\"__title-badge --{{ page?.badge()?.color }}\"\n [attr.title]=\"page?.badge()?.description ?? page?.badge()?.title\"\n [attr.aria-label]=\"page?.badge()?.title\"\n >\n <i class=\"fa-solid fa-circle\" aria-hidden=\"true\"></i>\n <span class=\"__title-badge-label\">{{ page?.badge()?.title }}</span>\n </div>\n }\n <!-------- Finish Title Badge -------->\n\n </div>\n <!-------- Finish Title Container -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Page Description -------->\n @if (page?.hasDescription()) {\n <axp-layout-description id=\"axp-page-description\">\n {{ page?.description() | translate | async }}</axp-layout-description>\n }\n <!-------- Finish Page Description -------->\n </div>\n <!-------- Finish Title Section -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Page Actions -------->\n <axp-layout-actions id=\"axp-page-actions\" class=\"ax-shrink-0\">\n <axp-component-slot name=\"page-header-actions\"></axp-component-slot>\n <!-------- Begin Primary Actions -------->\n @if (page?.hasPrimaryActions()) {\n @for (item of page?.primaryMenuItems(); track $index) {\n @if (item.visible != false) {\n <ax-button [attr.id]=\"'axp-btn-primary-' + (item.name || item.title)\" [class.ax-sm]=\"deviceService.isSmall()\"\n [iconOnly]=\"deviceService.isSmall()\" [disabled]=\"item.disabled\" [text]=\"(t(item.title) | async)!\"\n [look]=\"'solid'\" [color]=\"item.color\" (onClick)=\"handleActionClick(item)\">\n <ax-prefix>\n <i class=\"{{ item.icon }}\"></i>\n </ax-prefix>\n @if (item?.items) {\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (sub of item?.items; track $index) {\n @if (sub.visible != false) {\n <ax-button-item [attr.id]=\"'axp-btn-primary-' + (item.name || item.title) + '-' + (sub.name || sub.title)\"\n [text]=\"(t(sub.title) | async)!\" [color]=\"sub.color\" [disabled]=\"sub.disabled\"\n (onClick)=\"handleActionClick(sub)\">\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 <!-------- Finish Primary Actions -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Secondary Actions -------->\n @if (page?.hasSecondaryActions()) {\n <ax-button id=\"axp-btn-secondary\" [class.ax-sm]=\"deviceService.isSmall()\" [iconOnly]=\"deviceService.isSmall()\"\n [text]=\"'@general:terms.interface.actions' | translate | async\"\n [look]=\"deviceService.isSmall() ? 'blank' : 'solid'\" [color]=\"'default'\">\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 (item of page?.secondaryMenuItems(); track $index) {\n @if (item.visible != false) {\n <ax-button-item [attr.id]=\"'axp-btn-secondary-' + (item.name || item.title)\"\n [text]=\"(item.title | translate | async)!\" [color]=\"item.color\" [disabled]=\"item.disabled\"\n (onClick)=\"handleSecondaryActionClick(item)\">\n <ax-prefix>\n <ax-icon icon=\"fa-light {{ item.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n @if (item.break) {\n <ax-divider></ax-divider>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n <!-------- Finish Secondary Actions -------->\n </axp-layout-actions>\n <!-------- Finish Page Actions -------->\n </axp-layout-title-bar>\n <!-------- Finish Title Bar -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Page Toolbar / Navbar -------->\n @if (!sticky.isSticky) {}\n <ng-content select=\"axp-page-toolbar\"></ng-content>\n <!-------- Finish Page Toolbar / Navbar -------->\n </axp-layout-header>\n <!-------- Finish Page Header -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Page Content -------->\n <ng-content select=\"axp-page-content\"></ng-content>\n <!-------- Finish Page Content -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Page Footer -------->\n <axp-page-footer-container id=\"axp-page-footer-container\"\n [ngStyle]=\"{ display: tt.isEmpty() && prefixSlot.isEmpty() && suffixSlot.isEmpty() ? 'none' : 'block' }\">\n <axp-layout-container #tt>\n <ng-content select=\"axp-page-footer\"></ng-content>\n </axp-layout-container>\n <axp-page-footer id=\"axp-page-footer\">\n <axp-layout-prefix>\n <axp-component-slot name=\"page-footer-start\" #prefixSlot=\"slot\"></axp-component-slot>\n </axp-layout-prefix>\n <axp-layout-suffix>\n <axp-component-slot name=\"page-footer-end\" #suffixSlot=\"slot\"></axp-component-slot>\n </axp-layout-suffix>\n </axp-page-footer>\n </axp-page-footer-container>\n <!-------- Finish Page Footer -------->\n</axp-layout-container>\n<!-------- Finish Main Layout Container -------->", styles: ["@charset \"UTF-8\";.axp-status-icon{font-size:.875rem;line-height:1}.axp-status-chip{display:inline-flex}.axp-status-chip--primary{background-color:rgb(var(--ax-sys-color-primary-lighter-surface));color:rgb(var(--ax-sys-color-on-primary-lighter-surface))}.axp-status-icon--primary{color:rgb(var(--ax-sys-color-primary-dark-surface))}.axp-status-chip--secondary{background-color:rgb(var(--ax-sys-color-secondary-lighter-surface));color:rgb(var(--ax-sys-color-on-secondary-lighter-surface))}.axp-status-icon--secondary{color:rgb(var(--ax-sys-color-secondary-dark-surface))}.axp-status-chip--success{background-color:rgb(var(--ax-sys-color-success-lighter-surface));color:rgb(var(--ax-sys-color-on-success-lighter-surface))}.axp-status-icon--success{color:rgb(var(--ax-sys-color-success-dark-surface))}.axp-status-chip--warning{background-color:rgb(var(--ax-sys-color-warning-lighter-surface));color:rgb(var(--ax-sys-color-on-warning-lighter-surface))}.axp-status-icon--warning{color:rgb(var(--ax-sys-color-warning-dark-surface))}.axp-status-chip--danger{background-color:rgb(var(--ax-sys-color-danger-lighter-surface));color:rgb(var(--ax-sys-color-on-danger-lighter-surface))}.axp-status-icon--danger{color:rgb(var(--ax-sys-color-danger-dark-surface))}.axp-status-chip--info{background-color:rgb(var(--ax-sys-color-accent3-lighter-surface));color:rgb(var(--ax-sys-color-on-accent3-lighter-surface))}.axp-status-icon--info{color:rgb(var(--ax-sys-color-accent3-dark-surface))}.axp-status-chip--accent1{background-color:rgb(var(--ax-sys-color-accent1-lighter-surface));color:rgb(var(--ax-sys-color-on-accent1-lighter-surface))}.axp-status-icon--accent1{color:rgb(var(--ax-sys-color-accent1-dark-surface))}.axp-status-chip--accent2{background-color:rgb(var(--ax-sys-color-accent2-lighter-surface));color:rgb(var(--ax-sys-color-on-accent2-lighter-surface))}.axp-status-icon--accent2{color:rgb(var(--ax-sys-color-accent2-dark-surface))}.axp-status-chip--accent3{background-color:rgb(var(--ax-sys-color-accent3-lighter-surface));color:rgb(var(--ax-sys-color-on-accent3-lighter-surface))}.axp-status-icon--accent3{color:rgb(var(--ax-sys-color-accent3-dark-surface))}.axp-status-chip--neutral{background-color:rgb(var(--ax-sys-color-neutral-lighter-surface));color:rgb(var(--ax-sys-color-on-neutral-lighter-surface))}.axp-status-icon--neutral{color:rgb(var(--ax-sys-color-neutral-dark-surface))}axp-layout-title{display:block;width:100%;font-weight:600}axp-layout-description{display:block;width:100%;font-size:.875rem;line-height:1.25rem;opacity:.65}axp-layout-actions{display:flex;align-items:center;gap:.75rem}axp-layout-actions axp-layout-actions-primary{display:flex;align-items:center;gap:.75rem}axp-layout-footer,axp-layout-toolbar,axp-layout-header,axp-page-header,axp-page-footer,axp-page-toolbar{display:flex;width:100%;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.5rem}axp-layout-footer>axp-layout-prefix,axp-layout-footer>axp-layout-suffix,axp-layout-toolbar>axp-layout-prefix,axp-layout-toolbar>axp-layout-suffix,axp-layout-header>axp-layout-prefix,axp-layout-header>axp-layout-suffix,axp-page-header>axp-layout-prefix,axp-page-header>axp-layout-suffix,axp-page-footer>axp-layout-prefix,axp-page-footer>axp-layout-suffix,axp-page-toolbar>axp-layout-prefix,axp-page-toolbar>axp-layout-suffix{display:flex;flex-direction:row;align-items:center;gap:.5rem}axp-layout-footer>axp-layout-prefix,axp-layout-toolbar>axp-layout-prefix,axp-layout-header>axp-layout-prefix,axp-page-header>axp-layout-prefix,axp-page-footer>axp-layout-prefix,axp-page-toolbar>axp-layout-prefix{order:-9999}axp-layout-footer>axp-layout-suffix,axp-layout-toolbar>axp-layout-suffix,axp-layout-header>axp-layout-suffix,axp-page-header>axp-layout-suffix,axp-page-footer>axp-layout-suffix,axp-page-toolbar>axp-layout-suffix{order:9999;margin-inline-start:auto}axp-layout-list{display:flex;flex-direction:column}axp-layout-list>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse));border-style:dashed}axp-layout-list:focus{outline:none}axp-layout-list-group{display:flex;flex-direction:column;padding-top:.5rem;padding-bottom:.5rem}axp-layout-list-group>axp-layout-title{padding-bottom:.5rem;font-size:.875rem;line-height:1.25rem;font-weight:600}axp-layout-list-group>axp-layout-header{display:flex;justify-content:space-between;padding-top:.5rem;padding-bottom:.5rem}axp-layout-list-item{margin-top:.25rem;display:flex;flex-direction:row;align-items:center;justify-content:space-between;gap:.75rem;padding:.5rem;font-size:.875rem;line-height:1.25rem}axp-layout-list-item:focus{outline:none}axp-layout-list-item.axp-state-focused,axp-layout-list-item:hover{cursor:pointer;border-radius:.25rem;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-light-surface),var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lightest-surface),var(--tw-text-opacity, 1))}axp-layout-list-item>axp-layout-prefix{margin-inline-end:auto;display:flex;flex-direction:row;gap:.5rem}axp-layout-list-item>axp-layout-content{flex:1 1 0%}axp-layout-list-item>axp-layout-content axp-layout-description{margin-top:.25rem!important;font-size:.75rem!important;line-height:1rem!important}axp-layout-list-item>axp-layout-suffix{margin-inline-start:auto;display:flex;flex-direction:row;gap:.5rem}axp-layout-sections{display:flex;flex-direction:column;gap:1rem}axp-layout-sections axp-layout-section{display:block;border-radius:.375rem;border-width:1px;--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}axp-layout-sections axp-layout-section>axp-layout-footer,axp-layout-sections axp-layout-section>axp-layout-header{padding:.5rem 1rem}@media(min-width:1280px){axp-layout-sections axp-layout-section>axp-layout-footer,axp-layout-sections axp-layout-section>axp-layout-header{padding-top:1rem;padding-bottom:1rem}}axp-layout-sections axp-layout-section>axp-layout-header{display:flex;flex-direction:column;gap:0px;border-top-left-radius:.375rem;border-top-right-radius:.375rem;border-bottom-width:1px}axp-layout-sections axp-layout-section>axp-layout-header axp-layout-title{font-weight:700;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lightest-surface),var(--tw-text-opacity, 1))}axp-layout-sections axp-layout-section>axp-layout-header axp-layout-description{margin-top:.25rem;font-size:.875rem;line-height:1.25rem}axp-layout-sections axp-layout-section>axp-layout-footer{display:flex;align-items:center;justify-content:space-between;border-bottom-right-radius:.375rem;border-bottom-left-radius:.375rem;border-top-width:1px;padding:1rem}axp-layout-sections axp-layout-section>axp-layout-footer>axp-layout-suffix{margin-inline-start:auto;display:flex;gap:.5rem}axp-layout-sections axp-layout-section>axp-layout-footer{opacity:0;animation:fadeInDown .5s ease-out forwards}@keyframes fadeInDown{0%{opacity:0}to{opacity:1}}axp-page-layout{display:flex;width:100%;height:100%;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-page-layout:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-dark-surface));color:rgb(var(--ax-sys-color-on-dark-surface));border-color:rgb(var(--ax-sys-color-border-dark-surface))}axp-page-layout axp-layout-start-side,axp-page-layout axp-layout-end-side{display:flex;min-height:100%;min-width:16rem;flex-direction:column;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-page-layout axp-layout-start-side:is(.ax-dark *),axp-page-layout axp-layout-end-side:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-darker-surface));color:rgb(var(--ax-sys-color-on-darker-surface));border-color:rgb(var(--ax-sys-color-border-darker-surface))}axp-page-layout axp-layout-start-side axp-layout-header,axp-page-layout axp-layout-end-side axp-layout-header{display:flex;flex-direction:column;gap:.5rem;padding:1rem}axp-page-layout axp-layout-start-side axp-layout-header>axp-layout-title,axp-page-layout axp-layout-end-side axp-layout-header>axp-layout-title{font-size:1.125rem;line-height:1.75rem;font-weight:500}axp-page-layout axp-layout-start-side>axp-layout-content,axp-page-layout axp-layout-end-side>axp-layout-content{flex:1 1 0%}axp-page-layout>axp-layout-container{position:relative;display:flex;width:100%;height:100%;flex-direction:column;overflow:auto}axp-page-layout>axp-layout-container>axp-layout-header{position:sticky;top:0;z-index:20;display:flex;flex-direction:column;align-items:flex-start;gap:0px;padding-top:.5rem;padding-bottom:.5rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;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-page-layout>axp-layout-container>axp-layout-header:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-dark-surface));color:rgb(var(--ax-sys-color-on-dark-surface));border-color:rgb(var(--ax-sys-color-border-dark-surface))}@media(min-width:768px){axp-page-layout>axp-layout-container>axp-layout-header{padding-top:1rem;padding-bottom:1rem}}axp-page-layout>axp-layout-container>axp-layout-header.axp-is-sticky{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}axp-page-layout>axp-layout-container>axp-layout-header ax-breadcrumbs ax-breadcrumbs-item{font-size:.75rem;line-height:1rem}axp-page-layout>axp-layout-container>axp-layout-header ax-breadcrumbs ax-breadcrumbs-item.ax-state-active .ax-breadcrumb-item-content{cursor:default;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lightest-surface),var(--tw-text-opacity, 1));opacity:.75}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar{display:flex;width:100%;align-items:center;justify-content:space-between;padding-left:1rem;padding-right:1rem}@media(min-width:1280px){axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar{border-width:0px}}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar ax-layout-nav-button{display:flex;align-items:center;justify-content:space-between}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container{display:flex;align-items:baseline;gap:.75rem}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container axp-layout-title{display:inline-block;width:fit-content;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:1.25rem;line-height:1.75rem;font-weight:500;line-height:1}@media(min-width:1024px){axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container axp-layout-title{font-size:1.5rem;line-height:2rem}}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge{display:inline-flex;--tw-translate-y: -3px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));align-items:center;align-self:baseline;border-radius:.375rem;padding:.25rem .5rem;font-size:.75rem;line-height:1rem;font-weight:600;line-height:1}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge i{margin-inline-end:.25rem;line-height:1;font-size:.5rem}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--warning{background-color:rgb(var(--ax-sys-color-warning-lightest-surface));color:rgb(var(--ax-sys-color-on-warning-lightest-surface));border-color:rgb(var(--ax-sys-color-border-warning-lightest-surface))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--warning i{color:rgb(var(--ax-sys-color-warning-500))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--danger{background-color:rgb(var(--ax-sys-color-danger-lightest-surface));color:rgb(var(--ax-sys-color-on-danger-lightest-surface));border-color:rgb(var(--ax-sys-color-border-danger-lightest-surface))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--danger i{color:rgb(var(--ax-sys-color-danger-500))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--success{background-color:rgb(var(--ax-sys-color-success-lightest-surface));color:rgb(var(--ax-sys-color-on-success-lightest-surface));border-color:rgb(var(--ax-sys-color-border-success-lightest-surface))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--success i{color:rgb(var(--ax-sys-color-success-500))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--primary{background-color:rgb(var(--ax-sys-color-primary-lightest-surface));color:rgb(var(--ax-sys-color-on-primary-lightest-surface));border-color:rgb(var(--ax-sys-color-border-primary-lightest-surface))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--primary i{color:rgb(var(--ax-sys-color-primary-500))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--secondary i{color:rgb(var(--ax-sys-color-secondary-500))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--default i{color:rgb(var(--ax-sys-color-on-surface)/.45)}@media(max-width:600px){axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge{--tw-translate-y: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));background-color:transparent;padding:0;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge .__title-badge-label{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge i{margin:0;font-size:.625rem}}axp-page-layout>axp-layout-container>axp-layout-header axp-page-toolbar{margin-top:.5rem;padding-left:1rem;padding-right:1rem}axp-page-layout>axp-layout-container>axp-page-content{display:flex;width:100%;flex:1 1 0%;flex-direction:column;padding:.75rem 1rem}axp-page-layout>axp-layout-container>axp-page-content.--scrollable{padding-bottom:1rem}axp-page-layout>axp-layout-container>axp-page-footer-container{border-top-width:1px;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-page-layout>axp-layout-container>axp-page-footer-container:is(.ax-dark *){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-page-layout>axp-layout-container>axp-page-footer-container{position:sticky;bottom:0;z-index:20;padding:.75rem;--tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / .05);--tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}@keyframes ax-fadeInUp{0%{transform:translate3d(0,100%,0);opacity:0}}axp-page-layout>axp-layout-container>axp-page-footer-container.--animated{animation:1s both ax-fadeInUp;transition-duration:.3s;transition-timing-function:cubic-bezier(0,0,.2,1);animation-duration:.3s;animation-timing-function:cubic-bezier(0,0,.2,1)}\n"] }]
|
|
177
|
+
], selector: 'axp-page-layout', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, hostDirectives: [AXDrawerContainerDirective], providers: [], template: "<!-------- Begin Start Side Drawer -------->\n<div id=\"axp-drawer-start\" [mode]=\"deviceService.isSmall() ? 'overlay' : 'push'\" [transition]=\"250\" axDrawerItem\n [backDrop]=\"true\" (onBackdropClick)=\"handleBackdropClick($event)\" #startSideDrawer=\"axDrawerItem\"\n [backdropClass]=\"'ax-bg-darkest/75'\" [collapsed]=\"deviceService.isSmall()\" drawerLocation=\"start\" class=\"ax-h-full\">\n <ng-content select=\"axp-layout-start-side\"></ng-content>\n</div>\n<!-------- Finish Start Side Drawer -------->\n<!--------------------------------------------------------------->\n<!-------- Begin Main Layout Container -------->\n<axp-layout-container id=\"axp-page-layout\" #container>\n <!-------- Begin Page Header -------->\n <axp-layout-header id=\"axp-page-header\" *translate=\"let t\" #sticky=\"axpSticky\" [axpSticky]=\"'axp-is-sticky'\"\n [stickyOffset]=\"50\" [stickyParent]=\"container.hostElement\">\n <!-------- Begin Back Button (Mobile Only) -------->\n @if (page?.hasBackButton() && deviceService.isSmall()) {\n <ax-button id=\"axp-btn-back\" [look]=\"'blank'\" class=\"ax-sm ax-w-fit ax-ms-1\" color=\"secondary\"\n (click)=\"page?.onBackButtonClick()\" [text]=\"(page?.backButton()?.title | translate | async) ?? ''\">\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-chevron-left rtl:ax-rotate-180\"></ax-icon>\n </ax-prefix>\n </ax-button>\n }\n <!-------- Finish Back Button -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Title Bar -------->\n <axp-layout-title-bar id=\"axp-title-bar\">\n <!-------- Begin Title Section -------->\n <div class=\"ax-flex ax-flex-col ax-transition ax-shrink-1 ax-min-w-0\">\n <!-------- Begin Breadcrumbs -------->\n @if (page?.hasBreadcrumbs() && !deviceService.isSmall()) {\n <ax-breadcrumbs id=\"axp-breadcrumb\" class=\"ax-mb-1\">\n @for (item of page?.breadcrumbs(); track $index) {\n <ax-breadcrumbs-item [attr.id]=\"'axp-breadcrumb-item-' + $index\" [active]=\"$last\"\n (click)=\"!$last && item.command ? execute(item.command) : null\">\n @if (item.icon) {\n <i [class]=\"item.icon\"></i>\n }\n {{ t(item.title) | async }}\n </ax-breadcrumbs-item>\n }\n <ng-template #divider>\n <i class=\"fa-regular fa-chevron-right rtl:ax-rotate-180 fa-sm\"></i>\n </ng-template>\n </ax-breadcrumbs>\n }\n <!-------- Finish Breadcrumbs -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Title Container -------->\n <div class=\"__title-container\">\n <!-------- Begin Page Title -------->\n @if (page?.hasTitle()) {\n <axp-layout-title id=\"axp-page-title\">\n @if (page?.hasTitleIcon()) {\n <ax-icon [icon]=\"page?.titleIcon()!\" class=\"ax-me-2\"></ax-icon>\n }\n {{ page?.title() | translate | async }}\n </axp-layout-title>\n }\n <!-------- Finish Page Title -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Title Actions -------->\n @if (page?.hasTitleActions()) {\n <ax-button id=\"axp-btn-title-actions\" [look]=\"'blank'\" class=\"ax-sm -ax-mx-2\">\n <ax-prefix>\n <i class=\"fa-solid fa-caret-down fa-fw\"></i>\n </ax-prefix>\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (sub of page?.titleActions(); track $index) {\n <ng-container>\n <ax-button-item [attr.id]=\"'axp-btn-title-action-' + (sub.name || $index)\"\n [text]=\"(t(sub.title) | async)!\" [color]=\"sub.color\" [disabled]=\"sub.disabled\"\n [selected]=\"sub.command?.metadata?.['isSelected']\" (onClick)=\"handleActionClick(sub)\">\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 </ng-container>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n <!-------- Finish Title Actions -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Page Status -------->\n\n @if (page?.hasStatus()) {\n <axp-status-chip [value]=\"page?.status()?.value ?? null\" [readonly]=\"page?.status()?.readonly || false\"\n [definitionKey]=\"page?.status()?.definitionKey ?? null\" [entityData]=\"getEntityData()\"\n (transitionExecuted)=\"handleStatusTransition($event)\" class=\"__title-status\"></axp-status-chip>\n }\n <!-------- Finish Page Status -------->\n\n <!-------- Begin Title Badge -------->\n @if (page?.hasBadge()) {\n <div id=\"axp-page-badge\" class=\"__title-badge --{{ page?.badge()?.color }}\"\n [attr.title]=\"page?.badge()?.description ?? page?.badge()?.title\" [attr.aria-label]=\"page?.badge()?.title\">\n <i class=\"fa-solid fa-circle\" aria-hidden=\"true\"></i>\n <span class=\"__title-badge-label\">{{ page?.badge()?.title }}</span>\n </div>\n }\n <!-------- Finish Title Badge -------->\n\n </div>\n <!-------- Finish Title Container -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Page Description -------->\n @if (page?.hasDescription()) {\n <axp-layout-description id=\"axp-page-description\">\n {{ page?.description() | translate | async }}</axp-layout-description>\n }\n <!-------- Finish Page Description -------->\n </div>\n <!-------- Finish Title Section -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Page Actions -------->\n <axp-layout-actions id=\"axp-page-actions\" class=\"ax-shrink-0\">\n <axp-component-slot name=\"page-header-actions\"></axp-component-slot>\n <!-------- Begin Primary Actions -------->\n @if (page?.hasPrimaryActions()) {\n @for (item of page?.primaryMenuItems(); track $index) {\n @if (item.visible != false) {\n <ax-button [attr.id]=\"'axp-btn-primary-' + (item.name || item.title)\" [class.ax-sm]=\"deviceService.isSmall()\"\n [iconOnly]=\"deviceService.isSmall()\" [disabled]=\"item.disabled\" [text]=\"(t(item.title) | async)!\"\n [look]=\"'solid'\" [color]=\"item.color\" (onClick)=\"handleActionClick(item)\">\n <ax-prefix>\n <i class=\"{{ item.icon }}\"></i>\n </ax-prefix>\n @if (item?.items) {\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (sub of item?.items; track $index) {\n @if (sub.visible != false) {\n <ax-button-item [attr.id]=\"'axp-btn-primary-' + (item.name || item.title) + '-' + (sub.name || sub.title)\"\n [text]=\"(t(sub.title) | async)!\" [color]=\"sub.color\" [disabled]=\"sub.disabled\"\n (onClick)=\"handleActionClick(sub)\">\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 <!-------- Finish Primary Actions -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Secondary Actions -------->\n @if (page?.hasSecondaryActions()) {\n <ax-button id=\"axp-btn-secondary\" [class.ax-sm]=\"deviceService.isSmall()\" [iconOnly]=\"deviceService.isSmall()\"\n [text]=\"'@general:terms.interface.actions' | translate | async\"\n [look]=\"deviceService.isSmall() ? 'blank' : 'solid'\" [color]=\"'default'\">\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 (item of page?.secondaryMenuItems(); track $index) {\n @if (item.visible != false) {\n <ax-button-item [attr.id]=\"'axp-btn-secondary-' + (item.name || item.title)\"\n [text]=\"(item.title | translate | async)!\" [color]=\"item.color\" [disabled]=\"item.disabled\"\n (onClick)=\"handleSecondaryActionClick(item)\">\n <ax-prefix>\n <ax-icon icon=\"fa-light {{ item.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n @if (item.break) {\n <ax-divider></ax-divider>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n <!-------- Finish Secondary Actions -------->\n </axp-layout-actions>\n <!-------- Finish Page Actions -------->\n </axp-layout-title-bar>\n <!-------- Finish Title Bar -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Page Toolbar / Navbar -------->\n @if (!sticky.isSticky) {}\n <ng-content select=\"axp-page-toolbar\"></ng-content>\n <!-------- Finish Page Toolbar / Navbar -------->\n </axp-layout-header>\n <!-------- Finish Page Header -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Page Content -------->\n <ng-content select=\"axp-page-content\"></ng-content>\n <!-------- Finish Page Content -------->\n <!--------------------------------------------------------------->\n <!-------- Begin Page Footer -------->\n <axp-page-footer-container id=\"axp-page-footer-container\"\n [ngStyle]=\"{ display: tt.isEmpty() && prefixSlot.isEmpty() && suffixSlot.isEmpty() ? 'none' : 'block' }\">\n <axp-layout-container #tt>\n <ng-content select=\"axp-page-footer\"></ng-content>\n </axp-layout-container>\n <axp-page-footer id=\"axp-page-footer\">\n <axp-layout-prefix>\n <axp-component-slot name=\"page-footer-start\" #prefixSlot=\"slot\"></axp-component-slot>\n </axp-layout-prefix>\n <axp-layout-suffix>\n <axp-component-slot name=\"page-footer-end\" #suffixSlot=\"slot\"></axp-component-slot>\n </axp-layout-suffix>\n </axp-page-footer>\n </axp-page-footer-container>\n <!-------- Finish Page Footer -------->\n</axp-layout-container>\n<!-------- Finish Main Layout Container -------->", styles: ["@charset \"UTF-8\";.axp-status-icon{font-size:.875rem;line-height:1}.axp-status-chip{display:inline-flex}.axp-status-chip--primary{background-color:rgb(var(--ax-sys-color-primary-lighter-surface));color:rgb(var(--ax-sys-color-on-primary-lighter-surface))}.axp-status-icon--primary{color:rgb(var(--ax-sys-color-primary-dark-surface))}.axp-status-chip--secondary{background-color:rgb(var(--ax-sys-color-secondary-lighter-surface));color:rgb(var(--ax-sys-color-on-secondary-lighter-surface))}.axp-status-icon--secondary{color:rgb(var(--ax-sys-color-secondary-dark-surface))}.axp-status-chip--success{background-color:rgb(var(--ax-sys-color-success-lighter-surface));color:rgb(var(--ax-sys-color-on-success-lighter-surface))}.axp-status-icon--success{color:rgb(var(--ax-sys-color-success-dark-surface))}.axp-status-chip--warning{background-color:rgb(var(--ax-sys-color-warning-lighter-surface));color:rgb(var(--ax-sys-color-on-warning-lighter-surface))}.axp-status-icon--warning{color:rgb(var(--ax-sys-color-warning-dark-surface))}.axp-status-chip--danger{background-color:rgb(var(--ax-sys-color-danger-lighter-surface));color:rgb(var(--ax-sys-color-on-danger-lighter-surface))}.axp-status-icon--danger{color:rgb(var(--ax-sys-color-danger-dark-surface))}.axp-status-chip--info{background-color:rgb(var(--ax-sys-color-accent3-lighter-surface));color:rgb(var(--ax-sys-color-on-accent3-lighter-surface))}.axp-status-icon--info{color:rgb(var(--ax-sys-color-accent3-dark-surface))}.axp-status-chip--accent1{background-color:rgb(var(--ax-sys-color-accent1-lighter-surface));color:rgb(var(--ax-sys-color-on-accent1-lighter-surface))}.axp-status-icon--accent1{color:rgb(var(--ax-sys-color-accent1-dark-surface))}.axp-status-chip--accent2{background-color:rgb(var(--ax-sys-color-accent2-lighter-surface));color:rgb(var(--ax-sys-color-on-accent2-lighter-surface))}.axp-status-icon--accent2{color:rgb(var(--ax-sys-color-accent2-dark-surface))}.axp-status-chip--accent3{background-color:rgb(var(--ax-sys-color-accent3-lighter-surface));color:rgb(var(--ax-sys-color-on-accent3-lighter-surface))}.axp-status-icon--accent3{color:rgb(var(--ax-sys-color-accent3-dark-surface))}.axp-status-chip--neutral{background-color:rgb(var(--ax-sys-color-neutral-lighter-surface));color:rgb(var(--ax-sys-color-on-neutral-lighter-surface))}.axp-status-icon--neutral{color:rgb(var(--ax-sys-color-neutral-dark-surface))}axp-layout-title{display:block;width:100%;font-weight:600}axp-layout-description{display:block;width:100%;font-size:.875rem;line-height:1.25rem;opacity:.65}axp-layout-actions{display:flex;align-items:center;gap:.75rem}axp-layout-actions axp-layout-actions-primary{display:flex;align-items:center;gap:.75rem}axp-layout-footer,axp-layout-toolbar,axp-layout-header,axp-page-header,axp-page-footer,axp-page-toolbar{display:flex;width:100%;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.5rem}axp-layout-footer>axp-layout-prefix,axp-layout-footer>axp-layout-suffix,axp-layout-toolbar>axp-layout-prefix,axp-layout-toolbar>axp-layout-suffix,axp-layout-header>axp-layout-prefix,axp-layout-header>axp-layout-suffix,axp-page-header>axp-layout-prefix,axp-page-header>axp-layout-suffix,axp-page-footer>axp-layout-prefix,axp-page-footer>axp-layout-suffix,axp-page-toolbar>axp-layout-prefix,axp-page-toolbar>axp-layout-suffix{display:flex;flex-direction:row;align-items:center;gap:.5rem}axp-layout-footer>axp-layout-prefix,axp-layout-toolbar>axp-layout-prefix,axp-layout-header>axp-layout-prefix,axp-page-header>axp-layout-prefix,axp-page-footer>axp-layout-prefix,axp-page-toolbar>axp-layout-prefix{order:-9999}axp-layout-footer>axp-layout-suffix,axp-layout-toolbar>axp-layout-suffix,axp-layout-header>axp-layout-suffix,axp-page-header>axp-layout-suffix,axp-page-footer>axp-layout-suffix,axp-page-toolbar>axp-layout-suffix{order:9999;margin-inline-start:auto}axp-layout-list{display:flex;flex-direction:column}axp-layout-list>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse));border-style:dashed}axp-layout-list:focus{outline:none}axp-layout-list-group{display:flex;flex-direction:column;padding-top:.5rem;padding-bottom:.5rem}axp-layout-list-group>axp-layout-title{padding-bottom:.5rem;font-size:.875rem;line-height:1.25rem;font-weight:600}axp-layout-list-group>axp-layout-header{display:flex;justify-content:space-between;padding-top:.5rem;padding-bottom:.5rem}axp-layout-list-item{margin-top:.25rem;display:flex;flex-direction:row;align-items:center;justify-content:space-between;gap:.75rem;padding:.5rem;font-size:.875rem;line-height:1.25rem}axp-layout-list-item:focus{outline:none}axp-layout-list-item.axp-state-focused,axp-layout-list-item:hover{cursor:pointer;border-radius:.25rem;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-light-surface),var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lightest-surface),var(--tw-text-opacity, 1))}axp-layout-list-item>axp-layout-prefix{margin-inline-end:auto;display:flex;flex-direction:row;gap:.5rem}axp-layout-list-item>axp-layout-content{flex:1 1 0%}axp-layout-list-item>axp-layout-content axp-layout-description{margin-top:.25rem!important;font-size:.75rem!important;line-height:1rem!important}axp-layout-list-item>axp-layout-suffix{margin-inline-start:auto;display:flex;flex-direction:row;gap:.5rem}axp-layout-sections{display:flex;flex-direction:column;gap:1rem}axp-layout-sections axp-layout-section{display:block;border-radius:.375rem;border-width:1px;--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}axp-layout-sections axp-layout-section>axp-layout-footer,axp-layout-sections axp-layout-section>axp-layout-header{padding:.5rem 1rem}@media(min-width:1280px){axp-layout-sections axp-layout-section>axp-layout-footer,axp-layout-sections axp-layout-section>axp-layout-header{padding-top:1rem;padding-bottom:1rem}}axp-layout-sections axp-layout-section>axp-layout-header{display:flex;flex-direction:column;gap:0px;border-top-left-radius:.375rem;border-top-right-radius:.375rem;border-bottom-width:1px}axp-layout-sections axp-layout-section>axp-layout-header axp-layout-title{font-weight:700;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lightest-surface),var(--tw-text-opacity, 1))}axp-layout-sections axp-layout-section>axp-layout-header axp-layout-description{margin-top:.25rem;font-size:.875rem;line-height:1.25rem}axp-layout-sections axp-layout-section>axp-layout-footer{display:flex;align-items:center;justify-content:space-between;border-bottom-right-radius:.375rem;border-bottom-left-radius:.375rem;border-top-width:1px;padding:1rem}axp-layout-sections axp-layout-section>axp-layout-footer>axp-layout-suffix{margin-inline-start:auto;display:flex;gap:.5rem}axp-layout-sections axp-layout-section>axp-layout-footer{opacity:0;animation:fadeInDown .5s ease-out forwards}@keyframes fadeInDown{0%{opacity:0}to{opacity:1}}axp-page-layout{display:flex;width:100%;height:100%;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-page-layout:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-dark-surface));color:rgb(var(--ax-sys-color-on-dark-surface));border-color:rgb(var(--ax-sys-color-border-dark-surface))}axp-page-layout axp-layout-start-side,axp-page-layout axp-layout-end-side{display:flex;min-height:100%;min-width:16rem;flex-direction:column;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-page-layout axp-layout-start-side:is(.ax-dark *),axp-page-layout axp-layout-end-side:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-darker-surface));color:rgb(var(--ax-sys-color-on-darker-surface));border-color:rgb(var(--ax-sys-color-border-darker-surface))}axp-page-layout axp-layout-start-side axp-layout-header,axp-page-layout axp-layout-end-side axp-layout-header{display:flex;flex-direction:column;gap:.5rem;padding:1rem}axp-page-layout axp-layout-start-side axp-layout-header>axp-layout-title,axp-page-layout axp-layout-end-side axp-layout-header>axp-layout-title{font-size:1.125rem;line-height:1.75rem;font-weight:500}axp-page-layout axp-layout-start-side>axp-layout-content,axp-page-layout axp-layout-end-side>axp-layout-content{flex:1 1 0%}axp-page-layout>axp-layout-container{position:relative;display:flex;width:100%;height:100%;flex-direction:column;overflow:auto}axp-page-layout>axp-layout-container>axp-layout-header{position:sticky;top:0;z-index:20;display:flex;flex-direction:column;align-items:flex-start;gap:0px;padding-top:.5rem;padding-bottom:.5rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;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-page-layout>axp-layout-container>axp-layout-header:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-dark-surface));color:rgb(var(--ax-sys-color-on-dark-surface));border-color:rgb(var(--ax-sys-color-border-dark-surface))}@media(min-width:768px){axp-page-layout>axp-layout-container>axp-layout-header{padding-top:1rem;padding-bottom:1rem}}axp-page-layout>axp-layout-container>axp-layout-header.axp-is-sticky{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}axp-page-layout>axp-layout-container>axp-layout-header ax-breadcrumbs ax-breadcrumbs-item{font-size:.75rem;line-height:1rem}axp-page-layout>axp-layout-container>axp-layout-header ax-breadcrumbs ax-breadcrumbs-item.ax-state-active .ax-breadcrumb-item-content{cursor:default;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lightest-surface),var(--tw-text-opacity, 1));opacity:.75}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar{display:flex;width:100%;align-items:center;justify-content:space-between;padding-left:1rem;padding-right:1rem}@media(min-width:1280px){axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar{border-width:0px}}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar ax-layout-nav-button{display:flex;align-items:center;justify-content:space-between}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container{display:flex;align-items:baseline;gap:.75rem}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container axp-layout-title{display:inline-block;width:fit-content;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:1.25rem;line-height:1.75rem;font-weight:500;line-height:1}@media(min-width:1024px){axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container axp-layout-title{font-size:1.5rem;line-height:2rem}}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge{display:inline-flex;--tw-translate-y: -3px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));align-items:center;align-self:baseline;border-radius:.375rem;padding:.25rem .5rem;font-size:.75rem;line-height:1rem;font-weight:600;line-height:1}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge i{margin-inline-end:.25rem;line-height:1;font-size:.5rem}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--warning{background-color:rgb(var(--ax-sys-color-warning-lightest-surface));color:rgb(var(--ax-sys-color-on-warning-lightest-surface));border-color:rgb(var(--ax-sys-color-border-warning-lightest-surface))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--warning i{color:rgb(var(--ax-sys-color-warning-500))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--danger{background-color:rgb(var(--ax-sys-color-danger-lightest-surface));color:rgb(var(--ax-sys-color-on-danger-lightest-surface));border-color:rgb(var(--ax-sys-color-border-danger-lightest-surface))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--danger i{color:rgb(var(--ax-sys-color-danger-500))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--success{background-color:rgb(var(--ax-sys-color-success-lightest-surface));color:rgb(var(--ax-sys-color-on-success-lightest-surface));border-color:rgb(var(--ax-sys-color-border-success-lightest-surface))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--success i{color:rgb(var(--ax-sys-color-success-500))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--primary{background-color:rgb(var(--ax-sys-color-primary-lightest-surface));color:rgb(var(--ax-sys-color-on-primary-lightest-surface));border-color:rgb(var(--ax-sys-color-border-primary-lightest-surface))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--primary i{color:rgb(var(--ax-sys-color-primary-500))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--secondary i{color:rgb(var(--ax-sys-color-secondary-500))}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge.--default i{color:rgb(var(--ax-sys-color-on-surface)/.45)}@media(max-width:600px){axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge{--tw-translate-y: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));background-color:transparent;padding:0;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge .__title-badge-label{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}axp-page-layout>axp-layout-container>axp-layout-header axp-layout-title-bar .__title-container .__title-badge i{margin:0;font-size:.625rem}}axp-page-layout>axp-layout-container>axp-layout-header axp-page-toolbar{margin-top:.5rem;padding-left:1rem;padding-right:1rem}axp-page-layout>axp-layout-container>axp-page-content{display:flex;width:100%;flex:1 1 0%;flex-direction:column;padding:.75rem 1rem}axp-page-layout>axp-layout-container>axp-page-content.--scrollable{padding-bottom:1rem}axp-page-layout>axp-layout-container>axp-page-footer-container{border-top-width:1px;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-page-layout>axp-layout-container>axp-page-footer-container:is(.ax-dark *){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-page-layout>axp-layout-container>axp-page-footer-container{position:sticky;bottom:0;z-index:20;padding:.75rem;--tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / .05);--tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}@keyframes ax-fadeInUp{0%{transform:translate3d(0,100%,0);opacity:0}}axp-page-layout>axp-layout-container>axp-page-footer-container.--animated{animation:1s both ax-fadeInUp;transition-duration:.3s;transition-timing-function:cubic-bezier(0,0,.2,1);animation-duration:.3s;animation-timing-function:cubic-bezier(0,0,.2,1)}\n"] }]
|
|
178
178
|
}], propDecorators: { startSideDrawer: [{ type: i0.ViewChild, args: ['startSideDrawer', { isSignal: true }] }] } });
|
|
179
179
|
|
|
180
180
|
//#region ---- Page Unsaved Changes Utilities ----
|
|
@@ -223,7 +223,9 @@ class AXPPageLayoutBaseComponent {
|
|
|
223
223
|
this.tabNavigation = inject(AXPTabNavigationService);
|
|
224
224
|
this.tabPreviewService = inject(AXPTabPreviewService);
|
|
225
225
|
this.unsavedChangesConfirm = inject(AXPUnsavedChangesConfirmService);
|
|
226
|
+
this.browserTitleService = inject(AXPBrowserTitleService);
|
|
226
227
|
this.router = inject(Router);
|
|
228
|
+
this.pageLayoutDestroyRef = inject(DestroyRef);
|
|
227
229
|
//#endregion
|
|
228
230
|
//#region ---------------- Signal to force recomputation ----------------
|
|
229
231
|
this._updateTrigger = signal(0, ...(ngDevMode ? [{ debugName: "_updateTrigger" }] : /* istanbul ignore next */ []));
|
|
@@ -298,6 +300,19 @@ class AXPPageLayoutBaseComponent {
|
|
|
298
300
|
return false;
|
|
299
301
|
}, ...(ngDevMode ? [{ debugName: "hasTitle" }] : /* istanbul ignore next */ []));
|
|
300
302
|
this.hasTitleIcon = computed(() => this.titleIcon() !== null, ...(ngDevMode ? [{ debugName: "hasTitleIcon" }] : /* istanbul ignore next */ []));
|
|
303
|
+
this.#browserTitleEffect = effect(() => {
|
|
304
|
+
if (this.tabNavigation.effectiveMode() === 'tabular') {
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
if (!this.isActivePageForBrowserTitle()) {
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
this.updateTrigger();
|
|
311
|
+
this.title();
|
|
312
|
+
untracked(() => {
|
|
313
|
+
void this.publishBrowserTitleIfActive();
|
|
314
|
+
});
|
|
315
|
+
}, ...(ngDevMode ? [{ debugName: "#browserTitleEffect" }] : /* istanbul ignore next */ []));
|
|
301
316
|
//#endregion
|
|
302
317
|
//#region ---------------- Description ----------------
|
|
303
318
|
this.description = signal(null, ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
|
|
@@ -340,16 +355,17 @@ class AXPPageLayoutBaseComponent {
|
|
|
340
355
|
this.breadcrumbs.set(trail);
|
|
341
356
|
if (this.tabNavigation.effectiveMode() === 'tabular') {
|
|
342
357
|
const tabKey = this.pageTabKey();
|
|
343
|
-
|
|
358
|
+
const tabTitleSegments = await this.resolveBreadcrumbTabTitleSegments(breadCrumbs);
|
|
359
|
+
let tabTitle = tabTitleSegments.length ? axpJoinTabTitleSegments(tabTitleSegments) : null;
|
|
344
360
|
if (!tabTitle) {
|
|
345
361
|
tabTitle = await this.resolvePageTitleForTab();
|
|
346
362
|
}
|
|
347
363
|
if (tabKey && tabTitle) {
|
|
348
|
-
this.tabNavigation.syncTabTitle(tabKey, tabTitle);
|
|
364
|
+
this.tabNavigation.syncTabTitle(tabKey, tabTitleSegments.length ? tabTitleSegments : tabTitle);
|
|
349
365
|
}
|
|
350
366
|
}
|
|
351
367
|
}, ...(ngDevMode ? [{ debugName: "#breadcrumbsEffect" }] : /* istanbul ignore next */ []));
|
|
352
|
-
this.hasBreadcrumbs = computed(() => this.breadcrumbs().length > 1
|
|
368
|
+
this.hasBreadcrumbs = computed(() => this.breadcrumbs().length > 1, ...(ngDevMode ? [{ debugName: "hasBreadcrumbs" }] : /* istanbul ignore next */ []));
|
|
353
369
|
//#endregion
|
|
354
370
|
//#region ---------------- Badge ----------------
|
|
355
371
|
this.badge = signal(null, ...(ngDevMode ? [{ debugName: "badge" }] : /* istanbul ignore next */ []));
|
|
@@ -409,6 +425,11 @@ class AXPPageLayoutBaseComponent {
|
|
|
409
425
|
this.translateService.langChanges$.subscribe(() => {
|
|
410
426
|
this.recompute();
|
|
411
427
|
});
|
|
428
|
+
this.router.events
|
|
429
|
+
.pipe(filter((event) => event instanceof NavigationEnd), takeUntilDestroyed(this.pageLayoutDestroyRef))
|
|
430
|
+
.subscribe(() => {
|
|
431
|
+
void this.publishBrowserTitleIfActive();
|
|
432
|
+
});
|
|
412
433
|
}
|
|
413
434
|
/** Maps the home-page route to the pinned home tab key instead of a path-based key. */
|
|
414
435
|
resolvePageTabKey() {
|
|
@@ -418,6 +439,10 @@ class AXPPageLayoutBaseComponent {
|
|
|
418
439
|
}
|
|
419
440
|
return axpResolveTabKey(this.router);
|
|
420
441
|
}
|
|
442
|
+
/** Stable tab key for this cached page instance (tabular mode). */
|
|
443
|
+
getPageTabKey() {
|
|
444
|
+
return this.pageTabKey();
|
|
445
|
+
}
|
|
421
446
|
//#endregion
|
|
422
447
|
//#region ---------------- Tab Title Sync ----------------
|
|
423
448
|
/** Refreshes tab title when this cached page becomes the active tab again. */
|
|
@@ -481,6 +506,33 @@ class AXPPageLayoutBaseComponent {
|
|
|
481
506
|
getPageIcon() {
|
|
482
507
|
return null;
|
|
483
508
|
}
|
|
509
|
+
#browserTitleEffect;
|
|
510
|
+
/** Publishes the page title to the browser tab when this instance is the active route. */
|
|
511
|
+
async publishBrowserTitleIfActive() {
|
|
512
|
+
if (this.tabNavigation.effectiveMode() === 'tabular') {
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
if (!this.isActivePageForBrowserTitle()) {
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
const routeKey = this.pageTabKey();
|
|
519
|
+
if (!routeKey) {
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
const pageTitle = await this.resolvePageTitleForTab();
|
|
523
|
+
if (!this.isActivePageForBrowserTitle()) {
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
this.browserTitleService.setSimpleModePageTitle(pageTitle, routeKey);
|
|
527
|
+
}
|
|
528
|
+
/** True when this cached page instance matches the current router location. */
|
|
529
|
+
isActivePageForBrowserTitle() {
|
|
530
|
+
const pageKey = this.pageTabKey();
|
|
531
|
+
if (!pageKey) {
|
|
532
|
+
return false;
|
|
533
|
+
}
|
|
534
|
+
return pageKey === axpResolveTabKey(this.router);
|
|
535
|
+
}
|
|
484
536
|
#descriptionEffect;
|
|
485
537
|
getPageDescription() {
|
|
486
538
|
return null;
|
|
@@ -489,8 +541,8 @@ class AXPPageLayoutBaseComponent {
|
|
|
489
541
|
getPageBreadcrumbs() {
|
|
490
542
|
return [];
|
|
491
543
|
}
|
|
492
|
-
/**
|
|
493
|
-
async
|
|
544
|
+
/** Collects resolved breadcrumb labels (Home excluded upstream) for tab chrome. */
|
|
545
|
+
async resolveBreadcrumbTabTitleSegments(pageBreadcrumbs) {
|
|
494
546
|
const segments = [];
|
|
495
547
|
for (const item of pageBreadcrumbs) {
|
|
496
548
|
const title = await this.resolveBreadcrumbItemTitle(item);
|
|
@@ -498,10 +550,15 @@ class AXPPageLayoutBaseComponent {
|
|
|
498
550
|
segments.push(title);
|
|
499
551
|
}
|
|
500
552
|
}
|
|
553
|
+
return segments;
|
|
554
|
+
}
|
|
555
|
+
/** Joins breadcrumb segments as the stored tab title string. */
|
|
556
|
+
async resolveBreadcrumbTabTitle(pageBreadcrumbs) {
|
|
557
|
+
const segments = await this.resolveBreadcrumbTabTitleSegments(pageBreadcrumbs);
|
|
501
558
|
if (!segments.length) {
|
|
502
559
|
return null;
|
|
503
560
|
}
|
|
504
|
-
return segments
|
|
561
|
+
return axpJoinTabTitleSegments(segments);
|
|
505
562
|
}
|
|
506
563
|
/** Resolves a breadcrumb label the same way as page chrome (`t(item.title)`). */
|
|
507
564
|
async resolveBreadcrumbItemTitle(item) {
|
|
@@ -781,6 +838,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
781
838
|
}]
|
|
782
839
|
}], propDecorators: { layout: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXPPopupLayoutComponent), { isSignal: true }] }] } });
|
|
783
840
|
|
|
841
|
+
const AXP_LAYOUT_DETAILS_VIEW_ADAPTER_LOADER = new InjectionToken('AXP_LAYOUT_DETAILS_VIEW_ADAPTER_LOADER');
|
|
842
|
+
//#endregion
|
|
843
|
+
|
|
844
|
+
/** Trace namespace for details-view page / URL sync diagnostics. */
|
|
845
|
+
const DETAILS_VIEW_PAGE_TRACE_NS = 'details-view-page';
|
|
846
|
+
|
|
784
847
|
//#region ---- Root-context widget expression resolution ----
|
|
785
848
|
/**
|
|
786
849
|
* Evaluates `{{ ... }}` strings inside `options.customFilterDefinitions` using `rootContext`
|
|
@@ -820,10 +883,11 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
|
|
|
820
883
|
const state = {
|
|
821
884
|
adapter: null,
|
|
822
885
|
rootContext: {},
|
|
886
|
+
savedContext: {},
|
|
823
887
|
previousContext: {},
|
|
824
888
|
context: {},
|
|
825
889
|
scope: null,
|
|
826
|
-
status: AXPPageStatus.
|
|
890
|
+
status: AXPPageStatus.Idle,
|
|
827
891
|
currentPage: null,
|
|
828
892
|
currentTab: null,
|
|
829
893
|
pageSelectedRows: [],
|
|
@@ -848,6 +912,10 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
|
|
|
848
912
|
//
|
|
849
913
|
isBusy: computed(() => store.status() == AXPPageStatus.Processing),
|
|
850
914
|
isSaving: computed(() => store.status() == AXPPageStatus.Submitting),
|
|
915
|
+
isOverlayBusy: computed(() => store.status() === AXPPageStatus.Processing || store.status() === AXPPageStatus.Submitting),
|
|
916
|
+
isPageReady: computed(() => store.adapter() != null &&
|
|
917
|
+
store.currentPage() != null &&
|
|
918
|
+
store.status() === AXPPageStatus.Rendered),
|
|
851
919
|
isDirty: computed(() => {
|
|
852
920
|
if (store.currentPage()?.isReadonly) {
|
|
853
921
|
return false;
|
|
@@ -871,7 +939,7 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
|
|
|
871
939
|
const evaluatedByTab = store.evaluatedTabContentsById();
|
|
872
940
|
return evaluatedByTab[tab.id] ?? [];
|
|
873
941
|
}),
|
|
874
|
-
})), withMethods((store, evaluatorService = inject(AXPExpressionEvaluatorService), contextEvalFactory = inject(AXPContextEvalFactory), router = inject(Router), route = inject(ActivatedRoute), deviceService = inject(AXPDeviceService), formatService = inject(AXFormatService), toastService = inject(AXToastService), translateService = inject(AXTranslationService), settingsService = inject(AXPSettingsService)) => {
|
|
942
|
+
})), withMethods((store, evaluatorService = inject(AXPExpressionEvaluatorService), contextEvalFactory = inject(AXPContextEvalFactory), router = inject(Router), route = inject(ActivatedRoute), deviceService = inject(AXPDeviceService), formatService = inject(AXFormatService), toastService = inject(AXToastService), translateService = inject(AXTranslationService), settingsService = inject(AXPSettingsService), layout = inject(AXPLayoutThemeService), adapterLoader = inject(AXP_LAYOUT_DETAILS_VIEW_ADAPTER_LOADER)) => {
|
|
875
943
|
const resolvePageFromId = (adapter, pageId) => {
|
|
876
944
|
if (pageId) {
|
|
877
945
|
return adapter.pages.find((p) => p.id === pageId) ?? null;
|
|
@@ -881,49 +949,141 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
|
|
|
881
949
|
}
|
|
882
950
|
return null;
|
|
883
951
|
};
|
|
952
|
+
/** Serializes page activation so route sync and UI cannot run overlapping loads. */
|
|
953
|
+
let pageActivationChain = Promise.resolve();
|
|
954
|
+
/** Serializes route-driven adapter loads (initial navigation and layout refresh). */
|
|
955
|
+
let routeLoadChain = Promise.resolve();
|
|
956
|
+
/** `page` query param from the browser URL (reliable on hard refresh). */
|
|
957
|
+
const readPageQueryParam = () => {
|
|
958
|
+
const page = router.parseUrl(router.url).queryParams['page'];
|
|
959
|
+
return typeof page === 'string' && page.length > 0 ? page : null;
|
|
960
|
+
};
|
|
961
|
+
/** Snapshot of all page-query sources for trace logs. */
|
|
962
|
+
const pageQueryTraceContext = (extra = {}) => ({
|
|
963
|
+
routerUrl: router.url,
|
|
964
|
+
pageFromRouterUrl: readPageQueryParam(),
|
|
965
|
+
pageFromRouteSnapshot: route.snapshot.queryParamMap.get('page'),
|
|
966
|
+
pageFromRootSnapshot: router.routerState.snapshot.root.queryParams['page'] ?? null,
|
|
967
|
+
currentPageId: store.currentPage()?.id ?? null,
|
|
968
|
+
adapterPageIds: store.adapter()?.pages.map((p) => p.id) ?? [],
|
|
969
|
+
...extra,
|
|
970
|
+
});
|
|
884
971
|
/** Loads page data, context, and evaluated widgets for the target sidebar page. */
|
|
885
972
|
const activatePageById = async (pageId, forceRefresh) => {
|
|
973
|
+
const activation = pageActivationChain.then(() => runPageActivation(pageId, forceRefresh));
|
|
974
|
+
pageActivationChain = activation.catch(() => undefined);
|
|
975
|
+
await activation;
|
|
976
|
+
};
|
|
977
|
+
const runPageActivation = async (pageId, forceRefresh) => {
|
|
886
978
|
const adapter = store.adapter();
|
|
887
979
|
if (!adapter) {
|
|
888
980
|
return;
|
|
889
981
|
}
|
|
890
|
-
const
|
|
891
|
-
const targetPageId = pageId ?? queryParams['page'];
|
|
982
|
+
const targetPageId = pageId ?? readPageQueryParam() ?? undefined;
|
|
892
983
|
const currentPage = resolvePageFromId(adapter, targetPageId);
|
|
984
|
+
AXPDebugService.instance?.trace(DETAILS_VIEW_PAGE_TRACE_NS, 'viewmodel', 'runPageActivation', () => pageQueryTraceContext({
|
|
985
|
+
passedPageId: pageId ?? null,
|
|
986
|
+
targetPageId: targetPageId ?? null,
|
|
987
|
+
resolvedPageId: currentPage?.id ?? null,
|
|
988
|
+
forceRefresh: forceRefresh ?? false,
|
|
989
|
+
vmStatus: store.status(),
|
|
990
|
+
}));
|
|
893
991
|
if (!forceRefresh && currentPage?.id === store.currentPage()?.id && store.status() === AXPPageStatus.Rendered) {
|
|
992
|
+
AXPDebugService.instance?.trace(DETAILS_VIEW_PAGE_TRACE_NS, 'viewmodel', 'runPageActivation skipped (already rendered)', () => pageQueryTraceContext({
|
|
993
|
+
resolvedPageId: currentPage?.id ?? null,
|
|
994
|
+
}));
|
|
894
995
|
return;
|
|
895
996
|
}
|
|
997
|
+
const previousPageId = store.currentPage()?.id;
|
|
998
|
+
const isSidebarSwitch = previousPageId != null && previousPageId !== currentPage?.id;
|
|
999
|
+
if (isSidebarSwitch) {
|
|
1000
|
+
layout.setNavigationLoading(true);
|
|
1001
|
+
}
|
|
1002
|
+
const overlayAlreadyOn = layout.overlayTaskCount() > 0;
|
|
1003
|
+
if (!overlayAlreadyOn) {
|
|
1004
|
+
AXPDebugService.instance?.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'viewmodel', 'activatePage overlay ON', () => ({
|
|
1005
|
+
pageId: currentPage?.id,
|
|
1006
|
+
forceRefresh,
|
|
1007
|
+
isSidebarSwitch,
|
|
1008
|
+
}));
|
|
1009
|
+
layout.setOverlayLoading(true);
|
|
1010
|
+
}
|
|
1011
|
+
else {
|
|
1012
|
+
AXPDebugService.instance?.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'viewmodel', 'activatePage skipped overlay ON (task count > 0)', () => ({
|
|
1013
|
+
pageId: currentPage?.id,
|
|
1014
|
+
forceRefresh,
|
|
1015
|
+
isSidebarSwitch,
|
|
1016
|
+
taskCount: layout.overlayTaskCount(),
|
|
1017
|
+
}));
|
|
1018
|
+
}
|
|
896
1019
|
patchState(store, {
|
|
897
1020
|
status: AXPPageStatus.Processing,
|
|
898
1021
|
});
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
const
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
1022
|
+
try {
|
|
1023
|
+
let context = {};
|
|
1024
|
+
if (currentPage) {
|
|
1025
|
+
const currentPageIndex = adapter.pages.findIndex((p) => p.id === currentPage.id);
|
|
1026
|
+
const pageLoad = adapter.pages[currentPageIndex]?.load;
|
|
1027
|
+
if (typeof pageLoad === 'function') {
|
|
1028
|
+
const loadResult = await pageLoad({ forceRefresh });
|
|
1029
|
+
context = loadResult?.data ?? {};
|
|
1030
|
+
}
|
|
1031
|
+
else {
|
|
1032
|
+
// Component/list sidebar pages have no `load`; keep entity root context so widget
|
|
1033
|
+
// state is not cleared (Change History, etc. use `rootContext` instead).
|
|
1034
|
+
context = cloneDeep(store.rootContext());
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
const currentTab = currentPage?.tabs?.[0] ?? null;
|
|
1038
|
+
const shouldSyncRootContext = forceRefresh === true && currentPage?.isPrimary === true && !isEmpty(context);
|
|
1039
|
+
const rootCtx = shouldSyncRootContext
|
|
1040
|
+
? context
|
|
1041
|
+
: store.rootContext();
|
|
1042
|
+
const { evaluatedPageContent, evaluatedTabContentsById } = await buildEvaluatedPageContentsForRootContext(currentPage, rootCtx, evaluatorService);
|
|
1043
|
+
patchState(store, {
|
|
1044
|
+
previousContext: cloneDeep(context),
|
|
1045
|
+
context: cloneDeep(context),
|
|
1046
|
+
savedContext: cloneDeep(context),
|
|
1047
|
+
...(shouldSyncRootContext ? { rootContext: cloneDeep(context) } : {}),
|
|
1048
|
+
status: AXPPageStatus.Rendered,
|
|
1049
|
+
currentPage,
|
|
1050
|
+
currentTab,
|
|
1051
|
+
evaluatedPageContent,
|
|
1052
|
+
evaluatedTabContentsById,
|
|
1053
|
+
formDirty: false,
|
|
1054
|
+
pageSelectedRows: [],
|
|
1055
|
+
});
|
|
1056
|
+
AXPDebugService.instance?.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'viewmodel', 'activatePage VM ready (Rendered)', () => ({
|
|
1057
|
+
pageId: currentPage?.id,
|
|
1058
|
+
forceRefresh,
|
|
1059
|
+
}));
|
|
1060
|
+
const urlPageParam = readPageQueryParam();
|
|
1061
|
+
if (currentPage && axpIsEntityDetailsViewRoute(router)) {
|
|
1062
|
+
if (!urlPageParam) {
|
|
1063
|
+
AXPDebugService.instance?.trace(DETAILS_VIEW_PAGE_TRACE_NS, 'viewmodel', 'URL sync — add missing ?page=', () => pageQueryTraceContext({
|
|
1064
|
+
navigateToPageId: currentPage.id,
|
|
1065
|
+
}));
|
|
1066
|
+
router.navigate([], {
|
|
1067
|
+
relativeTo: route,
|
|
1068
|
+
queryParams: { page: currentPage.id },
|
|
1069
|
+
queryParamsHandling: 'merge',
|
|
1070
|
+
replaceUrl: true,
|
|
1071
|
+
});
|
|
1072
|
+
}
|
|
1073
|
+
else {
|
|
1074
|
+
AXPDebugService.instance?.trace(DETAILS_VIEW_PAGE_TRACE_NS, 'viewmodel', 'URL sync — skipped (page already in URL)', () => pageQueryTraceContext({
|
|
1075
|
+
urlPageParam,
|
|
1076
|
+
resolvedPageId: currentPage.id,
|
|
1077
|
+
}));
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
finally {
|
|
1082
|
+
if (isSidebarSwitch) {
|
|
1083
|
+
layout.setNavigationLoading(false);
|
|
1084
|
+
}
|
|
1085
|
+
if (store.status() === AXPPageStatus.Processing) {
|
|
1086
|
+
patchState(store, { status: AXPPageStatus.Rendered });
|
|
927
1087
|
}
|
|
928
1088
|
}
|
|
929
1089
|
};
|
|
@@ -937,16 +1097,33 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
|
|
|
937
1097
|
if (!adapter) {
|
|
938
1098
|
return;
|
|
939
1099
|
}
|
|
1100
|
+
// `load()` → `loadPage()` owns the first activation while `currentPage` is still null.
|
|
1101
|
+
if (store.currentPage() == null) {
|
|
1102
|
+
AXPDebugService.instance?.trace(DETAILS_VIEW_PAGE_TRACE_NS, 'viewmodel', 'queryParams effect — skipped (currentPage null)', () => pageQueryTraceContext({
|
|
1103
|
+
paramsPage: params['page'] ?? null,
|
|
1104
|
+
}));
|
|
1105
|
+
return;
|
|
1106
|
+
}
|
|
940
1107
|
const pageId = params['page'];
|
|
941
|
-
|
|
942
|
-
|
|
1108
|
+
if (!pageId) {
|
|
1109
|
+
AXPDebugService.instance?.trace(DETAILS_VIEW_PAGE_TRACE_NS, 'viewmodel', 'queryParams effect — skipped (no page param)', () => pageQueryTraceContext({
|
|
1110
|
+
params,
|
|
1111
|
+
}));
|
|
943
1112
|
return;
|
|
944
1113
|
}
|
|
945
|
-
|
|
946
|
-
if (store.currentPage()
|
|
1114
|
+
const targetPage = adapter.pages.find((p) => p.id === pageId);
|
|
1115
|
+
if (!targetPage || store.currentPage()?.id === targetPage.id) {
|
|
1116
|
+
AXPDebugService.instance?.trace(DETAILS_VIEW_PAGE_TRACE_NS, 'viewmodel', 'queryParams effect — skipped (same or unknown page)', () => pageQueryTraceContext({
|
|
1117
|
+
paramsPage: pageId,
|
|
1118
|
+
targetPageFound: !!targetPage,
|
|
1119
|
+
}));
|
|
947
1120
|
return;
|
|
948
1121
|
}
|
|
949
|
-
|
|
1122
|
+
AXPDebugService.instance?.trace(DETAILS_VIEW_PAGE_TRACE_NS, 'viewmodel', 'queryParams effect — activatePageById', () => pageQueryTraceContext({
|
|
1123
|
+
paramsPage: pageId,
|
|
1124
|
+
activatePageId: targetPage.id,
|
|
1125
|
+
}));
|
|
1126
|
+
void activatePageById(targetPage.id);
|
|
950
1127
|
});
|
|
951
1128
|
onCleanup(() => subscription.unsubscribe());
|
|
952
1129
|
});
|
|
@@ -1048,7 +1225,7 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
|
|
|
1048
1225
|
async loadPage(pageId, forceRefresh) {
|
|
1049
1226
|
await activatePageById(pageId, forceRefresh);
|
|
1050
1227
|
},
|
|
1051
|
-
async load(adapter) {
|
|
1228
|
+
async load(adapter, forceRefresh, pageIdFromUrl) {
|
|
1052
1229
|
const scope = {
|
|
1053
1230
|
context: {
|
|
1054
1231
|
...contextEvalFactory.createLiveScope(() => store.context()),
|
|
@@ -1060,7 +1237,81 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
|
|
|
1060
1237
|
});
|
|
1061
1238
|
//
|
|
1062
1239
|
await this.loadAdapter(adapter);
|
|
1063
|
-
|
|
1240
|
+
const pageId = pageIdFromUrl ?? readPageQueryParam() ?? undefined;
|
|
1241
|
+
AXPDebugService.instance?.trace(DETAILS_VIEW_PAGE_TRACE_NS, 'viewmodel', 'load — activate page', () => pageQueryTraceContext({
|
|
1242
|
+
pageIdFromUrl: pageIdFromUrl ?? null,
|
|
1243
|
+
resolvedPageId: pageId ?? null,
|
|
1244
|
+
forceRefresh: forceRefresh ?? false,
|
|
1245
|
+
}));
|
|
1246
|
+
await this.loadPage(pageId, forceRefresh);
|
|
1247
|
+
},
|
|
1248
|
+
async loadFromRoute(forceRefresh) {
|
|
1249
|
+
const run = async () => {
|
|
1250
|
+
const pageIdFromUrl = readPageQueryParam() ?? undefined;
|
|
1251
|
+
AXPDebugService.instance?.trace(DETAILS_VIEW_PAGE_TRACE_NS, 'viewmodel', 'loadFromRoute start', () => pageQueryTraceContext({
|
|
1252
|
+
pageIdFromUrl: pageIdFromUrl ?? null,
|
|
1253
|
+
forceRefresh: forceRefresh ?? false,
|
|
1254
|
+
}));
|
|
1255
|
+
const moduleName = route.parent?.snapshot.paramMap.get('module');
|
|
1256
|
+
const entityName = route.snapshot.paramMap.get('entity');
|
|
1257
|
+
const id = route.snapshot.paramMap.get('id');
|
|
1258
|
+
if (!moduleName || !entityName || !id) {
|
|
1259
|
+
return;
|
|
1260
|
+
}
|
|
1261
|
+
layout.setNavigationLoading(true);
|
|
1262
|
+
if (layout.overlayTaskCount() === 0) {
|
|
1263
|
+
AXPDebugService.instance?.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'viewmodel', 'loadFromRoute overlay ON', () => ({
|
|
1264
|
+
moduleName,
|
|
1265
|
+
entityName,
|
|
1266
|
+
id,
|
|
1267
|
+
forceRefresh,
|
|
1268
|
+
}));
|
|
1269
|
+
layout.setOverlayLoading(true);
|
|
1270
|
+
}
|
|
1271
|
+
else {
|
|
1272
|
+
AXPDebugService.instance?.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'viewmodel', 'loadFromRoute skipped overlay ON (task count > 0)', () => ({
|
|
1273
|
+
moduleName,
|
|
1274
|
+
entityName,
|
|
1275
|
+
id,
|
|
1276
|
+
forceRefresh,
|
|
1277
|
+
taskCount: layout.overlayTaskCount(),
|
|
1278
|
+
}));
|
|
1279
|
+
}
|
|
1280
|
+
try {
|
|
1281
|
+
if (forceRefresh) {
|
|
1282
|
+
patchState(store, {
|
|
1283
|
+
currentPage: null,
|
|
1284
|
+
status: AXPPageStatus.Idle,
|
|
1285
|
+
});
|
|
1286
|
+
}
|
|
1287
|
+
const adapter = await adapterLoader.load({ moduleName, entityName, id });
|
|
1288
|
+
AXPDebugService.instance?.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'viewmodel', 'adapter loaded (overlay still ON — details-view releases)', () => ({
|
|
1289
|
+
moduleName,
|
|
1290
|
+
entityName,
|
|
1291
|
+
id,
|
|
1292
|
+
}));
|
|
1293
|
+
await this.load(adapter, forceRefresh, pageIdFromUrl);
|
|
1294
|
+
}
|
|
1295
|
+
catch (error) {
|
|
1296
|
+
AXPDebugService.instance?.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'viewmodel', 'loadFromRoute overlay OFF (error)', () => ({
|
|
1297
|
+
moduleName,
|
|
1298
|
+
entityName,
|
|
1299
|
+
id,
|
|
1300
|
+
}));
|
|
1301
|
+
layout.setOverlayLoading(false);
|
|
1302
|
+
if (error instanceof AXPNotFoundError) {
|
|
1303
|
+
void router.navigateByUrl(AXP_NOT_FOUND_ROUTE);
|
|
1304
|
+
return;
|
|
1305
|
+
}
|
|
1306
|
+
throw error;
|
|
1307
|
+
}
|
|
1308
|
+
finally {
|
|
1309
|
+
layout.setNavigationLoading(false);
|
|
1310
|
+
}
|
|
1311
|
+
};
|
|
1312
|
+
const load = routeLoadChain.then(run);
|
|
1313
|
+
routeLoadChain = load.catch(() => undefined);
|
|
1314
|
+
await load;
|
|
1064
1315
|
},
|
|
1065
1316
|
updateContext(context) {
|
|
1066
1317
|
patchState(store, {
|
|
@@ -1129,10 +1380,23 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
|
|
|
1129
1380
|
},
|
|
1130
1381
|
setCurrentPage(page) {
|
|
1131
1382
|
const previousPage = store.currentPage();
|
|
1383
|
+
AXPDebugService.instance?.trace(DETAILS_VIEW_PAGE_TRACE_NS, 'viewmodel', 'setCurrentPage', () => pageQueryTraceContext({
|
|
1384
|
+
requestedPageId: page?.id ?? null,
|
|
1385
|
+
previousPageId: previousPage?.id ?? null,
|
|
1386
|
+
}));
|
|
1132
1387
|
if (page) {
|
|
1133
|
-
|
|
1388
|
+
if (!previousPage) {
|
|
1389
|
+
AXPDebugService.instance?.trace(DETAILS_VIEW_PAGE_TRACE_NS, 'viewmodel', 'setCurrentPage — ignored (initial load in progress)', () => pageQueryTraceContext({
|
|
1390
|
+
requestedPageId: page.id,
|
|
1391
|
+
}));
|
|
1392
|
+
return;
|
|
1393
|
+
}
|
|
1394
|
+
const pageParam = readPageQueryParam();
|
|
1134
1395
|
const isSamePage = previousPage?.id === page.id && pageParam === page.id;
|
|
1135
1396
|
if (!isSamePage && axpIsEntityDetailsViewRoute(router)) {
|
|
1397
|
+
AXPDebugService.instance?.trace(DETAILS_VIEW_PAGE_TRACE_NS, 'viewmodel', 'setCurrentPage — navigate', () => pageQueryTraceContext({
|
|
1398
|
+
navigateToPageId: page.id,
|
|
1399
|
+
}));
|
|
1136
1400
|
const queryParams = { page: page.id };
|
|
1137
1401
|
if (previousPage?.id && previousPage.id !== page.id) {
|
|
1138
1402
|
queryParams['filters'] = null;
|
|
@@ -1144,6 +1408,7 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
|
|
|
1144
1408
|
// Push history for desktop sidebar switches and mobile page-list picks.
|
|
1145
1409
|
replaceUrl: false,
|
|
1146
1410
|
});
|
|
1411
|
+
return;
|
|
1147
1412
|
}
|
|
1148
1413
|
void activatePageById(page.id);
|
|
1149
1414
|
}
|
|
@@ -1274,13 +1539,16 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
|
|
|
1274
1539
|
const snapshot = cloneDeep(context);
|
|
1275
1540
|
patchState(store, {
|
|
1276
1541
|
context: snapshot,
|
|
1542
|
+
savedContext: snapshot,
|
|
1277
1543
|
previousContext: snapshot,
|
|
1278
1544
|
formDirty: false,
|
|
1279
1545
|
});
|
|
1280
1546
|
},
|
|
1281
1547
|
async discard() {
|
|
1548
|
+
const saved = cloneDeep(store.savedContext());
|
|
1282
1549
|
patchState(store, {
|
|
1283
|
-
context:
|
|
1550
|
+
context: saved,
|
|
1551
|
+
previousContext: saved,
|
|
1284
1552
|
formDirty: false,
|
|
1285
1553
|
});
|
|
1286
1554
|
},
|
|
@@ -1295,10 +1563,6 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
|
|
|
1295
1563
|
});
|
|
1296
1564
|
try {
|
|
1297
1565
|
const result = await store.currentPage()?.execute?.(command, payload);
|
|
1298
|
-
// Clear submitting before post-save refresh so the footer is not left disabled.
|
|
1299
|
-
patchState(store, {
|
|
1300
|
-
status: AXPPageStatus.Rendered,
|
|
1301
|
-
});
|
|
1302
1566
|
const enableOperationToasts = await settingsService.get(AXPCommonSettings.EnableOperationToasts);
|
|
1303
1567
|
if (result?.success) {
|
|
1304
1568
|
try {
|
|
@@ -1309,6 +1573,7 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
|
|
|
1309
1573
|
}
|
|
1310
1574
|
patchState(store, {
|
|
1311
1575
|
previousContext: store.context(),
|
|
1576
|
+
savedContext: cloneDeep(store.context()),
|
|
1312
1577
|
formDirty: false,
|
|
1313
1578
|
});
|
|
1314
1579
|
if (enableOperationToasts) {
|
|
@@ -1322,9 +1587,6 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
|
|
|
1322
1587
|
timeOutProgress: true,
|
|
1323
1588
|
});
|
|
1324
1589
|
}
|
|
1325
|
-
patchState(store, {
|
|
1326
|
-
formDirty: false,
|
|
1327
|
-
});
|
|
1328
1590
|
return true;
|
|
1329
1591
|
}
|
|
1330
1592
|
const rawText = result?.message?.text;
|
|
@@ -1350,9 +1612,6 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
|
|
|
1350
1612
|
const errorText = error instanceof Error
|
|
1351
1613
|
? error.message
|
|
1352
1614
|
: await translateService.translateAsync('@general:messages.generic.error.description');
|
|
1353
|
-
patchState(store, {
|
|
1354
|
-
status: AXPPageStatus.Rendered,
|
|
1355
|
-
});
|
|
1356
1615
|
toastService.show({
|
|
1357
1616
|
color: 'danger',
|
|
1358
1617
|
title: await translateService.translateAsync('@general:messages.generic.error.title'),
|
|
@@ -1365,17 +1624,15 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
|
|
|
1365
1624
|
return false;
|
|
1366
1625
|
}
|
|
1367
1626
|
finally {
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
});
|
|
1372
|
-
}
|
|
1627
|
+
patchState(store, {
|
|
1628
|
+
status: AXPPageStatus.Rendered,
|
|
1629
|
+
});
|
|
1373
1630
|
}
|
|
1374
1631
|
},
|
|
1375
|
-
goToListPage() {
|
|
1632
|
+
async goToListPage() {
|
|
1376
1633
|
const exitUrl = store.adapter()?.exitUrl;
|
|
1377
1634
|
if (exitUrl) {
|
|
1378
|
-
|
|
1635
|
+
await axpNavigateAppPath(router, exitUrl);
|
|
1379
1636
|
}
|
|
1380
1637
|
},
|
|
1381
1638
|
};
|
|
@@ -1390,6 +1647,8 @@ const DEFAULT_FOOTER_COMMAND_SHORTCUTS = {
|
|
|
1390
1647
|
'update-entity': ['ctrl+s'],
|
|
1391
1648
|
discard: ['escape'],
|
|
1392
1649
|
};
|
|
1650
|
+
const SAVE_FOOTER_COMMAND_SUFFIX = ':Save';
|
|
1651
|
+
const DISCARD_FOOTER_COMMAND_SUFFIX = ':Discard';
|
|
1393
1652
|
/**
|
|
1394
1653
|
* Returns the base workflow/command name from a composite entity action command id (`cmd&actionName`).
|
|
1395
1654
|
*/
|
|
@@ -1420,7 +1679,34 @@ function resolveDetailsViewFooterCommandShortcuts(commandName, explicit) {
|
|
|
1420
1679
|
return chords.length ? chords : undefined;
|
|
1421
1680
|
}
|
|
1422
1681
|
const defaults = DEFAULT_FOOTER_COMMAND_SHORTCUTS[commandName];
|
|
1423
|
-
|
|
1682
|
+
if (defaults?.length) {
|
|
1683
|
+
return [...defaults];
|
|
1684
|
+
}
|
|
1685
|
+
return resolvePageFooterActionDefaultShortcuts(commandName);
|
|
1686
|
+
}
|
|
1687
|
+
/**
|
|
1688
|
+
* Platform defaults for component-page footer save/discard commands (e.g. `MetaDataBuilder:Save`).
|
|
1689
|
+
*/
|
|
1690
|
+
function resolvePageFooterActionDefaultShortcuts(commandName) {
|
|
1691
|
+
if (isSaveFooterCommand(commandName)) {
|
|
1692
|
+
return [...DEFAULT_FOOTER_COMMAND_SHORTCUTS['update-entity']];
|
|
1693
|
+
}
|
|
1694
|
+
if (isDiscardFooterCommand(commandName)) {
|
|
1695
|
+
return [...DEFAULT_FOOTER_COMMAND_SHORTCUTS['discard']];
|
|
1696
|
+
}
|
|
1697
|
+
return undefined;
|
|
1698
|
+
}
|
|
1699
|
+
function isSaveFooterCommand(commandName) {
|
|
1700
|
+
return commandName === 'update-entity' || commandName.endsWith(SAVE_FOOTER_COMMAND_SUFFIX);
|
|
1701
|
+
}
|
|
1702
|
+
function isDiscardFooterCommand(commandName) {
|
|
1703
|
+
return commandName === 'discard' || commandName.endsWith(DISCARD_FOOTER_COMMAND_SUFFIX);
|
|
1704
|
+
}
|
|
1705
|
+
/**
|
|
1706
|
+
* Resolves keyboard shortcuts for a footer action on entity detail sub-pages.
|
|
1707
|
+
*/
|
|
1708
|
+
function resolvePageFooterActionShortcuts(commandName, explicit) {
|
|
1709
|
+
return resolveDetailsViewFooterCommandShortcuts(commandName, explicit);
|
|
1424
1710
|
}
|
|
1425
1711
|
function flattenDetailsViewActionShortcuts(shortcuts) {
|
|
1426
1712
|
const chords = normalizeKeyboardShortcuts(shortcuts).flatMap((shortcut) => shortcut.keys);
|
|
@@ -1579,10 +1865,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
1579
1865
|
}]
|
|
1580
1866
|
}], propDecorators: { componentKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentKey", required: true }] }], rootContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "rootContext", required: false }] }], pageConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageConfig", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], componentReady: [{ type: i0.Output, args: ["componentReady"] }] } });
|
|
1581
1867
|
|
|
1868
|
+
/** Registered id of the data-list inside related-entity `page-list` sidebar pages. */
|
|
1869
|
+
const PAGE_LIST_TABLE_WIDGET_ID = 'page-list_table';
|
|
1582
1870
|
class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
1583
1871
|
constructor() {
|
|
1584
1872
|
super(...arguments);
|
|
1585
|
-
this.adapter = input.required(...(ngDevMode ? [{ debugName: "adapter" }] : /* istanbul ignore next */ []));
|
|
1586
1873
|
//
|
|
1587
1874
|
this.vm = inject(AXPLayoutDetailsViewViewModel);
|
|
1588
1875
|
this.route = inject(ActivatedRoute);
|
|
@@ -1591,13 +1878,23 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
1591
1878
|
this.unsavedChangesPopstate = inject(AXPUnsavedChangesPopstateService);
|
|
1592
1879
|
this.pageComponentInstanceRegistry = inject(AXPPageComponentInstanceRegistryService);
|
|
1593
1880
|
this.shortcutRegistry = inject(AXPKeyboardShortcutRegistry);
|
|
1881
|
+
this.workflowService = inject(AXPWorkflowService);
|
|
1594
1882
|
this.destroyRef = inject(DestroyRef);
|
|
1595
1883
|
this.elementRef = inject((ElementRef));
|
|
1596
|
-
|
|
1597
|
-
|
|
1884
|
+
this.debug = inject(AXPDebugService);
|
|
1885
|
+
/** Cancels in-flight list selection bind when the sidebar page or widget tree changes. */
|
|
1886
|
+
this.pageListSelectionBindGeneration = 0;
|
|
1887
|
+
/** Prevents sidebar tab init events from pushing history before the first page activation completes. */
|
|
1888
|
+
this.detailsLayoutReady = signal(false, ...(ngDevMode ? [{ debugName: "detailsLayoutReady" }] : /* istanbul ignore next */ []));
|
|
1598
1889
|
this.destroyed$ = new Subject();
|
|
1599
1890
|
this.footerActionsGeneration = 0;
|
|
1600
1891
|
this.keyboardShortcutRegistrationGeneration = 0;
|
|
1892
|
+
/** Page id the overlay release logic is bound to; reset on sidebar/page switch. */
|
|
1893
|
+
this.overlayTargetPageId = null;
|
|
1894
|
+
/** After a page switch, wait for widget registry to clear before accepting remounted widgets. */
|
|
1895
|
+
this.overlaySawZeroWidgetsAfterPageChange = false;
|
|
1896
|
+
/** Cancels in-flight overlay release when the page changes. */
|
|
1897
|
+
this.overlayReleaseGeneration = 0;
|
|
1601
1898
|
/** Header actions with resolved shortcut chords, keyed by command name. */
|
|
1602
1899
|
this.actionShortcutEntries = signal(new Map(), ...(ngDevMode ? [{ debugName: "actionShortcutEntries" }] : /* istanbul ignore next */ []));
|
|
1603
1900
|
this.form = viewChild('form', ...(ngDevMode ? [{ debugName: "form" }] : /* istanbul ignore next */ []));
|
|
@@ -1616,6 +1913,11 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
1616
1913
|
return;
|
|
1617
1914
|
}
|
|
1618
1915
|
untracked(() => queueMicrotask(() => {
|
|
1916
|
+
this.debug.trace(DETAILS_VIEW_PAGE_TRACE_NS, 'details-view', 'sidebarTabs select (sync indicator)', () => ({
|
|
1917
|
+
currentPageId: currentId,
|
|
1918
|
+
tabIndex: index,
|
|
1919
|
+
routerUrl: this.router.url,
|
|
1920
|
+
}));
|
|
1619
1921
|
this.sidebarTabChangeSuppressed = true;
|
|
1620
1922
|
try {
|
|
1621
1923
|
this.sidebarTabs()?.select(index);
|
|
@@ -1625,6 +1927,150 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
1625
1927
|
}
|
|
1626
1928
|
}));
|
|
1627
1929
|
}, ...(ngDevMode ? [{ debugName: "#sidebarTabsIndicatorEffect" }] : /* istanbul ignore next */ []));
|
|
1930
|
+
/**
|
|
1931
|
+
* Binds list selection whenever `page-list_table` registers (including after remount).
|
|
1932
|
+
* `find()` / `waitForWidget()` can return a destroyed instance; registration always carries the live widget.
|
|
1933
|
+
*/
|
|
1934
|
+
this.#pageListSelectionBindEffect = effect((onCleanup) => {
|
|
1935
|
+
const pageId = this.vm.currentPage()?.id;
|
|
1936
|
+
const isPageReady = this.vm.isPageReady();
|
|
1937
|
+
if (!pageId || this.vm.showPages() || !isPageReady || this.getActivePageComponentKey()) {
|
|
1938
|
+
return;
|
|
1939
|
+
}
|
|
1940
|
+
this.vm.currentPageContent();
|
|
1941
|
+
if (!this.pageHasEntityListWidget()) {
|
|
1942
|
+
return;
|
|
1943
|
+
}
|
|
1944
|
+
const generation = ++this.pageListSelectionBindGeneration;
|
|
1945
|
+
const container = this.widgetContainer();
|
|
1946
|
+
if (!container) {
|
|
1947
|
+
return;
|
|
1948
|
+
}
|
|
1949
|
+
const builder = container.builderService;
|
|
1950
|
+
onCleanup(() => {
|
|
1951
|
+
this.onSelectionChangeSubscription?.unsubscribe();
|
|
1952
|
+
this.onSelectionChangeSubscription = undefined;
|
|
1953
|
+
});
|
|
1954
|
+
const registrationSub = builder.widgetRegistered$.subscribe(({ id, widget }) => {
|
|
1955
|
+
if (id !== PAGE_LIST_TABLE_WIDGET_ID) {
|
|
1956
|
+
return;
|
|
1957
|
+
}
|
|
1958
|
+
this.attachSelectionToListWidget(pageId, generation, widget);
|
|
1959
|
+
});
|
|
1960
|
+
onCleanup(() => registrationSub.unsubscribe());
|
|
1961
|
+
const existing = builder.getWidget(PAGE_LIST_TABLE_WIDGET_ID);
|
|
1962
|
+
if (existing) {
|
|
1963
|
+
untracked(() => this.attachSelectionToListWidget(pageId, generation, existing));
|
|
1964
|
+
}
|
|
1965
|
+
}, ...(ngDevMode ? [{ debugName: "#pageListSelectionBindEffect" }] : /* istanbul ignore next */ []));
|
|
1966
|
+
/** Clears the page overlay reactively once VM + widget hydration are both idle. */
|
|
1967
|
+
this.#overlayReleaseEffect = effect(() => {
|
|
1968
|
+
const showPages = this.vm.showPages();
|
|
1969
|
+
const pageId = this.vm.currentPage()?.id;
|
|
1970
|
+
const isVmBusy = this.vm.isOverlayBusy();
|
|
1971
|
+
const isPageReady = this.vm.isPageReady();
|
|
1972
|
+
const container = this.widgetContainer();
|
|
1973
|
+
this.vm.currentPageContent();
|
|
1974
|
+
this.vm.activeTabContent();
|
|
1975
|
+
this.vm.context();
|
|
1976
|
+
container?.builderService.registeredWidgetsCount();
|
|
1977
|
+
container?.builderService.isHydrating();
|
|
1978
|
+
container?.isBusy();
|
|
1979
|
+
container?.isWidgetsReady();
|
|
1980
|
+
const widgetCount = container?.builderService.registeredWidgetsCount() ?? 0;
|
|
1981
|
+
const widgetsBusy = container?.isBusy() ?? false;
|
|
1982
|
+
const widgetsReady = container?.isWidgetsReady() ?? false;
|
|
1983
|
+
untracked(() => {
|
|
1984
|
+
const widgetSnapshot = container?.builderService.getWidgetStateSnapshot();
|
|
1985
|
+
if (pageId !== this.overlayTargetPageId) {
|
|
1986
|
+
const isInitialOverlayBind = this.overlayTargetPageId == null;
|
|
1987
|
+
this.debug.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'details-view', 'page bind changed', () => ({
|
|
1988
|
+
pageId,
|
|
1989
|
+
previousPageId: this.overlayTargetPageId,
|
|
1990
|
+
isInitialOverlayBind,
|
|
1991
|
+
overlayReleaseGeneration: this.overlayReleaseGeneration + 1,
|
|
1992
|
+
}));
|
|
1993
|
+
this.overlayTargetPageId = pageId ?? null;
|
|
1994
|
+
// First bind: widgets mount without a prior page registry. Sidebar switch: require clear first.
|
|
1995
|
+
this.overlaySawZeroWidgetsAfterPageChange = isInitialOverlayBind;
|
|
1996
|
+
this.overlayReleaseGeneration += 1;
|
|
1997
|
+
this.overlayReleasePromise = undefined;
|
|
1998
|
+
this.clearOverlayFallback();
|
|
1999
|
+
}
|
|
2000
|
+
if (showPages) {
|
|
2001
|
+
this.debug.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'details-view', 'showPages — release overlay', () => ({ isVmBusy }));
|
|
2002
|
+
this.overlayReleaseGeneration += 1;
|
|
2003
|
+
this.overlayReleasePromise = undefined;
|
|
2004
|
+
this.clearOverlayFallback();
|
|
2005
|
+
if (!isVmBusy) {
|
|
2006
|
+
this.clearPageOverlay('showPages — release overlay');
|
|
2007
|
+
}
|
|
2008
|
+
return;
|
|
2009
|
+
}
|
|
2010
|
+
if (isVmBusy || !isPageReady || !pageId) {
|
|
2011
|
+
this.debug.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'details-view', 'waiting on VM', () => ({
|
|
2012
|
+
pageId,
|
|
2013
|
+
isVmBusy,
|
|
2014
|
+
isPageReady,
|
|
2015
|
+
}));
|
|
2016
|
+
this.overlayReleaseGeneration += 1;
|
|
2017
|
+
this.overlayReleasePromise = undefined;
|
|
2018
|
+
this.clearOverlayFallback();
|
|
2019
|
+
return;
|
|
2020
|
+
}
|
|
2021
|
+
if (this.getActivePageComponentKey()) {
|
|
2022
|
+
this.debug.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'details-view', 'component page — release overlay', () => ({
|
|
2023
|
+
componentKey: this.getActivePageComponentKey(),
|
|
2024
|
+
}));
|
|
2025
|
+
this.overlayReleaseGeneration += 1;
|
|
2026
|
+
this.overlayReleasePromise = undefined;
|
|
2027
|
+
this.clearOverlayFallback();
|
|
2028
|
+
this.clearPageOverlay('component page — release overlay');
|
|
2029
|
+
return;
|
|
2030
|
+
}
|
|
2031
|
+
if (!this.pageHasWidgetNodes()) {
|
|
2032
|
+
this.debug.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'details-view', 'no widget nodes — release overlay', () => ({ pageId }));
|
|
2033
|
+
this.overlayReleaseGeneration += 1;
|
|
2034
|
+
this.overlayReleasePromise = undefined;
|
|
2035
|
+
this.clearOverlayFallback();
|
|
2036
|
+
this.clearPageOverlay('no widget nodes — release overlay');
|
|
2037
|
+
return;
|
|
2038
|
+
}
|
|
2039
|
+
if (widgetCount === 0) {
|
|
2040
|
+
this.overlaySawZeroWidgetsAfterPageChange = true;
|
|
2041
|
+
this.debug.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'details-view', 'widget registry cleared (remount gate open)', () => ({ pageId }));
|
|
2042
|
+
}
|
|
2043
|
+
if (!this.overlaySawZeroWidgetsAfterPageChange) {
|
|
2044
|
+
this.debug.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'details-view', 'blocked: remount gate (await widgetCount=0)', () => ({
|
|
2045
|
+
pageId,
|
|
2046
|
+
widgetCount,
|
|
2047
|
+
...widgetSnapshot,
|
|
2048
|
+
}));
|
|
2049
|
+
this.scheduleOverlayFallback();
|
|
2050
|
+
return;
|
|
2051
|
+
}
|
|
2052
|
+
if (!widgetsReady || widgetsBusy) {
|
|
2053
|
+
this.debug.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'details-view', 'blocked: widgets not ready', () => ({
|
|
2054
|
+
pageId,
|
|
2055
|
+
widgetsReady,
|
|
2056
|
+
widgetsBusy,
|
|
2057
|
+
overlaySawZero: this.overlaySawZeroWidgetsAfterPageChange,
|
|
2058
|
+
releaseInFlight: !!this.overlayReleasePromise,
|
|
2059
|
+
...widgetSnapshot,
|
|
2060
|
+
hydratingWidgets: widgetSnapshot?.widgets?.filter((w) => w.isHydrating).map((w) => w.id),
|
|
2061
|
+
renderingWidgets: widgetSnapshot?.widgets?.filter((w) => w.status === 'rendering').map((w) => w.id),
|
|
2062
|
+
}));
|
|
2063
|
+
this.scheduleOverlayFallback();
|
|
2064
|
+
return;
|
|
2065
|
+
}
|
|
2066
|
+
this.debug.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'details-view', 'request overlay release', () => ({
|
|
2067
|
+
pageId,
|
|
2068
|
+
overlayReleaseGeneration: this.overlayReleaseGeneration,
|
|
2069
|
+
...widgetSnapshot,
|
|
2070
|
+
}));
|
|
2071
|
+
void this.requestOverlayRelease(pageId);
|
|
2072
|
+
});
|
|
2073
|
+
}, ...(ngDevMode ? [{ debugName: "#overlayReleaseEffect" }] : /* istanbul ignore next */ []));
|
|
1628
2074
|
this.footerPrimaryActions = signal([], ...(ngDevMode ? [{ debugName: "footerPrimaryActions" }] : /* istanbul ignore next */ []));
|
|
1629
2075
|
this.footerSecondaryActions = signal([], ...(ngDevMode ? [{ debugName: "footerSecondaryActions" }] : /* istanbul ignore next */ []));
|
|
1630
2076
|
this.footerActions = computed(() => [...this.footerPrimaryActions(), ...this.footerSecondaryActions()], ...(ngDevMode ? [{ debugName: "footerActions" }] : /* istanbul ignore next */ []));
|
|
@@ -1648,7 +2094,14 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
1648
2094
|
if (this.vm.currentPage()?.isReadonly || this.getActivePageComponentKey()) {
|
|
1649
2095
|
return false;
|
|
1650
2096
|
}
|
|
1651
|
-
|
|
2097
|
+
if (this.vm.isOverlayBusy()) {
|
|
2098
|
+
return false;
|
|
2099
|
+
}
|
|
2100
|
+
const container = this.widgetContainer();
|
|
2101
|
+
if (!container?.isSavedCommitted()) {
|
|
2102
|
+
return false;
|
|
2103
|
+
}
|
|
2104
|
+
return container.isFormDirty();
|
|
1652
2105
|
}, ...(ngDevMode ? [{ debugName: "liveFormIsDirty" }] : /* istanbul ignore next */ []));
|
|
1653
2106
|
this.hasVisibleFooterPrimaryActions = computed(() => {
|
|
1654
2107
|
if (this.showSaveDiscardFooter()) {
|
|
@@ -1665,11 +2118,25 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
1665
2118
|
if (this.vm.currentPage()?.isReadonly || this.getActivePageComponentKey()) {
|
|
1666
2119
|
return;
|
|
1667
2120
|
}
|
|
1668
|
-
|
|
2121
|
+
if (this.vm.isOverlayBusy()) {
|
|
2122
|
+
return;
|
|
2123
|
+
}
|
|
2124
|
+
const container = this.widgetContainer();
|
|
2125
|
+
if (!container?.isSavedCommitted()) {
|
|
2126
|
+
if (this.vm.formDirty()) {
|
|
2127
|
+
untracked(() => this.vm.setFormDirty(false));
|
|
2128
|
+
}
|
|
2129
|
+
return;
|
|
2130
|
+
}
|
|
2131
|
+
const isDirty = container.isFormDirty();
|
|
1669
2132
|
if (this.vm.formDirty() === isDirty) {
|
|
1670
2133
|
return;
|
|
1671
2134
|
}
|
|
1672
2135
|
untracked(() => {
|
|
2136
|
+
this.debug.trace(FORM_DIRTY_TRACE_NS, 'details-view', 'formDirty effect', () => ({
|
|
2137
|
+
isDirty,
|
|
2138
|
+
vmFormDirty: this.vm.formDirty(),
|
|
2139
|
+
}));
|
|
1673
2140
|
this.vm.setFormDirty(isDirty);
|
|
1674
2141
|
this.recompute();
|
|
1675
2142
|
});
|
|
@@ -1685,18 +2152,21 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
1685
2152
|
const generation = ++this.footerActionsGeneration;
|
|
1686
2153
|
this.updateTrigger();
|
|
1687
2154
|
this.liveFormIsDirty();
|
|
1688
|
-
this.vm.
|
|
2155
|
+
this.vm.isOverlayBusy();
|
|
1689
2156
|
void this.refreshFooterActions(generation);
|
|
1690
2157
|
}, ...(ngDevMode ? [{ debugName: "#FooterActionsEffect" }] : /* istanbul ignore next */ []));
|
|
1691
2158
|
this.#keyboardShortcutsEffect = effect(() => {
|
|
1692
2159
|
const generation = ++this.keyboardShortcutRegistrationGeneration;
|
|
1693
2160
|
this.updateTrigger();
|
|
1694
2161
|
this.liveFormIsDirty();
|
|
1695
|
-
this.
|
|
2162
|
+
this.isActivePageComponentDirty();
|
|
2163
|
+
this.vm.isOverlayBusy();
|
|
1696
2164
|
this.vm.currentPage()?.id;
|
|
1697
2165
|
untracked(() => void this.refreshKeyboardShortcutRegistrations(generation));
|
|
1698
2166
|
}, ...(ngDevMode ? [{ debugName: "#keyboardShortcutsEffect" }] : /* istanbul ignore next */ []));
|
|
1699
2167
|
}
|
|
2168
|
+
/** Safety cap when widget ready detection does not settle. */
|
|
2169
|
+
static { this.overlayMaxWaitMs = 30_000; }
|
|
1700
2170
|
/** Save/discard use live {@link AXPLayoutDetailsViewViewModel.isDirty}; other actions use evaluated `visible`. */
|
|
1701
2171
|
static isTruthyActionFlag(value) {
|
|
1702
2172
|
if (value === true) {
|
|
@@ -1723,6 +2193,13 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
1723
2193
|
}
|
|
1724
2194
|
/** Syncs the line indicator when the active page changes programmatically. */
|
|
1725
2195
|
#sidebarTabsIndicatorEffect;
|
|
2196
|
+
/**
|
|
2197
|
+
* Binds list selection whenever `page-list_table` registers (including after remount).
|
|
2198
|
+
* `find()` / `waitForWidget()` can return a destroyed instance; registration always carries the live widget.
|
|
2199
|
+
*/
|
|
2200
|
+
#pageListSelectionBindEffect;
|
|
2201
|
+
/** Clears the page overlay reactively once VM + widget hydration are both idle. */
|
|
2202
|
+
#overlayReleaseEffect;
|
|
1726
2203
|
isSaveDiscardFooterAction(action) {
|
|
1727
2204
|
const commandName = action.command?.name;
|
|
1728
2205
|
const acceptCommand = this.vm.currentPage()?.settings?.commands?.accept?.command?.name;
|
|
@@ -1741,35 +2218,43 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
1741
2218
|
return AXPLayoutDetailsViewComponent.isTruthyActionFlag(action.visible);
|
|
1742
2219
|
}
|
|
1743
2220
|
isFooterActionDisabled(action) {
|
|
1744
|
-
if (this.vm.
|
|
2221
|
+
if (this.vm.isOverlayBusy()) {
|
|
1745
2222
|
return true;
|
|
1746
2223
|
}
|
|
1747
2224
|
return AXPLayoutDetailsViewComponent.isTruthyActionFlag(action.disabled);
|
|
1748
2225
|
}
|
|
1749
2226
|
/**
|
|
1750
|
-
*
|
|
2227
|
+
* Re-fetches the entity adapter and reloads the active page.
|
|
1751
2228
|
*/
|
|
1752
2229
|
async refreshLayout() {
|
|
1753
|
-
const router = this.router;
|
|
1754
|
-
const route = this.route;
|
|
1755
|
-
const now = Date.now();
|
|
1756
2230
|
this.unsavedChangesConfirm.markLeaveConfirmed();
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
2231
|
+
this.detailsLayoutReady.set(false);
|
|
2232
|
+
try {
|
|
2233
|
+
await this.vm.loadFromRoute(true);
|
|
2234
|
+
}
|
|
2235
|
+
finally {
|
|
2236
|
+
this.detailsLayoutReady.set(true);
|
|
2237
|
+
}
|
|
1763
2238
|
}
|
|
1764
2239
|
async ngOnInit() {
|
|
1765
2240
|
await super.ngOnInit();
|
|
2241
|
+
this.debug.trace(DETAILS_VIEW_PAGE_TRACE_NS, 'details-view', 'ngOnInit — before loadFromRoute', () => ({
|
|
2242
|
+
routerUrl: this.router.url,
|
|
2243
|
+
pageFromRouterUrl: this.router.parseUrl(this.router.url).queryParams['page'] ?? null,
|
|
2244
|
+
pageFromRouteSnapshot: this.route.snapshot.queryParamMap.get('page'),
|
|
2245
|
+
}));
|
|
1766
2246
|
this.unsavedChangesPopstate.registerSource({
|
|
1767
2247
|
id: 'axp-layout-details-view',
|
|
1768
|
-
isDirty: () => this.
|
|
2248
|
+
isDirty: () => this.hasUnsavedChanges(),
|
|
1769
2249
|
});
|
|
2250
|
+
this.destroyRef.onDestroy(() => this.unsavedChangesPopstate.unregisterSource('axp-layout-details-view'));
|
|
1770
2251
|
//
|
|
1771
|
-
await this.vm.
|
|
1772
|
-
this.
|
|
2252
|
+
await this.vm.loadFromRoute();
|
|
2253
|
+
this.debug.trace(DETAILS_VIEW_PAGE_TRACE_NS, 'details-view', 'ngOnInit — after loadFromRoute', () => ({
|
|
2254
|
+
routerUrl: this.router.url,
|
|
2255
|
+
currentPageId: this.vm.currentPage()?.id ?? null,
|
|
2256
|
+
}));
|
|
2257
|
+
this.detailsLayoutReady.set(true);
|
|
1773
2258
|
void this.refreshKeyboardShortcutRegistrations(++this.keyboardShortcutRegistrationGeneration);
|
|
1774
2259
|
this.eventService
|
|
1775
2260
|
//TODO: Use the constant from the entity module
|
|
@@ -1780,23 +2265,45 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
1780
2265
|
this.refreshLayout();
|
|
1781
2266
|
}
|
|
1782
2267
|
});
|
|
2268
|
+
this.workflowService.events$
|
|
2269
|
+
.pipe(filter$1((event) => event.type === AXP_ENTITY_DELETED_WORKFLOW_EVENT_TYPE), takeUntil(this.destroyed$))
|
|
2270
|
+
.subscribe((event) => {
|
|
2271
|
+
void this.handleEntityDeleted(event.payload);
|
|
2272
|
+
});
|
|
1783
2273
|
}
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
if (
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
2274
|
+
/** Navigates to {@link AXPLayoutDetailsViewAdapter.exitUrl} when the open record was deleted. */
|
|
2275
|
+
async handleEntityDeleted(payload) {
|
|
2276
|
+
if (!payload?.entity || !payload.ids?.length) {
|
|
2277
|
+
return;
|
|
2278
|
+
}
|
|
2279
|
+
const adapterName = this.vm.adapter()?.name;
|
|
2280
|
+
const recordId = this.vm.context()?.['id'];
|
|
2281
|
+
if (!adapterName || recordId == null) {
|
|
2282
|
+
return;
|
|
2283
|
+
}
|
|
2284
|
+
const deletedIds = payload.ids.map((id) => String(id));
|
|
2285
|
+
if (payload.entity !== adapterName || !deletedIds.includes(String(recordId))) {
|
|
2286
|
+
return;
|
|
2287
|
+
}
|
|
2288
|
+
this.unsavedChangesConfirm.markLeaveConfirmed();
|
|
2289
|
+
if (this.tabNavigation.effectiveMode() === 'tabular') {
|
|
2290
|
+
const tabKey = this.getPageTabKey();
|
|
2291
|
+
await this.vm.goToListPage();
|
|
2292
|
+
if (tabKey) {
|
|
2293
|
+
this.unsavedChangesConfirm.markLeaveConfirmed();
|
|
2294
|
+
await this.tabNavigation.closeTab(tabKey);
|
|
1793
2295
|
}
|
|
2296
|
+
return;
|
|
1794
2297
|
}
|
|
2298
|
+
await this.vm.goToListPage();
|
|
1795
2299
|
}
|
|
1796
2300
|
ngOnDestroy() {
|
|
1797
|
-
this.unsavedChangesPopstate.unregisterSource('axp-layout-details-view');
|
|
1798
2301
|
this.onSelectionChangeSubscription?.unsubscribe();
|
|
1799
2302
|
++this.keyboardShortcutRegistrationGeneration;
|
|
2303
|
+
this.clearOverlayFallback();
|
|
2304
|
+
this.overlayReleaseGeneration += 1;
|
|
2305
|
+
this.overlayReleasePromise = undefined;
|
|
2306
|
+
this.clearPageOverlay('ngOnDestroy');
|
|
1800
2307
|
this.destroyed$.next();
|
|
1801
2308
|
this.destroyed$.complete();
|
|
1802
2309
|
}
|
|
@@ -1816,29 +2323,196 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
1816
2323
|
this.footerPrimaryActions.set(footerPrimaryActions);
|
|
1817
2324
|
this.footerSecondaryActions.set(footerSecondaryActions);
|
|
1818
2325
|
}
|
|
2326
|
+
/** Whether the active page hosts a related-entity list (`page-list` widget). */
|
|
2327
|
+
pageHasEntityListWidget() {
|
|
2328
|
+
return this.vm.currentPageContent().some((item) => {
|
|
2329
|
+
if ('type' in item && item.type === 'component') {
|
|
2330
|
+
return false;
|
|
2331
|
+
}
|
|
2332
|
+
return item.name === 'page-list';
|
|
2333
|
+
});
|
|
2334
|
+
}
|
|
2335
|
+
/** Subscribes to the live data-list selection stream for Selected-scope header actions. */
|
|
2336
|
+
attachSelectionToListWidget(pageId, generation, widget) {
|
|
2337
|
+
if (generation !== this.pageListSelectionBindGeneration || this.vm.currentPage()?.id !== pageId) {
|
|
2338
|
+
return;
|
|
2339
|
+
}
|
|
2340
|
+
const selectionStream = widget.api()['onSelectionChange'];
|
|
2341
|
+
if (!selectionStream || typeof selectionStream.subscribe !== 'function') {
|
|
2342
|
+
return;
|
|
2343
|
+
}
|
|
2344
|
+
this.onSelectionChangeSubscription?.unsubscribe();
|
|
2345
|
+
this.onSelectionChangeSubscription = selectionStream.subscribe((rows) => {
|
|
2346
|
+
this.vm.updatePageSelectedRows(rows);
|
|
2347
|
+
this.recompute();
|
|
2348
|
+
});
|
|
2349
|
+
}
|
|
1819
2350
|
handleOnContextChanged(e) {
|
|
1820
|
-
this.vm.
|
|
2351
|
+
if (!this.vm.currentPage()?.isReadonly &&
|
|
2352
|
+
!this.getActivePageComponentKey() &&
|
|
2353
|
+
this.widgetContainer()?.isSavedCommitted()) {
|
|
2354
|
+
const isDirty = e.isFormDirty ?? false;
|
|
2355
|
+
const container = this.widgetContainer();
|
|
2356
|
+
this.debug.trace(FORM_DIRTY_TRACE_NS, 'details-view', 'handleOnContextChanged', () => ({
|
|
2357
|
+
isFormDirty: isDirty,
|
|
2358
|
+
vmFormDirty: this.vm.formDirty(),
|
|
2359
|
+
changePath: e.path,
|
|
2360
|
+
changeOrigin: e.origin,
|
|
2361
|
+
userEditedSinceCommit: container?.contextService.hasUserEditedSinceCommit(),
|
|
2362
|
+
dirtyPaths: container
|
|
2363
|
+
? summarizeFormContextDirtyDiff(container.contextService.data(), container.contextService.saved())
|
|
2364
|
+
: [],
|
|
2365
|
+
}));
|
|
2366
|
+
if (this.vm.formDirty() !== isDirty) {
|
|
2367
|
+
this.vm.setFormDirty(isDirty);
|
|
2368
|
+
}
|
|
2369
|
+
}
|
|
1821
2370
|
this.recompute();
|
|
1822
2371
|
}
|
|
1823
2372
|
getLiveFormContext() {
|
|
1824
2373
|
const container = this.widgetContainer();
|
|
1825
2374
|
return (container?.contextService.data() ?? this.vm.context());
|
|
1826
2375
|
}
|
|
2376
|
+
/** Whether the active page renders widget nodes (not only hosted components). */
|
|
2377
|
+
pageHasWidgetNodes() {
|
|
2378
|
+
const pageWidgets = this.vm.currentPageContent();
|
|
2379
|
+
if (pageWidgets.some((item) => !('type' in item && item.type === 'component'))) {
|
|
2380
|
+
return true;
|
|
2381
|
+
}
|
|
2382
|
+
return this.vm.activeTabContent().length > 0;
|
|
2383
|
+
}
|
|
2384
|
+
/** Clears all overlay loading tasks once the page (or hosted view) is ready. */
|
|
2385
|
+
clearPageOverlay(reason) {
|
|
2386
|
+
this.debug.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'details-view', reason, () => ({
|
|
2387
|
+
taskCount: this.layoutService.overlayTaskCount(),
|
|
2388
|
+
}));
|
|
2389
|
+
this.layoutService.clearOverlayLoading();
|
|
2390
|
+
}
|
|
2391
|
+
scheduleOverlayFallback() {
|
|
2392
|
+
if (this.overlayFallbackTimer) {
|
|
2393
|
+
return;
|
|
2394
|
+
}
|
|
2395
|
+
this.debug.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'details-view', 'schedule fallback timer', () => ({
|
|
2396
|
+
timeoutMs: AXPLayoutDetailsViewComponent.overlayMaxWaitMs,
|
|
2397
|
+
pageId: this.overlayTargetPageId,
|
|
2398
|
+
}));
|
|
2399
|
+
this.overlayFallbackTimer = setTimeout(() => {
|
|
2400
|
+
this.overlayFallbackTimer = undefined;
|
|
2401
|
+
const isOverlayLoading = this.layoutService.isOverlayLoading();
|
|
2402
|
+
const isVmBusy = this.vm.isOverlayBusy();
|
|
2403
|
+
this.debug.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'details-view', 'fallback timer fired', () => ({
|
|
2404
|
+
isOverlayLoading,
|
|
2405
|
+
isVmBusy,
|
|
2406
|
+
pageId: this.overlayTargetPageId,
|
|
2407
|
+
}));
|
|
2408
|
+
if (!isOverlayLoading) {
|
|
2409
|
+
return;
|
|
2410
|
+
}
|
|
2411
|
+
if (!isVmBusy) {
|
|
2412
|
+
this.debug.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'details-view', 'fallback forcing overlay off', () => ({
|
|
2413
|
+
taskCount: this.layoutService.overlayTaskCount(),
|
|
2414
|
+
}));
|
|
2415
|
+
this.clearPageOverlay('fallback forcing overlay off');
|
|
2416
|
+
}
|
|
2417
|
+
}, AXPLayoutDetailsViewComponent.overlayMaxWaitMs);
|
|
2418
|
+
}
|
|
2419
|
+
clearOverlayFallback() {
|
|
2420
|
+
if (this.overlayFallbackTimer) {
|
|
2421
|
+
clearTimeout(this.overlayFallbackTimer);
|
|
2422
|
+
this.overlayFallbackTimer = undefined;
|
|
2423
|
+
}
|
|
2424
|
+
}
|
|
2425
|
+
/**
|
|
2426
|
+
* Hides overlay after the widget container reports continuous idle (same gate as saved baseline).
|
|
2427
|
+
*/
|
|
2428
|
+
requestOverlayRelease(pageId) {
|
|
2429
|
+
if (this.overlayReleasePromise) {
|
|
2430
|
+
this.debug.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'details-view', 'release skipped — already in flight', () => ({ pageId }));
|
|
2431
|
+
return;
|
|
2432
|
+
}
|
|
2433
|
+
const generation = this.overlayReleaseGeneration;
|
|
2434
|
+
const container = this.widgetContainer();
|
|
2435
|
+
if (!container) {
|
|
2436
|
+
this.debug.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'details-view', 'release skipped — no container', () => ({ pageId }));
|
|
2437
|
+
this.scheduleOverlayFallback();
|
|
2438
|
+
return;
|
|
2439
|
+
}
|
|
2440
|
+
this.debug.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'details-view', 'waitUntilSettled started', () => ({ pageId, generation }));
|
|
2441
|
+
this.overlayReleasePromise = container
|
|
2442
|
+
.waitUntilSettled()
|
|
2443
|
+
.then(() => {
|
|
2444
|
+
const latest = this.widgetContainer();
|
|
2445
|
+
const snapshot = latest?.builderService.getWidgetStateSnapshot();
|
|
2446
|
+
if (generation !== this.overlayReleaseGeneration) {
|
|
2447
|
+
this.debug.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'details-view', 'release aborted — generation mismatch', () => ({
|
|
2448
|
+
pageId,
|
|
2449
|
+
generation,
|
|
2450
|
+
currentGeneration: this.overlayReleaseGeneration,
|
|
2451
|
+
}));
|
|
2452
|
+
return;
|
|
2453
|
+
}
|
|
2454
|
+
if (pageId !== this.overlayTargetPageId || pageId !== this.vm.currentPage()?.id) {
|
|
2455
|
+
this.debug.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'details-view', 'release aborted — page changed', () => ({
|
|
2456
|
+
pageId,
|
|
2457
|
+
overlayTargetPageId: this.overlayTargetPageId,
|
|
2458
|
+
currentPageId: this.vm.currentPage()?.id,
|
|
2459
|
+
}));
|
|
2460
|
+
return;
|
|
2461
|
+
}
|
|
2462
|
+
if (this.vm.isOverlayBusy()) {
|
|
2463
|
+
this.debug.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'details-view', 'release aborted — VM still busy', () => ({ pageId }));
|
|
2464
|
+
return;
|
|
2465
|
+
}
|
|
2466
|
+
if (!latest?.isWidgetsReady() || latest.isBusy()) {
|
|
2467
|
+
this.debug.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'details-view', 'release aborted — widgets not ready after settle', () => ({
|
|
2468
|
+
pageId,
|
|
2469
|
+
widgetsReady: latest?.isWidgetsReady(),
|
|
2470
|
+
widgetsBusy: latest?.isBusy(),
|
|
2471
|
+
...snapshot,
|
|
2472
|
+
}));
|
|
2473
|
+
return;
|
|
2474
|
+
}
|
|
2475
|
+
this.debug.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'details-view', 'release overlay OFF', () => ({
|
|
2476
|
+
pageId,
|
|
2477
|
+
generation,
|
|
2478
|
+
taskCount: this.layoutService.overlayTaskCount(),
|
|
2479
|
+
...snapshot,
|
|
2480
|
+
}));
|
|
2481
|
+
this.clearOverlayFallback();
|
|
2482
|
+
this.clearPageOverlay('widgets settled — release overlay');
|
|
2483
|
+
})
|
|
2484
|
+
.finally(() => {
|
|
2485
|
+
this.overlayReleasePromise = undefined;
|
|
2486
|
+
});
|
|
2487
|
+
}
|
|
1827
2488
|
async finalizeSave() {
|
|
1828
2489
|
const container = this.widgetContainer();
|
|
1829
2490
|
if (!container) {
|
|
1830
2491
|
this.vm.setFormDirty(false);
|
|
1831
2492
|
return;
|
|
1832
2493
|
}
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
2494
|
+
this.debug.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'details-view', 'finalizeSave overlay ON');
|
|
2495
|
+
this.layoutService.setOverlayLoading(true);
|
|
2496
|
+
try {
|
|
2497
|
+
const savedContext = this.vm.context();
|
|
2498
|
+
await container.replaceContext(savedContext);
|
|
2499
|
+
this.vm.applySavedState(container.contextService.data());
|
|
2500
|
+
if (!this.getActivePageComponentKey()) {
|
|
2501
|
+
await container.settleSavedBaseline();
|
|
2502
|
+
}
|
|
2503
|
+
}
|
|
2504
|
+
finally {
|
|
2505
|
+
this.debug.trace(OVERLAY_DETAILS_VIEW_TRACE_NS, 'details-view', 'finalizeSave overlay OFF');
|
|
2506
|
+
this.layoutService.setOverlayLoading(false);
|
|
2507
|
+
}
|
|
1836
2508
|
}
|
|
1837
2509
|
finalizeDiscard() {
|
|
2510
|
+
this.debug.trace(FORM_DIRTY_TRACE_NS, 'details-view', 'finalizeDiscard');
|
|
1838
2511
|
const container = this.widgetContainer();
|
|
1839
2512
|
if (container) {
|
|
1840
2513
|
container.revertAndSettle();
|
|
1841
|
-
|
|
2514
|
+
const saved = container.contextService.saved();
|
|
2515
|
+
this.vm.applySavedState(saved);
|
|
1842
2516
|
return;
|
|
1843
2517
|
}
|
|
1844
2518
|
void this.vm.discard();
|
|
@@ -1852,15 +2526,21 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
1852
2526
|
* `ax-tabs` selects on click before we can confirm. Revert synchronously, then confirm + switch.
|
|
1853
2527
|
*/
|
|
1854
2528
|
handleSidebarTabChanged(event) {
|
|
1855
|
-
if (!this.detailsLayoutReady || this.sidebarTabChangeSuppressed) {
|
|
2529
|
+
if (!this.detailsLayoutReady() || this.sidebarTabChangeSuppressed) {
|
|
1856
2530
|
return;
|
|
1857
2531
|
}
|
|
1858
2532
|
const pages = this.vm.adapter()?.pages ?? [];
|
|
1859
2533
|
const target = pages[event.index];
|
|
1860
2534
|
const currentId = this.vm.currentPage()?.id;
|
|
1861
|
-
if (!target || target.id === currentId) {
|
|
2535
|
+
if (!currentId || !target || target.id === currentId) {
|
|
1862
2536
|
return;
|
|
1863
2537
|
}
|
|
2538
|
+
this.debug.trace(DETAILS_VIEW_PAGE_TRACE_NS, 'details-view', 'handleSidebarTabChanged', () => ({
|
|
2539
|
+
routerUrl: this.router.url,
|
|
2540
|
+
targetPageId: target.id,
|
|
2541
|
+
currentPageId: currentId ?? null,
|
|
2542
|
+
tabIndex: event.index,
|
|
2543
|
+
}));
|
|
1864
2544
|
const activeIndex = pages.findIndex((page) => page.id === currentId);
|
|
1865
2545
|
if (activeIndex >= 0) {
|
|
1866
2546
|
this.sidebarTabChangeSuppressed = true;
|
|
@@ -1943,13 +2623,7 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
1943
2623
|
return this.vm.getBackButton();
|
|
1944
2624
|
}
|
|
1945
2625
|
hasUnsavedChanges() {
|
|
1946
|
-
|
|
1947
|
-
return false;
|
|
1948
|
-
}
|
|
1949
|
-
if (this.isActivePageComponentDirty()) {
|
|
1950
|
-
return true;
|
|
1951
|
-
}
|
|
1952
|
-
return this.liveFormIsDirty();
|
|
2626
|
+
return this.shouldPromptLeave();
|
|
1953
2627
|
}
|
|
1954
2628
|
async getPageBadge() {
|
|
1955
2629
|
if (this.vm.currentPage()?.isReadonly) {
|
|
@@ -1997,6 +2671,9 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
1997
2671
|
}
|
|
1998
2672
|
/** Background tab close — confirm without discarding (the cached instance is destroyed). */
|
|
1999
2673
|
onBeforeTabClose() {
|
|
2674
|
+
if (this.unsavedChangesConfirm.hasLeaveConfirmed()) {
|
|
2675
|
+
return Promise.resolve(true);
|
|
2676
|
+
}
|
|
2000
2677
|
return this.unsavedChangesConfirm.confirmIfDirty(this.shouldPromptLeave(), {
|
|
2001
2678
|
approveLeaveOnConfirm: false,
|
|
2002
2679
|
});
|
|
@@ -2026,15 +2703,33 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
2026
2703
|
return 'type' in item && item.type === 'component';
|
|
2027
2704
|
}
|
|
2028
2705
|
pageContentTrackKey(item, index) {
|
|
2706
|
+
const pageId = this.vm.currentPage()?.id ?? 'unknown';
|
|
2029
2707
|
if (AXPLayoutDetailsViewComponent.isComponentPageContent(item)) {
|
|
2030
|
-
return
|
|
2708
|
+
return `${pageId}:component:${item.componentKey}`;
|
|
2031
2709
|
}
|
|
2032
|
-
return item.name ?? `widget:${index}`;
|
|
2710
|
+
return `${pageId}:${item.name ?? `widget:${index}`}`;
|
|
2033
2711
|
}
|
|
2034
2712
|
/** Whether the active component-based entity page has unsaved edits. */
|
|
2035
2713
|
isActivePageComponentDirty() {
|
|
2036
2714
|
return this.getActivePageComponentInstance()?.hasUnsavedChanges() ?? false;
|
|
2037
2715
|
}
|
|
2716
|
+
/**
|
|
2717
|
+
* Widget-form dirty state for leave guards (popstate, canDeactivate).
|
|
2718
|
+
* Unlike {@link liveFormIsDirty}, does not suppress dirty while overlay is busy.
|
|
2719
|
+
*/
|
|
2720
|
+
hasWidgetFormUnsavedChanges() {
|
|
2721
|
+
if (this.getActivePageComponentKey()) {
|
|
2722
|
+
return false;
|
|
2723
|
+
}
|
|
2724
|
+
const container = this.widgetContainer();
|
|
2725
|
+
if (!container) {
|
|
2726
|
+
return this.vm.formDirty();
|
|
2727
|
+
}
|
|
2728
|
+
if (container.isSavedCommitted()) {
|
|
2729
|
+
return container.isFormDirty();
|
|
2730
|
+
}
|
|
2731
|
+
return container.contextService.hasUserEditedSinceCommit() || this.vm.formDirty();
|
|
2732
|
+
}
|
|
2038
2733
|
/** Whether the current details page has user-origin unsaved edits (form or component page). */
|
|
2039
2734
|
shouldPromptLeave() {
|
|
2040
2735
|
if (this.vm.currentPage()?.isReadonly) {
|
|
@@ -2043,7 +2738,7 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
2043
2738
|
if (this.isActivePageComponentDirty()) {
|
|
2044
2739
|
return true;
|
|
2045
2740
|
}
|
|
2046
|
-
return this.
|
|
2741
|
+
return this.hasWidgetFormUnsavedChanges();
|
|
2047
2742
|
}
|
|
2048
2743
|
/** Single gate for leaving the page or switching details sub-pages when dirty. */
|
|
2049
2744
|
async confirmLeaveIfDirty() {
|
|
@@ -2168,17 +2863,59 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
2168
2863
|
this.registerCoreKeyboardShortcuts();
|
|
2169
2864
|
this.registerActionKeyboardShortcuts(entries);
|
|
2170
2865
|
}
|
|
2866
|
+
/** i18n scope label for the active details sub-page shortcut group in the help dialog. */
|
|
2867
|
+
getKeyboardShortcutScope() {
|
|
2868
|
+
const page = this.vm.currentPage();
|
|
2869
|
+
if (page?.isPrimary) {
|
|
2870
|
+
return '@general:keyboard-shortcuts.groups.entity-details';
|
|
2871
|
+
}
|
|
2872
|
+
const label = page?.label;
|
|
2873
|
+
if (typeof label === 'string' && label.length > 0) {
|
|
2874
|
+
return label;
|
|
2875
|
+
}
|
|
2876
|
+
return page?.id ?? '@general:keyboard-shortcuts.groups.entity-details';
|
|
2877
|
+
}
|
|
2878
|
+
/** Primary overview page backed by the entity widget form (not a component-hosted sub-page). */
|
|
2879
|
+
isWidgetFormPrimaryPage() {
|
|
2880
|
+
return !!this.vm.currentPage()?.isPrimary && !this.getActivePageComponentKey();
|
|
2881
|
+
}
|
|
2882
|
+
registerDetailsViewShortcutScope(id, shortcuts) {
|
|
2883
|
+
const scope = this.getKeyboardShortcutScope();
|
|
2884
|
+
this.shortcutRegistry.register({
|
|
2885
|
+
owner: this.destroyRef,
|
|
2886
|
+
elementRef: this.elementRef,
|
|
2887
|
+
id,
|
|
2888
|
+
priority: AXPKeyboardShortcutPriority.Page,
|
|
2889
|
+
scope,
|
|
2890
|
+
shortcuts,
|
|
2891
|
+
});
|
|
2892
|
+
}
|
|
2171
2893
|
async collectActionShortcutEntries() {
|
|
2172
2894
|
const map = new Map();
|
|
2173
2895
|
if (this.vm.showPages()) {
|
|
2174
2896
|
return map;
|
|
2175
2897
|
}
|
|
2176
|
-
const
|
|
2177
|
-
|
|
2178
|
-
this.
|
|
2898
|
+
const includeAdapterActions = this.isWidgetFormPrimaryPage();
|
|
2899
|
+
const [adapterPrimaryActions, adapterSecondaryActions, pagePrimaryActions, pageSecondaryActions] = await Promise.all([
|
|
2900
|
+
includeAdapterActions ? this.vm.primaryActions() : Promise.resolve([]),
|
|
2901
|
+
includeAdapterActions ? this.vm.secondaryActions() : Promise.resolve([]),
|
|
2902
|
+
this.vm.currentPagePrimaryActions(),
|
|
2903
|
+
this.vm.currentPageSecondaryActions(),
|
|
2179
2904
|
]);
|
|
2180
|
-
for (const action of [
|
|
2181
|
-
|
|
2905
|
+
for (const action of [
|
|
2906
|
+
...adapterPrimaryActions,
|
|
2907
|
+
...adapterSecondaryActions,
|
|
2908
|
+
...pagePrimaryActions,
|
|
2909
|
+
...pageSecondaryActions,
|
|
2910
|
+
]) {
|
|
2911
|
+
const zone = action.zone ?? 'header';
|
|
2912
|
+
if (zone !== 'header' && zone !== 'footer') {
|
|
2913
|
+
continue;
|
|
2914
|
+
}
|
|
2915
|
+
if (zone === 'footer' && this.isWidgetFormPrimaryPage() && this.isSaveDiscardFooterAction(action)) {
|
|
2916
|
+
continue;
|
|
2917
|
+
}
|
|
2918
|
+
if (zone === 'header' && this.isSaveDiscardFooterAction(action)) {
|
|
2182
2919
|
continue;
|
|
2183
2920
|
}
|
|
2184
2921
|
const commandName = action.command?.name;
|
|
@@ -2187,7 +2924,9 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
2187
2924
|
continue;
|
|
2188
2925
|
}
|
|
2189
2926
|
const commandBaseName = getDetailsViewActionCommandBaseName(commandName);
|
|
2190
|
-
const chords =
|
|
2927
|
+
const chords = zone === 'footer'
|
|
2928
|
+
? resolvePageFooterActionShortcuts(commandBaseName, action.shortcuts)
|
|
2929
|
+
: resolveDetailsViewActionShortcuts(commandBaseName, action.shortcuts);
|
|
2191
2930
|
if (!chords?.length) {
|
|
2192
2931
|
continue;
|
|
2193
2932
|
}
|
|
@@ -2195,13 +2934,13 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
2195
2934
|
command,
|
|
2196
2935
|
title: typeof action.title === 'string' ? action.title : '',
|
|
2197
2936
|
chords,
|
|
2198
|
-
visible: this.
|
|
2937
|
+
visible: this.isShortcutActionAvailable(action),
|
|
2199
2938
|
disabled: AXPLayoutDetailsViewComponent.isTruthyActionFlag(action.disabled),
|
|
2200
2939
|
});
|
|
2201
2940
|
}
|
|
2202
2941
|
return map;
|
|
2203
2942
|
}
|
|
2204
|
-
|
|
2943
|
+
isShortcutActionAvailable(action) {
|
|
2205
2944
|
if (AXPLayoutDetailsViewComponent.isTruthyActionFlag(action.hidden)) {
|
|
2206
2945
|
return false;
|
|
2207
2946
|
}
|
|
@@ -2210,15 +2949,15 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
2210
2949
|
}
|
|
2211
2950
|
return true;
|
|
2212
2951
|
}
|
|
2213
|
-
/** Whether save/discard core shortcuts are listed in the help dialog (page
|
|
2952
|
+
/** Whether save/discard core shortcuts are listed in the help dialog (widget overview page only). */
|
|
2214
2953
|
isCoreSaveShortcutAvailable() {
|
|
2215
|
-
return !this.vm.currentPage()?.isReadonly && !!this.acceptFooterCommand();
|
|
2954
|
+
return this.isWidgetFormPrimaryPage() && !this.vm.currentPage()?.isReadonly && !!this.acceptFooterCommand();
|
|
2216
2955
|
}
|
|
2217
2956
|
isCoreDiscardShortcutAvailable() {
|
|
2218
|
-
return !this.vm.currentPage()?.isReadonly && !!this.rejectFooterCommand();
|
|
2957
|
+
return this.isWidgetFormPrimaryPage() && !this.vm.currentPage()?.isReadonly && !!this.rejectFooterCommand();
|
|
2219
2958
|
}
|
|
2220
2959
|
canExecuteSaveShortcut() {
|
|
2221
|
-
if (this.vm.currentPage()?.isReadonly || this.vm.
|
|
2960
|
+
if (this.vm.currentPage()?.isReadonly || this.vm.isOverlayBusy()) {
|
|
2222
2961
|
return false;
|
|
2223
2962
|
}
|
|
2224
2963
|
if (!this.acceptFooterCommand()) {
|
|
@@ -2227,7 +2966,7 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
2227
2966
|
return this.shouldPromptLeave();
|
|
2228
2967
|
}
|
|
2229
2968
|
canExecuteDiscardShortcut() {
|
|
2230
|
-
if (this.vm.currentPage()?.isReadonly || this.vm.
|
|
2969
|
+
if (this.vm.currentPage()?.isReadonly || this.vm.isOverlayBusy()) {
|
|
2231
2970
|
return false;
|
|
2232
2971
|
}
|
|
2233
2972
|
if (this.unsavedChangesConfirm.isConfirmPending()) {
|
|
@@ -2252,8 +2991,31 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
2252
2991
|
}
|
|
2253
2992
|
await this.execute({ name: rejectCommandName });
|
|
2254
2993
|
}
|
|
2994
|
+
async executeActionShortcut(entry) {
|
|
2995
|
+
const commandName = entry.command.name;
|
|
2996
|
+
if (isDiscardFooterCommand(commandName)) {
|
|
2997
|
+
if (this.vm.currentPage()?.isReadonly || this.vm.isOverlayBusy()) {
|
|
2998
|
+
return;
|
|
2999
|
+
}
|
|
3000
|
+
if (this.unsavedChangesConfirm.isConfirmPending()) {
|
|
3001
|
+
return;
|
|
3002
|
+
}
|
|
3003
|
+
if (!this.shouldPromptLeave()) {
|
|
3004
|
+
return;
|
|
3005
|
+
}
|
|
3006
|
+
const confirmed = await this.unsavedChangesConfirm.confirmIfDirty(true, {
|
|
3007
|
+
title: '@general:messages.unsaved-changes.title',
|
|
3008
|
+
message: '@general:messages.discard-changes.message',
|
|
3009
|
+
approveLeaveOnConfirm: false,
|
|
3010
|
+
});
|
|
3011
|
+
if (!confirmed) {
|
|
3012
|
+
return;
|
|
3013
|
+
}
|
|
3014
|
+
}
|
|
3015
|
+
await this.execute(entry.command);
|
|
3016
|
+
}
|
|
2255
3017
|
isActionShortcutActive(entryId) {
|
|
2256
|
-
if (this.vm.currentPage()?.isReadonly || this.vm.
|
|
3018
|
+
if (this.vm.currentPage()?.isReadonly || this.vm.isOverlayBusy()) {
|
|
2257
3019
|
return false;
|
|
2258
3020
|
}
|
|
2259
3021
|
const entry = this.actionShortcutEntries().get(entryId);
|
|
@@ -2263,18 +3025,23 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
2263
3025
|
return entry.visible && !entry.disabled;
|
|
2264
3026
|
}
|
|
2265
3027
|
registerCoreKeyboardShortcuts() {
|
|
3028
|
+
if (!this.isWidgetFormPrimaryPage()) {
|
|
3029
|
+
this.registerDetailsViewShortcutScope('layout-details-view-core', []);
|
|
3030
|
+
return;
|
|
3031
|
+
}
|
|
2266
3032
|
const accept = this.vm.currentPage()?.settings?.commands?.accept;
|
|
2267
3033
|
const reject = this.vm.currentPage()?.settings?.commands?.reject;
|
|
2268
3034
|
const acceptCommandName = accept?.command.name ?? 'update-entity';
|
|
2269
3035
|
const rejectCommandName = reject?.command.name ?? 'discard';
|
|
2270
3036
|
const saveKeys = resolveDetailsViewFooterCommandShortcuts(acceptCommandName, accept?.shortcuts);
|
|
2271
3037
|
const discardKeys = resolveDetailsViewFooterCommandShortcuts(rejectCommandName, reject?.shortcuts);
|
|
3038
|
+
const scope = this.getKeyboardShortcutScope();
|
|
2272
3039
|
const shortcuts = [];
|
|
2273
3040
|
if (saveKeys?.length && this.isCoreSaveShortcutAvailable()) {
|
|
2274
3041
|
shortcuts.push({
|
|
2275
3042
|
keys: saveKeys,
|
|
2276
3043
|
title: accept?.title ?? '@general:actions.save.title',
|
|
2277
|
-
group:
|
|
3044
|
+
group: scope,
|
|
2278
3045
|
allowInEditableFields: true,
|
|
2279
3046
|
when: () => this.canExecuteSaveShortcut(),
|
|
2280
3047
|
handler: () => {
|
|
@@ -2286,7 +3053,7 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
2286
3053
|
shortcuts.push({
|
|
2287
3054
|
keys: discardKeys,
|
|
2288
3055
|
title: reject?.title ?? '@general:actions.discard.title',
|
|
2289
|
-
group:
|
|
3056
|
+
group: scope,
|
|
2290
3057
|
allowInEditableFields: true,
|
|
2291
3058
|
when: () => this.canExecuteDiscardShortcut(),
|
|
2292
3059
|
handler: () => {
|
|
@@ -2294,62 +3061,44 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
|
|
|
2294
3061
|
},
|
|
2295
3062
|
});
|
|
2296
3063
|
}
|
|
2297
|
-
|
|
2298
|
-
return;
|
|
2299
|
-
}
|
|
2300
|
-
this.shortcutRegistry.register({
|
|
2301
|
-
owner: this.destroyRef,
|
|
2302
|
-
elementRef: this.elementRef,
|
|
2303
|
-
id: 'layout-details-view-core',
|
|
2304
|
-
priority: AXPKeyboardShortcutPriority.Page,
|
|
2305
|
-
scope: '@general:keyboard-shortcuts.groups.entity-details',
|
|
2306
|
-
shortcuts,
|
|
2307
|
-
});
|
|
3064
|
+
this.registerDetailsViewShortcutScope('layout-details-view-core', shortcuts);
|
|
2308
3065
|
}
|
|
2309
3066
|
registerActionKeyboardShortcuts(entries) {
|
|
3067
|
+
const scope = this.getKeyboardShortcutScope();
|
|
2310
3068
|
const shortcuts = [];
|
|
2311
3069
|
for (const [entryId, entry] of entries) {
|
|
2312
3070
|
for (const chord of entry.chords) {
|
|
2313
3071
|
shortcuts.push({
|
|
2314
3072
|
keys: [chord],
|
|
2315
3073
|
title: entry.title,
|
|
2316
|
-
group:
|
|
3074
|
+
group: scope,
|
|
3075
|
+
allowInEditableFields: entry.command.name ? isSaveFooterCommand(entry.command.name) || isDiscardFooterCommand(entry.command.name) : false,
|
|
2317
3076
|
when: () => this.isActionShortcutActive(entryId),
|
|
2318
3077
|
handler: () => {
|
|
2319
3078
|
if (!this.isActionShortcutActive(entryId)) {
|
|
2320
3079
|
return;
|
|
2321
3080
|
}
|
|
2322
|
-
void this.
|
|
3081
|
+
void this.executeActionShortcut(entry);
|
|
2323
3082
|
},
|
|
2324
3083
|
});
|
|
2325
3084
|
}
|
|
2326
3085
|
}
|
|
2327
|
-
|
|
2328
|
-
return;
|
|
2329
|
-
}
|
|
2330
|
-
this.shortcutRegistry.register({
|
|
2331
|
-
owner: this.destroyRef,
|
|
2332
|
-
elementRef: this.elementRef,
|
|
2333
|
-
id: 'layout-details-view-actions',
|
|
2334
|
-
priority: AXPKeyboardShortcutPriority.Page,
|
|
2335
|
-
scope: '@general:keyboard-shortcuts.groups.entity-details',
|
|
2336
|
-
shortcuts,
|
|
2337
|
-
});
|
|
3086
|
+
this.registerDetailsViewShortcutScope('layout-details-view-actions', shortcuts);
|
|
2338
3087
|
}
|
|
2339
3088
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutDetailsViewComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
2340
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPLayoutDetailsViewComponent, isStandalone: true, selector: "axp-layout-details-view",
|
|
3089
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPLayoutDetailsViewComponent, isStandalone: true, selector: "axp-layout-details-view", providers: [
|
|
2341
3090
|
{
|
|
2342
3091
|
provide: AXPPageLayoutBase,
|
|
2343
3092
|
useExisting: AXPLayoutDetailsViewComponent,
|
|
2344
3093
|
},
|
|
2345
3094
|
AXPLayoutDetailsViewViewModel,
|
|
2346
|
-
], 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 formatService.format(\n vm.showPages() ? (vm.adapter()?.title ?? '') : (vm.adapter()?.label ?? ''),\n 'string',\n vm.rootContext()\n )\n | translate\n | async\n }}</axp-layout-title>\n <axp-layout-description>{{\n formatService.format(vm.adapter()?.description ?? '', 'string', vm.rootContext()) | translate | 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]=\"(formatService.format(item.label, 'string', vm.rootContext()) | 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 class=\"ax-flex ax-flex-row ax-gap-4\">\n @if (vm.showPages()) {\n <axp-layout-list class=\"ax-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 icon=\"far ${{ item.icon }}\" class=\"ax-text-gray-500\"></ax-icon>\n </axp-layout-prefix>\n <axp-layout-content>\n <a class=\"ax-font-semibold\">{{\n formatService.format(item.label, 'string', vm.rootContext()) | translate | async\n }}</a>\n </axp-layout-content>\n <axp-layout-suffix>\n <ax-icon icon=\" far fa-chevron-right\" class=\"ax-text-gray-400\"></ax-icon>\n </axp-layout-suffix>\n </axp-layout-list-item>\n }\n </axp-layout-list>\n } @else {\n @if (vm.isBusy()) {\n <div class=\"ax-flex ax-h-full ax-w-full ax-items-center ax-justify-center\">\n <ax-loading></ax-loading>\n </div>\n } @else {\n <ax-form class=\"ax-h-full ax-w-full\" #form>\n <axp-widgets-container\n #widgetsContainerRef\n [context]=\"vm.context()\"\n (onContextChanged)=\"handleOnContextChanged($event)\"\n >\n <div class=\"ax-flex ax-flex-col ax-w-full ax-gap-4 ax-h-full\">\n @for (item of vm.currentPageContent(); track pageContentTrackKey($any(item), $index)) {\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 axp-widget-renderer [node]=\"$any(item)\" [mode]=\"$any(item).mode ?? 'view'\"></ng-container>\n }\n }\n @if (vm.currentPage()?.tabs?.length) {\n <div class=\"axp-horizontal-tabs\">\n <ax-tabs [location]=\"'bottom'\" [fitParent]=\"false\" look=\"classic\">\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 (content of vm.activeTabContent(); track content.name) {\n <ng-container axp-widget-renderer [node]=\"content\" [mode]=\"content.mode ?? 'view'\">\n </ng-container>\n }\n }\n </div>\n </div>\n }\n </div>\n </axp-widgets-container>\n </ax-form>\n }\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.isSaving()\"\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.isSaving()\"\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: ["axp-layout-details-view .axp-vertical-tabs{--ax-comp-tabs-default-border-radius: 0}axp-layout-details-view .axp-vertical-tabs ax-tab-item{margin-top:0!important;margin-bottom:0!important;padding-top:.75rem!important;padding-bottom:.75rem!important;font-weight:600!important}axp-layout-details-view .axp-vertical-tabs ax-tab-item>div{display:flex!important;align-items:center!important}axp-layout-details-view .axp-vertical-tabs ax-tab-item>div .ax-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-top:1rem;margin-bottom:1rem;display:block;width:100%}axp-layout-details-view axp-layout-section axp-layout-content{display:flex;width:100%;flex-direction:column}axp-layout-details-view axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse));border-style:dashed;--tw-divide-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-divide-opacity, 1))}axp-layout-details-view axp-layout-section axp-layout-content .--item-container{align-items:center;gap:1rem;padding:1rem}@media(min-width:1024px){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-left:1.5rem;padding-right:1.5rem}}@media(min-width:1280px){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-left:2rem;padding-right:2rem}}@media(min-width:1536px){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-left:2.5rem;padding-right:2.5rem}}axp-layout-details-view axp-layout-section axp-layout-content .--item-container{display:grid;grid-template-columns:repeat(12,minmax(0,1fr))}axp-layout-details-view axp-layout-section axp-layout-content .--item-container axp-layout-description{margin-top:.5rem!important;font-size:.75rem!important;line-height:1rem!important}axp-layout-details-view axp-page-content ax-form form{height:100%}axp-layout-details-view axp-layout-start-side{border-inline-end-width:1px}\n"], dependencies: [{ kind: "ngmodule", type:
|
|
3095
|
+
], 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 formatService.format(\n vm.showPages() ? (vm.adapter()?.title ?? '') : (vm.adapter()?.label ?? ''),\n 'string',\n vm.rootContext()\n )\n | translate\n | async\n }}</axp-layout-title>\n <axp-layout-description>{{\n formatService.format(vm.adapter()?.description ?? '', 'string', vm.rootContext()) | translate | async\n }}</axp-layout-description>\n </axp-layout-header>\n <axp-layout-content>\n <ax-tabs #sidebarTabs class=\"axp-vertical-tabs\" [look]=\"'with-line-color'\" [location]=\"'end'\" [fitParent]=\"true\"\n (onActiveTabChanged)=\"handleSidebarTabChanged($event)\">\n @for (item of vm.adapter()?.pages; track item.id) {\n <ax-tab-item [key]=\"item.id\"\n [text]=\"(formatService.format(item.label, 'string', vm.rootContext()) | translate | async)!\"\n [active]=\"vm.currentPage()?.id === item.id\">\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 class=\"ax-flex ax-flex-row ax-gap-4\">\n @if (vm.showPages()) {\n <axp-layout-list class=\"ax-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 icon=\"far ${{ item.icon }}\" class=\"ax-text-gray-500\"></ax-icon>\n </axp-layout-prefix>\n <axp-layout-content>\n <a class=\"ax-font-semibold\">{{\n formatService.format(item.label, 'string', vm.rootContext()) | translate | async\n }}</a>\n </axp-layout-content>\n <axp-layout-suffix>\n <ax-icon icon=\" far fa-chevron-right\" class=\"ax-text-gray-400\"></ax-icon>\n </axp-layout-suffix>\n </axp-layout-list-item>\n }\n </axp-layout-list>\n } @else {\n <ax-form class=\"ax-h-full ax-w-full\" #form>\n <axp-widgets-container #widgetsContainerRef [context]=\"vm.context()\"\n (onContextChanged)=\"handleOnContextChanged($event)\">\n <div class=\"ax-flex ax-flex-col ax-w-full ax-gap-4 ax-h-full\">\n @for (item of vm.currentPageContent(); track pageContentTrackKey($any(item), $index)) {\n @if ('type' in item && item.type === 'component') {\n <!-- Component-based content -->\n <div axp-page-component-renderer [componentKey]=\"$any(item).componentKey\" [rootContext]=\"vm.rootContext()\"\n [pageConfig]=\"$any(item).pageConfig\" [options]=\"$any(item).options\" (componentReady)=\"recompute()\"></div>\n } @else {\n <!-- Widget-based content -->\n <ng-container axp-widget-renderer [node]=\"$any(item)\" [mode]=\"$any(item).mode ?? 'view'\"></ng-container>\n }\n }\n @if (vm.currentPage()?.tabs?.length) {\n <div class=\"axp-horizontal-tabs\">\n <ax-tabs [location]=\"'bottom'\" [fitParent]=\"false\" look=\"classic\">\n @for (tab of vm.currentPageTabs(); track $index) {\n <ax-tab-item (onClick)=\"vm.setCurrentTab(tab)\" [text]=\"(tab.title | translate | async)!\"\n [active]=\"vm.currentTab()?.id === tab.id\">\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 (content of vm.activeTabContent(); track content.name) {\n <ng-container axp-widget-renderer [node]=\"content\" [mode]=\"content.mode ?? 'view'\">\n </ng-container>\n }\n }\n </div>\n </div>\n }\n </div>\n </axp-widgets-container>\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 [class.ax-sm]=\"deviceService.isSmall()\" [iconOnly]=\"deviceService.isSmall()\"\n [text]=\"'@general:terms.interface.actions' | translate | async\"\n [look]=\"deviceService.isSmall() ? 'blank' : 'solid'\" [color]=\"'default'\">\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 [text]=\"(t(action.title) | async)!\" [color]=\"action.color\"\n [disabled]=\"isFooterActionDisabled(action)\" (onClick)=\"execute(action.command!)\">\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 [class.ax-sm]=\"deviceService.isSmall()\" [disabled]=\"vm.isOverlayBusy()\"\n [text]=\"(t(reject.title) | async)!\" [look]=\"'solid'\" [color]=\"reject.color\" (onClick)=\"execute(reject.command)\">\n <ax-prefix>\n <i class=\"{{ reject.icon }}\"></i>\n </ax-prefix>\n </ax-button>\n }\n @if (acceptFooterCommand(); as accept) {\n <ax-button [class.ax-sm]=\"deviceService.isSmall()\" [disabled]=\"vm.isOverlayBusy()\"\n [text]=\"(t(accept.title) | async)!\" [look]=\"'solid'\" [color]=\"accept.color\" (onClick)=\"execute(accept.command)\">\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 [class.ax-sm]=\"deviceService.isSmall()\" [disabled]=\"isFooterActionDisabled(action)\"\n [text]=\"(t(action.title) | async)!\" [look]=\"'solid'\" [color]=\"action.color\"\n (onClick)=\"execute(action.command!)\">\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 [text]=\"(t(sub.title) | async)!\" [color]=\"sub.color\"\n [disabled]=\"isFooterActionDisabled(sub)\" (onClick)=\"execute(sub.command!)\">\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>", styles: ["axp-layout-details-view .axp-vertical-tabs{--ax-comp-tabs-default-border-radius: 0}axp-layout-details-view .axp-vertical-tabs ax-tab-item{margin-top:0!important;margin-bottom:0!important;padding-top:.75rem!important;padding-bottom:.75rem!important;font-weight:600!important}axp-layout-details-view .axp-vertical-tabs ax-tab-item>div{display:flex!important;align-items:center!important}axp-layout-details-view .axp-vertical-tabs ax-tab-item>div .ax-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-top:1rem;margin-bottom:1rem;display:block;width:100%}axp-layout-details-view axp-layout-section axp-layout-content{display:flex;width:100%;flex-direction:column}axp-layout-details-view axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse));border-style:dashed;--tw-divide-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-divide-opacity, 1))}axp-layout-details-view axp-layout-section axp-layout-content .--item-container{align-items:center;gap:1rem;padding:1rem}@media(min-width:1024px){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-left:1.5rem;padding-right:1.5rem}}@media(min-width:1280px){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-left:2rem;padding-right:2rem}}@media(min-width:1536px){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-left:2.5rem;padding-right:2.5rem}}axp-layout-details-view axp-layout-section axp-layout-content .--item-container{display:grid;grid-template-columns:repeat(12,minmax(0,1fr))}axp-layout-details-view axp-layout-section axp-layout-content .--item-container axp-layout-description{margin-top:.5rem!important;font-size:.75rem!important;line-height:1rem!important}axp-layout-details-view axp-page-content ax-form form{height:100%}axp-layout-details-view axp-layout-start-side{border-inline-end-width:1px}\n"], dependencies: [{ kind: "ngmodule", type:
|
|
2347
3096
|
// Angular
|
|
2348
3097
|
CommonModule }, { kind: "ngmodule", type:
|
|
2349
3098
|
// ACoreX
|
|
2350
|
-
AXMenuModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i6.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: "component", type: i6.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i6.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXButtonGroupModule }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i5.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i3$1.AXTranslatorDirective, selector: "[translate]" }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3.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:
|
|
3099
|
+
AXMenuModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i6.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: "component", type: i6.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i6.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXButtonGroupModule }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i5.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i3$1.AXTranslatorDirective, selector: "[translate]" }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3.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: AXBreadcrumbsModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "ngmodule", type: AXFormatModule }, { kind: "ngmodule", type: AXFileModule }, { kind: "ngmodule", type: AXDateTimeModule }, { kind: "ngmodule", type: AXTabsModule }, { kind: "component", type: i5$1.AXTabsComponent, selector: "ax-tabs", inputs: ["look", "location", "fitParent", "minWidth", "content"], outputs: ["onActiveTabChanged"] }, { kind: "component", type: i5$1.AXTabItemComponent, selector: "ax-tab-item", inputs: ["disabled", "text", "key", "headerTemplate", "active"], outputs: ["disabledChange", "onClick", "onBlur", "onFocus", "activeChange"] }, { kind: "component", type:
|
|
2351
3100
|
//
|
|
2352
|
-
AXPThemeLayoutListComponent, selector: "axp-layout-list" }, { kind: "component", type: AXPThemeLayoutListItemComponent, selector: "axp-layout-list-item" }, { 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: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type:
|
|
3101
|
+
AXPThemeLayoutListComponent, selector: "axp-layout-list" }, { kind: "component", type: AXPThemeLayoutListItemComponent, selector: "axp-layout-list-item" }, { 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: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: i6$1.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i6$1.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged", "onLoad"], exportAs: ["widgetRenderer"] }, { kind: "component", type: AXPThemeLayoutStartSideComponent, selector: "axp-layout-page-start-side, axp-layout-start-side" }, { kind: "component", type: AXPThemeLayoutHeaderComponent, selector: "axp-layout-header" }, { kind: "ngmodule", type: AXFormModule }, { kind: "component", type: i7.AXFormComponent, selector: "ax-form", inputs: ["disabled", "readonly", "labelMode", "look", "messageStyle", "updateOn", "inUserInteractionActive"], outputs: ["onValidate", "updateOnChange"] }, { kind: "directive", type: AXPPageComponentRendererDirective, selector: "[axp-page-component-renderer]", inputs: ["componentKey", "rootContext", "pageConfig", "options"], outputs: ["componentReady"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2353
3102
|
}
|
|
2354
3103
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutDetailsViewComponent, decorators: [{
|
|
2355
3104
|
type: Component,
|
|
@@ -2364,7 +3113,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
2364
3113
|
AXDropdownModule,
|
|
2365
3114
|
AXTranslationModule,
|
|
2366
3115
|
AXDecoratorModule,
|
|
2367
|
-
AXLoadingModule,
|
|
2368
3116
|
AXBreadcrumbsModule,
|
|
2369
3117
|
AXBadgeModule,
|
|
2370
3118
|
AXSearchBoxModule,
|
|
@@ -2389,8 +3137,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
2389
3137
|
useExisting: AXPLayoutDetailsViewComponent,
|
|
2390
3138
|
},
|
|
2391
3139
|
AXPLayoutDetailsViewViewModel,
|
|
2392
|
-
], 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 formatService.format(\n vm.showPages() ? (vm.adapter()?.title ?? '') : (vm.adapter()?.label ?? ''),\n 'string',\n vm.rootContext()\n )\n | translate\n | async\n }}</axp-layout-title>\n <axp-layout-description>{{\n formatService.format(vm.adapter()?.description ?? '', 'string', vm.rootContext()) | translate | 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]=\"(formatService.format(item.label, 'string', vm.rootContext()) | 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 class=\"ax-flex ax-flex-row ax-gap-4\">\n @if (vm.showPages()) {\n <axp-layout-list class=\"ax-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 icon=\"far ${{ item.icon }}\" class=\"ax-text-gray-500\"></ax-icon>\n </axp-layout-prefix>\n <axp-layout-content>\n <a class=\"ax-font-semibold\">{{\n formatService.format(item.label, 'string', vm.rootContext()) | translate | async\n }}</a>\n </axp-layout-content>\n <axp-layout-suffix>\n <ax-icon icon=\" far fa-chevron-right\" class=\"ax-text-gray-400\"></ax-icon>\n </axp-layout-suffix>\n </axp-layout-list-item>\n }\n </axp-layout-list>\n } @else {\n @if (vm.isBusy()) {\n <div class=\"ax-flex ax-h-full ax-w-full ax-items-center ax-justify-center\">\n <ax-loading></ax-loading>\n </div>\n } @else {\n <ax-form class=\"ax-h-full ax-w-full\" #form>\n <axp-widgets-container\n #widgetsContainerRef\n [context]=\"vm.context()\"\n (onContextChanged)=\"handleOnContextChanged($event)\"\n >\n <div class=\"ax-flex ax-flex-col ax-w-full ax-gap-4 ax-h-full\">\n @for (item of vm.currentPageContent(); track pageContentTrackKey($any(item), $index)) {\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 axp-widget-renderer [node]=\"$any(item)\" [mode]=\"$any(item).mode ?? 'view'\"></ng-container>\n }\n }\n @if (vm.currentPage()?.tabs?.length) {\n <div class=\"axp-horizontal-tabs\">\n <ax-tabs [location]=\"'bottom'\" [fitParent]=\"false\" look=\"classic\">\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 (content of vm.activeTabContent(); track content.name) {\n <ng-container axp-widget-renderer [node]=\"content\" [mode]=\"content.mode ?? 'view'\">\n </ng-container>\n }\n }\n </div>\n </div>\n }\n </div>\n </axp-widgets-container>\n </ax-form>\n }\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.isSaving()\"\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.isSaving()\"\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: ["axp-layout-details-view .axp-vertical-tabs{--ax-comp-tabs-default-border-radius: 0}axp-layout-details-view .axp-vertical-tabs ax-tab-item{margin-top:0!important;margin-bottom:0!important;padding-top:.75rem!important;padding-bottom:.75rem!important;font-weight:600!important}axp-layout-details-view .axp-vertical-tabs ax-tab-item>div{display:flex!important;align-items:center!important}axp-layout-details-view .axp-vertical-tabs ax-tab-item>div .ax-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-top:1rem;margin-bottom:1rem;display:block;width:100%}axp-layout-details-view axp-layout-section axp-layout-content{display:flex;width:100%;flex-direction:column}axp-layout-details-view axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse));border-style:dashed;--tw-divide-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-divide-opacity, 1))}axp-layout-details-view axp-layout-section axp-layout-content .--item-container{align-items:center;gap:1rem;padding:1rem}@media(min-width:1024px){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-left:1.5rem;padding-right:1.5rem}}@media(min-width:1280px){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-left:2rem;padding-right:2rem}}@media(min-width:1536px){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-left:2.5rem;padding-right:2.5rem}}axp-layout-details-view axp-layout-section axp-layout-content .--item-container{display:grid;grid-template-columns:repeat(12,minmax(0,1fr))}axp-layout-details-view axp-layout-section axp-layout-content .--item-container axp-layout-description{margin-top:.5rem!important;font-size:.75rem!important;line-height:1rem!important}axp-layout-details-view axp-page-content ax-form form{height:100%}axp-layout-details-view axp-layout-start-side{border-inline-end-width:1px}\n"] }]
|
|
2393
|
-
}], propDecorators: {
|
|
3140
|
+
], 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 formatService.format(\n vm.showPages() ? (vm.adapter()?.title ?? '') : (vm.adapter()?.label ?? ''),\n 'string',\n vm.rootContext()\n )\n | translate\n | async\n }}</axp-layout-title>\n <axp-layout-description>{{\n formatService.format(vm.adapter()?.description ?? '', 'string', vm.rootContext()) | translate | async\n }}</axp-layout-description>\n </axp-layout-header>\n <axp-layout-content>\n <ax-tabs #sidebarTabs class=\"axp-vertical-tabs\" [look]=\"'with-line-color'\" [location]=\"'end'\" [fitParent]=\"true\"\n (onActiveTabChanged)=\"handleSidebarTabChanged($event)\">\n @for (item of vm.adapter()?.pages; track item.id) {\n <ax-tab-item [key]=\"item.id\"\n [text]=\"(formatService.format(item.label, 'string', vm.rootContext()) | translate | async)!\"\n [active]=\"vm.currentPage()?.id === item.id\">\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 class=\"ax-flex ax-flex-row ax-gap-4\">\n @if (vm.showPages()) {\n <axp-layout-list class=\"ax-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 icon=\"far ${{ item.icon }}\" class=\"ax-text-gray-500\"></ax-icon>\n </axp-layout-prefix>\n <axp-layout-content>\n <a class=\"ax-font-semibold\">{{\n formatService.format(item.label, 'string', vm.rootContext()) | translate | async\n }}</a>\n </axp-layout-content>\n <axp-layout-suffix>\n <ax-icon icon=\" far fa-chevron-right\" class=\"ax-text-gray-400\"></ax-icon>\n </axp-layout-suffix>\n </axp-layout-list-item>\n }\n </axp-layout-list>\n } @else {\n <ax-form class=\"ax-h-full ax-w-full\" #form>\n <axp-widgets-container #widgetsContainerRef [context]=\"vm.context()\"\n (onContextChanged)=\"handleOnContextChanged($event)\">\n <div class=\"ax-flex ax-flex-col ax-w-full ax-gap-4 ax-h-full\">\n @for (item of vm.currentPageContent(); track pageContentTrackKey($any(item), $index)) {\n @if ('type' in item && item.type === 'component') {\n <!-- Component-based content -->\n <div axp-page-component-renderer [componentKey]=\"$any(item).componentKey\" [rootContext]=\"vm.rootContext()\"\n [pageConfig]=\"$any(item).pageConfig\" [options]=\"$any(item).options\" (componentReady)=\"recompute()\"></div>\n } @else {\n <!-- Widget-based content -->\n <ng-container axp-widget-renderer [node]=\"$any(item)\" [mode]=\"$any(item).mode ?? 'view'\"></ng-container>\n }\n }\n @if (vm.currentPage()?.tabs?.length) {\n <div class=\"axp-horizontal-tabs\">\n <ax-tabs [location]=\"'bottom'\" [fitParent]=\"false\" look=\"classic\">\n @for (tab of vm.currentPageTabs(); track $index) {\n <ax-tab-item (onClick)=\"vm.setCurrentTab(tab)\" [text]=\"(tab.title | translate | async)!\"\n [active]=\"vm.currentTab()?.id === tab.id\">\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 (content of vm.activeTabContent(); track content.name) {\n <ng-container axp-widget-renderer [node]=\"content\" [mode]=\"content.mode ?? 'view'\">\n </ng-container>\n }\n }\n </div>\n </div>\n }\n </div>\n </axp-widgets-container>\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 [class.ax-sm]=\"deviceService.isSmall()\" [iconOnly]=\"deviceService.isSmall()\"\n [text]=\"'@general:terms.interface.actions' | translate | async\"\n [look]=\"deviceService.isSmall() ? 'blank' : 'solid'\" [color]=\"'default'\">\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 [text]=\"(t(action.title) | async)!\" [color]=\"action.color\"\n [disabled]=\"isFooterActionDisabled(action)\" (onClick)=\"execute(action.command!)\">\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 [class.ax-sm]=\"deviceService.isSmall()\" [disabled]=\"vm.isOverlayBusy()\"\n [text]=\"(t(reject.title) | async)!\" [look]=\"'solid'\" [color]=\"reject.color\" (onClick)=\"execute(reject.command)\">\n <ax-prefix>\n <i class=\"{{ reject.icon }}\"></i>\n </ax-prefix>\n </ax-button>\n }\n @if (acceptFooterCommand(); as accept) {\n <ax-button [class.ax-sm]=\"deviceService.isSmall()\" [disabled]=\"vm.isOverlayBusy()\"\n [text]=\"(t(accept.title) | async)!\" [look]=\"'solid'\" [color]=\"accept.color\" (onClick)=\"execute(accept.command)\">\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 [class.ax-sm]=\"deviceService.isSmall()\" [disabled]=\"isFooterActionDisabled(action)\"\n [text]=\"(t(action.title) | async)!\" [look]=\"'solid'\" [color]=\"action.color\"\n (onClick)=\"execute(action.command!)\">\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 [text]=\"(t(sub.title) | async)!\" [color]=\"sub.color\"\n [disabled]=\"isFooterActionDisabled(sub)\" (onClick)=\"execute(sub.command!)\">\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>", styles: ["axp-layout-details-view .axp-vertical-tabs{--ax-comp-tabs-default-border-radius: 0}axp-layout-details-view .axp-vertical-tabs ax-tab-item{margin-top:0!important;margin-bottom:0!important;padding-top:.75rem!important;padding-bottom:.75rem!important;font-weight:600!important}axp-layout-details-view .axp-vertical-tabs ax-tab-item>div{display:flex!important;align-items:center!important}axp-layout-details-view .axp-vertical-tabs ax-tab-item>div .ax-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-top:1rem;margin-bottom:1rem;display:block;width:100%}axp-layout-details-view axp-layout-section axp-layout-content{display:flex;width:100%;flex-direction:column}axp-layout-details-view axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse));border-style:dashed;--tw-divide-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-divide-opacity, 1))}axp-layout-details-view axp-layout-section axp-layout-content .--item-container{align-items:center;gap:1rem;padding:1rem}@media(min-width:1024px){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-left:1.5rem;padding-right:1.5rem}}@media(min-width:1280px){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-left:2rem;padding-right:2rem}}@media(min-width:1536px){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-left:2.5rem;padding-right:2.5rem}}axp-layout-details-view axp-layout-section axp-layout-content .--item-container{display:grid;grid-template-columns:repeat(12,minmax(0,1fr))}axp-layout-details-view axp-layout-section axp-layout-content .--item-container axp-layout-description{margin-top:.5rem!important;font-size:.75rem!important;line-height:1rem!important}axp-layout-details-view axp-page-content ax-form form{height:100%}axp-layout-details-view axp-layout-start-side{border-inline-end-width:1px}\n"] }]
|
|
3141
|
+
}], 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 }] }] } });
|
|
2394
3142
|
|
|
2395
3143
|
//#region ---- Details View Can Deactivate Guard ----
|
|
2396
3144
|
/**
|
|
@@ -2403,5 +3151,5 @@ const axpDetailsViewCanDeactivateGuard = createUnsavedChangesCanDeactivateGuard(
|
|
|
2403
3151
|
* Generated bundle index. Do not edit.
|
|
2404
3152
|
*/
|
|
2405
3153
|
|
|
2406
|
-
export { AXPLayoutDetailsViewComponent, AXPLayoutDetailsViewViewModel, AXPPageComponentInstanceRegistryService, AXPPageComponentRendererDirective, AXPPageLayoutBase, AXPPageLayoutBaseComponent, AXPPageLayoutComponent, AXPPopupLayoutBase, AXPPopupLayoutBaseComponent, AXPPopupLayoutComponent, axpDetailsViewCanDeactivateGuard, buildNotSavedPageBadge, getDetailsViewActionCommandBaseName, isDiscardCommand, resolveDetailsViewActionShortcuts, resolveDetailsViewFooterCommandShortcuts };
|
|
3154
|
+
export { AXPLayoutDetailsViewComponent, AXPLayoutDetailsViewViewModel, AXPPageComponentInstanceRegistryService, AXPPageComponentRendererDirective, AXPPageLayoutBase, AXPPageLayoutBaseComponent, AXPPageLayoutComponent, AXPPopupLayoutBase, AXPPopupLayoutBaseComponent, AXPPopupLayoutComponent, AXP_LAYOUT_DETAILS_VIEW_ADAPTER_LOADER, axpDetailsViewCanDeactivateGuard, buildNotSavedPageBadge, getDetailsViewActionCommandBaseName, isDiscardCommand, isDiscardFooterCommand, isSaveFooterCommand, resolveDetailsViewActionShortcuts, resolveDetailsViewFooterCommandShortcuts, resolvePageFooterActionDefaultShortcuts, resolvePageFooterActionShortcuts };
|
|
2407
3155
|
//# sourceMappingURL=acorex-platform-layout-views.mjs.map
|