@acorex-platform/framework-client 2.0.0-next.25 → 2.0.0-next.27

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.
Files changed (34) hide show
  1. package/fesm2022/acorex-platform-framework-client-common.mjs +558 -106
  2. package/fesm2022/acorex-platform-framework-client-common.mjs.map +1 -1
  3. package/fesm2022/{acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-Bte8Trz3.mjs → acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-DmkFxSuJ.mjs} +18 -11
  4. package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-DmkFxSuJ.mjs.map +1 -0
  5. package/fesm2022/{acorex-platform-framework-client-layout-entity-attachments-page.component-bCZHSHRa.mjs → acorex-platform-framework-client-layout-entity-attachments-page.component-BV5WLQVo.mjs} +2 -2
  6. package/fesm2022/{acorex-platform-framework-client-layout-entity-attachments-page.component-bCZHSHRa.mjs.map → acorex-platform-framework-client-layout-entity-attachments-page.component-BV5WLQVo.mjs.map} +1 -1
  7. package/fesm2022/{acorex-platform-framework-client-layout-entity-bulk-entity.command-BRN0AcG-.mjs → acorex-platform-framework-client-layout-entity-bulk-entity.command-O8zdiHRH.mjs} +2 -2
  8. package/fesm2022/{acorex-platform-framework-client-layout-entity-bulk-entity.command-BRN0AcG-.mjs.map → acorex-platform-framework-client-layout-entity-bulk-entity.command-O8zdiHRH.mjs.map} +1 -1
  9. package/fesm2022/{acorex-platform-framework-client-layout-entity-file-list-popup.component-BXAl2p0t.mjs → acorex-platform-framework-client-layout-entity-file-list-popup.component-B3-0gJTQ.mjs} +2 -2
  10. package/fesm2022/{acorex-platform-framework-client-layout-entity-file-list-popup.component-BXAl2p0t.mjs.map → acorex-platform-framework-client-layout-entity-file-list-popup.component-B3-0gJTQ.mjs.map} +1 -1
  11. package/fesm2022/{acorex-platform-framework-client-layout-entity-gallery-page.component-Cc2kuwvV.mjs → acorex-platform-framework-client-layout-entity-gallery-page.component-CjfLUBPZ.mjs} +2 -2
  12. package/fesm2022/{acorex-platform-framework-client-layout-entity-gallery-page.component-Cc2kuwvV.mjs.map → acorex-platform-framework-client-layout-entity-gallery-page.component-CjfLUBPZ.mjs.map} +1 -1
  13. package/fesm2022/acorex-platform-framework-client-layout-entity.mjs +1 -1
  14. package/fesm2022/acorex-platform-framework-client-layout-views.mjs +24 -8
  15. package/fesm2022/acorex-platform-framework-client-layout-views.mjs.map +1 -1
  16. package/fesm2022/{acorex-platform-framework-client-themes-default-error-401.component-1lfBpY_d.mjs → acorex-platform-framework-client-themes-default-error-401.component-DszlyIaw.mjs} +5 -11
  17. package/fesm2022/acorex-platform-framework-client-themes-default-error-401.component-DszlyIaw.mjs.map +1 -0
  18. package/fesm2022/{acorex-platform-framework-client-themes-default-error-404.component-BeWyRCJr.mjs → acorex-platform-framework-client-themes-default-error-404.component-BusKNAit.mjs} +5 -11
  19. package/fesm2022/acorex-platform-framework-client-themes-default-error-404.component-BusKNAit.mjs.map +1 -0
  20. package/fesm2022/{acorex-platform-framework-client-themes-default-error-offline.component-PvveUj5c.mjs → acorex-platform-framework-client-themes-default-error-offline.component-Abf14p44.mjs} +15 -4
  21. package/fesm2022/acorex-platform-framework-client-themes-default-error-offline.component-Abf14p44.mjs.map +1 -0
  22. package/fesm2022/acorex-platform-framework-client-themes-default-error-page-go-home-B9VmB9Vt.mjs +19 -0
  23. package/fesm2022/acorex-platform-framework-client-themes-default-error-page-go-home-B9VmB9Vt.mjs.map +1 -0
  24. package/fesm2022/acorex-platform-framework-client-themes-default.mjs +15 -6
  25. package/fesm2022/acorex-platform-framework-client-themes-default.mjs.map +1 -1
  26. package/fesm2022/acorex-platform-framework-client-themes-shared.mjs +10 -4
  27. package/fesm2022/acorex-platform-framework-client-themes-shared.mjs.map +1 -1
  28. package/package.json +2 -2
  29. package/types/acorex-platform-framework-client-common.d.ts +122 -7
  30. package/types/acorex-platform-framework-client-layout-entity.d.ts +1 -0
  31. package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-Bte8Trz3.mjs.map +0 -1
  32. package/fesm2022/acorex-platform-framework-client-themes-default-error-401.component-1lfBpY_d.mjs.map +0 -1
  33. package/fesm2022/acorex-platform-framework-client-themes-default-error-404.component-BeWyRCJr.mjs.map +0 -1
  34. package/fesm2022/acorex-platform-framework-client-themes-default-error-offline.component-PvveUj5c.mjs.map +0 -1
@@ -14,7 +14,7 @@ import { AXDecoratorModule } from '@acorex/components/decorators';
14
14
  import * as i6 from '@acorex/components/dropdown';
15
15
  import { AXDropdownModule } from '@acorex/components/dropdown';
16
16
  import { AXDropdownButtonModule } from '@acorex/components/dropdown-button';
17
- import { AXPTabNavigationService, axpSplitCollapsedBreadcrumbs, AXPStickyDirective, AXPCommonSettings, AXPHomePageService, AXPSettingsService, AXPTabPreviewService, AXPUnsavedChangesConfirmService, AXPBrowserTitleService, AXPEntityDetailsNavTrailService, axpJoinTabTitleSegments, axpGetLeafRouteSnapshot, normalizeRouterUrl, AXP_HOME_TAB_KEY, axpResolveTabKey, axpIsEntityListPath, axpParseEntityListRoute, axpGetEntityListReturnUrl, axpIsEntityDetailsPath, axpParseEntityDetailsRoute, axpSetEntityDetailsPageQuery, axpIsEntityDetailsViewRoute, AXPNotFoundError, AXP_NOT_FOUND_ROUTE, AXPUnsavedChangesPopstateService, createUnsavedChangesCanDeactivateGuard } from '@acorex-platform/framework-client/common';
17
+ import { AXPTabNavigationService, axpSplitCollapsedBreadcrumbs, AXPStickyDirective, AXPCommonSettings, AXPHomePageService, AXPSettingsService, AXPTabPreviewService, AXPUnsavedChangesConfirmService, AXPBrowserTitleService, AXPEntityDetailsNavTrailService, axpJoinTabTitleSegments, axpGetLeafRouteSnapshot, normalizeRouterUrl, AXP_HOME_TAB_KEY, axpResolveTabKey, axpIsEntityListPath, axpParseEntityListRoute, axpGetEntityListReturnUrl, axpIsEntityDetailsPath, axpParseEntityDetailsRoute, axpSetEntityDetailsPageQuery, axpIsEntityDetailsViewRoute, AXPNotFoundError, axpInTabErrorLocation, AXPUnsavedChangesPopstateService, createUnsavedChangesCanDeactivateGuard } from '@acorex-platform/framework-client/common';
18
18
  import * as i9 from '@acorex-platform/framework-client/core';
19
19
  import { AXPDeviceService, AXPComponentSlotModule, AXPDebugService, OVERLAY_DETAILS_VIEW_TRACE_NS, AXPExpressionEvaluatorService, AXPContextEvalFactory, normalizeKeyboardShortcuts, AXPContextStore, AXPEntityBroadcastService, AXPKeyboardShortcutRegistry } from '@acorex-platform/framework-client/core';
20
20
  import * as i1 from '@acorex/cdk/drawer';
@@ -1167,6 +1167,12 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
1167
1167
  let pageActivationChain = Promise.resolve();
1168
1168
  /** Serializes route-driven adapter loads (initial navigation and layout refresh). */
1169
1169
  let routeLoadChain = Promise.resolve();
1170
+ /** Invalidates a queued load once this component's route changes or a newer load starts. */
1171
+ let routeLoadGeneration = 0;
1172
+ const routePath = () => {
1173
+ const tree = router.createUrlTree([], { relativeTo: route });
1174
+ return router.serializeUrl(tree).split('?')[0]?.split('#')[0] ?? '';
1175
+ };
1170
1176
  /** `page` query param from the browser URL (reliable on hard refresh). */
1171
1177
  const readPageQueryParam = () => {
1172
1178
  const page = router.parseUrl(router.url).queryParams['page'];
@@ -1454,11 +1460,18 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
1454
1460
  await this.loadPage(pageId, forceRefresh);
1455
1461
  },
1456
1462
  async loadFromRoute(forceRefresh, reason = 'unspecified') {
1463
+ const generation = ++routeLoadGeneration;
1464
+ const moduleName = route.parent?.snapshot.paramMap.get('module');
1465
+ const entityName = route.snapshot.paramMap.get('entity');
1466
+ const id = route.snapshot.paramMap.get('id');
1467
+ const requestUrl = router.serializeUrl(router.createUrlTree([], { relativeTo: route }));
1468
+ const requestPath = requestUrl.split('?')[0]?.split('#')[0] ?? '';
1469
+ const requestStillOwnsThisPage = () => generation === routeLoadGeneration &&
1470
+ route.parent?.snapshot.paramMap.get('module') === moduleName &&
1471
+ route.snapshot.paramMap.get('entity') === entityName &&
1472
+ route.snapshot.paramMap.get('id') === id;
1457
1473
  const run = async () => {
1458
1474
  const pageIdFromUrl = readPageQueryParam() ?? undefined;
1459
- const moduleName = route.parent?.snapshot.paramMap.get('module');
1460
- const entityName = route.snapshot.paramMap.get('entity');
1461
- const id = route.snapshot.paramMap.get('id');
1462
1475
  AXPDebugService.instance?.trace(DETAILS_VIEW_PAGE_TRACE_NS, 'viewmodel', 'loadFromRoute start', () => ({
1463
1476
  moduleName,
1464
1477
  entityName,
@@ -1468,7 +1481,7 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
1468
1481
  reason,
1469
1482
  note: 'Entity/route load started',
1470
1483
  }));
1471
- if (!moduleName || !entityName || !id) {
1484
+ if (!moduleName || !entityName || !id || !requestStillOwnsThisPage()) {
1472
1485
  return;
1473
1486
  }
1474
1487
  layout.setNavigationLoading(true);
@@ -1494,7 +1507,10 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
1494
1507
  }));
1495
1508
  layout.setOverlayLoading(false);
1496
1509
  if (error instanceof AXPNotFoundError) {
1497
- void router.navigateByUrl(AXP_NOT_FOUND_ROUTE);
1510
+ const currentPath = router.url.split('?')[0]?.split('#')[0] ?? '';
1511
+ if (requestStillOwnsThisPage() && currentPath === requestPath && routePath() === requestPath) {
1512
+ void router.navigateByUrl(axpInTabErrorLocation('404', requestUrl));
1513
+ }
1498
1514
  return;
1499
1515
  }
1500
1516
  throw error;
@@ -3363,7 +3379,7 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
3363
3379
  useExisting: AXPLayoutDetailsViewComponent,
3364
3380
  },
3365
3381
  AXPLayoutDetailsViewViewModel,
3366
- ], viewQueries: [{ propertyName: "form", first: true, predicate: ["form"], descendants: true, isSignal: true }, { propertyName: "widgetContainer", first: true, predicate: AXPWidgetContainerComponent, descendants: true, isSignal: true }, { propertyName: "sidebarTabs", first: true, predicate: ["sidebarTabs"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<axp-page-layout *translate=\"let t\">\n @if (vm.adapter()?.pages?.length! > 1 && vm.isLarge()) {\n <axp-layout-start-side>\n <axp-layout-header>\n <axp-layout-title>{{\n formatPageLabel(\n vm.showPages()\n ? (vm.adapter()?.title ?? '')\n : (vm.adapter()?.label ?? '')\n )\n | translate\n | async\n }}</axp-layout-title>\n <axp-layout-description>{{\n formatPageLabel(vm.adapter()?.description ?? '')\n | translate\n | async\n }}</axp-layout-description>\n </axp-layout-header>\n <axp-layout-content>\n <ax-tabs\n #sidebarTabs\n class=\"axp-vertical-tabs\"\n [look]=\"'with-line-color'\"\n [location]=\"'end'\"\n [fitParent]=\"true\"\n (onActiveTabChanged)=\"handleSidebarTabChanged($event)\"\n >\n @for (item of vm.adapter()?.pages; track item.id) {\n <ax-tab-item\n [key]=\"item.id\"\n [text]=\"(formatPageLabel(item.label) | translate | async)!\"\n [active]=\"vm.currentPage()?.id === item.id\"\n >\n <ax-prefix>\n <ax-icon icon=\"far ${{ item.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n }\n </ax-tabs>\n </axp-layout-content>\n </axp-layout-start-side>\n }\n <!-- Content Section -->\n <axp-page-content\n class=\"flex flex-row gap-4\"\n [class.axp-details-page-list]=\"isEntityListPage()\"\n >\n @if (vm.showPages()) {\n <axp-layout-list class=\"w-full\">\n @for (item of vm.adapter()?.pages; track $index) {\n <axp-layout-list-item (click)=\"handleSelectPage(item)\">\n <axp-layout-prefix>\n <ax-icon\n icon=\"far ${{ item.icon }}\"\n class=\"text-gray-500\"\n ></ax-icon>\n </axp-layout-prefix>\n <axp-layout-content>\n <a class=\"font-semibold\">{{\n formatPageLabel(item.label) | translate | async\n }}</a>\n </axp-layout-content>\n <axp-layout-suffix>\n <ax-icon\n icon=\" far fa-chevron-right\"\n class=\"text-gray-400\"\n ></ax-icon>\n </axp-layout-suffix>\n </axp-layout-list-item>\n }\n </axp-layout-list>\n } @else {\n <ax-form class=\"h-full w-full\" #form>\n <axp-widgets-container\n #widgetsContainerRef\n [context]=\"vm.context()\"\n (onContextChanged)=\"handleOnContextChanged($event)\"\n >\n <div class=\"flex h-full min-h-0 w-full flex-col\">\n @for (\n item of vm.currentPageContent();\n track pageContentTrackKey($any(item), $index)\n ) {\n @if ('type' in item && item.type === 'component') {\n <!-- Component-based content -->\n <div\n axp-page-component-renderer\n [componentKey]=\"$any(item).componentKey\"\n [rootContext]=\"vm.rootContext()\"\n [pageConfig]=\"$any(item).pageConfig\"\n [options]=\"$any(item).options\"\n (componentReady)=\"recompute()\"\n ></div>\n } @else {\n <!-- Widget-based content -->\n <ng-container\n axp-widget-renderer\n [node]=\"$any(item)\"\n [mode]=\"$any(item).mode ?? 'view'\"\n ></ng-container>\n }\n }\n @if (vm.currentPage()?.tabs?.length) {\n <div class=\"axp-horizontal-tabs\">\n <ax-tabs\n [location]=\"'bottom'\"\n [fitParent]=\"false\"\n look=\"classic\"\n >\n @for (tab of vm.currentPageTabs(); track $index) {\n <ax-tab-item\n (onClick)=\"vm.setCurrentTab(tab)\"\n [text]=\"(tab.title | translate | async)!\"\n [active]=\"vm.currentTab()?.id === tab.id\"\n >\n <ax-prefix>\n <ax-icon icon=\"far ${{ tab.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n }\n </ax-tabs>\n <div class=\"content\">\n @if (vm.currentTab()) {\n @for (\n content of vm.activeTabContent();\n track content.name\n ) {\n <ng-container\n axp-widget-renderer\n [node]=\"content\"\n [mode]=\"content.mode ?? 'view'\"\n >\n </ng-container>\n }\n }\n </div>\n </div>\n }\n </div>\n </axp-widgets-container>\n <ax-validation-summary\n [displayMode]=\"'toast'\"\n [autoHide]=\"true\"\n ></ax-validation-summary>\n </ax-form>\n }\n </axp-page-content>\n\n <!-- Footer Section -->\n @if (hasFooter()) {\n <axp-page-footer class=\"--animated\">\n <axp-layout-suffix>\n <!-- secondary footer actions -->\n @if (hasVisibleFooterSecondaryActions()) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [iconOnly]=\"deviceService.isSmall()\"\n [text]=\"'@general:terms.interface.actions' | translate | async\"\n [look]=\"deviceService.isSmall() ? 'blank' : 'solid'\"\n [color]=\"'default'\"\n >\n <ax-prefix>\n <i class=\"fa-solid fa-ellipsis-vertical\"></i>\n </ax-prefix>\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (action of footerSecondaryActions(); track $index) {\n @if (isFooterActionVisible(action)) {\n <ax-button-item\n [text]=\"(t(action.title) | async)!\"\n [color]=\"action.color\"\n [disabled]=\"isFooterActionDisabled(action)\"\n (onClick)=\"execute(action.command!)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light {{ action.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n @if (action.break) {\n <ax-divider></ax-divider>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n\n @if (hasVisibleFooterPrimaryActions()) {\n @if (showSaveDiscardFooter()) {\n @if (rejectFooterCommand(); as reject) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [disabled]=\"vm.isOverlayBusy()\"\n [text]=\"(t(reject.title) | async)!\"\n [look]=\"'solid'\"\n [color]=\"reject.color\"\n (onClick)=\"execute(reject.command)\"\n >\n <ax-prefix>\n <i class=\"{{ reject.icon }}\"></i>\n </ax-prefix>\n </ax-button>\n }\n @if (acceptFooterCommand(); as accept) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [disabled]=\"vm.isOverlayBusy()\"\n [text]=\"(t(accept.title) | async)!\"\n [look]=\"'solid'\"\n [color]=\"accept.color\"\n (onClick)=\"execute(accept.command)\"\n >\n <ax-prefix>\n <i class=\"{{ accept.icon }}\"></i>\n </ax-prefix>\n </ax-button>\n }\n }\n @for (action of footerPrimaryActions(); track $index) {\n @if (isFooterActionVisible(action)) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [disabled]=\"isFooterActionDisabled(action)\"\n [text]=\"(t(action.title) | async)!\"\n [look]=\"'solid'\"\n [color]=\"action.color\"\n (onClick)=\"execute(action.command!)\"\n >\n <ax-prefix>\n <i class=\"{{ action.icon }}\"></i>\n </ax-prefix>\n @if (action?.items) {\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (sub of action?.items; track $index) {\n @if (isFooterActionVisible(sub)) {\n <ax-button-item\n [text]=\"(t(sub.title) | async)!\"\n [color]=\"sub.color\"\n [disabled]=\"isFooterActionDisabled(sub)\"\n (onClick)=\"execute(sub.command!)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light {{ sub.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n @if (sub.break) {\n <ax-divider></ax-divider>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n }\n </ax-button>\n }\n }\n }\n </axp-layout-suffix>\n </axp-page-footer>\n }\n</axp-page-layout>\n", styles: ["@layer properties;axp-layout-details-view .axp-vertical-tabs ax-tab-item{margin-block:0px;border-radius:0!important;padding-block:calc(var(--spacing, .25rem) * 3);--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}axp-layout-details-view .axp-vertical-tabs ax-tab-item>div{display:flex;align-items:center}axp-layout-details-view .axp-vertical-tabs ax-tab-item>div .tab-item-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}axp-layout-details-view .axp-horizontal-tabs{display:flex;width:100%;flex-direction:column}axp-layout-details-view .axp-horizontal-tabs .content{margin-block:calc(var(--spacing, .25rem) * 4);display:block;width:100%}axp-layout-details-view axp-layout-section axp-layout-content{display:flex;width:100%;flex-direction:column}:where(axp-layout-details-view axp-layout-section axp-layout-content>:not(:last-child)){--tw-divide-y-reverse: 0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(axp-layout-details-view axp-layout-section axp-layout-content>:not(:last-child)){--tw-border-style: dashed;border-style:dashed}:where(axp-layout-details-view axp-layout-section axp-layout-content>:not(:last-child)){border-color:var(--color-gray-200, oklch(92.8% .006 264.531))}axp-layout-details-view axp-layout-section axp-layout-content .--item-container{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));align-items:center;gap:calc(var(--spacing, .25rem) * 4);padding-inline:calc(var(--spacing, .25rem) * 4);padding-block:calc(var(--spacing, .25rem) * 4)}@media(width>=64rem){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-inline:calc(var(--spacing, .25rem) * 6)}}@media(width>=80rem){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-inline:calc(var(--spacing, .25rem) * 8)}}@media(width>=96rem){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-inline:calc(var(--spacing, .25rem) * 10)}}axp-layout-details-view axp-layout-section axp-layout-content .--item-container axp-layout-description{margin-top:calc(var(--spacing, .25rem) * 2);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)))}axp-layout-details-view axp-page-content ax-form form{height:100%}axp-layout-details-view:has(axp-page-content.axp-details-page-list) axp-page-layout>axp-layout-container{overflow:hidden}axp-layout-details-view axp-page-content.axp-details-page-list{display:flex;min-height:0px;flex-direction:column;overflow:hidden}axp-layout-details-view axp-page-content.axp-details-page-list>ax-form,axp-layout-details-view axp-page-content.axp-details-page-list ax-form form,axp-layout-details-view axp-page-content.axp-details-page-list ax-form form>div,axp-layout-details-view axp-page-content.axp-details-page-list .axp-entity-list,axp-layout-details-view axp-page-content.axp-details-page-list .axp-entity-list-body,axp-layout-details-view axp-page-content.axp-details-page-list axp-data-list-widget-view{display:flex;min-height:0px;flex:1;flex-direction:column;height:100%}axp-layout-details-view axp-page-content.axp-details-page-list axp-data-list-widget-view{min-height:0!important}axp-layout-details-view axp-page-content.axp-details-page-list ax-data-table{min-height:0px;flex:1;height:100%}axp-layout-details-view .axp-entity-list ax-data-table .ax-data-table-wrapper:has(tfoot) table{height:100%}axp-layout-details-view .axp-entity-list ax-data-table .ax-data-table-wrapper:has(tfoot) table tbody tr.empty-row{height:100%!important}axp-layout-details-view axp-layout-start-side{border-inline-end-style:var(--tw-border-style);border-inline-end-width:1px}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-divide-y-reverse{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-divide-y-reverse: 0;--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type:
3382
+ ], viewQueries: [{ propertyName: "form", first: true, predicate: ["form"], descendants: true, isSignal: true }, { propertyName: "widgetContainer", first: true, predicate: AXPWidgetContainerComponent, descendants: true, isSignal: true }, { propertyName: "sidebarTabs", first: true, predicate: ["sidebarTabs"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<axp-page-layout *translate=\"let t\">\n @if (vm.adapter()?.pages?.length! > 1 && vm.isLarge()) {\n <axp-layout-start-side>\n <axp-layout-header>\n <axp-layout-title>{{\n formatPageLabel(\n vm.showPages()\n ? (vm.adapter()?.title ?? '')\n : (vm.adapter()?.label ?? '')\n )\n | translate\n | async\n }}</axp-layout-title>\n <axp-layout-description>{{\n formatPageLabel(vm.adapter()?.description ?? '')\n | translate\n | async\n }}</axp-layout-description>\n </axp-layout-header>\n <axp-layout-content>\n <ax-tabs\n #sidebarTabs\n class=\"axp-vertical-tabs\"\n [look]=\"'with-line-color'\"\n [location]=\"'end'\"\n [fitParent]=\"true\"\n (onActiveTabChanged)=\"handleSidebarTabChanged($event)\"\n >\n @for (item of vm.adapter()?.pages; track item.id) {\n <ax-tab-item\n [key]=\"item.id\"\n [text]=\"(formatPageLabel(item.label) | translate | async)!\"\n [active]=\"vm.currentPage()?.id === item.id\"\n >\n <ax-prefix>\n <ax-icon icon=\"far ${{ item.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n }\n </ax-tabs>\n </axp-layout-content>\n </axp-layout-start-side>\n }\n <!-- Content Section -->\n <axp-page-content\n class=\"flex flex-row gap-4\"\n [class.axp-details-page-list]=\"isEntityListPage()\"\n >\n @if (vm.showPages()) {\n <axp-layout-list class=\"w-full\">\n @for (item of vm.adapter()?.pages; track $index) {\n <axp-layout-list-item (click)=\"handleSelectPage(item)\">\n <axp-layout-prefix>\n <ax-icon\n icon=\"far ${{ item.icon }}\"\n class=\"text-gray-500\"\n ></ax-icon>\n </axp-layout-prefix>\n <axp-layout-content>\n <a class=\"font-semibold\">{{\n formatPageLabel(item.label) | translate | async\n }}</a>\n </axp-layout-content>\n <axp-layout-suffix>\n <ax-icon\n icon=\" far fa-chevron-right\"\n class=\"text-gray-400\"\n ></ax-icon>\n </axp-layout-suffix>\n </axp-layout-list-item>\n }\n </axp-layout-list>\n } @else {\n <ax-form class=\"h-full w-full\" #form>\n <axp-widgets-container\n #widgetsContainerRef\n [context]=\"vm.context()\"\n (onContextChanged)=\"handleOnContextChanged($event)\"\n >\n <div class=\"flex h-full min-h-0 w-full flex-col\">\n @for (\n item of vm.currentPageContent();\n track pageContentTrackKey($any(item), $index)\n ) {\n @if ('type' in item && item.type === 'component') {\n <!-- Component-based content -->\n <div\n axp-page-component-renderer\n [componentKey]=\"$any(item).componentKey\"\n [rootContext]=\"vm.rootContext()\"\n [pageConfig]=\"$any(item).pageConfig\"\n [options]=\"$any(item).options\"\n (componentReady)=\"recompute()\"\n ></div>\n } @else {\n <!-- Widget-based content -->\n <ng-container\n axp-widget-renderer\n [node]=\"$any(item)\"\n [mode]=\"$any(item).mode ?? 'view'\"\n ></ng-container>\n }\n }\n @if (vm.currentPage()?.tabs?.length) {\n <div class=\"axp-horizontal-tabs\">\n <ax-tabs\n [location]=\"'bottom'\"\n [fitParent]=\"false\"\n look=\"classic\"\n >\n @for (tab of vm.currentPageTabs(); track $index) {\n <ax-tab-item\n (onClick)=\"vm.setCurrentTab(tab)\"\n [text]=\"(tab.title | translate | async)!\"\n [active]=\"vm.currentTab()?.id === tab.id\"\n >\n <ax-prefix>\n <ax-icon icon=\"far ${{ tab.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n }\n </ax-tabs>\n <div class=\"content\">\n @if (vm.currentTab()) {\n @for (\n content of vm.activeTabContent();\n track content.name\n ) {\n <ng-container\n axp-widget-renderer\n [node]=\"content\"\n [mode]=\"content.mode ?? 'view'\"\n >\n </ng-container>\n }\n }\n </div>\n </div>\n }\n </div>\n </axp-widgets-container>\n <ax-validation-summary\n [displayMode]=\"'toast'\"\n [autoHide]=\"true\"\n ></ax-validation-summary>\n </ax-form>\n }\n </axp-page-content>\n\n <!-- Footer Section -->\n @if (hasFooter()) {\n <axp-page-footer class=\"--animated\">\n <axp-layout-suffix>\n <!-- secondary footer actions -->\n @if (hasVisibleFooterSecondaryActions()) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [iconOnly]=\"deviceService.isSmall()\"\n [text]=\"'@general:terms.interface.actions' | translate | async\"\n [look]=\"deviceService.isSmall() ? 'blank' : 'solid'\"\n [color]=\"'default'\"\n >\n <ax-prefix>\n <i class=\"fa-solid fa-ellipsis-vertical\"></i>\n </ax-prefix>\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (action of footerSecondaryActions(); track $index) {\n @if (isFooterActionVisible(action)) {\n <ax-button-item\n [text]=\"(t(action.title) | async)!\"\n [color]=\"action.color\"\n [disabled]=\"isFooterActionDisabled(action)\"\n (onClick)=\"execute(action.command!)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light {{ action.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n @if (action.break) {\n <ax-divider></ax-divider>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n\n @if (hasVisibleFooterPrimaryActions()) {\n @if (showSaveDiscardFooter()) {\n @if (rejectFooterCommand(); as reject) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [disabled]=\"vm.isOverlayBusy()\"\n [text]=\"(t(reject.title) | async)!\"\n [look]=\"'solid'\"\n [color]=\"reject.color\"\n (onClick)=\"execute(reject.command)\"\n >\n <ax-prefix>\n <i class=\"{{ reject.icon }}\"></i>\n </ax-prefix>\n </ax-button>\n }\n @if (acceptFooterCommand(); as accept) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [disabled]=\"vm.isOverlayBusy()\"\n [text]=\"(t(accept.title) | async)!\"\n [look]=\"'solid'\"\n [color]=\"accept.color\"\n (onClick)=\"execute(accept.command)\"\n >\n <ax-prefix>\n <i class=\"{{ accept.icon }}\"></i>\n </ax-prefix>\n </ax-button>\n }\n }\n @for (action of footerPrimaryActions(); track $index) {\n @if (isFooterActionVisible(action)) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [disabled]=\"isFooterActionDisabled(action)\"\n [text]=\"(t(action.title) | async)!\"\n [look]=\"'solid'\"\n [color]=\"action.color\"\n (onClick)=\"execute(action.command!)\"\n >\n <ax-prefix>\n <i class=\"{{ action.icon }}\"></i>\n </ax-prefix>\n @if (action?.items) {\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (sub of action?.items; track $index) {\n @if (isFooterActionVisible(sub)) {\n <ax-button-item\n [text]=\"(t(sub.title) | async)!\"\n [color]=\"sub.color\"\n [disabled]=\"isFooterActionDisabled(sub)\"\n (onClick)=\"execute(sub.command!)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light {{ sub.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n @if (sub.break) {\n <ax-divider></ax-divider>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n }\n </ax-button>\n }\n }\n }\n </axp-layout-suffix>\n </axp-page-footer>\n }\n</axp-page-layout>\n", styles: ["@layer properties;axp-layout-details-view .axp-vertical-tabs ax-tab-item{margin-block:0px;border-radius:0!important;padding-block:calc(var(--spacing, .25rem) * 3);--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}axp-layout-details-view .axp-vertical-tabs ax-tab-item>div{display:flex;align-items:center}axp-layout-details-view .axp-vertical-tabs ax-tab-item>div .tab-item-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}axp-layout-details-view .axp-horizontal-tabs{margin-top:calc(var(--spacing, .25rem) * 6);display:flex;width:100%;flex-shrink:0;flex-direction:column}axp-layout-details-view .axp-horizontal-tabs .content{margin-top:calc(var(--spacing, .25rem) * 2);display:block;width:100%}axp-layout-details-view .axp-horizontal-tabs .content .axp-entity-list{height:auto;min-height:0;flex:none}axp-layout-details-view axp-layout-section axp-layout-content{display:flex;width:100%;flex-direction:column}:where(axp-layout-details-view axp-layout-section axp-layout-content>:not(:last-child)){--tw-divide-y-reverse: 0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(axp-layout-details-view axp-layout-section axp-layout-content>:not(:last-child)){--tw-border-style: dashed;border-style:dashed}:where(axp-layout-details-view axp-layout-section axp-layout-content>:not(:last-child)){border-color:var(--color-gray-200, oklch(92.8% .006 264.531))}axp-layout-details-view axp-layout-section axp-layout-content .--item-container{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));align-items:center;gap:calc(var(--spacing, .25rem) * 4);padding-inline:calc(var(--spacing, .25rem) * 4);padding-block:calc(var(--spacing, .25rem) * 4)}@media(width>=64rem){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-inline:calc(var(--spacing, .25rem) * 6)}}@media(width>=80rem){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-inline:calc(var(--spacing, .25rem) * 8)}}@media(width>=96rem){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-inline:calc(var(--spacing, .25rem) * 10)}}axp-layout-details-view axp-layout-section axp-layout-content .--item-container axp-layout-description{margin-top:calc(var(--spacing, .25rem) * 2);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)))}axp-layout-details-view axp-page-content ax-form form{height:100%}axp-layout-details-view:has(axp-page-content.axp-details-page-list) axp-page-layout>axp-layout-container{overflow:hidden}axp-layout-details-view axp-page-content.axp-details-page-list{display:flex;min-height:0px;flex-direction:column;overflow:hidden}axp-layout-details-view axp-page-content.axp-details-page-list>ax-form,axp-layout-details-view axp-page-content.axp-details-page-list ax-form form,axp-layout-details-view axp-page-content.axp-details-page-list ax-form form>div,axp-layout-details-view axp-page-content.axp-details-page-list .axp-entity-list,axp-layout-details-view axp-page-content.axp-details-page-list .axp-entity-list-body,axp-layout-details-view axp-page-content.axp-details-page-list axp-data-list-widget-view{display:flex;min-height:0px;flex:1;flex-direction:column;height:100%}axp-layout-details-view axp-page-content.axp-details-page-list axp-data-list-widget-view{min-height:0!important}axp-layout-details-view axp-page-content.axp-details-page-list ax-data-table{min-height:0px;flex:1;height:100%}axp-layout-details-view .axp-entity-list ax-data-table .ax-data-table-wrapper:has(tfoot) table{height:100%}axp-layout-details-view .axp-entity-list ax-data-table .ax-data-table-wrapper:has(tfoot) table tbody tr.empty-row{height:100%!important}axp-layout-details-view axp-layout-start-side{border-inline-end-style:var(--tw-border-style);border-inline-end-width:1px}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-divide-y-reverse{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-divide-y-reverse: 0;--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type:
3367
3383
  // Angular
3368
3384
  CommonModule }, { kind: "ngmodule", type:
3369
3385
  // ACoreX
@@ -3408,7 +3424,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
3408
3424
  useExisting: AXPLayoutDetailsViewComponent,
3409
3425
  },
3410
3426
  AXPLayoutDetailsViewViewModel,
3411
- ], template: "<axp-page-layout *translate=\"let t\">\n @if (vm.adapter()?.pages?.length! > 1 && vm.isLarge()) {\n <axp-layout-start-side>\n <axp-layout-header>\n <axp-layout-title>{{\n formatPageLabel(\n vm.showPages()\n ? (vm.adapter()?.title ?? '')\n : (vm.adapter()?.label ?? '')\n )\n | translate\n | async\n }}</axp-layout-title>\n <axp-layout-description>{{\n formatPageLabel(vm.adapter()?.description ?? '')\n | translate\n | async\n }}</axp-layout-description>\n </axp-layout-header>\n <axp-layout-content>\n <ax-tabs\n #sidebarTabs\n class=\"axp-vertical-tabs\"\n [look]=\"'with-line-color'\"\n [location]=\"'end'\"\n [fitParent]=\"true\"\n (onActiveTabChanged)=\"handleSidebarTabChanged($event)\"\n >\n @for (item of vm.adapter()?.pages; track item.id) {\n <ax-tab-item\n [key]=\"item.id\"\n [text]=\"(formatPageLabel(item.label) | translate | async)!\"\n [active]=\"vm.currentPage()?.id === item.id\"\n >\n <ax-prefix>\n <ax-icon icon=\"far ${{ item.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n }\n </ax-tabs>\n </axp-layout-content>\n </axp-layout-start-side>\n }\n <!-- Content Section -->\n <axp-page-content\n class=\"flex flex-row gap-4\"\n [class.axp-details-page-list]=\"isEntityListPage()\"\n >\n @if (vm.showPages()) {\n <axp-layout-list class=\"w-full\">\n @for (item of vm.adapter()?.pages; track $index) {\n <axp-layout-list-item (click)=\"handleSelectPage(item)\">\n <axp-layout-prefix>\n <ax-icon\n icon=\"far ${{ item.icon }}\"\n class=\"text-gray-500\"\n ></ax-icon>\n </axp-layout-prefix>\n <axp-layout-content>\n <a class=\"font-semibold\">{{\n formatPageLabel(item.label) | translate | async\n }}</a>\n </axp-layout-content>\n <axp-layout-suffix>\n <ax-icon\n icon=\" far fa-chevron-right\"\n class=\"text-gray-400\"\n ></ax-icon>\n </axp-layout-suffix>\n </axp-layout-list-item>\n }\n </axp-layout-list>\n } @else {\n <ax-form class=\"h-full w-full\" #form>\n <axp-widgets-container\n #widgetsContainerRef\n [context]=\"vm.context()\"\n (onContextChanged)=\"handleOnContextChanged($event)\"\n >\n <div class=\"flex h-full min-h-0 w-full flex-col\">\n @for (\n item of vm.currentPageContent();\n track pageContentTrackKey($any(item), $index)\n ) {\n @if ('type' in item && item.type === 'component') {\n <!-- Component-based content -->\n <div\n axp-page-component-renderer\n [componentKey]=\"$any(item).componentKey\"\n [rootContext]=\"vm.rootContext()\"\n [pageConfig]=\"$any(item).pageConfig\"\n [options]=\"$any(item).options\"\n (componentReady)=\"recompute()\"\n ></div>\n } @else {\n <!-- Widget-based content -->\n <ng-container\n axp-widget-renderer\n [node]=\"$any(item)\"\n [mode]=\"$any(item).mode ?? 'view'\"\n ></ng-container>\n }\n }\n @if (vm.currentPage()?.tabs?.length) {\n <div class=\"axp-horizontal-tabs\">\n <ax-tabs\n [location]=\"'bottom'\"\n [fitParent]=\"false\"\n look=\"classic\"\n >\n @for (tab of vm.currentPageTabs(); track $index) {\n <ax-tab-item\n (onClick)=\"vm.setCurrentTab(tab)\"\n [text]=\"(tab.title | translate | async)!\"\n [active]=\"vm.currentTab()?.id === tab.id\"\n >\n <ax-prefix>\n <ax-icon icon=\"far ${{ tab.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n }\n </ax-tabs>\n <div class=\"content\">\n @if (vm.currentTab()) {\n @for (\n content of vm.activeTabContent();\n track content.name\n ) {\n <ng-container\n axp-widget-renderer\n [node]=\"content\"\n [mode]=\"content.mode ?? 'view'\"\n >\n </ng-container>\n }\n }\n </div>\n </div>\n }\n </div>\n </axp-widgets-container>\n <ax-validation-summary\n [displayMode]=\"'toast'\"\n [autoHide]=\"true\"\n ></ax-validation-summary>\n </ax-form>\n }\n </axp-page-content>\n\n <!-- Footer Section -->\n @if (hasFooter()) {\n <axp-page-footer class=\"--animated\">\n <axp-layout-suffix>\n <!-- secondary footer actions -->\n @if (hasVisibleFooterSecondaryActions()) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [iconOnly]=\"deviceService.isSmall()\"\n [text]=\"'@general:terms.interface.actions' | translate | async\"\n [look]=\"deviceService.isSmall() ? 'blank' : 'solid'\"\n [color]=\"'default'\"\n >\n <ax-prefix>\n <i class=\"fa-solid fa-ellipsis-vertical\"></i>\n </ax-prefix>\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (action of footerSecondaryActions(); track $index) {\n @if (isFooterActionVisible(action)) {\n <ax-button-item\n [text]=\"(t(action.title) | async)!\"\n [color]=\"action.color\"\n [disabled]=\"isFooterActionDisabled(action)\"\n (onClick)=\"execute(action.command!)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light {{ action.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n @if (action.break) {\n <ax-divider></ax-divider>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n\n @if (hasVisibleFooterPrimaryActions()) {\n @if (showSaveDiscardFooter()) {\n @if (rejectFooterCommand(); as reject) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [disabled]=\"vm.isOverlayBusy()\"\n [text]=\"(t(reject.title) | async)!\"\n [look]=\"'solid'\"\n [color]=\"reject.color\"\n (onClick)=\"execute(reject.command)\"\n >\n <ax-prefix>\n <i class=\"{{ reject.icon }}\"></i>\n </ax-prefix>\n </ax-button>\n }\n @if (acceptFooterCommand(); as accept) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [disabled]=\"vm.isOverlayBusy()\"\n [text]=\"(t(accept.title) | async)!\"\n [look]=\"'solid'\"\n [color]=\"accept.color\"\n (onClick)=\"execute(accept.command)\"\n >\n <ax-prefix>\n <i class=\"{{ accept.icon }}\"></i>\n </ax-prefix>\n </ax-button>\n }\n }\n @for (action of footerPrimaryActions(); track $index) {\n @if (isFooterActionVisible(action)) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [disabled]=\"isFooterActionDisabled(action)\"\n [text]=\"(t(action.title) | async)!\"\n [look]=\"'solid'\"\n [color]=\"action.color\"\n (onClick)=\"execute(action.command!)\"\n >\n <ax-prefix>\n <i class=\"{{ action.icon }}\"></i>\n </ax-prefix>\n @if (action?.items) {\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (sub of action?.items; track $index) {\n @if (isFooterActionVisible(sub)) {\n <ax-button-item\n [text]=\"(t(sub.title) | async)!\"\n [color]=\"sub.color\"\n [disabled]=\"isFooterActionDisabled(sub)\"\n (onClick)=\"execute(sub.command!)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light {{ sub.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n @if (sub.break) {\n <ax-divider></ax-divider>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n }\n </ax-button>\n }\n }\n }\n </axp-layout-suffix>\n </axp-page-footer>\n }\n</axp-page-layout>\n", styles: ["@layer properties;axp-layout-details-view .axp-vertical-tabs ax-tab-item{margin-block:0px;border-radius:0!important;padding-block:calc(var(--spacing, .25rem) * 3);--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}axp-layout-details-view .axp-vertical-tabs ax-tab-item>div{display:flex;align-items:center}axp-layout-details-view .axp-vertical-tabs ax-tab-item>div .tab-item-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}axp-layout-details-view .axp-horizontal-tabs{display:flex;width:100%;flex-direction:column}axp-layout-details-view .axp-horizontal-tabs .content{margin-block:calc(var(--spacing, .25rem) * 4);display:block;width:100%}axp-layout-details-view axp-layout-section axp-layout-content{display:flex;width:100%;flex-direction:column}:where(axp-layout-details-view axp-layout-section axp-layout-content>:not(:last-child)){--tw-divide-y-reverse: 0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(axp-layout-details-view axp-layout-section axp-layout-content>:not(:last-child)){--tw-border-style: dashed;border-style:dashed}:where(axp-layout-details-view axp-layout-section axp-layout-content>:not(:last-child)){border-color:var(--color-gray-200, oklch(92.8% .006 264.531))}axp-layout-details-view axp-layout-section axp-layout-content .--item-container{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));align-items:center;gap:calc(var(--spacing, .25rem) * 4);padding-inline:calc(var(--spacing, .25rem) * 4);padding-block:calc(var(--spacing, .25rem) * 4)}@media(width>=64rem){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-inline:calc(var(--spacing, .25rem) * 6)}}@media(width>=80rem){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-inline:calc(var(--spacing, .25rem) * 8)}}@media(width>=96rem){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-inline:calc(var(--spacing, .25rem) * 10)}}axp-layout-details-view axp-layout-section axp-layout-content .--item-container axp-layout-description{margin-top:calc(var(--spacing, .25rem) * 2);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)))}axp-layout-details-view axp-page-content ax-form form{height:100%}axp-layout-details-view:has(axp-page-content.axp-details-page-list) axp-page-layout>axp-layout-container{overflow:hidden}axp-layout-details-view axp-page-content.axp-details-page-list{display:flex;min-height:0px;flex-direction:column;overflow:hidden}axp-layout-details-view axp-page-content.axp-details-page-list>ax-form,axp-layout-details-view axp-page-content.axp-details-page-list ax-form form,axp-layout-details-view axp-page-content.axp-details-page-list ax-form form>div,axp-layout-details-view axp-page-content.axp-details-page-list .axp-entity-list,axp-layout-details-view axp-page-content.axp-details-page-list .axp-entity-list-body,axp-layout-details-view axp-page-content.axp-details-page-list axp-data-list-widget-view{display:flex;min-height:0px;flex:1;flex-direction:column;height:100%}axp-layout-details-view axp-page-content.axp-details-page-list axp-data-list-widget-view{min-height:0!important}axp-layout-details-view axp-page-content.axp-details-page-list ax-data-table{min-height:0px;flex:1;height:100%}axp-layout-details-view .axp-entity-list ax-data-table .ax-data-table-wrapper:has(tfoot) table{height:100%}axp-layout-details-view .axp-entity-list ax-data-table .ax-data-table-wrapper:has(tfoot) table tbody tr.empty-row{height:100%!important}axp-layout-details-view axp-layout-start-side{border-inline-end-style:var(--tw-border-style);border-inline-end-width:1px}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-divide-y-reverse{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-divide-y-reverse: 0;--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
3427
+ ], template: "<axp-page-layout *translate=\"let t\">\n @if (vm.adapter()?.pages?.length! > 1 && vm.isLarge()) {\n <axp-layout-start-side>\n <axp-layout-header>\n <axp-layout-title>{{\n formatPageLabel(\n vm.showPages()\n ? (vm.adapter()?.title ?? '')\n : (vm.adapter()?.label ?? '')\n )\n | translate\n | async\n }}</axp-layout-title>\n <axp-layout-description>{{\n formatPageLabel(vm.adapter()?.description ?? '')\n | translate\n | async\n }}</axp-layout-description>\n </axp-layout-header>\n <axp-layout-content>\n <ax-tabs\n #sidebarTabs\n class=\"axp-vertical-tabs\"\n [look]=\"'with-line-color'\"\n [location]=\"'end'\"\n [fitParent]=\"true\"\n (onActiveTabChanged)=\"handleSidebarTabChanged($event)\"\n >\n @for (item of vm.adapter()?.pages; track item.id) {\n <ax-tab-item\n [key]=\"item.id\"\n [text]=\"(formatPageLabel(item.label) | translate | async)!\"\n [active]=\"vm.currentPage()?.id === item.id\"\n >\n <ax-prefix>\n <ax-icon icon=\"far ${{ item.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n }\n </ax-tabs>\n </axp-layout-content>\n </axp-layout-start-side>\n }\n <!-- Content Section -->\n <axp-page-content\n class=\"flex flex-row gap-4\"\n [class.axp-details-page-list]=\"isEntityListPage()\"\n >\n @if (vm.showPages()) {\n <axp-layout-list class=\"w-full\">\n @for (item of vm.adapter()?.pages; track $index) {\n <axp-layout-list-item (click)=\"handleSelectPage(item)\">\n <axp-layout-prefix>\n <ax-icon\n icon=\"far ${{ item.icon }}\"\n class=\"text-gray-500\"\n ></ax-icon>\n </axp-layout-prefix>\n <axp-layout-content>\n <a class=\"font-semibold\">{{\n formatPageLabel(item.label) | translate | async\n }}</a>\n </axp-layout-content>\n <axp-layout-suffix>\n <ax-icon\n icon=\" far fa-chevron-right\"\n class=\"text-gray-400\"\n ></ax-icon>\n </axp-layout-suffix>\n </axp-layout-list-item>\n }\n </axp-layout-list>\n } @else {\n <ax-form class=\"h-full w-full\" #form>\n <axp-widgets-container\n #widgetsContainerRef\n [context]=\"vm.context()\"\n (onContextChanged)=\"handleOnContextChanged($event)\"\n >\n <div class=\"flex h-full min-h-0 w-full flex-col\">\n @for (\n item of vm.currentPageContent();\n track pageContentTrackKey($any(item), $index)\n ) {\n @if ('type' in item && item.type === 'component') {\n <!-- Component-based content -->\n <div\n axp-page-component-renderer\n [componentKey]=\"$any(item).componentKey\"\n [rootContext]=\"vm.rootContext()\"\n [pageConfig]=\"$any(item).pageConfig\"\n [options]=\"$any(item).options\"\n (componentReady)=\"recompute()\"\n ></div>\n } @else {\n <!-- Widget-based content -->\n <ng-container\n axp-widget-renderer\n [node]=\"$any(item)\"\n [mode]=\"$any(item).mode ?? 'view'\"\n ></ng-container>\n }\n }\n @if (vm.currentPage()?.tabs?.length) {\n <div class=\"axp-horizontal-tabs\">\n <ax-tabs\n [location]=\"'bottom'\"\n [fitParent]=\"false\"\n look=\"classic\"\n >\n @for (tab of vm.currentPageTabs(); track $index) {\n <ax-tab-item\n (onClick)=\"vm.setCurrentTab(tab)\"\n [text]=\"(tab.title | translate | async)!\"\n [active]=\"vm.currentTab()?.id === tab.id\"\n >\n <ax-prefix>\n <ax-icon icon=\"far ${{ tab.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-tab-item>\n }\n </ax-tabs>\n <div class=\"content\">\n @if (vm.currentTab()) {\n @for (\n content of vm.activeTabContent();\n track content.name\n ) {\n <ng-container\n axp-widget-renderer\n [node]=\"content\"\n [mode]=\"content.mode ?? 'view'\"\n >\n </ng-container>\n }\n }\n </div>\n </div>\n }\n </div>\n </axp-widgets-container>\n <ax-validation-summary\n [displayMode]=\"'toast'\"\n [autoHide]=\"true\"\n ></ax-validation-summary>\n </ax-form>\n }\n </axp-page-content>\n\n <!-- Footer Section -->\n @if (hasFooter()) {\n <axp-page-footer class=\"--animated\">\n <axp-layout-suffix>\n <!-- secondary footer actions -->\n @if (hasVisibleFooterSecondaryActions()) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [iconOnly]=\"deviceService.isSmall()\"\n [text]=\"'@general:terms.interface.actions' | translate | async\"\n [look]=\"deviceService.isSmall() ? 'blank' : 'solid'\"\n [color]=\"'default'\"\n >\n <ax-prefix>\n <i class=\"fa-solid fa-ellipsis-vertical\"></i>\n </ax-prefix>\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (action of footerSecondaryActions(); track $index) {\n @if (isFooterActionVisible(action)) {\n <ax-button-item\n [text]=\"(t(action.title) | async)!\"\n [color]=\"action.color\"\n [disabled]=\"isFooterActionDisabled(action)\"\n (onClick)=\"execute(action.command!)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light {{ action.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n @if (action.break) {\n <ax-divider></ax-divider>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n\n @if (hasVisibleFooterPrimaryActions()) {\n @if (showSaveDiscardFooter()) {\n @if (rejectFooterCommand(); as reject) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [disabled]=\"vm.isOverlayBusy()\"\n [text]=\"(t(reject.title) | async)!\"\n [look]=\"'solid'\"\n [color]=\"reject.color\"\n (onClick)=\"execute(reject.command)\"\n >\n <ax-prefix>\n <i class=\"{{ reject.icon }}\"></i>\n </ax-prefix>\n </ax-button>\n }\n @if (acceptFooterCommand(); as accept) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [disabled]=\"vm.isOverlayBusy()\"\n [text]=\"(t(accept.title) | async)!\"\n [look]=\"'solid'\"\n [color]=\"accept.color\"\n (onClick)=\"execute(accept.command)\"\n >\n <ax-prefix>\n <i class=\"{{ accept.icon }}\"></i>\n </ax-prefix>\n </ax-button>\n }\n }\n @for (action of footerPrimaryActions(); track $index) {\n @if (isFooterActionVisible(action)) {\n <ax-button\n [class.ax-sm]=\"deviceService.isSmall()\"\n [disabled]=\"isFooterActionDisabled(action)\"\n [text]=\"(t(action.title) | async)!\"\n [look]=\"'solid'\"\n [color]=\"action.color\"\n (onClick)=\"execute(action.command!)\"\n >\n <ax-prefix>\n <i class=\"{{ action.icon }}\"></i>\n </ax-prefix>\n @if (action?.items) {\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (sub of action?.items; track $index) {\n @if (isFooterActionVisible(sub)) {\n <ax-button-item\n [text]=\"(t(sub.title) | async)!\"\n [color]=\"sub.color\"\n [disabled]=\"isFooterActionDisabled(sub)\"\n (onClick)=\"execute(sub.command!)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light {{ sub.icon }}\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n @if (sub.break) {\n <ax-divider></ax-divider>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n }\n </ax-button>\n }\n }\n }\n </axp-layout-suffix>\n </axp-page-footer>\n }\n</axp-page-layout>\n", styles: ["@layer properties;axp-layout-details-view .axp-vertical-tabs ax-tab-item{margin-block:0px;border-radius:0!important;padding-block:calc(var(--spacing, .25rem) * 3);--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}axp-layout-details-view .axp-vertical-tabs ax-tab-item>div{display:flex;align-items:center}axp-layout-details-view .axp-vertical-tabs ax-tab-item>div .tab-item-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}axp-layout-details-view .axp-horizontal-tabs{margin-top:calc(var(--spacing, .25rem) * 6);display:flex;width:100%;flex-shrink:0;flex-direction:column}axp-layout-details-view .axp-horizontal-tabs .content{margin-top:calc(var(--spacing, .25rem) * 2);display:block;width:100%}axp-layout-details-view .axp-horizontal-tabs .content .axp-entity-list{height:auto;min-height:0;flex:none}axp-layout-details-view axp-layout-section axp-layout-content{display:flex;width:100%;flex-direction:column}:where(axp-layout-details-view axp-layout-section axp-layout-content>:not(:last-child)){--tw-divide-y-reverse: 0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(axp-layout-details-view axp-layout-section axp-layout-content>:not(:last-child)){--tw-border-style: dashed;border-style:dashed}:where(axp-layout-details-view axp-layout-section axp-layout-content>:not(:last-child)){border-color:var(--color-gray-200, oklch(92.8% .006 264.531))}axp-layout-details-view axp-layout-section axp-layout-content .--item-container{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));align-items:center;gap:calc(var(--spacing, .25rem) * 4);padding-inline:calc(var(--spacing, .25rem) * 4);padding-block:calc(var(--spacing, .25rem) * 4)}@media(width>=64rem){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-inline:calc(var(--spacing, .25rem) * 6)}}@media(width>=80rem){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-inline:calc(var(--spacing, .25rem) * 8)}}@media(width>=96rem){axp-layout-details-view axp-layout-section axp-layout-content .--item-container{padding-inline:calc(var(--spacing, .25rem) * 10)}}axp-layout-details-view axp-layout-section axp-layout-content .--item-container axp-layout-description{margin-top:calc(var(--spacing, .25rem) * 2);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)))}axp-layout-details-view axp-page-content ax-form form{height:100%}axp-layout-details-view:has(axp-page-content.axp-details-page-list) axp-page-layout>axp-layout-container{overflow:hidden}axp-layout-details-view axp-page-content.axp-details-page-list{display:flex;min-height:0px;flex-direction:column;overflow:hidden}axp-layout-details-view axp-page-content.axp-details-page-list>ax-form,axp-layout-details-view axp-page-content.axp-details-page-list ax-form form,axp-layout-details-view axp-page-content.axp-details-page-list ax-form form>div,axp-layout-details-view axp-page-content.axp-details-page-list .axp-entity-list,axp-layout-details-view axp-page-content.axp-details-page-list .axp-entity-list-body,axp-layout-details-view axp-page-content.axp-details-page-list axp-data-list-widget-view{display:flex;min-height:0px;flex:1;flex-direction:column;height:100%}axp-layout-details-view axp-page-content.axp-details-page-list axp-data-list-widget-view{min-height:0!important}axp-layout-details-view axp-page-content.axp-details-page-list ax-data-table{min-height:0px;flex:1;height:100%}axp-layout-details-view .axp-entity-list ax-data-table .ax-data-table-wrapper:has(tfoot) table{height:100%}axp-layout-details-view .axp-entity-list ax-data-table .ax-data-table-wrapper:has(tfoot) table tbody tr.empty-row{height:100%!important}axp-layout-details-view axp-layout-start-side{border-inline-end-style:var(--tw-border-style);border-inline-end-width:1px}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-divide-y-reverse{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-divide-y-reverse: 0;--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
3412
3428
  }], propDecorators: { form: [{ type: i0.ViewChild, args: ['form', { isSignal: true }] }], widgetContainer: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXPWidgetContainerComponent), { isSignal: true }] }], sidebarTabs: [{ type: i0.ViewChild, args: ['sidebarTabs', { isSignal: true }] }] } });
3413
3429
 
3414
3430
  //#region ---- Details View Can Deactivate Guard ----