@acorex/platform 21.0.0-next.8 → 21.0.0-next.83

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 (133) hide show
  1. package/contracts/README.md +3 -0
  2. package/fesm2022/acorex-platform-auth.mjs +201 -81
  3. package/fesm2022/acorex-platform-auth.mjs.map +1 -1
  4. package/fesm2022/acorex-platform-common-common-settings.provider-Ytey9uhY.mjs +177 -0
  5. package/fesm2022/acorex-platform-common-common-settings.provider-Ytey9uhY.mjs.map +1 -0
  6. package/fesm2022/acorex-platform-common.mjs +4490 -880
  7. package/fesm2022/acorex-platform-common.mjs.map +1 -1
  8. package/fesm2022/acorex-platform-contracts.mjs +38 -0
  9. package/fesm2022/acorex-platform-contracts.mjs.map +1 -0
  10. package/fesm2022/acorex-platform-core.mjs +2612 -667
  11. package/fesm2022/acorex-platform-core.mjs.map +1 -1
  12. package/fesm2022/acorex-platform-domain.mjs +557 -826
  13. package/fesm2022/acorex-platform-domain.mjs.map +1 -1
  14. package/fesm2022/acorex-platform-layout-builder.mjs +1255 -209
  15. package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
  16. package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-CXEdvDTf.mjs +121 -0
  17. package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-CXEdvDTf.mjs.map +1 -0
  18. package/fesm2022/acorex-platform-layout-components.mjs +6486 -1915
  19. package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
  20. package/fesm2022/acorex-platform-layout-designer.mjs +612 -287
  21. package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
  22. package/fesm2022/acorex-platform-layout-entity-attachments-page.component-CwG6n_Yb.mjs +376 -0
  23. package/fesm2022/acorex-platform-layout-entity-attachments-page.component-CwG6n_Yb.mjs.map +1 -0
  24. package/fesm2022/acorex-platform-layout-entity-file-list-popup.component--IeMZLIr.mjs +100 -0
  25. package/fesm2022/acorex-platform-layout-entity-file-list-popup.component--IeMZLIr.mjs.map +1 -0
  26. package/fesm2022/acorex-platform-layout-entity.mjs +22502 -9964
  27. package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
  28. package/fesm2022/acorex-platform-layout-views.mjs +1360 -338
  29. package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
  30. package/fesm2022/acorex-platform-layout-widget-core.mjs +2226 -524
  31. package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -1
  32. package/fesm2022/{acorex-platform-layout-widgets-button-widget-designer.component-C3VoBb_b.mjs → acorex-platform-layout-widgets-button-widget-designer.component-Dy7jF-oD.mjs} +10 -10
  33. package/fesm2022/acorex-platform-layout-widgets-button-widget-designer.component-Dy7jF-oD.mjs.map +1 -0
  34. package/fesm2022/{acorex-platform-layout-widgets-image-preview.popup-V31OpYah.mjs → acorex-platform-layout-widgets-image-preview.popup-C_EPAvCU.mjs} +6 -7
  35. package/fesm2022/acorex-platform-layout-widgets-image-preview.popup-C_EPAvCU.mjs.map +1 -0
  36. package/fesm2022/{acorex-platform-layout-widgets-page-widget-designer.component-BtZMBxYp.mjs → acorex-platform-layout-widgets-page-widget-designer.component-D10yO28c.mjs} +12 -12
  37. package/fesm2022/acorex-platform-layout-widgets-page-widget-designer.component-D10yO28c.mjs.map +1 -0
  38. package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-J0zcGKBX.mjs +116 -0
  39. package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-J0zcGKBX.mjs.map +1 -0
  40. package/fesm2022/{acorex-platform-layout-widgets-tabular-data-edit-popup.component-Ck7-wpT2.mjs → acorex-platform-layout-widgets-tabular-data-edit-popup.component-DjpZU6gz.mjs} +6 -6
  41. package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-DjpZU6gz.mjs.map +1 -0
  42. package/fesm2022/{acorex-platform-layout-widgets-tabular-data-view-popup.component-y8vjUiVs.mjs → acorex-platform-layout-widgets-tabular-data-view-popup.component-gX-3Kx9I.mjs} +5 -5
  43. package/fesm2022/acorex-platform-layout-widgets-tabular-data-view-popup.component-gX-3Kx9I.mjs.map +1 -0
  44. package/fesm2022/{acorex-platform-layout-widgets-text-block-widget-designer.component-Df1BFkSa.mjs → acorex-platform-layout-widgets-text-block-widget-designer.component-Vo4fWHtX.mjs} +6 -6
  45. package/fesm2022/acorex-platform-layout-widgets-text-block-widget-designer.component-Vo4fWHtX.mjs.map +1 -0
  46. package/fesm2022/acorex-platform-layout-widgets.mjs +18742 -16715
  47. package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
  48. package/fesm2022/acorex-platform-native.mjs +8 -7
  49. package/fesm2022/acorex-platform-native.mjs.map +1 -1
  50. package/fesm2022/acorex-platform-runtime.mjs +391 -166
  51. package/fesm2022/acorex-platform-runtime.mjs.map +1 -1
  52. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-CWLfNqV0.mjs +160 -0
  53. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-CWLfNqV0.mjs.map +1 -0
  54. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-C7cT82K2.mjs +120 -0
  55. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-C7cT82K2.mjs.map +1 -0
  56. package/fesm2022/{acorex-platform-themes-default-entity-master-single-view.component-eMBby9k4.mjs → acorex-platform-themes-default-entity-master-single-view.component-Br9p5aXT.mjs} +21 -28
  57. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-Br9p5aXT.mjs.map +1 -0
  58. package/fesm2022/acorex-platform-themes-default-error-401.component-B1nsdpTY.mjs +48 -0
  59. package/fesm2022/acorex-platform-themes-default-error-401.component-B1nsdpTY.mjs.map +1 -0
  60. package/fesm2022/acorex-platform-themes-default-error-404.component-D4UvRe8u.mjs +42 -0
  61. package/fesm2022/acorex-platform-themes-default-error-404.component-D4UvRe8u.mjs.map +1 -0
  62. package/fesm2022/acorex-platform-themes-default-error-offline.component-DR6G8gPC.mjs +19 -0
  63. package/fesm2022/acorex-platform-themes-default-error-offline.component-DR6G8gPC.mjs.map +1 -0
  64. package/fesm2022/acorex-platform-themes-default.mjs +2337 -94
  65. package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
  66. package/fesm2022/{acorex-platform-themes-shared-icon-chooser-column.component-C0EpfU2k.mjs → acorex-platform-themes-shared-icon-chooser-column.component-CqkWJYdv.mjs} +6 -6
  67. package/fesm2022/acorex-platform-themes-shared-icon-chooser-column.component-CqkWJYdv.mjs.map +1 -0
  68. package/fesm2022/{acorex-platform-themes-shared-icon-chooser-view.component-9W52W6Nu.mjs → acorex-platform-themes-shared-icon-chooser-view.component-BOTuLdWN.mjs} +6 -6
  69. package/fesm2022/acorex-platform-themes-shared-icon-chooser-view.component-BOTuLdWN.mjs.map +1 -0
  70. package/fesm2022/{acorex-platform-themes-shared-settings.provider-DSs1o1M6.mjs → acorex-platform-themes-shared-settings.provider-BjuzSe0T.mjs} +52 -33
  71. package/fesm2022/acorex-platform-themes-shared-settings.provider-BjuzSe0T.mjs.map +1 -0
  72. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-D566Kdvy.mjs +94 -0
  73. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-D566Kdvy.mjs.map +1 -0
  74. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-D7-rCGl7.mjs +86 -0
  75. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-D7-rCGl7.mjs.map +1 -0
  76. package/fesm2022/acorex-platform-themes-shared.mjs +793 -612
  77. package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
  78. package/fesm2022/acorex-platform-workflow.mjs +997 -274
  79. package/fesm2022/acorex-platform-workflow.mjs.map +1 -1
  80. package/fesm2022/acorex-platform.mjs.map +1 -1
  81. package/package.json +41 -35
  82. package/{auth/index.d.ts → types/acorex-platform-auth.d.ts} +40 -19
  83. package/types/acorex-platform-common.d.ts +3673 -0
  84. package/types/acorex-platform-contracts.d.ts +940 -0
  85. package/{core/index.d.ts → types/acorex-platform-core.d.ts} +1029 -170
  86. package/{domain/index.d.ts → types/acorex-platform-domain.d.ts} +744 -412
  87. package/{layout/builder/index.d.ts → types/acorex-platform-layout-builder.d.ts} +262 -55
  88. package/types/acorex-platform-layout-components.d.ts +3329 -0
  89. package/{layout/designer/index.d.ts → types/acorex-platform-layout-designer.d.ts} +96 -18
  90. package/types/acorex-platform-layout-entity.d.ts +4512 -0
  91. package/{layout/views/index.d.ts → types/acorex-platform-layout-views.d.ts} +334 -91
  92. package/{layout/widget-core/index.d.ts → types/acorex-platform-layout-widget-core.d.ts} +438 -162
  93. package/{layout/widgets/index.d.ts → types/acorex-platform-layout-widgets.d.ts} +1152 -507
  94. package/{native/index.d.ts → types/acorex-platform-native.d.ts} +0 -7
  95. package/types/acorex-platform-runtime.d.ts +571 -0
  96. package/{themes/default/index.d.ts → types/acorex-platform-themes-default.d.ts} +268 -11
  97. package/{themes/shared/index.d.ts → types/acorex-platform-themes-shared.d.ts} +30 -2
  98. package/{workflow/index.d.ts → types/acorex-platform-workflow.d.ts} +436 -748
  99. package/common/index.d.ts +0 -2470
  100. package/fesm2022/acorex-platform-common-common-settings.provider-zhqNP3xb.mjs +0 -71
  101. package/fesm2022/acorex-platform-common-common-settings.provider-zhqNP3xb.mjs.map +0 -1
  102. package/fesm2022/acorex-platform-layout-widgets-button-widget-designer.component-C3VoBb_b.mjs.map +0 -1
  103. package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-CxrsI6Hn.mjs +0 -135
  104. package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-CxrsI6Hn.mjs.map +0 -1
  105. package/fesm2022/acorex-platform-layout-widgets-image-preview.popup-V31OpYah.mjs.map +0 -1
  106. package/fesm2022/acorex-platform-layout-widgets-page-widget-designer.component-BtZMBxYp.mjs.map +0 -1
  107. package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-Ck7-wpT2.mjs.map +0 -1
  108. package/fesm2022/acorex-platform-layout-widgets-tabular-data-view-popup.component-y8vjUiVs.mjs.map +0 -1
  109. package/fesm2022/acorex-platform-layout-widgets-text-block-widget-designer.component-Df1BFkSa.mjs.map +0 -1
  110. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-VIGuU5M4.mjs +0 -157
  111. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-VIGuU5M4.mjs.map +0 -1
  112. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-D3qZa5fM.mjs +0 -1542
  113. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-D3qZa5fM.mjs.map +0 -1
  114. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-Ua3ZA5hk.mjs +0 -101
  115. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-Ua3ZA5hk.mjs.map +0 -1
  116. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-eMBby9k4.mjs.map +0 -1
  117. package/fesm2022/acorex-platform-themes-default-error-401.component-cfREo88K.mjs +0 -31
  118. package/fesm2022/acorex-platform-themes-default-error-401.component-cfREo88K.mjs.map +0 -1
  119. package/fesm2022/acorex-platform-themes-default-error-404.component-CdCV5ZoA.mjs +0 -25
  120. package/fesm2022/acorex-platform-themes-default-error-404.component-CdCV5ZoA.mjs.map +0 -1
  121. package/fesm2022/acorex-platform-themes-default-error-offline.component-E7SzBcAt.mjs +0 -19
  122. package/fesm2022/acorex-platform-themes-default-error-offline.component-E7SzBcAt.mjs.map +0 -1
  123. package/fesm2022/acorex-platform-themes-shared-icon-chooser-column.component-C0EpfU2k.mjs.map +0 -1
  124. package/fesm2022/acorex-platform-themes-shared-icon-chooser-view.component-9W52W6Nu.mjs.map +0 -1
  125. package/fesm2022/acorex-platform-themes-shared-settings.provider-DSs1o1M6.mjs.map +0 -1
  126. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-Dz0cylyQ.mjs +0 -65
  127. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-Dz0cylyQ.mjs.map +0 -1
  128. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-DY0JtT1v.mjs +0 -64
  129. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-DY0JtT1v.mjs.map +0 -1
  130. package/layout/components/index.d.ts +0 -1670
  131. package/layout/entity/index.d.ts +0 -2294
  132. package/runtime/index.d.ts +0 -307
  133. /package/{index.d.ts → types/acorex-platform.d.ts} +0 -0
@@ -1,6 +1,6 @@
1
1
  import * as i1 from '@acorex/components/action-sheet';
2
2
  import { AXActionSheetModule } from '@acorex/components/action-sheet';
3
- import * as i4 from '@acorex/components/badge';
3
+ import * as i1$2 from '@acorex/components/badge';
4
4
  import { AXBadgeModule } from '@acorex/components/badge';
5
5
  import { AXBreadcrumbsModule } from '@acorex/components/breadcrumbs';
6
6
  import * as i3 from '@acorex/components/button';
@@ -10,46 +10,60 @@ import { AXDataTableModule } from '@acorex/components/data-table';
10
10
  import * as i2$1 from '@acorex/components/decorators';
11
11
  import { AXDecoratorModule } from '@acorex/components/decorators';
12
12
  import { AXDialogModule } from '@acorex/components/dialog';
13
- import * as i3$1 from '@acorex/components/drawer';
13
+ import * as i3$4 from '@acorex/components/drawer';
14
14
  import { AXDrawerModule } from '@acorex/components/drawer';
15
15
  import * as i5 from '@acorex/components/dropdown';
16
16
  import { AXDropdownModule } from '@acorex/components/dropdown';
17
17
  import { AXFormModule } from '@acorex/components/form';
18
18
  import { AXLoadingModule } from '@acorex/components/loading';
19
+ import * as i3$2 from '@acorex/components/popover';
19
20
  import { AXPopoverModule } from '@acorex/components/popover';
20
21
  import * as i6 from '@acorex/components/search-box';
21
22
  import { AXSearchBoxModule } from '@acorex/components/search-box';
22
23
  import { AXTabsModule } from '@acorex/components/tabs';
23
24
  import { AXTooltipModule } from '@acorex/components/tooltip';
24
- import * as i10 from '@acorex/core/translation';
25
- import { AXTranslationModule } from '@acorex/core/translation';
25
+ import * as i3$1 from '@acorex/core/translation';
26
+ import { AXTranslationModule, AXTranslationService, translateSync } from '@acorex/core/translation';
26
27
  import * as i2 from '@acorex/core/utils';
27
28
  import { AXUnsubscriber } from '@acorex/core/utils';
28
- import { AXPAuthModule, AXPSessionService, AXPSessionStatus, AXPAuthGuard } from '@acorex/platform/auth';
29
- import { AXPRefreshEvent, AXP_PLATFORM_CONFIG_TOKEN, AXPMenuService, AXPSettingsService, AXPMenuVisibilityService, AXPCommonModule } from '@acorex/platform/common';
30
- import { AXPDeviceService, AXPPlatformScope, AXPBroadcastEventService, AXPContextStore } from '@acorex/platform/core';
31
- import { AXP_ENTITY_CONFIG_TOKEN } from '@acorex/platform/layout/entity';
29
+ import { AXPAuthModule, AXPSessionService, AXPSessionStatus } from '@acorex/platform/auth';
30
+ import { AXPRefreshEvent, AXPSettingsService, AXPCommonSettings, axpIsEntityListRoute, axpReplaceEntityListRouteQueryParams, axpIsEntityListPath, AXP_PLATFORM_CONFIG_TOKEN, AXPMenuService, AXPMenuVisibilityService, AXP_PROTECTED_ROUTE_GUARDS, AXPCommonModule } from '@acorex/platform/common';
31
+ import * as i1$5 from '@acorex/platform/core';
32
+ import { AXPDeviceService, AXHighlightService, AXPGridLayoutDirective, AXPComponentSlotModule, AXPKeyboardShortcutRegistry, AXPKeyboardShortcutPriority, AXPBroadcastEventService, AXPContextStore } from '@acorex/platform/core';
33
+ import { AXP_CATEGORY_TREE_ROOT_TITLE_I18N_KEY, AXPEntityDefinitionRegistryService, AXPCategoryTreeService, AXPEntityListViewColumnViewModel, AXPEntityMasterListCardSelectActionName, applyDataSourcePagingWithoutLoad, getDataSourcePageIndex, restoreEntityListExpandedRows, AXP_ENTITY_CONFIG_TOKEN } from '@acorex/platform/layout/entity';
32
34
  import * as i7$1 from '@acorex/platform/layout/widget-core';
33
- import { AXPWidgetCoreModule } from '@acorex/platform/layout/widget-core';
35
+ import { AXPWidgetCoreModule, AXPWidgetColumnCellComponent } from '@acorex/platform/layout/widget-core';
34
36
  import { AXPWidgetsModule } from '@acorex/platform/layout/widgets';
35
37
  import { AXPLayoutThemeService, AXPThemeLayoutSetting, AXPThemesSharedModule } from '@acorex/platform/themes/shared';
36
38
  import { AXPWorkflowService, ofType } from '@acorex/platform/workflow';
37
39
  import * as i1$1 from '@angular/common';
38
- import { CommonModule } from '@angular/common';
40
+ import { CommonModule, AsyncPipe } from '@angular/common';
39
41
  import * as i0 from '@angular/core';
40
- import { inject, signal, computed, effect, ViewChild, Input, ChangeDetectionStrategy, ViewEncapsulation, Component, NgModule } from '@angular/core';
42
+ import { inject, signal, computed, effect, ViewChild, Input, ChangeDetectionStrategy, ViewEncapsulation, Component, input, viewChild, afterNextRender, output, untracked, DestroyRef, NgModule } from '@angular/core';
41
43
  import { FormsModule } from '@angular/forms';
42
- import * as i1$3 from '@angular/router';
43
- import { RouterModule, Router, NavigationEnd, RouteReuseStrategy, ROUTES } from '@angular/router';
44
+ import * as i1$6 from '@angular/router';
45
+ import { RouterModule, Router, ActivatedRoute, NavigationStart, NavigationEnd, RouteReuseStrategy, ROUTES } from '@angular/router';
44
46
  import { Subject, takeUntil, filter, firstValueFrom } from 'rxjs';
45
- import * as i1$2 from '@acorex/platform/layout/components';
46
- import { AXPComponentSlotModule, AXPTaskBadgeService, AXPMenuBadgeHelper, AXPTaskBadgeDirective, AXPLogoComponent } from '@acorex/platform/layout/components';
47
- import * as i2$2 from '@acorex/components/side-menu';
47
+ import * as i1$4 from '@acorex/core/platform';
48
+ import { AXPThemeLayoutBlockComponent, AXPThemeLayoutHeaderComponent, AXPThemeLayoutToolbarComponent, AXPStateMessageComponent, AXPQueryFiltersComponent, AXPQuerySortsComponent, AXPQueryViewsComponent, AXPQueryColumnsComponent, AXPThemeLayoutStartSideComponent, AXPTaskBadgeService, AXPMenuBadgeHelper, AXPTaskBadgeDirective, AXPLogoComponent } from '@acorex/platform/layout/components';
49
+ import { DragDropModule } from '@angular/cdk/drag-drop';
50
+ import { AXDropdownButtonModule } from '@acorex/components/dropdown-button';
51
+ import { AXPPageLayoutBaseComponent, AXPPageLayoutComponent, AXPPageLayoutBase } from '@acorex/platform/layout/views';
52
+ import * as i2$2 from '@acorex/components/skeleton';
53
+ import { AXSkeletonModule } from '@acorex/components/skeleton';
54
+ import { AXTreeViewModule, AXTreeViewComponent } from '@acorex/components/tree-view';
55
+ import { AXPCommandService } from '@acorex/platform/runtime';
56
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
57
+ import { isEqual, get, sortBy } from 'lodash-es';
58
+ import * as i1$3 from '@acorex/components/data-pager';
59
+ import { AXDataPagerModule } from '@acorex/components/data-pager';
60
+ import * as i3$3 from '@acorex/components/check-box';
61
+ import { AXCheckBoxModule } from '@acorex/components/check-box';
62
+ import * as i2$3 from '@acorex/components/side-menu';
48
63
  import { AXSideMenuModule } from '@acorex/components/side-menu';
49
- import { sortBy } from 'lodash-es';
50
64
  import { AXAvatarModule } from '@acorex/components/avatar';
51
65
  import { AXImageModule } from '@acorex/components/image';
52
- import * as i4$1 from '@acorex/components/menu';
66
+ import * as i4 from '@acorex/components/menu';
53
67
  import { AXMenuModule } from '@acorex/components/menu';
54
68
  import sortBy$1 from 'lodash-es/sortBy';
55
69
  import { AXResizableDirective } from '@acorex/cdk/resizable';
@@ -61,8 +75,8 @@ class AXPEntityDetailListViewComponent {
61
75
  this.workflow = inject(AXPWorkflowService);
62
76
  this.store = inject(AXPLayoutThemeService);
63
77
  this.deviceService = inject(AXPDeviceService);
64
- this.toolbarPrimaryActions = signal([], ...(ngDevMode ? [{ debugName: "toolbarPrimaryActions" }] : []));
65
- this.toolbarSecondaryActions = signal([], ...(ngDevMode ? [{ debugName: "toolbarSecondaryActions" }] : []));
78
+ this.toolbarPrimaryActions = signal([], ...(ngDevMode ? [{ debugName: "toolbarPrimaryActions" }] : /* istanbul ignore next */ []));
79
+ this.toolbarSecondaryActions = signal([], ...(ngDevMode ? [{ debugName: "toolbarSecondaryActions" }] : /* istanbul ignore next */ []));
66
80
  this.destroyed = new Subject();
67
81
  this.dropdownRowItems = computed(() => {
68
82
  return this.vm.secondaryRowActions().map((c) => ({
@@ -71,7 +85,7 @@ class AXPEntityDetailListViewComponent {
71
85
  text: c.title,
72
86
  color: c.color,
73
87
  }));
74
- }, ...(ngDevMode ? [{ debugName: "dropdownRowItems" }] : []));
88
+ }, ...(ngDevMode ? [{ debugName: "dropdownRowItems" }] : /* istanbul ignore next */ []));
75
89
  this.commandRowItems = computed(() => {
76
90
  return this.vm.primaryRowActions().map((c) => {
77
91
  return {
@@ -81,7 +95,7 @@ class AXPEntityDetailListViewComponent {
81
95
  color: c.color,
82
96
  };
83
97
  });
84
- }, ...(ngDevMode ? [{ debugName: "commandRowItems" }] : []));
98
+ }, ...(ngDevMode ? [{ debugName: "commandRowItems" }] : /* istanbul ignore next */ []));
85
99
  this.getCommandRowItems = () => {
86
100
  return this.commandRowItems();
87
101
  };
@@ -147,14 +161,15 @@ class AXPEntityDetailListViewComponent {
147
161
  this.destroyed.complete();
148
162
  }
149
163
  ngOnDestroy() {
164
+ this.vm?.destroy();
150
165
  this.destroy();
151
166
  }
152
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPEntityDetailListViewComponent, deps: [{ token: i1.AXActionSheetService }, { token: i2.AXUnsubscriber }], target: i0.ɵɵFactoryTarget.Component }); }
153
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXPEntityDetailListViewComponent, isStandalone: true, selector: "axp-entity-detail-list-view", inputs: { vm: ["viewModel", "vm"] }, providers: [AXUnsubscriber], viewQueries: [{ propertyName: "grid", first: true, predicate: ["grid"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"ax-flex ax-p-2\">\n <div class=\"ax-flex ax-flex-col ax-items-end ax-gap-3 ax-flex-1 ax-overflow-auto ax-min-h-72\">\n <div class=\"ax-flex ax-justify-between ax-items-center ax-w-full\">\n <div class=\"ax-flex ax-justify-between ax-items-center\">\n <div class=\"ax-flex ax-justify-start ax-items-center ax-gap-4\">\n @if (vm.hasSelectedItems()) {\n <div class=\"ax-flex ax-gap-3 ax-items-center ax-h-10\">\n <span class=\"ax-text-xl ax-font-bold\">\n {{ vm.selectedItems().length }}\n {{ '@general:terms.items-selected' | translate | async }}\n </span>\n <span\n (click)=\"vm.clearSelection()\"\n class=\"ax-text-sm ax-text-primary-500 ax-underline ax-cursor-pointer\"\n >{{ '@general:actions.unselect.title' | translate | async }}</span\n >\n </div>\n } @else {\n @if (vm.hasInlineFilters() && !deviceService.isSmall()) {\n <div class=\"ax-w-72\">\n <ax-search-box\n [placeholder]=\"\n ('@general:widgets.lookup.search' | translate | async) + vm.inlineFiltersPlaceholders().join(', ')\n \"\n (onValueChanged)=\"handleChangeSearchValue($event)\"\n ><ax-clear-button></ax-clear-button\n ></ax-search-box>\n </div>\n }\n }\n </div>\n </div>\n <div class=\"ax-flex ax-items-center ax-gap-3\">\n @for (tr of toolbarPrimaryActions(); track $index) {\n <ax-button\n [text]=\"(tr.title | translate | async)!\"\n [color]=\"tr.color\"\n [disabled]=\"tr.disabled\"\n (onClick)=\"vm.executeCommand(tr.name)\"\n >\n <ax-prefix>\n <ax-icon [icon]=\"tr.icon\"> </ax-icon>\n </ax-prefix>\n </ax-button>\n }\n @if (toolbarSecondaryActions().length) {\n <ax-button\n [text]=\"deviceService.isSmall() ? null : ('@general:terms.interface.actions' | translate | async)\"\n [color]=\"'default'\"\n >\n <ax-prefix>\n <i class=\"fa-solid fa-ellipsis-vertical\"></i>\n </ax-prefix>\n <ax-dropdown-panel>\n <ax-button-item-list>\n @for (tr of toolbarSecondaryActions(); track $index) {\n <ng-container>\n @if (tr.separated && !$first) {\n <ax-divider></ax-divider>\n }\n <ax-button-item\n [text]=\"(tr.title | translate | async)!\"\n class=\"ax-font-semibold ax-text-{{ tr.color }}\"\n (onClick)=\"vm.executeCommand(tr.name)\"\n >\n <ax-prefix>\n <ax-icon [icon]=\"tr.icon\"> </ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ng-container>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n </div>\n </div>\n\n <div class=\"ax-flex ax-flex-1 ax-pt-0 ax-overflow-auto ax-max-w-full\">\n <ax-data-table\n #grid\n [showFooter]=\"false\"\n class=\"ax-flex-1\"\n [paging]=\"true\"\n [fetchDataMode]=\"'manual'\"\n [parentField]=\"vm.parentKey()\"\n [loading]=\"{ enabled: true, animation: true }\"\n [dataSource]=\"vm.dataSource\"\n (selectedRowsChange)=\"handleSelectedRowsChange($event)\"\n (onRowDbClick)=\"handleRowDbClick($event)\"\n >\n <ax-index-column fixed=\"start\" [width]=\"'80px'\" [padZero]=\"true\"></ax-index-column>\n @if (vm.selectedScopeActionsCount()) {\n <ax-select-column fixed=\"start\" [width]=\"'50px'\"></ax-select-column>\n }\n @for (col of vm.columns(); track col.name) {\n @if (col.visible) {\n <axp-widget-column-renderer\n [expandHandler]=\"$index === 0 && vm.parentKey() ? true : false\"\n [caption]=\"(col.title | translate | async)!\"\n [node]=\"col.node()\"\n ></axp-widget-column-renderer>\n }\n }\n @if (getCommandRowItems().length) {\n <ax-command-column\n fixed=\"end\"\n [width]=\"getCommandRowItems().length * 60 + 'px'\"\n [items]=\"getCommandRowItems()\"\n (onItemClick)=\"handleRowCommandClick($event)\"\n ></ax-command-column>\n }\n @if (dropdownRowItems().length) {\n <ax-dropdown-command-column\n fixed=\"end\"\n [width]=\"'60px'\"\n [items]=\"getDropdownRowItems\"\n (onItemClick)=\"handleRowCommandClick($event)\"\n ></ax-dropdown-command-column>\n }\n </ax-data-table>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i3.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i3.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorClearButtonComponent, selector: "ax-clear-button", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "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: AXPopoverModule }, { kind: "ngmodule", type: AXFormModule }, { kind: "ngmodule", type: AXActionSheetModule }, { kind: "ngmodule", type: AXDrawerModule }, { kind: "ngmodule", type: AXDialogModule }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "ngmodule", type: AXTabsModule }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "ngmodule", type: AXBreadcrumbsModule }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i6.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXDataTableModule }, { kind: "component", type: i7.AXDataTableComponent, selector: "ax-data-table", inputs: ["dataSource", "selectedRows", "parentField", "rowDetailsTemplate", "rowTemplate", "emptyTemplate", "noDataTemplate", "alternative", "showHeader", "fixedHeader", "showFooter", "fixedFooter", "itemHeight", "allowReordering", "paging", "fetchDataMode", "loading", "focusedRow"], outputs: ["selectedRowsChange", "focusedRowChange", "onRowClick", "onRowDbClick", "onColumnsOrderChanged", "onColumnSizeChanged", "onPageChanged"] }, { kind: "component", type: i7.AXRowIndexColumnComponent, selector: "ax-index-column", inputs: ["width", "caption", "fixed", "footerTemplate", "padZero"] }, { kind: "component", type: i7.AXRowSelectColumnComponent, selector: "ax-select-column", inputs: ["width", "caption", "fixed"] }, { kind: "component", type: i7.AXRowCommandColumnComponent, selector: "ax-command-column", inputs: ["width", "caption", "fixed", "footerTemplate", "items"], outputs: ["onItemClick"] }, { kind: "component", type: i7.AXRowDropdownCommandColumnComponent, selector: "ax-dropdown-command-column", inputs: ["width", "caption", "fixed", "footerTemplate", "emptyStateTemplate", "emptyStateText", "items"], outputs: ["onItemClick"] }, { kind: "ngmodule", type:
167
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityDetailListViewComponent, deps: [{ token: i1.AXActionSheetService }, { token: i2.AXUnsubscriber }], target: i0.ɵɵFactoryTarget.Component }); }
168
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPEntityDetailListViewComponent, isStandalone: true, selector: "axp-entity-detail-list-view", inputs: { vm: ["viewModel", "vm"] }, providers: [AXUnsubscriber], viewQueries: [{ propertyName: "grid", first: true, predicate: ["grid"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"ax-flex ax-p-2\">\n <div class=\"ax-flex ax-flex-col ax-items-end ax-gap-3 ax-flex-1 ax-overflow-auto ax-min-h-72\">\n <div class=\"ax-flex ax-justify-between ax-items-center ax-w-full\">\n <div class=\"ax-flex ax-justify-between ax-items-center\">\n <div class=\"ax-flex ax-justify-start ax-items-center ax-gap-4\">\n @if (vm.hasSelectedItems()) {\n <div class=\"ax-flex ax-gap-3 ax-items-center ax-h-10\">\n <span class=\"ax-text-xl ax-font-bold\">\n {{ vm.selectedItems().length }}\n {{ '@general:terms.items-selected' | translate | async }}\n </span>\n <span\n (click)=\"vm.clearSelection()\"\n class=\"ax-text-sm ax-text-primary-500 ax-underline ax-cursor-pointer\"\n >{{ '@general:actions.unselect.title' | translate | async }}</span\n >\n </div>\n } @else {\n @if (vm.hasInlineFilters() && !deviceService.isSmall()) {\n <div class=\"ax-w-72\">\n <ax-search-box\n [placeholder]=\"\n ('@general:widgets.lookup.search' | translate | async) + vm.inlineFiltersPlaceholders().join(', ')\n \"\n (onValueChanged)=\"handleChangeSearchValue($event)\"\n ><ax-clear-button></ax-clear-button\n ></ax-search-box>\n </div>\n }\n }\n </div>\n </div>\n <div class=\"ax-flex ax-items-center ax-gap-3\">\n @for (tr of toolbarPrimaryActions(); track $index) {\n <ax-button\n [text]=\"(tr.title | translate | async)!\"\n [color]=\"tr.color\"\n [disabled]=\"tr.disabled\"\n (onClick)=\"vm.executeCommand(tr.name)\"\n >\n <ax-prefix>\n <ax-icon [icon]=\"tr.icon\"> </ax-icon>\n </ax-prefix>\n </ax-button>\n }\n @if (toolbarSecondaryActions().length) {\n <ax-button\n [text]=\"deviceService.isSmall() ? null : ('@general:terms.interface.actions' | translate | async)\"\n [color]=\"'default'\"\n >\n <ax-prefix>\n <i class=\"fa-solid fa-ellipsis-vertical\"></i>\n </ax-prefix>\n <ax-dropdown-panel>\n <ax-button-item-list>\n @for (tr of toolbarSecondaryActions(); track $index) {\n <ng-container>\n @if (tr.separated && !$first) {\n <ax-divider></ax-divider>\n }\n <ax-button-item\n [text]=\"(tr.title | translate | async)!\"\n class=\"ax-font-semibold ax-text-{{ tr.color }}\"\n (onClick)=\"vm.executeCommand(tr.name)\"\n >\n <ax-prefix>\n <ax-icon [icon]=\"tr.icon\"> </ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ng-container>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n </div>\n </div>\n\n <div class=\"ax-flex ax-flex-1 ax-pt-0 ax-overflow-auto ax-max-w-full\">\n <ax-data-table\n #grid\n [showFooter]=\"false\"\n class=\"ax-flex-1\"\n [paging]=\"true\"\n [fetchDataMode]=\"'manual'\"\n [parentField]=\"vm.parentKey()\"\n [loading]=\"{ enabled: true, animation: true }\"\n [dataSource]=\"vm.dataSource\"\n (selectedRowsChange)=\"handleSelectedRowsChange($event)\"\n (onRowDbClick)=\"handleRowDbClick($event)\"\n >\n @if (vm.showIndexColumn()) {\n <ax-index-column\n [caption]=\"('@general:terms.common.row-number' | translate | async)!\"\n fixed=\"start\"\n [width]=\"'80px'\"\n [padZero]=\"false\"\n ></ax-index-column>\n }\n @if (vm.selectedScopeActionsCount()) {\n <ax-select-column fixed=\"start\" [width]=\"'50px'\"></ax-select-column>\n }\n @for (col of vm.columns(); track col.name) {\n @if (col.visible) {\n <axp-widget-column-renderer\n [expandHandler]=\"$index === 0 && vm.parentKey() ? true : false\"\n [caption]=\"(col.title | translate | async)!\"\n [node]=\"col.node()\"\n ></axp-widget-column-renderer>\n }\n }\n @if (getCommandRowItems().length) {\n <ax-command-column\n fixed=\"end\"\n [width]=\"getCommandRowItems().length * 60 + 'px'\"\n [items]=\"getCommandRowItems()\"\n (onItemClick)=\"handleRowCommandClick($event)\"\n ></ax-command-column>\n }\n @if (dropdownRowItems().length) {\n <ax-dropdown-command-column\n fixed=\"end\"\n [width]=\"'60px'\"\n [items]=\"getDropdownRowItems\"\n (onItemClick)=\"handleRowCommandClick($event)\"\n ></ax-dropdown-command-column>\n }\n </ax-data-table>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i3.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i3.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorClearButtonComponent, selector: "ax-clear-button", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "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: AXPopoverModule }, { kind: "ngmodule", type: AXFormModule }, { kind: "ngmodule", type: AXActionSheetModule }, { kind: "ngmodule", type: AXDrawerModule }, { kind: "ngmodule", type: AXDialogModule }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "ngmodule", type: AXTabsModule }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "ngmodule", type: AXBreadcrumbsModule }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i6.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXDataTableModule }, { kind: "component", type: i7.AXDataTableComponent, selector: "ax-data-table", inputs: ["dataSource", "selectedRows", "parentField", "hasChildrenField", "rowDetailsTemplate", "look", "rowTemplate", "emptyTemplate", "noDataTemplate", "alternative", "showHeader", "fixedHeader", "showFooter", "fixedFooter", "itemHeight", "allowReordering", "paging", "fetchDataMode", "loading", "focusedRow"], outputs: ["selectedRowsChange", "focusedRowChange", "onRowClick", "onRowDbClick", "onColumnsOrderChanged", "onColumnSizeChanged", "onPageChanged"] }, { kind: "component", type: i7.AXRowIndexColumnComponent, selector: "ax-index-column", inputs: ["width", "caption", "fixed", "footerTemplate", "padZero"] }, { kind: "component", type: i7.AXRowSelectColumnComponent, selector: "ax-select-column", inputs: ["width", "caption", "fixed"] }, { kind: "component", type: i7.AXRowCommandColumnComponent, selector: "ax-command-column", inputs: ["width", "caption", "fixed", "footerTemplate", "items"], outputs: ["onItemClick"] }, { kind: "component", type: i7.AXRowDropdownCommandColumnComponent, selector: "ax-dropdown-command-column", inputs: ["width", "caption", "fixed", "footerTemplate", "emptyStateTemplate", "emptyStateText", "items"], outputs: ["onItemClick"] }, { kind: "ngmodule", type:
154
169
  //
155
- AXPWidgetCoreModule }, { kind: "component", type: i7$1.AXPWidgetColumnRendererComponent, selector: "axp-widget-column-renderer", inputs: ["caption", "customExpandIcon", "customCollapseIcon", "customWidth", "node", "footerTemplate", "expandHandler", "cellTemplate", "headerTemplate"] }, { kind: "ngmodule", type: AXPWidgetsModule }, { kind: "ngmodule", type: AXPAuthModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i10.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
170
+ AXPWidgetCoreModule }, { kind: "component", type: i7$1.AXPWidgetColumnRendererComponent, selector: "axp-widget-column-renderer", inputs: ["caption", "customExpandIcon", "customCollapseIcon", "customWidth", "node", "footerTemplate", "expandHandler", "sortEnabled", "headerSortDirection", "headerSortPriority", "columnFixed", "cellTemplate", "headerTemplate"], outputs: ["sortToggle"] }, { kind: "ngmodule", type: AXPWidgetsModule }, { kind: "ngmodule", type: AXPAuthModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
156
171
  }
157
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPEntityDetailListViewComponent, decorators: [{
172
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityDetailListViewComponent, decorators: [{
158
173
  type: Component,
159
174
  args: [{ selector: 'axp-entity-detail-list-view', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [AXUnsubscriber], imports: [
160
175
  CommonModule,
@@ -180,7 +195,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
180
195
  AXPWidgetsModule,
181
196
  AXPAuthModule,
182
197
  AXTranslationModule,
183
- ], template: "<div class=\"ax-flex ax-p-2\">\n <div class=\"ax-flex ax-flex-col ax-items-end ax-gap-3 ax-flex-1 ax-overflow-auto ax-min-h-72\">\n <div class=\"ax-flex ax-justify-between ax-items-center ax-w-full\">\n <div class=\"ax-flex ax-justify-between ax-items-center\">\n <div class=\"ax-flex ax-justify-start ax-items-center ax-gap-4\">\n @if (vm.hasSelectedItems()) {\n <div class=\"ax-flex ax-gap-3 ax-items-center ax-h-10\">\n <span class=\"ax-text-xl ax-font-bold\">\n {{ vm.selectedItems().length }}\n {{ '@general:terms.items-selected' | translate | async }}\n </span>\n <span\n (click)=\"vm.clearSelection()\"\n class=\"ax-text-sm ax-text-primary-500 ax-underline ax-cursor-pointer\"\n >{{ '@general:actions.unselect.title' | translate | async }}</span\n >\n </div>\n } @else {\n @if (vm.hasInlineFilters() && !deviceService.isSmall()) {\n <div class=\"ax-w-72\">\n <ax-search-box\n [placeholder]=\"\n ('@general:widgets.lookup.search' | translate | async) + vm.inlineFiltersPlaceholders().join(', ')\n \"\n (onValueChanged)=\"handleChangeSearchValue($event)\"\n ><ax-clear-button></ax-clear-button\n ></ax-search-box>\n </div>\n }\n }\n </div>\n </div>\n <div class=\"ax-flex ax-items-center ax-gap-3\">\n @for (tr of toolbarPrimaryActions(); track $index) {\n <ax-button\n [text]=\"(tr.title | translate | async)!\"\n [color]=\"tr.color\"\n [disabled]=\"tr.disabled\"\n (onClick)=\"vm.executeCommand(tr.name)\"\n >\n <ax-prefix>\n <ax-icon [icon]=\"tr.icon\"> </ax-icon>\n </ax-prefix>\n </ax-button>\n }\n @if (toolbarSecondaryActions().length) {\n <ax-button\n [text]=\"deviceService.isSmall() ? null : ('@general:terms.interface.actions' | translate | async)\"\n [color]=\"'default'\"\n >\n <ax-prefix>\n <i class=\"fa-solid fa-ellipsis-vertical\"></i>\n </ax-prefix>\n <ax-dropdown-panel>\n <ax-button-item-list>\n @for (tr of toolbarSecondaryActions(); track $index) {\n <ng-container>\n @if (tr.separated && !$first) {\n <ax-divider></ax-divider>\n }\n <ax-button-item\n [text]=\"(tr.title | translate | async)!\"\n class=\"ax-font-semibold ax-text-{{ tr.color }}\"\n (onClick)=\"vm.executeCommand(tr.name)\"\n >\n <ax-prefix>\n <ax-icon [icon]=\"tr.icon\"> </ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ng-container>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n </div>\n </div>\n\n <div class=\"ax-flex ax-flex-1 ax-pt-0 ax-overflow-auto ax-max-w-full\">\n <ax-data-table\n #grid\n [showFooter]=\"false\"\n class=\"ax-flex-1\"\n [paging]=\"true\"\n [fetchDataMode]=\"'manual'\"\n [parentField]=\"vm.parentKey()\"\n [loading]=\"{ enabled: true, animation: true }\"\n [dataSource]=\"vm.dataSource\"\n (selectedRowsChange)=\"handleSelectedRowsChange($event)\"\n (onRowDbClick)=\"handleRowDbClick($event)\"\n >\n <ax-index-column fixed=\"start\" [width]=\"'80px'\" [padZero]=\"true\"></ax-index-column>\n @if (vm.selectedScopeActionsCount()) {\n <ax-select-column fixed=\"start\" [width]=\"'50px'\"></ax-select-column>\n }\n @for (col of vm.columns(); track col.name) {\n @if (col.visible) {\n <axp-widget-column-renderer\n [expandHandler]=\"$index === 0 && vm.parentKey() ? true : false\"\n [caption]=\"(col.title | translate | async)!\"\n [node]=\"col.node()\"\n ></axp-widget-column-renderer>\n }\n }\n @if (getCommandRowItems().length) {\n <ax-command-column\n fixed=\"end\"\n [width]=\"getCommandRowItems().length * 60 + 'px'\"\n [items]=\"getCommandRowItems()\"\n (onItemClick)=\"handleRowCommandClick($event)\"\n ></ax-command-column>\n }\n @if (dropdownRowItems().length) {\n <ax-dropdown-command-column\n fixed=\"end\"\n [width]=\"'60px'\"\n [items]=\"getDropdownRowItems\"\n (onItemClick)=\"handleRowCommandClick($event)\"\n ></ax-dropdown-command-column>\n }\n </ax-data-table>\n </div>\n </div>\n</div>\n" }]
198
+ ], template: "<div class=\"ax-flex ax-p-2\">\n <div class=\"ax-flex ax-flex-col ax-items-end ax-gap-3 ax-flex-1 ax-overflow-auto ax-min-h-72\">\n <div class=\"ax-flex ax-justify-between ax-items-center ax-w-full\">\n <div class=\"ax-flex ax-justify-between ax-items-center\">\n <div class=\"ax-flex ax-justify-start ax-items-center ax-gap-4\">\n @if (vm.hasSelectedItems()) {\n <div class=\"ax-flex ax-gap-3 ax-items-center ax-h-10\">\n <span class=\"ax-text-xl ax-font-bold\">\n {{ vm.selectedItems().length }}\n {{ '@general:terms.items-selected' | translate | async }}\n </span>\n <span\n (click)=\"vm.clearSelection()\"\n class=\"ax-text-sm ax-text-primary-500 ax-underline ax-cursor-pointer\"\n >{{ '@general:actions.unselect.title' | translate | async }}</span\n >\n </div>\n } @else {\n @if (vm.hasInlineFilters() && !deviceService.isSmall()) {\n <div class=\"ax-w-72\">\n <ax-search-box\n [placeholder]=\"\n ('@general:widgets.lookup.search' | translate | async) + vm.inlineFiltersPlaceholders().join(', ')\n \"\n (onValueChanged)=\"handleChangeSearchValue($event)\"\n ><ax-clear-button></ax-clear-button\n ></ax-search-box>\n </div>\n }\n }\n </div>\n </div>\n <div class=\"ax-flex ax-items-center ax-gap-3\">\n @for (tr of toolbarPrimaryActions(); track $index) {\n <ax-button\n [text]=\"(tr.title | translate | async)!\"\n [color]=\"tr.color\"\n [disabled]=\"tr.disabled\"\n (onClick)=\"vm.executeCommand(tr.name)\"\n >\n <ax-prefix>\n <ax-icon [icon]=\"tr.icon\"> </ax-icon>\n </ax-prefix>\n </ax-button>\n }\n @if (toolbarSecondaryActions().length) {\n <ax-button\n [text]=\"deviceService.isSmall() ? null : ('@general:terms.interface.actions' | translate | async)\"\n [color]=\"'default'\"\n >\n <ax-prefix>\n <i class=\"fa-solid fa-ellipsis-vertical\"></i>\n </ax-prefix>\n <ax-dropdown-panel>\n <ax-button-item-list>\n @for (tr of toolbarSecondaryActions(); track $index) {\n <ng-container>\n @if (tr.separated && !$first) {\n <ax-divider></ax-divider>\n }\n <ax-button-item\n [text]=\"(tr.title | translate | async)!\"\n class=\"ax-font-semibold ax-text-{{ tr.color }}\"\n (onClick)=\"vm.executeCommand(tr.name)\"\n >\n <ax-prefix>\n <ax-icon [icon]=\"tr.icon\"> </ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ng-container>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n </div>\n </div>\n\n <div class=\"ax-flex ax-flex-1 ax-pt-0 ax-overflow-auto ax-max-w-full\">\n <ax-data-table\n #grid\n [showFooter]=\"false\"\n class=\"ax-flex-1\"\n [paging]=\"true\"\n [fetchDataMode]=\"'manual'\"\n [parentField]=\"vm.parentKey()\"\n [loading]=\"{ enabled: true, animation: true }\"\n [dataSource]=\"vm.dataSource\"\n (selectedRowsChange)=\"handleSelectedRowsChange($event)\"\n (onRowDbClick)=\"handleRowDbClick($event)\"\n >\n @if (vm.showIndexColumn()) {\n <ax-index-column\n [caption]=\"('@general:terms.common.row-number' | translate | async)!\"\n fixed=\"start\"\n [width]=\"'80px'\"\n [padZero]=\"false\"\n ></ax-index-column>\n }\n @if (vm.selectedScopeActionsCount()) {\n <ax-select-column fixed=\"start\" [width]=\"'50px'\"></ax-select-column>\n }\n @for (col of vm.columns(); track col.name) {\n @if (col.visible) {\n <axp-widget-column-renderer\n [expandHandler]=\"$index === 0 && vm.parentKey() ? true : false\"\n [caption]=\"(col.title | translate | async)!\"\n [node]=\"col.node()\"\n ></axp-widget-column-renderer>\n }\n }\n @if (getCommandRowItems().length) {\n <ax-command-column\n fixed=\"end\"\n [width]=\"getCommandRowItems().length * 60 + 'px'\"\n [items]=\"getCommandRowItems()\"\n (onItemClick)=\"handleRowCommandClick($event)\"\n ></ax-command-column>\n }\n @if (dropdownRowItems().length) {\n <ax-dropdown-command-column\n fixed=\"end\"\n [width]=\"'60px'\"\n [items]=\"getDropdownRowItems\"\n (onItemClick)=\"handleRowCommandClick($event)\"\n ></ax-dropdown-command-column>\n }\n </ax-data-table>\n </div>\n </div>\n</div>\n" }]
184
199
  }], ctorParameters: () => [{ type: i1.AXActionSheetService }, { type: i2.AXUnsubscriber }], propDecorators: { vm: [{
185
200
  type: Input,
186
201
  args: ['viewModel']
@@ -189,13 +204,2165 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
189
204
  args: ['grid', { static: true }]
190
205
  }] } });
191
206
 
207
+ //#region ---- Constants ----
208
+ const ROOT_NODE_ID = 'all';
209
+ const LOADING_DELAY_MS = 300;
210
+ const DEFAULT_TEXT_FIELD = 'title';
211
+ const DEFAULT_VALUE_FIELD = 'id';
212
+ //#endregion
213
+ class AXPEntityCategoryComponent {
214
+ //#endregion
215
+ //#region ---- Constructor & Lifecycle ----
216
+ constructor() {
217
+ //#region ---- Services & Dependencies ----
218
+ /** i18n key for the synthetic "all items" root row; resolved in the template with the translate pipe. */
219
+ this.categoryTreeRootTitleI18nKey = AXP_CATEGORY_TREE_ROOT_TITLE_I18N_KEY;
220
+ this.translate = inject(AXTranslationService);
221
+ this.workflow = inject(AXPWorkflowService);
222
+ this.commandService = inject(AXPCommandService);
223
+ this.entityRegistry = inject(AXPEntityDefinitionRegistryService);
224
+ this.categoryTreeService = inject(AXPCategoryTreeService);
225
+ this.highlightService = inject(AXHighlightService);
226
+ //#endregion
227
+ //#region ---- Component Inputs & View Queries ----
228
+ this.vm = input.required(...(ngDevMode ? [{ debugName: "vm" }] : /* istanbul ignore next */ []));
229
+ this.tree = viewChild('tree', ...(ngDevMode ? [{ debugName: "tree" }] : /* istanbul ignore next */ []));
230
+ this.searchValue = input('', ...(ngDevMode ? [{ debugName: "searchValue" }] : /* istanbul ignore next */ []));
231
+ // Tree view inputs with defaults
232
+ this.selectMode = input('single', ...(ngDevMode ? [{ debugName: "selectMode" }] : /* istanbul ignore next */ []));
233
+ this.selectionBehavior = input('intermediate', ...(ngDevMode ? [{ debugName: "selectionBehavior" }] : /* istanbul ignore next */ []));
234
+ this.dragArea = input('handler', ...(ngDevMode ? [{ debugName: "dragArea" }] : /* istanbul ignore next */ []));
235
+ this.dragBehavior = input('none', ...(ngDevMode ? [{ debugName: "dragBehavior" }] : /* istanbul ignore next */ []));
236
+ this.showIcons = input(true, ...(ngDevMode ? [{ debugName: "showIcons" }] : /* istanbul ignore next */ []));
237
+ this.showChildrenBadge = input(false, ...(ngDevMode ? [{ debugName: "showChildrenBadge" }] : /* istanbul ignore next */ []));
238
+ this.expandedIcon = input('fa-solid fa-chevron-down', ...(ngDevMode ? [{ debugName: "expandedIcon" }] : /* istanbul ignore next */ []));
239
+ this.collapsedIcon = input('fa-solid fa-chevron-right', ...(ngDevMode ? [{ debugName: "collapsedIcon" }] : /* istanbul ignore next */ []));
240
+ this.indentSize = input(16, ...(ngDevMode ? [{ debugName: "indentSize" }] : /* istanbul ignore next */ []));
241
+ this.look = input('default', ...(ngDevMode ? [{ debugName: "look" }] : /* istanbul ignore next */ []));
242
+ this.searchWithChildren = input(true, ...(ngDevMode ? [{ debugName: "searchWithChildren" }] : /* istanbul ignore next */ [])); // Include children of search results
243
+ //#endregion
244
+ //#region ---- Component State ----
245
+ this.isLoading = signal(true, ...(ngDevMode ? [{ debugName: "isLoading" }] : /* istanbul ignore next */ []));
246
+ this.isSearching = signal(false, ...(ngDevMode ? [{ debugName: "isSearching" }] : /* istanbul ignore next */ []));
247
+ this.searchResultCount = signal(0, ...(ngDevMode ? [{ debugName: "searchResultCount" }] : /* istanbul ignore next */ []));
248
+ this.currentSearchValue = signal('', ...(ngDevMode ? [{ debugName: "currentSearchValue" }] : /* istanbul ignore next */ []));
249
+ this.resultsFoundText = signal('', ...(ngDevMode ? [{ debugName: "resultsFoundText" }] : /* istanbul ignore next */ []));
250
+ //#endregion
251
+ //#region ---- Private Properties ----
252
+ this.loadingTimeoutId = null;
253
+ this.treeData = null;
254
+ this.treeConfig = null;
255
+ this.matchingNodeIds = new Set();
256
+ this.relevantNodeIds = new Set(); // For search filtering
257
+ this.nodeDataCache = new Map(); // Cache parent data from search results
258
+ this.expandedNodesBeforeSearch = [];
259
+ this.nodesExpandedDuringSearch = [];
260
+ this.currentSearchTerm = null;
261
+ //#endregion
262
+ //#region ---- Computed Properties ----
263
+ this.textField = computed(() => this.vm().entityDef.category?.textField || DEFAULT_TEXT_FIELD, ...(ngDevMode ? [{ debugName: "textField" }] : /* istanbul ignore next */ []));
264
+ this.valueField = computed(() => this.vm().entityDef.category?.valueField || DEFAULT_VALUE_FIELD, ...(ngDevMode ? [{ debugName: "valueField" }] : /* istanbul ignore next */ []));
265
+ /** When true, add/edit/delete category actions are hidden (from category plugin readonly option). */
266
+ this.categoryReadonly = computed(() => this.vm().entityDef?.extensions?.category?.readonly === true, ...(ngDevMode ? [{ debugName: "categoryReadonly" }] : /* istanbul ignore next */ []));
267
+ /**
268
+ * Computed property to check if we should show the "no search results" empty state.
269
+ * Returns true when search is active, not searching, and no results found.
270
+ */
271
+ this.showNoSearchResults = computed(() => {
272
+ const searchValue = this.currentSearchValue().trim();
273
+ const isSearching = this.isSearching();
274
+ const resultCount = this.searchResultCount();
275
+ return searchValue.length > 0 && !isSearching && resultCount === 0;
276
+ }, ...(ngDevMode ? [{ debugName: "showNoSearchResults" }] : /* istanbul ignore next */ []));
277
+ this.categoryEntityKey = computed(() => {
278
+ const key = this.vm().entityDef.category?.entity;
279
+ if (!key) {
280
+ throw new Error('Category entity is not configured');
281
+ }
282
+ return key;
283
+ }, ...(ngDevMode ? [{ debugName: "categoryEntityKey" }] : /* istanbul ignore next */ []));
284
+ // protected toggleExpand(e: AXTreeViewNodeDoubleClickEvent) {
285
+ // (e.component as AXTreeViewComponent).toggleNodeExpansion(String(e.node[this.valueField()] ?? ''));
286
+ // }
287
+ //#endregion
288
+ //#region ---- Tree Data Source ----
289
+ /**
290
+ * Datasource callback for tree-view component.
291
+ * Provides lazy loading support for tree nodes.
292
+ */
293
+ this.datasource = async (parentId) => {
294
+ if (!this.isTreeInitialized()) {
295
+ return [];
296
+ }
297
+ // Load root nodes if no parent ID provided
298
+ if (!parentId) {
299
+ return await this.loadRootNodes();
300
+ }
301
+ // Load children for the specified parent
302
+ return await this.loadChildNodes(parentId);
303
+ };
304
+ afterNextRender(() => {
305
+ this.initializeTree();
306
+ });
307
+ this.workflow.events$
308
+ .pipe(ofType(AXPRefreshEvent))
309
+ .pipe(takeUntilDestroyed())
310
+ .subscribe((event) => {
311
+ this.tree()?.reloadData();
312
+ // this.tree()?.refresh();
313
+ });
314
+ }
315
+ //#endregion
316
+ //#region ---- Public Methods ----
317
+ /**
318
+ * Handles category search input changes - Uses server-side search for efficiency and reliability
319
+ */
320
+ async handleCategorySearchChange(event) {
321
+ if (!this.isTreeInitialized()) {
322
+ return;
323
+ }
324
+ const searchTerm = (event.value ?? '').trim().toLowerCase();
325
+ const previousSearchTerm = this.currentSearchValue();
326
+ // If search is cleared, reset tree
327
+ if (!searchTerm) {
328
+ if (previousSearchTerm || this.matchingNodeIds.size > 0) {
329
+ this.currentSearchValue.set('');
330
+ this.currentSearchTerm = null;
331
+ await this.resetSearch();
332
+ }
333
+ return;
334
+ }
335
+ // For non-empty search, only process user interactions
336
+ if (!event.isUserInteraction) {
337
+ return;
338
+ }
339
+ // Prevent concurrent searches
340
+ if (this.isSearching() && this.currentSearchTerm !== null) {
341
+ if (this.currentSearchTerm === searchTerm) {
342
+ return;
343
+ }
344
+ }
345
+ this.currentSearchValue.set(event.value ?? '');
346
+ this.currentSearchTerm = searchTerm;
347
+ const treeComponent = this.tree();
348
+ if (!treeComponent) {
349
+ return;
350
+ }
351
+ // Store expanded nodes before starting a new search (only on first search)
352
+ if (!previousSearchTerm && this.expandedNodesBeforeSearch.length === 0) {
353
+ const expandedNodes = treeComponent.getExpandedNodes();
354
+ this.expandedNodesBeforeSearch = expandedNodes
355
+ .map((node) => String(node['id'] ?? ''))
356
+ .filter((id) => id && id !== ROOT_NODE_ID);
357
+ }
358
+ // Collapse nodes from previous search before starting new search
359
+ if (previousSearchTerm && this.nodesExpandedDuringSearch.length > 0) {
360
+ const nodesToCollapse = [...this.nodesExpandedDuringSearch].reverse();
361
+ this.nodesExpandedDuringSearch = [];
362
+ for (const nodeId of nodesToCollapse) {
363
+ // Only collapse if it wasn't originally expanded before search
364
+ if (!this.expandedNodesBeforeSearch.includes(nodeId)) {
365
+ try {
366
+ treeComponent.collapseNode(nodeId);
367
+ }
368
+ catch {
369
+ // Node might not exist anymore, ignore
370
+ }
371
+ }
372
+ }
373
+ }
374
+ this.isSearching.set(true);
375
+ try {
376
+ // Step 1: Use server-side search to get matching items
377
+ const searchResults = await this.categoryTreeService.searchCategories(searchTerm, this.treeData, this.treeConfig);
378
+ // Check if search term changed during the API call
379
+ if (this.currentSearchTerm !== searchTerm) {
380
+ return;
381
+ }
382
+ if (!searchResults || searchResults.length === 0) {
383
+ this.matchingNodeIds.clear();
384
+ this.relevantNodeIds.clear();
385
+ this.searchResultCount.set(0);
386
+ await this.updateTranslatedMessages(0);
387
+ // Clear highlighting and reload tree to show all nodes
388
+ this.highlightService.clear();
389
+ await treeComponent.reloadData();
390
+ return;
391
+ }
392
+ // Store matching node IDs from search results
393
+ this.matchingNodeIds.clear();
394
+ const valueField = this.valueField();
395
+ searchResults.forEach((item) => {
396
+ const nodeId = String(item[valueField] ?? '');
397
+ if (nodeId) {
398
+ this.matchingNodeIds.add(nodeId);
399
+ }
400
+ });
401
+ const resultCount = searchResults.length;
402
+ this.searchResultCount.set(resultCount);
403
+ // Update translated messages
404
+ await this.updateTranslatedMessages(resultCount);
405
+ // Step 2: Collect parent IDs (builds relevantNodeIds for filtering)
406
+ const parentsToExpand = await this.collectParentIds(searchResults);
407
+ // Step 2.5: Collect children IDs if searchWithChildren is enabled
408
+ if (this.searchWithChildren()) {
409
+ await this.collectChildrenIds(searchResults);
410
+ }
411
+ // Step 3: Reload tree to apply filtering
412
+ await treeComponent.reloadData();
413
+ // Step 4: Expand root node
414
+ if (!treeComponent.isNodeExpanded(ROOT_NODE_ID)) {
415
+ try {
416
+ await treeComponent.expandNode(ROOT_NODE_ID);
417
+ this.nodesExpandedDuringSearch.push(ROOT_NODE_ID);
418
+ }
419
+ catch {
420
+ // Root might not exist
421
+ }
422
+ }
423
+ // Step 4: Expand all parent nodes in order (from root to leaves)
424
+ // Sort parents by their depth to expand in correct order
425
+ const sortedParents = await this.sortParentsByDepth(Array.from(parentsToExpand));
426
+ for (const parentId of sortedParents) {
427
+ // Only expand if not already expanded
428
+ if (!treeComponent.isNodeExpanded(parentId)) {
429
+ try {
430
+ await treeComponent.expandNode(parentId);
431
+ this.nodesExpandedDuringSearch.push(parentId);
432
+ // Small delay to prevent overwhelming the tree component
433
+ await new Promise((resolve) => setTimeout(resolve, 10));
434
+ }
435
+ catch {
436
+ // Node might not exist, ignore
437
+ }
438
+ }
439
+ }
440
+ // Step 5: Apply highlighting after tree is rendered
441
+ // Use setTimeout to ensure DOM is updated after tree reload
442
+ setTimeout(() => {
443
+ if (this.currentSearchValue().trim()) {
444
+ this.highlightService.highlight('ax-tree-view .ax-truncate', this.currentSearchValue().trim());
445
+ }
446
+ }, 100);
447
+ }
448
+ catch (error) {
449
+ console.error('Error searching categories:', error);
450
+ this.matchingNodeIds.clear();
451
+ this.relevantNodeIds.clear();
452
+ this.searchResultCount.set(0);
453
+ this.highlightService.clear();
454
+ // Reload tree to clear any filters
455
+ const treeComponent = this.tree();
456
+ if (treeComponent) {
457
+ await treeComponent.reloadData();
458
+ }
459
+ }
460
+ finally {
461
+ if (this.currentSearchTerm === searchTerm) {
462
+ this.currentSearchTerm = null;
463
+ }
464
+ this.isSearching.set(false);
465
+ }
466
+ }
467
+ /**
468
+ * Collects all parent IDs for the given search results
469
+ * Handles both nested 'parent' object and 'parentId' field in search results
470
+ * Recursively fetches parent nodes to build the full parent chain
471
+ */
472
+ async collectParentIds(items) {
473
+ const parentsToExpand = new Set();
474
+ const valueField = this.valueField();
475
+ const parentKey = this.treeData?.categoryEntityDef?.parentKey || 'parentId';
476
+ // Build relevantNodeIds = matching nodes + all parents
477
+ this.relevantNodeIds.clear();
478
+ this.matchingNodeIds.forEach((id) => this.relevantNodeIds.add(id));
479
+ // Recursively extract all parent IDs
480
+ const extractParentIds = async (item) => {
481
+ // First, try to get parent from nested 'parent' object (if available)
482
+ const parent = item['parent'];
483
+ if (parent) {
484
+ const parentId = String(parent[valueField] ?? parent['id'] ?? '');
485
+ if (parentId && parentId !== ROOT_NODE_ID) {
486
+ parentsToExpand.add(parentId);
487
+ this.relevantNodeIds.add(parentId); // Add to filter set
488
+ this.nodeDataCache.set(parentId, parent);
489
+ await extractParentIds(parent);
490
+ }
491
+ }
492
+ else {
493
+ // Fallback: use parentId field and fetch parent from server
494
+ // Try both parentKey from entity definition and common 'parentId' field
495
+ const parentIdValue = item[parentKey] ?? item['parentId'];
496
+ if (parentIdValue) {
497
+ const parentId = String(parentIdValue);
498
+ if (parentId && parentId !== ROOT_NODE_ID) {
499
+ // Add to sets first
500
+ parentsToExpand.add(parentId);
501
+ this.relevantNodeIds.add(parentId);
502
+ // Fetch parent from server if not already cached
503
+ if (!this.nodeDataCache.has(parentId)) {
504
+ const parentItem = await this.fetchItemById(parentId);
505
+ if (parentItem) {
506
+ this.nodeDataCache.set(parentId, parentItem);
507
+ // Recursively fetch parent's parent
508
+ await extractParentIds(parentItem);
509
+ }
510
+ }
511
+ else {
512
+ // Parent already in cache, recursively process it
513
+ const cachedParent = this.nodeDataCache.get(parentId);
514
+ if (cachedParent) {
515
+ await extractParentIds(cachedParent);
516
+ }
517
+ }
518
+ }
519
+ }
520
+ }
521
+ };
522
+ // Process all items
523
+ for (const item of items) {
524
+ await extractParentIds(item);
525
+ }
526
+ return parentsToExpand;
527
+ }
528
+ /**
529
+ * Collects children IDs for matching search results recursively
530
+ * Adds all descendants (children, grandchildren, etc.) to relevantNodeIds so they appear in the filtered tree
531
+ */
532
+ async collectChildrenIds(items) {
533
+ if (!this.treeData?.categoryEntityQueryFunc || !this.treeConfig) {
534
+ return;
535
+ }
536
+ const valueField = this.valueField();
537
+ const parentKey = this.treeData.categoryEntityDef?.parentKey;
538
+ if (!parentKey) {
539
+ return;
540
+ }
541
+ // For each matching node, recursively fetch all its descendants
542
+ for (const item of items) {
543
+ const nodeId = String(item[valueField] ?? '');
544
+ if (!nodeId || nodeId === ROOT_NODE_ID) {
545
+ continue;
546
+ }
547
+ await this.collectChildrenRecursively(nodeId, valueField, parentKey);
548
+ }
549
+ }
550
+ /**
551
+ * Recursively collects all descendant IDs for a given node
552
+ */
553
+ async collectChildrenRecursively(nodeId, valueField, parentKey) {
554
+ if (!this.treeData?.categoryEntityQueryFunc) {
555
+ return;
556
+ }
557
+ try {
558
+ // Fetch children for this node
559
+ const event = {
560
+ ...this.treeData.basicQueryEvent,
561
+ filter: {
562
+ field: parentKey,
563
+ value: nodeId,
564
+ operator: { type: 'equal' },
565
+ },
566
+ };
567
+ const res = await this.treeData.categoryEntityQueryFunc(event);
568
+ if (res?.items && res.items.length > 0) {
569
+ // Add children IDs to relevantNodeIds so they appear in filtered tree
570
+ for (const child of res.items) {
571
+ const childId = String(child[valueField] ?? '');
572
+ if (childId && childId !== ROOT_NODE_ID) {
573
+ this.relevantNodeIds.add(childId);
574
+ // Cache child data
575
+ this.nodeDataCache.set(childId, child);
576
+ // Recursively fetch children of this child
577
+ await this.collectChildrenRecursively(childId, valueField, parentKey);
578
+ }
579
+ }
580
+ }
581
+ }
582
+ catch (error) {
583
+ console.error(`Error fetching children for node ${nodeId}:`, error);
584
+ }
585
+ }
586
+ /**
587
+ * Fetches a single item by ID from the server
588
+ */
589
+ async fetchItemById(id) {
590
+ if (!this.treeData?.categoryEntityQueryFunc) {
591
+ return null;
592
+ }
593
+ try {
594
+ const valueField = this.valueField();
595
+ const event = {
596
+ ...this.treeData.basicQueryEvent,
597
+ filter: {
598
+ field: valueField,
599
+ value: id,
600
+ operator: { type: 'equal' },
601
+ },
602
+ };
603
+ const res = await this.treeData.categoryEntityQueryFunc(event);
604
+ return res?.items?.[0] ?? null;
605
+ }
606
+ catch (error) {
607
+ console.error('Error fetching item by ID:', error);
608
+ return null;
609
+ }
610
+ }
611
+ /**
612
+ * Sorts parent IDs by their depth (root first, leaves last)
613
+ * Uses cached data from collectParentIds
614
+ */
615
+ async sortParentsByDepth(parentIds) {
616
+ const parentKey = this.treeData?.categoryEntityDef?.parentKey;
617
+ if (!parentKey || parentIds.length === 0) {
618
+ return parentIds;
619
+ }
620
+ // Build depth map using cached data
621
+ const depthMap = new Map();
622
+ for (const parentId of parentIds) {
623
+ if (depthMap.has(parentId)) {
624
+ continue;
625
+ }
626
+ let depth = 0;
627
+ let currentId = parentId;
628
+ const visited = new Set();
629
+ while (currentId && currentId !== ROOT_NODE_ID && !visited.has(currentId)) {
630
+ visited.add(currentId);
631
+ depth++;
632
+ // Use nodeDataCache which was populated by collectParentIds
633
+ const item = this.nodeDataCache.get(currentId);
634
+ if (item) {
635
+ currentId = item[parentKey] ? String(item[parentKey]) : null;
636
+ }
637
+ else {
638
+ break;
639
+ }
640
+ }
641
+ depthMap.set(parentId, depth);
642
+ }
643
+ // Sort by depth (lower depth = closer to root = expand first)
644
+ return parentIds.sort((a, b) => {
645
+ const depthA = depthMap.get(a) ?? 0;
646
+ const depthB = depthMap.get(b) ?? 0;
647
+ return depthA - depthB;
648
+ });
649
+ }
650
+ /**
651
+ * Updates translated messages for search results
652
+ */
653
+ async updateTranslatedMessages(resultCount) {
654
+ if (resultCount > 0) {
655
+ const key = resultCount === 1
656
+ ? '@general:terms.interface.category.search.results-found.singular'
657
+ : '@general:terms.interface.category.search.results-found.plural';
658
+ const text = await this.translate.translateAsync(key, { params: { count: resultCount } });
659
+ this.resultsFoundText.set(text);
660
+ }
661
+ else {
662
+ this.resultsFoundText.set('');
663
+ }
664
+ }
665
+ /**
666
+ * Resets search state and restores tree to original expanded state
667
+ */
668
+ async resetSearch() {
669
+ this.searchResultCount.set(0);
670
+ this.resultsFoundText.set('');
671
+ this.currentSearchTerm = null;
672
+ this.isSearching.set(false);
673
+ this.matchingNodeIds.clear();
674
+ this.relevantNodeIds.clear();
675
+ this.nodeDataCache.clear();
676
+ // Clear highlighting
677
+ this.highlightService.clear();
678
+ const treeComponent = this.tree();
679
+ if (!treeComponent) {
680
+ this.expandedNodesBeforeSearch = [];
681
+ this.nodesExpandedDuringSearch = [];
682
+ return;
683
+ }
684
+ // Reload tree to show all nodes (no filtering)
685
+ await treeComponent.reloadData();
686
+ // Collapse nodes that were expanded during search (in reverse order - leaves first)
687
+ const nodesToCollapse = [...this.nodesExpandedDuringSearch].reverse();
688
+ this.nodesExpandedDuringSearch = [];
689
+ for (const nodeId of nodesToCollapse) {
690
+ // Only collapse if it wasn't originally expanded before search
691
+ if (!this.expandedNodesBeforeSearch.includes(nodeId)) {
692
+ try {
693
+ treeComponent.collapseNode(nodeId);
694
+ }
695
+ catch {
696
+ // Node might not exist anymore, ignore
697
+ }
698
+ }
699
+ }
700
+ // Clear the stored expanded nodes
701
+ this.expandedNodesBeforeSearch = [];
702
+ }
703
+ /**
704
+ * Checks if a node matches the current search term
705
+ */
706
+ isMatchingNode(nodeId) {
707
+ return this.matchingNodeIds.has(nodeId);
708
+ }
709
+ /**
710
+ * Handles node click events to apply category filters and track selected category for create command
711
+ */
712
+ handleNodeClick(node) {
713
+ const nodeData = this.extractNodeData(node);
714
+ const applyConditions = this.vm().entityDef.category?.applyConditions || [];
715
+ const valueField = this.valueField();
716
+ const textField = this.textField();
717
+ const nodeId = String(nodeData[valueField] ?? node['id'] ?? '');
718
+ // Track selected category for default category when creating new entities
719
+ if (nodeId === 'all' || !nodeId) {
720
+ this.vm().setSelectedCategory(null);
721
+ }
722
+ else {
723
+ this.vm().setSelectedCategory({
724
+ id: nodeId,
725
+ title: String(nodeData[textField] ?? node['title'] ?? ''),
726
+ });
727
+ }
728
+ const categoryFilters = this.buildCategoryFilters(nodeData, applyConditions);
729
+ const viewFilters = this.buildViewFilters();
730
+ this.vm().dataSource.filter({
731
+ filters: [...viewFilters, ...categoryFilters],
732
+ logic: 'and',
733
+ });
734
+ this.vm().dataSource.refresh();
735
+ }
736
+ /**
737
+ * Handles node toggle events (expansion/collapse)
738
+ */
739
+ async onNodeToggle(_event) {
740
+ // Tree component handles lazy loading via datasource callback
741
+ }
742
+ //#endregion
743
+ //#region ---- CRUD Operations ----
744
+ /**
745
+ * Creates a new root category node (uses Entity:Create command).
746
+ */
747
+ async handleCreateRootClick(event) {
748
+ this.preventDefaultAndStopPropagation(event);
749
+ try {
750
+ const result = await this.executeCreateCommand(undefined);
751
+ await this.applyCreateResult(result, undefined);
752
+ }
753
+ catch (error) {
754
+ console.error('Error creating root category:', error);
755
+ }
756
+ }
757
+ /**
758
+ * Creates a new child category under the given parent node (uses Entity:Create command).
759
+ */
760
+ async handleCreateChildClick(node, event) {
761
+ this.preventDefaultAndStopPropagation(event);
762
+ try {
763
+ const parentId = this.extractNodeId(node);
764
+ const result = await this.executeCreateCommand(parentId);
765
+ await this.applyCreateResult(result, parentId);
766
+ }
767
+ catch (error) {
768
+ console.error('Error creating child category:', error);
769
+ }
770
+ }
771
+ /**
772
+ * Updates an existing category node (uses Entity:Update command).
773
+ */
774
+ async handleEditNodeClick(node, event) {
775
+ this.preventDefaultAndStopPropagation(event);
776
+ try {
777
+ const nodeData = this.extractNodeData(node);
778
+ const result = await this.executeUpdateCommand(nodeData);
779
+ await this.applyUpdateResult(result, node);
780
+ }
781
+ catch (error) {
782
+ console.error('Error editing category:', error);
783
+ }
784
+ }
785
+ /**
786
+ * Deletes a category node
787
+ */
788
+ async handleDeleteNodeClick(node, event) {
789
+ this.preventDefaultAndStopPropagation(event);
790
+ try {
791
+ const nodeData = this.extractNodeData(node);
792
+ const context = await this.executeDeleteWorkflow(nodeData);
793
+ await this.handleDeleteResult(context, node);
794
+ }
795
+ catch (error) {
796
+ console.error('Error deleting category:', error);
797
+ }
798
+ }
799
+ //#endregion
800
+ //#region ---- Private Tree Management Methods ----
801
+ /**
802
+ * Initializes the category tree data structure
803
+ */
804
+ async initializeTree() {
805
+ this.setLoadingWithDelay(true);
806
+ try {
807
+ const entityKey = this.categoryEntityKey();
808
+ this.treeConfig = {
809
+ entityKey,
810
+ textField: this.textField(),
811
+ valueField: this.valueField(),
812
+ };
813
+ this.treeData = await this.categoryTreeService.initializeCategoryTree(this.treeConfig);
814
+ if (!this.treeData) {
815
+ this.clearLoadingState();
816
+ return;
817
+ }
818
+ // Set parent key from entity definition
819
+ if (this.treeData.categoryEntityDef?.parentKey) {
820
+ this.treeConfig.parentKey = this.treeData.categoryEntityDef.parentKey;
821
+ }
822
+ }
823
+ catch (error) {
824
+ console.error('Error loading categories:', error);
825
+ }
826
+ finally {
827
+ this.clearLoadingState();
828
+ }
829
+ }
830
+ /**
831
+ * Loads root nodes for the tree
832
+ */
833
+ async loadRootNodes() {
834
+ if (!this.isTreeInitialized()) {
835
+ return [];
836
+ }
837
+ // Load root categories
838
+ const items = await this.categoryTreeService.loadRootCategories(this.treeData, this.treeConfig);
839
+ if (!items) {
840
+ return [];
841
+ }
842
+ const rootNode = await this.categoryTreeService.createRootNode(items, this.treeConfig);
843
+ // Filter root's children when search is active
844
+ if (this.relevantNodeIds.size > 0 && rootNode['children']) {
845
+ rootNode['children'] = rootNode['children'].filter((child) => {
846
+ const childId = String(child['id'] ?? '');
847
+ return this.relevantNodeIds.has(childId);
848
+ });
849
+ rootNode['childrenCount'] = rootNode['children'].length;
850
+ }
851
+ return [rootNode];
852
+ }
853
+ /**
854
+ * Loads child nodes for a given parent ID
855
+ */
856
+ async loadChildNodes(parentId) {
857
+ if (!this.isTreeInitialized()) {
858
+ return [];
859
+ }
860
+ // Create minimal node object - loadChildren only needs node.id
861
+ const targetNode = {
862
+ id: parentId,
863
+ };
864
+ let children = await this.categoryTreeService.loadChildren(targetNode, this.treeData, this.treeConfig);
865
+ // Filter children when search is active
866
+ if (this.relevantNodeIds.size > 0) {
867
+ children = children.filter((child) => {
868
+ const childId = String(child['id'] ?? '');
869
+ return this.relevantNodeIds.has(childId);
870
+ });
871
+ }
872
+ return children;
873
+ }
874
+ /**
875
+ * Refreshes the tree view component
876
+ */
877
+ refreshTree() {
878
+ const treeComponent = this.tree();
879
+ if (treeComponent) {
880
+ treeComponent.refresh();
881
+ }
882
+ }
883
+ /**
884
+ * Refreshes tree after CRUD operations
885
+ */
886
+ async refreshAfterChange(parentId) {
887
+ this.refreshTree();
888
+ }
889
+ /**
890
+ * Adds a new node to the tree after create operation
891
+ */
892
+ async addNodeToTree(entityData, parentId) {
893
+ if (!this.isTreeInitialized()) {
894
+ return;
895
+ }
896
+ const treeComponent = this.tree();
897
+ if (!treeComponent) {
898
+ return;
899
+ }
900
+ const newNode = this.categoryTreeService.convertToTreeNode(entityData, this.treeConfig);
901
+ if (parentId) {
902
+ await this.addChildNode(treeComponent, parentId, newNode);
903
+ }
904
+ else {
905
+ await this.addRootNode(treeComponent, newNode);
906
+ }
907
+ }
908
+ /**
909
+ * Adds a child node to a parent node
910
+ */
911
+ async addChildNode(treeComponent, parentId, newNode) {
912
+ const parentNode = treeComponent.findNode(parentId);
913
+ if (!parentNode) {
914
+ await this.refreshAfterChange(parentId);
915
+ return;
916
+ }
917
+ if (!treeComponent.isNodeExpanded(parentId)) {
918
+ await treeComponent.expandNode(parentId);
919
+ }
920
+ treeComponent.addChild(parentId, newNode);
921
+ }
922
+ /**
923
+ * Adds a root node to the tree
924
+ */
925
+ async addRootNode(treeComponent, newNode) {
926
+ const rootNode = treeComponent.findNode(ROOT_NODE_ID);
927
+ if (!rootNode) {
928
+ await this.refreshAfterChange();
929
+ return;
930
+ }
931
+ if (!treeComponent.isNodeExpanded(ROOT_NODE_ID)) {
932
+ await treeComponent.expandNode(ROOT_NODE_ID);
933
+ }
934
+ treeComponent.addChild(ROOT_NODE_ID, newNode);
935
+ }
936
+ /**
937
+ * Updates an existing node in the tree after edit operation
938
+ */
939
+ async updateNodeInTree(nodeId, entityData) {
940
+ if (!this.isTreeInitialized()) {
941
+ return;
942
+ }
943
+ const treeComponent = this.tree();
944
+ if (!treeComponent) {
945
+ return;
946
+ }
947
+ const existingNode = treeComponent.findNode(nodeId);
948
+ if (!existingNode) {
949
+ await this.refreshNodeParent(entityData);
950
+ return;
951
+ }
952
+ // Check if parent changed
953
+ const parentKey = this.treeData?.categoryEntityDef?.parentKey;
954
+ let newParentId = undefined;
955
+ if (parentKey && entityData[parentKey]) {
956
+ const parentValue = String(entityData[parentKey]);
957
+ // 'all' means root, so treat it as undefined
958
+ newParentId = parentValue !== 'all' && parentValue !== '' ? parentValue : undefined;
959
+ }
960
+ const currentParent = treeComponent.getParent(nodeId);
961
+ const currentParentId = currentParent ? String(currentParent['id'] ?? '') : undefined;
962
+ // Normalize current parent: 'all' means root (undefined)
963
+ const normalizedCurrentParentId = currentParentId === 'all' || currentParentId === '' ? undefined : currentParentId;
964
+ // Handle parent change: move node to new parent if parent changed
965
+ if (newParentId !== normalizedCurrentParentId) {
966
+ // If parent changed, move the node first
967
+ const moved = treeComponent.moveNode(nodeId, newParentId);
968
+ if (!moved) {
969
+ // If move failed, refresh the tree to ensure consistency
970
+ await this.refreshNodeParent(entityData);
971
+ return;
972
+ }
973
+ // After moving, we need to ensure the new parent is expanded
974
+ if (newParentId) {
975
+ if (!treeComponent.isNodeExpanded(newParentId)) {
976
+ await treeComponent.expandNode(newParentId);
977
+ }
978
+ }
979
+ else {
980
+ // Moving to root - ensure root is expanded
981
+ if (!treeComponent.isNodeExpanded(ROOT_NODE_ID)) {
982
+ await treeComponent.expandNode(ROOT_NODE_ID);
983
+ }
984
+ }
985
+ }
986
+ // Update node properties (title, data, etc.)
987
+ const updatedNode = this.categoryTreeService.convertToTreeNode(entityData, this.treeConfig);
988
+ const updates = {
989
+ ['title']: updatedNode['title'],
990
+ ['data']: updatedNode['data'],
991
+ ['childrenCount']: updatedNode['childrenCount'],
992
+ ['icon']: updatedNode['icon'],
993
+ };
994
+ treeComponent.editNode(nodeId, updates);
995
+ }
996
+ /**
997
+ * Removes a node from the tree after delete operation
998
+ */
999
+ async removeNodeFromTree(nodeId) {
1000
+ const treeComponent = this.tree();
1001
+ if (!treeComponent) {
1002
+ return;
1003
+ }
1004
+ const nodeToDelete = treeComponent.findNode(nodeId);
1005
+ if (!nodeToDelete) {
1006
+ await this.refreshAfterChange();
1007
+ return;
1008
+ }
1009
+ treeComponent.removeNode(nodeId);
1010
+ }
1011
+ //#endregion
1012
+ //#region ---- Entity CRUD (Commands) ----
1013
+ /**
1014
+ * Executes Entity:Create command for category (standard command-based create).
1015
+ */
1016
+ async executeCreateCommand(parentId) {
1017
+ const entityKey = this.categoryEntityKey();
1018
+ const [moduleName, entityName] = entityKey.split('.');
1019
+ const entityRef = await this.entityRegistry.resolve(moduleName, entityName);
1020
+ const data = {};
1021
+ if (parentId && this.treeData?.categoryEntityDef?.parentKey) {
1022
+ data[this.treeData.categoryEntityDef.parentKey] = parentId;
1023
+ }
1024
+ const createCategoryTitle = await this.translate.translateAsync('@general:actions.create-category.title');
1025
+ const result = await this.commandService.execute('Entity:Create', {
1026
+ __context__: {
1027
+ entity: entityKey,
1028
+ entityInfo: {
1029
+ name: entityRef.name,
1030
+ module: entityRef.module,
1031
+ title: entityRef.title ?? entityRef.formats?.individual ?? '',
1032
+ parentKey: entityRef.parentKey,
1033
+ },
1034
+ data: Object.keys(data).length > 0 ? data : undefined,
1035
+ options: {
1036
+ process: { redirect: false, canCreateNewOne: !!parentId },
1037
+ decoration: { header: { title: createCategoryTitle } },
1038
+ },
1039
+ },
1040
+ });
1041
+ return result ?? { success: false };
1042
+ }
1043
+ /**
1044
+ * Executes Entity:Update command for category (standard command-based update).
1045
+ */
1046
+ async executeUpdateCommand(nodeData) {
1047
+ const entityKey = this.categoryEntityKey();
1048
+ const [moduleName, entityName] = entityKey.split('.');
1049
+ const entityRef = await this.entityRegistry.resolve(moduleName, entityName);
1050
+ const result = await this.commandService.execute('Entity:Update', {
1051
+ __context__: {
1052
+ entity: entityKey,
1053
+ entityInfo: {
1054
+ name: entityRef.name,
1055
+ module: entityRef.module,
1056
+ title: entityRef.title ?? entityRef.formats?.individual ?? '',
1057
+ parentKey: entityRef.parentKey,
1058
+ },
1059
+ data: nodeData,
1060
+ options: { layout: { size: 'md' } },
1061
+ },
1062
+ });
1063
+ return result ?? { success: false };
1064
+ }
1065
+ /**
1066
+ * Applies create command result to the tree (add node or refresh).
1067
+ */
1068
+ async applyCreateResult(result, parentId) {
1069
+ if (!result.success || !this.isTreeInitialized()) {
1070
+ await this.refreshAfterChange(parentId);
1071
+ return;
1072
+ }
1073
+ const newEntityData = result.data;
1074
+ if (newEntityData) {
1075
+ await this.addNodeToTree(newEntityData, parentId);
1076
+ }
1077
+ else {
1078
+ await this.refreshAfterChange(parentId);
1079
+ }
1080
+ }
1081
+ /**
1082
+ * Applies update command result to the tree (update node or refresh).
1083
+ */
1084
+ async applyUpdateResult(result, node) {
1085
+ if (!result.success || !this.isTreeInitialized()) {
1086
+ await this.refreshNodeParent(this.extractNodeData(node));
1087
+ return;
1088
+ }
1089
+ const updatedEntityData = result.data;
1090
+ if (updatedEntityData) {
1091
+ await this.updateNodeInTree(this.extractNodeId(node), updatedEntityData);
1092
+ }
1093
+ else {
1094
+ await this.refreshNodeParent(this.extractNodeData(node));
1095
+ }
1096
+ }
1097
+ //#endregion
1098
+ //#region ---- Delete (Workflow) ----
1099
+ /**
1100
+ * Executes delete-entity workflow (platform has no Entity:Delete command).
1101
+ */
1102
+ async executeDeleteWorkflow(nodeData) {
1103
+ return await this.workflow.execute('delete-entity', {
1104
+ entity: this.categoryEntityKey(),
1105
+ data: nodeData,
1106
+ options: { process: { showResult: true } },
1107
+ });
1108
+ }
1109
+ /**
1110
+ * Handles the result of a delete operation
1111
+ */
1112
+ async handleDeleteResult(context, node) {
1113
+ const result = context.getOutput('result');
1114
+ if (result) {
1115
+ await this.removeNodeFromTree(this.extractNodeId(node));
1116
+ }
1117
+ else {
1118
+ await this.refreshNodeParent(this.extractNodeData(node));
1119
+ }
1120
+ }
1121
+ //#endregion
1122
+ //#region ---- Utility Methods ----
1123
+ /**
1124
+ * Checks if tree data and config are initialized
1125
+ */
1126
+ isTreeInitialized() {
1127
+ return !!(this.treeData && this.treeConfig);
1128
+ }
1129
+ /**
1130
+ * Extracts node data from a tree node
1131
+ */
1132
+ extractNodeData(node) {
1133
+ return (node['data'] || node);
1134
+ }
1135
+ /**
1136
+ * Extracts node ID from a tree node
1137
+ */
1138
+ extractNodeId(node) {
1139
+ return String(node['id'] ?? '');
1140
+ }
1141
+ /**
1142
+ * Builds category filters from node data and apply conditions
1143
+ */
1144
+ buildCategoryFilters(nodeData, applyConditions) {
1145
+ return applyConditions
1146
+ .map((condition) => {
1147
+ const value = nodeData[condition.value];
1148
+ if (value === 'all' || value == null) {
1149
+ return null;
1150
+ }
1151
+ return {
1152
+ field: condition.name,
1153
+ value,
1154
+ operator: condition.operator,
1155
+ };
1156
+ })
1157
+ .filter((item) => item !== null);
1158
+ }
1159
+ /**
1160
+ * Builds view filters from view conditions
1161
+ */
1162
+ buildViewFilters() {
1163
+ return this.vm()
1164
+ .view()
1165
+ .conditions.map((condition) => ({ ...condition, field: condition.name }));
1166
+ }
1167
+ /**
1168
+ * Refreshes the parent node of the given entity data
1169
+ */
1170
+ async refreshNodeParent(entityData) {
1171
+ const parentKey = this.treeData?.categoryEntityDef?.parentKey;
1172
+ const parentId = parentKey && entityData[parentKey] ? entityData[parentKey] : undefined;
1173
+ await this.refreshAfterChange(parentId);
1174
+ }
1175
+ /**
1176
+ * Prevents default behavior and stops event propagation
1177
+ */
1178
+ preventDefaultAndStopPropagation(event) {
1179
+ event.nativeEvent.preventDefault();
1180
+ event.nativeEvent.stopPropagation();
1181
+ }
1182
+ //#endregion
1183
+ //#region ---- Loading State Management ----
1184
+ /**
1185
+ * Sets loading state with delay to avoid flickering for fast responses
1186
+ */
1187
+ setLoadingWithDelay(loading) {
1188
+ if (!loading) {
1189
+ return;
1190
+ }
1191
+ if (this.loadingTimeoutId) {
1192
+ clearTimeout(this.loadingTimeoutId);
1193
+ }
1194
+ this.loadingTimeoutId = setTimeout(() => {
1195
+ this.isLoading.set(true);
1196
+ this.loadingTimeoutId = null;
1197
+ }, LOADING_DELAY_MS);
1198
+ }
1199
+ /**
1200
+ * Clears loading state and cancels any pending timeout
1201
+ */
1202
+ clearLoadingState() {
1203
+ if (this.loadingTimeoutId) {
1204
+ clearTimeout(this.loadingTimeoutId);
1205
+ this.loadingTimeoutId = null;
1206
+ }
1207
+ this.isLoading.set(false);
1208
+ }
1209
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityCategoryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1210
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPEntityCategoryComponent, isStandalone: true, selector: "axp-entity-category", inputs: { vm: { classPropertyName: "vm", publicName: "vm", isSignal: true, isRequired: true, transformFunction: null }, searchValue: { classPropertyName: "searchValue", publicName: "searchValue", isSignal: true, isRequired: false, transformFunction: null }, selectMode: { classPropertyName: "selectMode", publicName: "selectMode", isSignal: true, isRequired: false, transformFunction: null }, selectionBehavior: { classPropertyName: "selectionBehavior", publicName: "selectionBehavior", isSignal: true, isRequired: false, transformFunction: null }, dragArea: { classPropertyName: "dragArea", publicName: "dragArea", isSignal: true, isRequired: false, transformFunction: null }, dragBehavior: { classPropertyName: "dragBehavior", publicName: "dragBehavior", isSignal: true, isRequired: false, transformFunction: null }, showIcons: { classPropertyName: "showIcons", publicName: "showIcons", isSignal: true, isRequired: false, transformFunction: null }, showChildrenBadge: { classPropertyName: "showChildrenBadge", publicName: "showChildrenBadge", isSignal: true, isRequired: false, transformFunction: null }, expandedIcon: { classPropertyName: "expandedIcon", publicName: "expandedIcon", isSignal: true, isRequired: false, transformFunction: null }, collapsedIcon: { classPropertyName: "collapsedIcon", publicName: "collapsedIcon", isSignal: true, isRequired: false, transformFunction: null }, indentSize: { classPropertyName: "indentSize", publicName: "indentSize", isSignal: true, isRequired: false, transformFunction: null }, look: { classPropertyName: "look", publicName: "look", isSignal: true, isRequired: false, transformFunction: null }, searchWithChildren: { classPropertyName: "searchWithChildren", publicName: "searchWithChildren", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "tree", first: true, predicate: ["tree"], descendants: true, isSignal: true }], ngImport: i0, template: "<axp-layout-header>\n <axp-layout-title>{{\n vm().entityDef.category?.title || '@general:terms.classification.category' | translate | async\n }}</axp-layout-title>\n <axp-layout-toolbar>\n <div class=\"ax-flex ax-flex-col ax-gap-1 ax-w-full\">\n <ax-search-box\n (onValueChanged)=\"handleCategorySearchChange($event)\"\n [delayTime]=\"300\"\n [placeholder]=\"'@general:terms.interface.category.search.placeholder' | translate | async\"\n >\n </ax-search-box>\n @if (isSearching() && currentSearchValue().trim()) {\n <div class=\"ax-text-xs ax-text-muted ax-flex ax-items-center ax-gap-1\">\n <span>{{ '@general:terms.interface.category.search.searching' | translate | async }}</span>\n </div>\n } @else if (currentSearchValue().trim() && !isSearching()) {\n <div class=\"ax-text-xs ax-text-muted ax-flex ax-items-center ax-gap-1\">\n @if (searchResultCount() > 0) {\n <span>{{ resultsFoundText() }}</span>\n }\n </div>\n }\n </div>\n </axp-layout-toolbar>\n</axp-layout-header>\n<axp-layout-content>\n @if (isLoading()) {\n <div class=\"ax-p-4 ax-flex ax-flex-col ax-gap-3\">\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n </div>\n } @else if (showNoSearchResults()) {\n <div class=\"__empty-state\">\n <axp-state-message\n icon=\"fa-light fa-search\"\n [title]=\"'@general:terms.interface.category.search.no-results-found.title'\"\n [description]=\"'@general:terms.interface.category.search.no-results-found.description'\"\n >\n </axp-state-message>\n </div>\n } @else if (treeData) {\n <div class=\"ax-px-4 ax-max-h-[calc(100vh-250px)] ax-overflow-auto\">\n <ax-tree-view\n [datasource]=\"datasource\"\n [selectMode]=\"selectMode()\"\n [selectionBehavior]=\"selectionBehavior()\"\n [dragArea]=\"dragArea()\"\n [dragBehavior]=\"dragBehavior()\"\n [showIcons]=\"showIcons()\"\n [showChildrenBadge]=\"showChildrenBadge()\"\n [expandedIcon]=\"expandedIcon()\"\n [collapsedIcon]=\"collapsedIcon()\"\n [indentSize]=\"indentSize()\"\n [look]=\"look()\"\n [titleField]=\"textField()\"\n [idField]=\"valueField()\"\n [expandOnDoubleClick]=\"true\"\n [nodeTemplate]=\"itemTemplate\"\n (onNodeToggle)=\"onNodeToggle($event)\"\n (onNodeClick)=\"handleNodeClick($event.node)\"\n #tree\n >\n </ax-tree-view>\n </div>\n } @else {\n <div class=\"__empty-state\">\n <axp-state-message\n icon=\"fa-light fa-folder-open\"\n [title]=\"'@general:terms.interface.category.search.no-records.title'\"\n [description]=\"'@general:terms.interface.category.search.no-records.description'\"\n >\n @if (!categoryReadonly()) {\n <ax-button\n slot=\"actions\"\n (onClick)=\"handleCreateRootClick($event)\"\n look=\"solid\"\n color=\"primary\"\n [text]=\"'@general:actions.add-new.title' | translate | async\"\n >\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button>\n }\n </axp-state-message>\n </div>\n }\n\n <ng-template #itemTemplate let-node=\"node\" let-level=\"level\">\n @let item = node.data || node;\n @let textField = vm().entityDef.category?.textField || 'title';\n @let valueField = vm().entityDef.category?.valueField || 'id';\n @let itemId = item[valueField] || node.id;\n @let rawLabel = item[textField] || node.title;\n @let itemTitle = rawLabel | translate | async;\n <div class=\"ax-flex ax-items-center ax-justify-between ax-w-full ax-gap-2 ax-overflow-hidden ax-py-1\">\n <div class=\"ax-flex ax-items-center ax-gap-2 ax-min-w-0\">\n <ax-icon\n class=\"fas fa-folder\"\n [style.color]=\"item.color ?? 'rgba(var(--ax-sys-color-warning-500), 1)'\"\n ></ax-icon>\n <span class=\"ax-truncate\">\n @if (itemId === 'all') {\n {{ categoryTreeRootTitleI18nKey | translate | async }}\n } @else {\n {{ itemTitle }}\n }\n </span>\n </div>\n @if (itemId && itemId !== 'all' && !categoryReadonly()) {\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <ax-button class=\"ax-xs\" color=\"default\" look=\"blank\" (onClick)=\"$event.nativeEvent.stopPropagation()\">\n <ax-icon class=\"fas fa-ellipsis-v\"></ax-icon>\n <ax-dropdown-panel>\n <ax-button-item-list>\n <ax-button-item\n (onClick)=\"handleCreateChildClick(node, $event)\"\n look=\"blank\"\n color=\"default\"\n [text]=\"('@general:actions.add-new-child.title' | translate | async)!\"\n >\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button-item>\n <ax-button-item\n (onClick)=\"handleEditNodeClick(node, $event)\"\n look=\"blank\"\n [text]=\"('@general:actions.edit.title' | translate | async)!\"\n >\n <ax-icon class=\"fas fa-pen\"></ax-icon>\n </ax-button-item>\n <ax-button-item\n (onClick)=\"handleDeleteNodeClick(node, $event)\"\n color=\"danger\"\n look=\"blank\"\n [text]=\"('@general:actions.delete.title' | translate | async)!\"\n >\n <ax-icon class=\"fas fa-trash\"></ax-icon>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n </div>\n } @else if (itemId === 'all' && !categoryReadonly()) {\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <ax-button class=\"ax-xs\" (onClick)=\"handleCreateRootClick($event)\" look=\"blank\" color=\"default\">\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button>\n </div>\n }\n </div>\n </ng-template>\n</axp-layout-content>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTreeViewModule }, { kind: "component", type: AXTreeViewComponent, selector: "ax-tree-view", inputs: ["datasource", "selectMode", "selectionBehavior", "dragArea", "dragBehavior", "showIcons", "showChildrenBadge", "expandedIcon", "collapsedIcon", "indentSize", "look", "nodeTemplate", "idField", "titleField", "tooltipField", "iconField", "expandedField", "selectedField", "indeterminateField", "disabledField", "hiddenField", "childrenField", "childrenCountField", "dataField", "inheritDisabled", "expandOnDoubleClick", "doubleClickDuration", "tooltipDelay", "controlledSelection", "selectedIds"], outputs: ["datasourceChange", "selectedIdsChange", "onBeforeDrop", "onNodeToggle", "onNodeSelect", "onNodeDoubleClick", "onNodeClick", "onSelectionChange", "onOrderChange", "onMoveChange", "onItemsChange"] }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i2$2.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { 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: AXSearchBoxModule }, { kind: "component", type: i6.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "component", type: AXPThemeLayoutHeaderComponent, selector: "axp-layout-header" }, { kind: "component", type: AXPThemeLayoutToolbarComponent, selector: "axp-layout-toolbar" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i3.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i3.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { 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: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "look"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
1211
+ }
1212
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityCategoryComponent, decorators: [{
1213
+ type: Component,
1214
+ args: [{ selector: 'axp-entity-category', standalone: true, encapsulation: ViewEncapsulation.None, imports: [
1215
+ CommonModule,
1216
+ AXDecoratorModule,
1217
+ AXTreeViewModule,
1218
+ AXTreeViewComponent,
1219
+ AXSkeletonModule,
1220
+ AXPThemeLayoutBlockComponent,
1221
+ AXSearchBoxModule,
1222
+ AXPThemeLayoutHeaderComponent,
1223
+ AXPThemeLayoutToolbarComponent,
1224
+ AXTranslationModule,
1225
+ AXButtonModule,
1226
+ AXDropdownModule,
1227
+ AXPStateMessageComponent,
1228
+ ], template: "<axp-layout-header>\n <axp-layout-title>{{\n vm().entityDef.category?.title || '@general:terms.classification.category' | translate | async\n }}</axp-layout-title>\n <axp-layout-toolbar>\n <div class=\"ax-flex ax-flex-col ax-gap-1 ax-w-full\">\n <ax-search-box\n (onValueChanged)=\"handleCategorySearchChange($event)\"\n [delayTime]=\"300\"\n [placeholder]=\"'@general:terms.interface.category.search.placeholder' | translate | async\"\n >\n </ax-search-box>\n @if (isSearching() && currentSearchValue().trim()) {\n <div class=\"ax-text-xs ax-text-muted ax-flex ax-items-center ax-gap-1\">\n <span>{{ '@general:terms.interface.category.search.searching' | translate | async }}</span>\n </div>\n } @else if (currentSearchValue().trim() && !isSearching()) {\n <div class=\"ax-text-xs ax-text-muted ax-flex ax-items-center ax-gap-1\">\n @if (searchResultCount() > 0) {\n <span>{{ resultsFoundText() }}</span>\n }\n </div>\n }\n </div>\n </axp-layout-toolbar>\n</axp-layout-header>\n<axp-layout-content>\n @if (isLoading()) {\n <div class=\"ax-p-4 ax-flex ax-flex-col ax-gap-3\">\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n </div>\n } @else if (showNoSearchResults()) {\n <div class=\"__empty-state\">\n <axp-state-message\n icon=\"fa-light fa-search\"\n [title]=\"'@general:terms.interface.category.search.no-results-found.title'\"\n [description]=\"'@general:terms.interface.category.search.no-results-found.description'\"\n >\n </axp-state-message>\n </div>\n } @else if (treeData) {\n <div class=\"ax-px-4 ax-max-h-[calc(100vh-250px)] ax-overflow-auto\">\n <ax-tree-view\n [datasource]=\"datasource\"\n [selectMode]=\"selectMode()\"\n [selectionBehavior]=\"selectionBehavior()\"\n [dragArea]=\"dragArea()\"\n [dragBehavior]=\"dragBehavior()\"\n [showIcons]=\"showIcons()\"\n [showChildrenBadge]=\"showChildrenBadge()\"\n [expandedIcon]=\"expandedIcon()\"\n [collapsedIcon]=\"collapsedIcon()\"\n [indentSize]=\"indentSize()\"\n [look]=\"look()\"\n [titleField]=\"textField()\"\n [idField]=\"valueField()\"\n [expandOnDoubleClick]=\"true\"\n [nodeTemplate]=\"itemTemplate\"\n (onNodeToggle)=\"onNodeToggle($event)\"\n (onNodeClick)=\"handleNodeClick($event.node)\"\n #tree\n >\n </ax-tree-view>\n </div>\n } @else {\n <div class=\"__empty-state\">\n <axp-state-message\n icon=\"fa-light fa-folder-open\"\n [title]=\"'@general:terms.interface.category.search.no-records.title'\"\n [description]=\"'@general:terms.interface.category.search.no-records.description'\"\n >\n @if (!categoryReadonly()) {\n <ax-button\n slot=\"actions\"\n (onClick)=\"handleCreateRootClick($event)\"\n look=\"solid\"\n color=\"primary\"\n [text]=\"'@general:actions.add-new.title' | translate | async\"\n >\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button>\n }\n </axp-state-message>\n </div>\n }\n\n <ng-template #itemTemplate let-node=\"node\" let-level=\"level\">\n @let item = node.data || node;\n @let textField = vm().entityDef.category?.textField || 'title';\n @let valueField = vm().entityDef.category?.valueField || 'id';\n @let itemId = item[valueField] || node.id;\n @let rawLabel = item[textField] || node.title;\n @let itemTitle = rawLabel | translate | async;\n <div class=\"ax-flex ax-items-center ax-justify-between ax-w-full ax-gap-2 ax-overflow-hidden ax-py-1\">\n <div class=\"ax-flex ax-items-center ax-gap-2 ax-min-w-0\">\n <ax-icon\n class=\"fas fa-folder\"\n [style.color]=\"item.color ?? 'rgba(var(--ax-sys-color-warning-500), 1)'\"\n ></ax-icon>\n <span class=\"ax-truncate\">\n @if (itemId === 'all') {\n {{ categoryTreeRootTitleI18nKey | translate | async }}\n } @else {\n {{ itemTitle }}\n }\n </span>\n </div>\n @if (itemId && itemId !== 'all' && !categoryReadonly()) {\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <ax-button class=\"ax-xs\" color=\"default\" look=\"blank\" (onClick)=\"$event.nativeEvent.stopPropagation()\">\n <ax-icon class=\"fas fa-ellipsis-v\"></ax-icon>\n <ax-dropdown-panel>\n <ax-button-item-list>\n <ax-button-item\n (onClick)=\"handleCreateChildClick(node, $event)\"\n look=\"blank\"\n color=\"default\"\n [text]=\"('@general:actions.add-new-child.title' | translate | async)!\"\n >\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button-item>\n <ax-button-item\n (onClick)=\"handleEditNodeClick(node, $event)\"\n look=\"blank\"\n [text]=\"('@general:actions.edit.title' | translate | async)!\"\n >\n <ax-icon class=\"fas fa-pen\"></ax-icon>\n </ax-button-item>\n <ax-button-item\n (onClick)=\"handleDeleteNodeClick(node, $event)\"\n color=\"danger\"\n look=\"blank\"\n [text]=\"('@general:actions.delete.title' | translate | async)!\"\n >\n <ax-icon class=\"fas fa-trash\"></ax-icon>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n </div>\n } @else if (itemId === 'all' && !categoryReadonly()) {\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <ax-button class=\"ax-xs\" (onClick)=\"handleCreateRootClick($event)\" look=\"blank\" color=\"default\">\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button>\n </div>\n }\n </div>\n </ng-template>\n</axp-layout-content>\n" }]
1229
+ }], ctorParameters: () => [], propDecorators: { vm: [{ type: i0.Input, args: [{ isSignal: true, alias: "vm", required: true }] }], tree: [{ type: i0.ViewChild, args: ['tree', { isSignal: true }] }], searchValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchValue", required: false }] }], selectMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectMode", required: false }] }], selectionBehavior: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionBehavior", required: false }] }], dragArea: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragArea", required: false }] }], dragBehavior: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragBehavior", required: false }] }], showIcons: [{ type: i0.Input, args: [{ isSignal: true, alias: "showIcons", required: false }] }], showChildrenBadge: [{ type: i0.Input, args: [{ isSignal: true, alias: "showChildrenBadge", required: false }] }], expandedIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedIcon", required: false }] }], collapsedIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsedIcon", required: false }] }], indentSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "indentSize", required: false }] }], look: [{ type: i0.Input, args: [{ isSignal: true, alias: "look", required: false }] }], searchWithChildren: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchWithChildren", required: false }] }] } });
1230
+
1231
+ class AXPEntityMasterToolbarViewComponent {
1232
+ constructor() {
1233
+ this.layoutService = inject(AXPLayoutThemeService);
1234
+ this.deviceService = inject(AXPDeviceService);
1235
+ this.parent = inject(AXPEntityMasterListViewComponent);
1236
+ this.router = inject(Router);
1237
+ this.activeRoute = inject(ActivatedRoute);
1238
+ this.settingsService = inject(AXPSettingsService);
1239
+ this.isInitializing = false;
1240
+ this.pendingInitialFilters = true;
1241
+ this.pendingInitialSorts = true;
1242
+ this.filterTriggerMode = 'manual';
1243
+ this.previousFilterQueries = signal([], ...(ngDevMode ? [{ debugName: "previousFilterQueries" }] : /* istanbul ignore next */ []));
1244
+ this.initialFilters = signal([], ...(ngDevMode ? [{ debugName: "initialFilters" }] : /* istanbul ignore next */ []));
1245
+ this.filtersDefinitions = signal([], ...(ngDevMode ? [{ debugName: "filtersDefinitions" }] : /* istanbul ignore next */ []));
1246
+ this.viewQueries = computed(() => this.vm.views().map((v) => ({
1247
+ name: v.name,
1248
+ fixed: false,
1249
+ title: v.title,
1250
+ columns: v.columns,
1251
+ conditions: v.conditions.map((c) => ({
1252
+ field: c.name,
1253
+ operator: c.operator,
1254
+ value: c.value,
1255
+ })),
1256
+ sorts: v.sorts,
1257
+ })), ...(ngDevMode ? [{ debugName: "viewQueries" }] : /* istanbul ignore next */ []));
1258
+ this.selectedViewQuery = computed(() => ({
1259
+ name: this.vm.view().name,
1260
+ fixed: false,
1261
+ title: this.vm.view().title,
1262
+ columns: this.vm.view().columns,
1263
+ conditions: this.vm.view().conditions.map((c) => ({
1264
+ field: c.name,
1265
+ operator: c.operator,
1266
+ value: c.value,
1267
+ })),
1268
+ sorts: this.vm.view().sorts,
1269
+ }), ...(ngDevMode ? [{ debugName: "selectedViewQuery" }] : /* istanbul ignore next */ []));
1270
+ this.isFiltersDirty = computed(() => !isEqual(this.vm.filterQueries(), this.previousFilterQueries()), ...(ngDevMode ? [{ debugName: "isFiltersDirty" }] : /* istanbul ignore next */ []));
1271
+ this.showListDisplayModeControl = computed(() => this.vm.enabledListLayouts().includes('card'), ...(ngDevMode ? [{ debugName: "showListDisplayModeControl" }] : /* istanbul ignore next */ []));
1272
+ this.listDisplayMode = computed(() => this.vm.listDisplayMode(), ...(ngDevMode ? [{ debugName: "listDisplayMode" }] : /* istanbul ignore next */ []));
1273
+ this.hasTableListDisplayOption = computed(() => this.vm.enabledListLayouts().includes('table'), ...(ngDevMode ? [{ debugName: "hasTableListDisplayOption" }] : /* istanbul ignore next */ []));
1274
+ this.listDisplayModeButtonIcon = computed(() => {
1275
+ switch (this.listDisplayMode()) {
1276
+ case 'table':
1277
+ return 'fa-light fa-table';
1278
+ case 'card-compact':
1279
+ return 'fa-light fa-grip-lines';
1280
+ case 'card-expanded':
1281
+ return 'fa-light fa-grid-2';
1282
+ }
1283
+ }, ...(ngDevMode ? [{ debugName: "listDisplayModeButtonIcon" }] : /* istanbul ignore next */ []));
1284
+ this.listDisplayModePopover = viewChild('listDisplayModePopover', ...(ngDevMode ? [{ debugName: "listDisplayModePopover" }] : /* istanbul ignore next */ []));
1285
+ // Debounced apply to coalesce multiple UI changes (filters/sorts/columns)
1286
+ this.applyTimer = null;
1287
+ this.#effect = effect(() => {
1288
+ // Keep definitions up to date; initial filters are set explicitly from settings or view
1289
+ this.filtersDefinitions.set(this.vm.filtersDef);
1290
+ }, ...(ngDevMode ? [{ debugName: "#effect" }] : /* istanbul ignore next */ []));
1291
+ this.sortQueries = computed(() => this.vm
1292
+ .sortedFields()
1293
+ .filter((s) => !!s.dir)
1294
+ .map((s) => ({
1295
+ name: s.name,
1296
+ dir: s.dir,
1297
+ })), ...(ngDevMode ? [{ debugName: "sortQueries" }] : /* istanbul ignore next */ []));
1298
+ this.sortDefinitions = computed(() => {
1299
+ const sortable = this.vm.sortableFields();
1300
+ const active = this.vm.sortedFields();
1301
+ const activeNames = new Set(active.map((s) => s.name));
1302
+ const activeDefs = active.map((s) => ({
1303
+ name: s.name,
1304
+ title: s.title,
1305
+ dir: s.dir,
1306
+ }));
1307
+ const inactiveDefs = sortable
1308
+ .filter((s) => !activeNames.has(s.name))
1309
+ .map((s) => ({
1310
+ name: s.name,
1311
+ title: s.title,
1312
+ dir: undefined,
1313
+ }));
1314
+ return [...activeDefs, ...inactiveDefs];
1315
+ }, ...(ngDevMode ? [{ debugName: "sortDefinitions" }] : /* istanbul ignore next */ []));
1316
+ }
1317
+ async ngOnInit() {
1318
+ // Prefer saved settings (view/columns/sorts/filters) if available, then apply
1319
+ await this.loadSettings();
1320
+ await this.vm.setView();
1321
+ await this.vm.ensureListPagingResolved();
1322
+ this.filtersDefinitions.set(this.vm.filtersDef);
1323
+ this.isInitializing = true;
1324
+ // this.pendingInitialFilters = true;
1325
+ // this.pendingInitialSorts = true;
1326
+ this.setInitialFiltersFromSettingsOrView();
1327
+ // Ensure initial load even when filters/sorts are absent
1328
+ setTimeout(() => {
1329
+ this.isInitializing = false;
1330
+ this.scheduleApply();
1331
+ }, 0);
1332
+ }
1333
+ async loadSettings() {
1334
+ const filterTriggerMode = await this.settingsService.get(AXPCommonSettings.EntityFilterApplyMode);
1335
+ this.filterTriggerMode = (filterTriggerMode?.value ?? 'auto');
1336
+ }
1337
+ setListDisplayMode(mode) {
1338
+ this.vm.setListDisplayMode(mode);
1339
+ this.listDisplayModePopover()?.close();
1340
+ }
1341
+ scheduleApply() {
1342
+ clearTimeout(this.applyTimer);
1343
+ this.applyTimer = setTimeout(() => {
1344
+ this.vm.applyFilterAndSort();
1345
+ }, 50);
1346
+ }
1347
+ async onViewChanged(view) {
1348
+ await this.vm.setView(view.name);
1349
+ if (axpIsEntityListRoute(this.router)) {
1350
+ axpReplaceEntityListRouteQueryParams(this.router, { view: view.name });
1351
+ }
1352
+ this.isInitializing = true;
1353
+ this.pendingInitialFilters = true;
1354
+ this.pendingInitialSorts = true;
1355
+ this.setInitialFiltersFromSettingsOrView();
1356
+ // Ensure initial load after view change
1357
+ setTimeout(() => {
1358
+ this.isInitializing = false;
1359
+ this.scheduleApply();
1360
+ }, 0);
1361
+ }
1362
+ #effect;
1363
+ setInitialFiltersFromSettingsOrView() {
1364
+ const saved = this.vm.filterQueries();
1365
+ this.previousFilterQueries.set(saved);
1366
+ const viewConditions = this.vm.view().conditions.map((c) => c.name);
1367
+ if (saved && saved.length) {
1368
+ this.initialFilters.set(saved.map((s) => ({ ...s, hidden: viewConditions.includes(s.field) })));
1369
+ return;
1370
+ }
1371
+ this.initialFilters.set(this.vm.view().conditions.map((c) => ({
1372
+ field: c.name,
1373
+ operator: c.operator,
1374
+ value: c.value,
1375
+ hidden: true,
1376
+ })));
1377
+ }
1378
+ onFiltersChanged(filters) {
1379
+ if (this.isInitializing || this.pendingInitialFilters) {
1380
+ this.pendingInitialFilters = false;
1381
+ return;
1382
+ }
1383
+ this.vm.filterQueries.set(filters);
1384
+ if (this.filterTriggerMode === 'auto') {
1385
+ this.applyFilters();
1386
+ }
1387
+ }
1388
+ applyFilters() {
1389
+ this.previousFilterQueries.set(this.vm.filterQueries());
1390
+ this.vm.saveSettings('filters', this.vm.filterQueries());
1391
+ this.scheduleApply();
1392
+ }
1393
+ onSortQueriesChange(e) {
1394
+ if (this.isInitializing || this.pendingInitialSorts) {
1395
+ this.pendingInitialSorts = false;
1396
+ return;
1397
+ }
1398
+ const sortableByName = new Map(this.vm.sortableFields().map((f) => [f.name, f]));
1399
+ const nextSortedFields = e
1400
+ .filter((s) => s.dir && sortableByName.has(s.name))
1401
+ .map((s) => ({
1402
+ name: s.name,
1403
+ title: sortableByName.get(s.name).title,
1404
+ dir: s.dir,
1405
+ }));
1406
+ const sortSignature = (fields) => fields.map((s) => `${s.name}:${s.dir ?? ''}`).join('|');
1407
+ if (sortSignature(nextSortedFields) === sortSignature(this.vm.sortedFields())) {
1408
+ return;
1409
+ }
1410
+ this.vm.sortedFields.set(nextSortedFields);
1411
+ this.vm.saveSettings('sorts', e);
1412
+ this.scheduleApply();
1413
+ }
1414
+ onColumnsChange(columns) {
1415
+ const keyOf = (c) => c.column?.options?.dataPath ?? c.name;
1416
+ this.vm.columns.update((prev) => {
1417
+ const byKey = new Map(prev.map((c) => [keyOf(c), c]));
1418
+ return columns
1419
+ .map((newColumn) => {
1420
+ const existing = byKey.get(keyOf(newColumn));
1421
+ if (!existing) {
1422
+ return null;
1423
+ }
1424
+ return new AXPEntityListViewColumnViewModel(existing.property, {
1425
+ ...existing.column,
1426
+ options: {
1427
+ ...existing.column.options,
1428
+ visible: newColumn.visible,
1429
+ },
1430
+ });
1431
+ })
1432
+ .filter((c) => c != null);
1433
+ });
1434
+ // Persist column order/visibility
1435
+ this.vm.onColumnsChanged(this.vm.columns());
1436
+ // Use debounced apply to avoid triple refresh when combined with sorts/filters
1437
+ // this.scheduleApply();
1438
+ }
1439
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityMasterToolbarViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1440
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPEntityMasterToolbarViewComponent, isStandalone: true, selector: "axp-entity-master-toolbar-view", inputs: { vm: ["viewModel", "vm"] }, host: { classAttribute: "ax-w-full" }, viewQueries: [{ propertyName: "listDisplayModePopover", first: true, predicate: ["listDisplayModePopover"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- <axp-entity-view-toolbar [viewModel]=\"vm\"></axp-entity-view-toolbar> -->\n<axp-query-views\n id=\"axp-toolbar-view-selector\"\n [views]=\"viewQueries()\"\n [selectedView]=\"selectedViewQuery()\"\n (selectedViewChange)=\"onViewChanged($event)\"\n></axp-query-views>\n<div class=\"ax-flex ax-items-center ax-gap-2 ax-border-b ax-border-light w-full\">\n <!-- <axp-entity-filter-toolbar [viewModel]=\"vm\"></axp-entity-filter-toolbar> -->\n <axp-query-filters\n id=\"axp-toolbar-filters\"\n [filtersDefinitions]=\"filtersDefinitions()\"\n [initialFilters]=\"initialFilters()\"\n (onFiltersChanged)=\"onFiltersChanged($event)\"\n ></axp-query-filters>\n\n <div class=\"ax-flex ax-items-center ax-gap-2 md:ax-gap-2\">\n @if (filterTriggerMode === 'manual' && isFiltersDirty()) {\n <ax-button\n id=\"axp-toolbar-btn-filter\"\n [title]=\"'@general:actions.apply.title'\"\n [iconOnly]=\"true\"\n #filterButton\n [color]=\"'primary'\"\n (onClick)=\"applyFilters()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-search\"></i>\n </ax-prefix>\n </ax-button>\n }\n @if (vm.activeListLayout() === 'table') {\n <div>\n <ax-button id=\"axp-toolbar-btn-columns\" [iconOnly]=\"true\" #columnButton [color]=\"'default'\">\n <i class=\"fa-light fa-table-columns\"></i>\n </ax-button>\n <ax-popover\n id=\"axp-popover-columns\"\n [adaptivityEnabled]=\"true\"\n [offsetY]=\"10\"\n [target]=\"columnButton\"\n [openOn]=\"'toggle'\"\n [closeOn]=\"'clickOut'\"\n #columnsPopover\n >\n <div class=\"ax-lightest-surface ax-shadow-md ax-border md:ax-w-72 ax-w-full ax-rounded-md\">\n <ax-header class=\"ax-border-b ax-lighter-surface ax-rounded-t-md ax-p-4 ax-font-bold\">\n {{ '@general:terms.common.columns' | translate | async }}\n </ax-header>\n <div class=\"ax-py-2 ax-px-4\">\n <axp-query-columns [columns]=\"vm.columns()\" (columnsChange)=\"onColumnsChange($event)\"></axp-query-columns>\n </div>\n </div>\n </ax-popover>\n </div>\n }\n\n @if (vm.canSort()) {\n <div>\n <ax-button id=\"axp-toolbar-btn-sort\" [iconOnly]=\"true\" [text]=\"'Sorts'\" #sortButton [color]=\"'default'\">\n <i class=\"fa-light fa-sort-amount-up\"></i>\n </ax-button>\n <ax-popover\n id=\"axp-popover-sort\"\n [adaptivityEnabled]=\"true\"\n [offsetY]=\"10\"\n [target]=\"sortButton\"\n [openOn]=\"'toggle'\"\n [closeOn]=\"'clickOut'\"\n #popover\n >\n <div class=\"ax-lightest-surface ax-shadow-md ax-border md:ax-w-72 ax-w-full ax-rounded-md\">\n <ax-header class=\"ax-border-b ax-lighter-surface ax-rounded-t-md ax-p-4 ax-font-bold\">\n {{ '@general:terms.common.sorts' | translate | async }}\n </ax-header>\n <div class=\"ax-py-2 ax-px-4\">\n <!-- <axp-list-view-option-sorting [viewModel]=\"vm\"></axp-list-view-option-sorting> -->\n <axp-query-sorts\n [sortDefinitions]=\"sortDefinitions()\"\n (sortQueriesChange)=\"onSortQueriesChange($event)\"\n [initialSortQueries]=\"sortQueries()\"\n ></axp-query-sorts>\n </div>\n </div>\n </ax-popover>\n </div>\n }\n @if (deviceService.isSmall()) {\n <ax-button\n id=\"axp-toolbar-btn-category\"\n (onClick)=\"parent.toggleCategoryDrawer()\"\n [iconOnly]=\"true\"\n [color]=\"'default'\"\n >\n <i class=\"fa-light fa-bars\"></i>\n </ax-button>\n }\n\n @if (showListDisplayModeControl()) {\n <div>\n <ax-button id=\"axp-toolbar-btn-list-display\" [iconOnly]=\"true\" #listDisplayButton [color]=\"'default'\">\n <i [class]=\"listDisplayModeButtonIcon()\"></i>\n </ax-button>\n <ax-popover\n id=\"axp-popover-list-display\"\n [adaptivityEnabled]=\"true\"\n [offsetY]=\"10\"\n [target]=\"listDisplayButton\"\n [openOn]=\"'toggle'\"\n [closeOn]=\"'clickOut'\"\n #listDisplayModePopover\n >\n <div class=\"ax-lightest-surface ax-shadow-md ax-border md:ax-w-72 ax-w-full ax-rounded-md\">\n <ax-header class=\"ax-border-b ax-lighter-surface ax-rounded-t-md ax-p-4 ax-font-bold\">\n {{ '@general:terms.interface.list-display' | translate | async }}\n </ax-header>\n <div class=\"ax-py-2 ax-px-2\">\n <ax-button-item-list>\n @if (hasTableListDisplayOption()) {\n <ax-button-item\n [text]=\"('@general:terms.interface.table-view' | translate | async)!\"\n [selected]=\"listDisplayMode() === 'table'\"\n (onClick)=\"setListDisplayMode('table')\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-table\"></i>\n </ax-prefix>\n </ax-button-item>\n }\n @if (hasTableListDisplayOption()) {\n <ax-divider />\n }\n <ax-button-item\n [text]=\"('@general:terms.interface.card-compact-view' | translate | async)!\"\n [selected]=\"listDisplayMode() === 'card-compact'\"\n (onClick)=\"setListDisplayMode('card-compact')\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-grip-lines\"></i>\n </ax-prefix>\n </ax-button-item>\n <ax-button-item\n [text]=\"('@general:terms.interface.card-expanded-view' | translate | async)!\"\n [selected]=\"listDisplayMode() === 'card-expanded'\"\n (onClick)=\"setListDisplayMode('card-expanded')\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-grid-2\"></i>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </div>\n </div>\n </ax-popover>\n </div>\n }\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i3.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i3.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPQueryFiltersComponent, selector: "axp-query-filters", inputs: ["filtersDefinitions", "initialFilters"], outputs: ["onFiltersChanged"] }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i3$2.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disablePanelClass", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "closeOnScroll", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "component", type: AXPQuerySortsComponent, selector: "axp-query-sorts", inputs: ["sortDefinitions", "initialSortQueries"], outputs: ["sortDefinitionsChange", "sortQueriesChange"] }, { kind: "component", type: AXPQueryViewsComponent, selector: "axp-query-views", inputs: ["views", "selectedView"], outputs: ["viewsChange", "selectedViewChange"] }, { kind: "component", type: AXPQueryColumnsComponent, selector: "axp-query-columns", inputs: ["columns"], outputs: ["columnsChange"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1441
+ }
1442
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityMasterToolbarViewComponent, decorators: [{
1443
+ type: Component,
1444
+ args: [{ selector: 'axp-entity-master-toolbar-view', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
1445
+ AsyncPipe,
1446
+ AXButtonModule,
1447
+ AXDecoratorModule,
1448
+ AXDropdownModule,
1449
+ AXTranslationModule,
1450
+ AXPQueryFiltersComponent,
1451
+ AXPopoverModule,
1452
+ AXPQuerySortsComponent,
1453
+ AXPQueryViewsComponent,
1454
+ AXPQueryColumnsComponent,
1455
+ ], host: {
1456
+ class: 'ax-w-full',
1457
+ }, template: "<!-- <axp-entity-view-toolbar [viewModel]=\"vm\"></axp-entity-view-toolbar> -->\n<axp-query-views\n id=\"axp-toolbar-view-selector\"\n [views]=\"viewQueries()\"\n [selectedView]=\"selectedViewQuery()\"\n (selectedViewChange)=\"onViewChanged($event)\"\n></axp-query-views>\n<div class=\"ax-flex ax-items-center ax-gap-2 ax-border-b ax-border-light w-full\">\n <!-- <axp-entity-filter-toolbar [viewModel]=\"vm\"></axp-entity-filter-toolbar> -->\n <axp-query-filters\n id=\"axp-toolbar-filters\"\n [filtersDefinitions]=\"filtersDefinitions()\"\n [initialFilters]=\"initialFilters()\"\n (onFiltersChanged)=\"onFiltersChanged($event)\"\n ></axp-query-filters>\n\n <div class=\"ax-flex ax-items-center ax-gap-2 md:ax-gap-2\">\n @if (filterTriggerMode === 'manual' && isFiltersDirty()) {\n <ax-button\n id=\"axp-toolbar-btn-filter\"\n [title]=\"'@general:actions.apply.title'\"\n [iconOnly]=\"true\"\n #filterButton\n [color]=\"'primary'\"\n (onClick)=\"applyFilters()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-search\"></i>\n </ax-prefix>\n </ax-button>\n }\n @if (vm.activeListLayout() === 'table') {\n <div>\n <ax-button id=\"axp-toolbar-btn-columns\" [iconOnly]=\"true\" #columnButton [color]=\"'default'\">\n <i class=\"fa-light fa-table-columns\"></i>\n </ax-button>\n <ax-popover\n id=\"axp-popover-columns\"\n [adaptivityEnabled]=\"true\"\n [offsetY]=\"10\"\n [target]=\"columnButton\"\n [openOn]=\"'toggle'\"\n [closeOn]=\"'clickOut'\"\n #columnsPopover\n >\n <div class=\"ax-lightest-surface ax-shadow-md ax-border md:ax-w-72 ax-w-full ax-rounded-md\">\n <ax-header class=\"ax-border-b ax-lighter-surface ax-rounded-t-md ax-p-4 ax-font-bold\">\n {{ '@general:terms.common.columns' | translate | async }}\n </ax-header>\n <div class=\"ax-py-2 ax-px-4\">\n <axp-query-columns [columns]=\"vm.columns()\" (columnsChange)=\"onColumnsChange($event)\"></axp-query-columns>\n </div>\n </div>\n </ax-popover>\n </div>\n }\n\n @if (vm.canSort()) {\n <div>\n <ax-button id=\"axp-toolbar-btn-sort\" [iconOnly]=\"true\" [text]=\"'Sorts'\" #sortButton [color]=\"'default'\">\n <i class=\"fa-light fa-sort-amount-up\"></i>\n </ax-button>\n <ax-popover\n id=\"axp-popover-sort\"\n [adaptivityEnabled]=\"true\"\n [offsetY]=\"10\"\n [target]=\"sortButton\"\n [openOn]=\"'toggle'\"\n [closeOn]=\"'clickOut'\"\n #popover\n >\n <div class=\"ax-lightest-surface ax-shadow-md ax-border md:ax-w-72 ax-w-full ax-rounded-md\">\n <ax-header class=\"ax-border-b ax-lighter-surface ax-rounded-t-md ax-p-4 ax-font-bold\">\n {{ '@general:terms.common.sorts' | translate | async }}\n </ax-header>\n <div class=\"ax-py-2 ax-px-4\">\n <!-- <axp-list-view-option-sorting [viewModel]=\"vm\"></axp-list-view-option-sorting> -->\n <axp-query-sorts\n [sortDefinitions]=\"sortDefinitions()\"\n (sortQueriesChange)=\"onSortQueriesChange($event)\"\n [initialSortQueries]=\"sortQueries()\"\n ></axp-query-sorts>\n </div>\n </div>\n </ax-popover>\n </div>\n }\n @if (deviceService.isSmall()) {\n <ax-button\n id=\"axp-toolbar-btn-category\"\n (onClick)=\"parent.toggleCategoryDrawer()\"\n [iconOnly]=\"true\"\n [color]=\"'default'\"\n >\n <i class=\"fa-light fa-bars\"></i>\n </ax-button>\n }\n\n @if (showListDisplayModeControl()) {\n <div>\n <ax-button id=\"axp-toolbar-btn-list-display\" [iconOnly]=\"true\" #listDisplayButton [color]=\"'default'\">\n <i [class]=\"listDisplayModeButtonIcon()\"></i>\n </ax-button>\n <ax-popover\n id=\"axp-popover-list-display\"\n [adaptivityEnabled]=\"true\"\n [offsetY]=\"10\"\n [target]=\"listDisplayButton\"\n [openOn]=\"'toggle'\"\n [closeOn]=\"'clickOut'\"\n #listDisplayModePopover\n >\n <div class=\"ax-lightest-surface ax-shadow-md ax-border md:ax-w-72 ax-w-full ax-rounded-md\">\n <ax-header class=\"ax-border-b ax-lighter-surface ax-rounded-t-md ax-p-4 ax-font-bold\">\n {{ '@general:terms.interface.list-display' | translate | async }}\n </ax-header>\n <div class=\"ax-py-2 ax-px-2\">\n <ax-button-item-list>\n @if (hasTableListDisplayOption()) {\n <ax-button-item\n [text]=\"('@general:terms.interface.table-view' | translate | async)!\"\n [selected]=\"listDisplayMode() === 'table'\"\n (onClick)=\"setListDisplayMode('table')\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-table\"></i>\n </ax-prefix>\n </ax-button-item>\n }\n @if (hasTableListDisplayOption()) {\n <ax-divider />\n }\n <ax-button-item\n [text]=\"('@general:terms.interface.card-compact-view' | translate | async)!\"\n [selected]=\"listDisplayMode() === 'card-compact'\"\n (onClick)=\"setListDisplayMode('card-compact')\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-grip-lines\"></i>\n </ax-prefix>\n </ax-button-item>\n <ax-button-item\n [text]=\"('@general:terms.interface.card-expanded-view' | translate | async)!\"\n [selected]=\"listDisplayMode() === 'card-expanded'\"\n (onClick)=\"setListDisplayMode('card-expanded')\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-grid-2\"></i>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </div>\n </div>\n </ax-popover>\n </div>\n }\n </div>\n</div>\n" }]
1458
+ }], propDecorators: { vm: [{
1459
+ type: Input,
1460
+ args: ['viewModel']
1461
+ }], listDisplayModePopover: [{ type: i0.ViewChild, args: ['listDisplayModePopover', { isSignal: true }] }] } });
1462
+
1463
+ class AXPEntityMasterListCardItemSkeletonComponent {
1464
+ constructor() {
1465
+ //#region ---- Inputs ----
1466
+ this.fieldCount = input(4, ...(ngDevMode ? [{ debugName: "fieldCount" }] : /* istanbul ignore next */ []));
1467
+ this.badgeCount = input(1, ...(ngDevMode ? [{ debugName: "badgeCount" }] : /* istanbul ignore next */ []));
1468
+ this.showFooter = input(true, ...(ngDevMode ? [{ debugName: "showFooter" }] : /* istanbul ignore next */ []));
1469
+ this.showHeaderMenu = input(false, ...(ngDevMode ? [{ debugName: "showHeaderMenu" }] : /* istanbul ignore next */ []));
1470
+ this.showContent = input(true, ...(ngDevMode ? [{ debugName: "showContent" }] : /* istanbul ignore next */ []));
1471
+ //#endregion
1472
+ //#region ---- Computed ----
1473
+ this.fieldPlaceholders = computed(() => Array.from({ length: Math.max(this.fieldCount(), 0) }, (_, index) => index), ...(ngDevMode ? [{ debugName: "fieldPlaceholders" }] : /* istanbul ignore next */ []));
1474
+ this.badgePlaceholders = computed(() => Array.from({ length: Math.max(this.badgeCount(), 0) }, (_, index) => index), ...(ngDevMode ? [{ debugName: "badgePlaceholders" }] : /* istanbul ignore next */ []));
1475
+ }
1476
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityMasterListCardItemSkeletonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1477
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPEntityMasterListCardItemSkeletonComponent, isStandalone: true, selector: "axp-entity-master-list-card-item-skeleton", inputs: { fieldCount: { classPropertyName: "fieldCount", publicName: "fieldCount", isSignal: true, isRequired: false, transformFunction: null }, badgeCount: { classPropertyName: "badgeCount", publicName: "badgeCount", isSignal: true, isRequired: false, transformFunction: null }, showFooter: { classPropertyName: "showFooter", publicName: "showFooter", isSignal: true, isRequired: false, transformFunction: null }, showHeaderMenu: { classPropertyName: "showHeaderMenu", publicName: "showHeaderMenu", isSignal: true, isRequired: false, transformFunction: null }, showContent: { classPropertyName: "showContent", publicName: "showContent", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<article class=\"axp-entity-card-skeleton\" aria-hidden=\"true\">\n <div class=\"axp-entity-card-skeleton__header\">\n <div class=\"axp-entity-card-skeleton__header-main\">\n <div class=\"axp-entity-card-skeleton__header-text\">\n <ax-skeleton [animated]=\"true\" class=\"axp-entity-card-skeleton__title\"></ax-skeleton>\n @if (showContent()) {\n <ax-skeleton [animated]=\"true\" class=\"axp-entity-card-skeleton__description\"></ax-skeleton>\n }\n </div>\n @for (index of badgePlaceholders(); track index) {\n <ax-skeleton [animated]=\"true\" class=\"axp-entity-card-skeleton__badge\"></ax-skeleton>\n }\n </div>\n @if (showHeaderMenu()) {\n <ax-skeleton [animated]=\"true\" class=\"axp-entity-card-skeleton__menu\"></ax-skeleton>\n }\n </div>\n\n @if (showContent()) {\n @if (fieldPlaceholders().length) {\n <div class=\"axp-entity-card-skeleton__fields\">\n @for (index of fieldPlaceholders(); track index) {\n <div class=\"axp-entity-card-skeleton__field-row\">\n <ax-skeleton [animated]=\"true\" class=\"axp-entity-card-skeleton__field-label\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"axp-entity-card-skeleton__field-value\"></ax-skeleton>\n </div>\n }\n </div>\n }\n }\n\n @if (showFooter()) {\n <footer class=\"axp-entity-card-skeleton__footer\">\n <ax-skeleton [animated]=\"true\" class=\"axp-entity-card-skeleton__primary-action\"></ax-skeleton>\n </footer>\n }\n</article>\n", styles: [":host{display:block;height:auto;width:100%}.axp-entity-card-skeleton{display:flex;height:auto;width:100%;flex-direction:column;gap:1rem;border-radius:.75rem;border-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lightest-surface),var(--tw-bg-opacity, 1));padding:1rem}.axp-entity-card-skeleton__header{display:flex;align-items:center;justify-content:space-between;gap:.5rem}.axp-entity-card-skeleton__header-main{display:flex;min-width:0px;flex:1 1 0%;flex-wrap:wrap;align-items:flex-start;gap:.5rem}.axp-entity-card-skeleton__header-text{display:flex;min-width:0px;flex:1 1 0%;flex-direction:column;gap:.125rem}.axp-entity-card-skeleton__title{height:1.25rem;width:10rem;max-width:100%;border-radius:.25rem}.axp-entity-card-skeleton__badge{height:1.25rem;width:3.5rem;flex-shrink:0;border-radius:9999px}.axp-entity-card-skeleton__menu{height:2rem;width:2rem;flex-shrink:0;border-radius:.25rem}.axp-entity-card-skeleton__description{height:.875rem;width:8rem;max-width:100%;border-radius:.25rem;--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.axp-entity-card-skeleton__fields{display:flex;flex-direction:column;gap:.75rem;border-top-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));padding-top:1rem}.axp-entity-card-skeleton__field-row{display:flex;align-items:center;justify-content:space-between;gap:.75rem}.axp-entity-card-skeleton__field-label{height:1rem;width:6rem;border-radius:.25rem}.axp-entity-card-skeleton__field-value{height:1rem;width:7rem;border-radius:.25rem}.axp-entity-card-skeleton__footer{margin-left:-1rem;margin-right:-1rem;margin-top:auto;margin-bottom:-1rem;border-bottom-right-radius:.75rem;border-bottom-left-radius:.75rem;border-top-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lighter-surface),var(--tw-bg-opacity, 1));padding:.75rem 1rem}.axp-entity-card-skeleton__primary-action{height:2.5rem;width:100%;border-radius:.5rem}\n"], dependencies: [{ kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i2$2.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1478
+ }
1479
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityMasterListCardItemSkeletonComponent, decorators: [{
1480
+ type: Component,
1481
+ args: [{ selector: 'axp-entity-master-list-card-item-skeleton', changeDetection: ChangeDetectionStrategy.OnPush, imports: [AXSkeletonModule], template: "<article class=\"axp-entity-card-skeleton\" aria-hidden=\"true\">\n <div class=\"axp-entity-card-skeleton__header\">\n <div class=\"axp-entity-card-skeleton__header-main\">\n <div class=\"axp-entity-card-skeleton__header-text\">\n <ax-skeleton [animated]=\"true\" class=\"axp-entity-card-skeleton__title\"></ax-skeleton>\n @if (showContent()) {\n <ax-skeleton [animated]=\"true\" class=\"axp-entity-card-skeleton__description\"></ax-skeleton>\n }\n </div>\n @for (index of badgePlaceholders(); track index) {\n <ax-skeleton [animated]=\"true\" class=\"axp-entity-card-skeleton__badge\"></ax-skeleton>\n }\n </div>\n @if (showHeaderMenu()) {\n <ax-skeleton [animated]=\"true\" class=\"axp-entity-card-skeleton__menu\"></ax-skeleton>\n }\n </div>\n\n @if (showContent()) {\n @if (fieldPlaceholders().length) {\n <div class=\"axp-entity-card-skeleton__fields\">\n @for (index of fieldPlaceholders(); track index) {\n <div class=\"axp-entity-card-skeleton__field-row\">\n <ax-skeleton [animated]=\"true\" class=\"axp-entity-card-skeleton__field-label\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"axp-entity-card-skeleton__field-value\"></ax-skeleton>\n </div>\n }\n </div>\n }\n }\n\n @if (showFooter()) {\n <footer class=\"axp-entity-card-skeleton__footer\">\n <ax-skeleton [animated]=\"true\" class=\"axp-entity-card-skeleton__primary-action\"></ax-skeleton>\n </footer>\n }\n</article>\n", styles: [":host{display:block;height:auto;width:100%}.axp-entity-card-skeleton{display:flex;height:auto;width:100%;flex-direction:column;gap:1rem;border-radius:.75rem;border-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lightest-surface),var(--tw-bg-opacity, 1));padding:1rem}.axp-entity-card-skeleton__header{display:flex;align-items:center;justify-content:space-between;gap:.5rem}.axp-entity-card-skeleton__header-main{display:flex;min-width:0px;flex:1 1 0%;flex-wrap:wrap;align-items:flex-start;gap:.5rem}.axp-entity-card-skeleton__header-text{display:flex;min-width:0px;flex:1 1 0%;flex-direction:column;gap:.125rem}.axp-entity-card-skeleton__title{height:1.25rem;width:10rem;max-width:100%;border-radius:.25rem}.axp-entity-card-skeleton__badge{height:1.25rem;width:3.5rem;flex-shrink:0;border-radius:9999px}.axp-entity-card-skeleton__menu{height:2rem;width:2rem;flex-shrink:0;border-radius:.25rem}.axp-entity-card-skeleton__description{height:.875rem;width:8rem;max-width:100%;border-radius:.25rem;--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.axp-entity-card-skeleton__fields{display:flex;flex-direction:column;gap:.75rem;border-top-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));padding-top:1rem}.axp-entity-card-skeleton__field-row{display:flex;align-items:center;justify-content:space-between;gap:.75rem}.axp-entity-card-skeleton__field-label{height:1rem;width:6rem;border-radius:.25rem}.axp-entity-card-skeleton__field-value{height:1rem;width:7rem;border-radius:.25rem}.axp-entity-card-skeleton__footer{margin-left:-1rem;margin-right:-1rem;margin-top:auto;margin-bottom:-1rem;border-bottom-right-radius:.75rem;border-bottom-left-radius:.75rem;border-top-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lighter-surface),var(--tw-bg-opacity, 1));padding:.75rem 1rem}.axp-entity-card-skeleton__primary-action{height:2.5rem;width:100%;border-radius:.5rem}\n"] }]
1482
+ }], propDecorators: { fieldCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldCount", required: false }] }], badgeCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "badgeCount", required: false }] }], showFooter: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFooter", required: false }] }], showHeaderMenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "showHeaderMenu", required: false }] }], showContent: [{ type: i0.Input, args: [{ isSignal: true, alias: "showContent", required: false }] }] } });
1483
+
1484
+ class AXPEntityMasterListCardItemComponent {
1485
+ //#endregion
1486
+ //#region ---- Lifecycle ----
1487
+ constructor() {
1488
+ this.translation = inject(AXTranslationService);
1489
+ //#region ---- Inputs & Outputs ----
1490
+ this.vm = input.required(...(ngDevMode ? [{ debugName: "vm" }] : /* istanbul ignore next */ []));
1491
+ this.row = input.required(...(ngDevMode ? [{ debugName: "row" }] : /* istanbul ignore next */ []));
1492
+ this.selected = input(false, ...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
1493
+ this.showSelection = input(false, ...(ngDevMode ? [{ debugName: "showSelection" }] : /* istanbul ignore next */ []));
1494
+ this.selectionChange = output();
1495
+ this.commandClick = output();
1496
+ //#endregion
1497
+ //#region ---- Computed ----
1498
+ this.header = computed(() => this.vm().cardLayout()?.header, ...(ngDevMode ? [{ debugName: "header" }] : /* istanbul ignore next */ []));
1499
+ this.showCardContent = computed(() => this.vm().cardContentExpanded(), ...(ngDevMode ? [{ debugName: "showCardContent" }] : /* istanbul ignore next */ []));
1500
+ this.headerBadgeFields = computed(() => this.vm()
1501
+ .cardFields()
1502
+ .filter((field) => field.visible !== false && field.isBadgeDisplay), ...(ngDevMode ? [{ debugName: "headerBadgeFields" }] : /* istanbul ignore next */ []));
1503
+ /** Column name to omit from body when `header.title` is a simple property path (not an expression). */
1504
+ this.headerTitleColumnName = computed(() => {
1505
+ const title = this.header()?.title;
1506
+ if (!title || title.includes('{{')) {
1507
+ return undefined;
1508
+ }
1509
+ return title;
1510
+ }, ...(ngDevMode ? [{ debugName: "headerTitleColumnName" }] : /* istanbul ignore next */ []));
1511
+ this.bodyFields = computed(() => {
1512
+ const titleColumn = this.headerTitleColumnName();
1513
+ return this.vm()
1514
+ .cardFields()
1515
+ .filter((field) => field.visible !== false && !field.isBadgeDisplay && field.name !== titleColumn);
1516
+ }, ...(ngDevMode ? [{ debugName: "bodyFields" }] : /* istanbul ignore next */ []));
1517
+ this.badgeColorByField = signal({}, ...(ngDevMode ? [{ debugName: "badgeColorByField" }] : /* istanbul ignore next */ []));
1518
+ this.titleText = signal('', ...(ngDevMode ? [{ debugName: "titleText" }] : /* istanbul ignore next */ []));
1519
+ this.descriptionText = signal('', ...(ngDevMode ? [{ debugName: "descriptionText" }] : /* istanbul ignore next */ []));
1520
+ this.iconClass = signal(null, ...(ngDevMode ? [{ debugName: "iconClass" }] : /* istanbul ignore next */ []));
1521
+ this.primaryActions = computed(() => this.vm().primaryRowActions(), ...(ngDevMode ? [{ debugName: "primaryActions" }] : /* istanbul ignore next */ []));
1522
+ this.primaryActionsIconOnly = computed(() => !this.vm().cardContentExpanded(), ...(ngDevMode ? [{ debugName: "primaryActionsIconOnly" }] : /* istanbul ignore next */ []));
1523
+ this.secondaryActions = signal([], ...(ngDevMode ? [{ debugName: "secondaryActions" }] : /* istanbul ignore next */ []));
1524
+ effect(() => {
1525
+ const row = this.row();
1526
+ const header = this.header();
1527
+ const badgeFields = this.headerBadgeFields().filter((field) => !this.isStatusBadgeField(field));
1528
+ untracked(() => {
1529
+ void this.loadSecondaryActions(row);
1530
+ void this.resolveHeaderFields(row, header);
1531
+ void this.resolveBadgeColors(row, badgeFields);
1532
+ });
1533
+ });
1534
+ }
1535
+ //#endregion
1536
+ //#region ---- Row Actions ----
1537
+ async loadSecondaryActions(row) {
1538
+ const actions = await this.vm().cardSecondaryRowActions(row);
1539
+ this.secondaryActions.set(actions);
1540
+ }
1541
+ //#endregion
1542
+ //#region ---- UI Handlers ----
1543
+ onCardClick(event) {
1544
+ if (event.ctrlKey || event.metaKey) {
1545
+ event.preventDefault();
1546
+ this.selectionChange.emit(!this.selected());
1547
+ }
1548
+ }
1549
+ onCardDblClick(event) {
1550
+ event.preventDefault();
1551
+ void this.runDefaultAction();
1552
+ }
1553
+ onCardKeydown(event) {
1554
+ if (event.key === 'Enter' || event.key === ' ') {
1555
+ event.preventDefault();
1556
+ void this.runDefaultAction();
1557
+ }
1558
+ }
1559
+ onPrimaryActionClick(actionName, event) {
1560
+ event.nativeEvent?.stopPropagation();
1561
+ const action = this.primaryActions().find((a) => a.name === actionName);
1562
+ if (action && !action.disabled) {
1563
+ this.commandClick.emit(action.name);
1564
+ }
1565
+ }
1566
+ onSecondaryActionClick(item, event) {
1567
+ event.nativeEvent?.stopPropagation();
1568
+ if (item.isCardSelect || item.name === AXPEntityMasterListCardSelectActionName) {
1569
+ if (!this.selected()) {
1570
+ this.selectionChange.emit(true);
1571
+ }
1572
+ return;
1573
+ }
1574
+ this.commandClick.emit(item.name);
1575
+ }
1576
+ onSelectionCheckboxChange(event) {
1577
+ this.selectionChange.emit(!!event.value);
1578
+ }
1579
+ onSelectionCheckboxClick(event) {
1580
+ event.stopPropagation();
1581
+ }
1582
+ stopClickPropagation(event) {
1583
+ event.nativeEvent?.stopPropagation();
1584
+ }
1585
+ isStatusBadgeField(field) {
1586
+ return field.isStatusWidget;
1587
+ }
1588
+ resolveBadgeText(field) {
1589
+ const path = field.node().path ?? field.name;
1590
+ const value = get(this.row(), path);
1591
+ if (value == null) {
1592
+ return '';
1593
+ }
1594
+ if (typeof value === 'object') {
1595
+ const record = value;
1596
+ const label = record['title'] ?? record['name'] ?? record['label'];
1597
+ return label == null ? '' : String(label);
1598
+ }
1599
+ return String(value);
1600
+ }
1601
+ resolveBadgeColor(field) {
1602
+ return this.badgeColorByField()[field.name] ?? 'default';
1603
+ }
1604
+ //#endregion
1605
+ //#region ---- Private Helpers ----
1606
+ async resolveBadgeColors(row, fields) {
1607
+ const vm = this.vm();
1608
+ const entries = await Promise.all(fields.map(async (field) => [field.name, await vm.resolveCardBadgeColor(field, row)]));
1609
+ this.badgeColorByField.set(Object.fromEntries(entries));
1610
+ }
1611
+ async resolveHeaderFields(row, header) {
1612
+ const vm = this.vm();
1613
+ const [title, description, icon] = await Promise.all([
1614
+ vm.resolveCardHeaderValue(header?.title, row),
1615
+ vm.resolveCardHeaderValue(header?.description, row),
1616
+ vm.resolveCardHeaderValue(header?.icon, row),
1617
+ ]);
1618
+ this.titleText.set(title);
1619
+ this.descriptionText.set(description);
1620
+ this.iconClass.set(this.toIconClass(this.toIconString(icon)));
1621
+ }
1622
+ toIconString(value) {
1623
+ if (!value) {
1624
+ return '';
1625
+ }
1626
+ if (typeof value === 'string') {
1627
+ return value;
1628
+ }
1629
+ if (this.translation.isValidMultiLanguageObject(value)) {
1630
+ return this.translation.resolve(value);
1631
+ }
1632
+ return '';
1633
+ }
1634
+ toIconClass(value) {
1635
+ if (!value) {
1636
+ return null;
1637
+ }
1638
+ return value.includes('fa-') ? value : `fa-light fa-${value}`;
1639
+ }
1640
+ async runDefaultAction() {
1641
+ const primary = this.primaryActions();
1642
+ const secondary = this.secondaryActions().filter((a) => !a.isCardSelect);
1643
+ const all = [...primary, ...secondary].filter(Boolean);
1644
+ const defaultAction = all.find((a) => {
1645
+ if (!a) {
1646
+ return false;
1647
+ }
1648
+ const commandName = a.name.split('&')[0];
1649
+ return (a.default || commandName === 'open-entity') && !a.disabled;
1650
+ });
1651
+ if (defaultAction) {
1652
+ this.commandClick.emit(defaultAction.name);
1653
+ }
1654
+ }
1655
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityMasterListCardItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1656
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPEntityMasterListCardItemComponent, isStandalone: true, selector: "axp-entity-master-list-card-item", inputs: { vm: { classPropertyName: "vm", publicName: "vm", isSignal: true, isRequired: true, transformFunction: null }, row: { classPropertyName: "row", publicName: "row", isSignal: true, isRequired: true, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, showSelection: { classPropertyName: "showSelection", publicName: "showSelection", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange", commandClick: "commandClick" }, ngImport: i0, template: "<article\n class=\"axp-entity-card\"\n role=\"button\"\n tabindex=\"0\"\n [class.axp-entity-card--selected]=\"selected()\"\n [attr.aria-selected]=\"selected()\"\n (click)=\"onCardClick($event)\"\n (dblclick)=\"onCardDblClick($event)\"\n (keydown)=\"onCardKeydown($event)\"\n>\n <div class=\"axp-entity-card__header\">\n <div class=\"axp-entity-card__header-main\">\n <div class=\"axp-entity-card__header-text\">\n <div class=\"axp-entity-card__title-row\">\n @if (iconClass(); as icon) {\n <i [class]=\"icon + ' axp-entity-card__icon'\" aria-hidden=\"true\"></i>\n }\n\n <h3 class=\"axp-entity-card__title\" title=\"{{ titleText() | translate | async }}\">\n {{ titleText() | translate | async }}\n </h3>\n\n @for (field of headerBadgeFields(); track field.name) {\n @if (isStatusBadgeField(field)) {\n <div class=\"axp-entity-card__header-badge\">\n <axp-widget-column-cell [node]=\"field.headerBadgeNode()\" [rowData]=\"row()\" [caption]=\"field.title\" />\n </div>\n } @else if (resolveBadgeText(field)) {\n <ax-badge\n class=\"axp-entity-card__header-badge\"\n [text]=\"resolveBadgeText(field)\"\n [color]=\"resolveBadgeColor(field)\"\n />\n }\n }\n </div>\n\n @if (descriptionText()) {\n <p class=\"axp-entity-card__description\" title=\"{{ descriptionText() | translate | async }}\">\n {{ descriptionText() | translate | async }}\n </p>\n }\n </div>\n </div>\n\n @if (showSelection() || secondaryActions().length) {\n <div class=\"axp-entity-card__header-actions\">\n @if (showSelection()) {\n <ax-check-box\n class=\"axp-entity-card__select-checkbox\"\n [value]=\"selected()\"\n (onValueChanged)=\"onSelectionCheckboxChange($event)\"\n (click)=\"onSelectionCheckboxClick($event)\"\n />\n } @else if (secondaryActions().length) {\n <ax-button [look]=\"'blank'\" [color]=\"'default'\" (onClick)=\"stopClickPropagation($event)\">\n <ax-prefix>\n <i class=\"fa-solid fa-ellipsis\" aria-hidden=\"true\"></i>\n </ax-prefix>\n\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (item of secondaryActions(); track item.name) {\n @if (item.divided) {\n <ax-divider />\n }\n <ax-button-item\n [text]=\"(item.title | translate | async)!\"\n [color]=\"item.color\"\n [disabled]=\"item.disabled\"\n (onClick)=\"onSecondaryActionClick(item, $event)\"\n >\n @if (item.icon) {\n <ax-prefix>\n <ax-icon icon=\"fa-light {{ item.icon }}\"></ax-icon>\n </ax-prefix>\n }\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n </div>\n }\n </div>\n\n @if (showCardContent()) {\n @if (bodyFields().length) {\n <div class=\"axp-entity-card__fields ax-grid ax-grid-cols-12 ax-gap-y-3 ax-gap-x-4\">\n @for (field of bodyFields(); track field.name) {\n <div\n class=\"axp-entity-card__field ax-col-span-12\"\n [axp-grid-layout]=\"field.layout ?? { positions: { sm: { colSpan: 12 } } }\"\n >\n <div class=\"axp-entity-card__field-row\">\n <span class=\"axp-entity-card__field-label\">{{ field.title | translate | async }}</span>\n\n <div class=\"axp-entity-card__field-value\">\n <axp-widget-column-cell [node]=\"field.node()\" [rowData]=\"row()\" [caption]=\"field.title\" />\n </div>\n </div>\n </div>\n }\n </div>\n }\n }\n\n @if (primaryActions().length) {\n <footer class=\"axp-entity-card__footer\">\n @for (action of primaryActions(); track action.name) {\n <ax-button\n class=\"axp-entity-card__primary-action ax-text-xs\"\n [class.ax-flex-1]=\"!primaryActionsIconOnly()\"\n [look]=\"'outline'\"\n [color]=\"action.color\"\n [size]=\"'sm'\"\n [iconOnly]=\"primaryActionsIconOnly()\"\n [disabled]=\"action.disabled\"\n [text]=\"(action.title | translate | async)!\"\n (onClick)=\"onPrimaryActionClick(action.name, $event)\"\n >\n @if (action.icon) {\n <ax-prefix>\n <i class=\"fa-light {{ action.icon }}\"></i>\n </ax-prefix>\n }\n </ax-button>\n }\n </footer>\n }\n</article>\n", styles: [":host{display:block;height:auto;width:100%}.axp-entity-card{display:flex;height:auto;width:100%;flex-direction:column;gap:1rem;border-radius:.75rem;border-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lightest-surface),var(--tw-bg-opacity, 1));padding:1rem;cursor:pointer;transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.axp-entity-card:hover{--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-entity-card:focus-visible{outline-width:2px;outline-offset:2px;outline-color:rgba(var(--ax-sys-color-primary-500),1)}.axp-entity-card--selected{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-primary-500),var(--tw-border-opacity, 1));--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 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);box-shadow:0 0 0 1px rgb(var(--ax-sys-color-primary-500)/.25),0 2px 6px #0000000f}.axp-entity-card__header{display:flex;align-items:center;justify-content:space-between;gap:.5rem}.axp-entity-card__header-main{display:flex;min-width:0px;flex:1 1 0%;flex-wrap:wrap;align-items:center;gap:.5rem}.axp-entity-card__header-text{display:flex;min-width:0px;flex:1 1 0%;flex-direction:column;gap:.125rem}.axp-entity-card__title-row{display:flex;min-width:0px;align-items:center;gap:.5rem}.axp-entity-card__select-checkbox,.axp-entity-card__header-badge{flex-shrink:0}.axp-entity-card__header-actions{display:flex;flex-shrink:0;align-items:center;gap:.125rem}.axp-entity-card__title{min-width:0px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:1.125rem;line-height:1.75rem;font-weight:700;line-height:1.25}.axp-entity-card__icon{flex-shrink:0;font-size:1.125rem;line-height:1.75rem;--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.axp-entity-card__description{min-width:0px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;line-height:1.375;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lightest-surface),var(--tw-text-opacity, 1))}.axp-entity-card__fields{border-top-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));padding-top:1rem}.axp-entity-card__field-row{display:grid;width:100%;align-items:center;gap:.75rem;grid-template-columns:auto minmax(0,1fr)}.axp-entity-card__field-label{flex-shrink:0;font-size:.875rem;line-height:1.25rem;font-weight:600;--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.axp-entity-card__field-value{min-width:0px;max-width:100%;justify-self:end;text-align:end;font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lightest-surface),var(--tw-text-opacity, 1));width:fit-content}.axp-entity-card__field-value axp-widget-column-cell{display:block;max-width:100%}.axp-entity-card__footer{margin-left:-1rem;margin-right:-1rem;margin-top:auto;margin-bottom:-1rem;display:flex;align-items:center;justify-content:flex-end;gap:1rem;border-bottom-right-radius:.75rem;border-bottom-left-radius:.75rem;border-top-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lighter-surface),var(--tw-bg-opacity, 1));padding:.75rem 1rem}.axp-entity-card__primary-action{min-width:0px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i1$2.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i3.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i3.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXCheckBoxModule }, { kind: "component", type: i3$3.AXCheckBoxComponent, selector: "ax-check-box", inputs: ["disabled", "tabIndex", "readonly", "color", "value", "name", "id", "isLoading", "indeterminate"], outputs: ["onBlur", "onFocus", "valueChange", "onValueChanged"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: 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: AXPGridLayoutDirective, selector: "[axp-grid-layout]", inputs: ["axp-grid-layout"] }, { kind: "component", type: AXPWidgetColumnCellComponent, selector: "axp-widget-column-cell", inputs: ["node", "rowData", "caption"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1657
+ }
1658
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityMasterListCardItemComponent, decorators: [{
1659
+ type: Component,
1660
+ args: [{ selector: 'axp-entity-master-list-card-item', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
1661
+ CommonModule,
1662
+ AXBadgeModule,
1663
+ AXButtonModule,
1664
+ AXCheckBoxModule,
1665
+ AXDecoratorModule,
1666
+ AXDropdownModule,
1667
+ AXTranslationModule,
1668
+ AXPGridLayoutDirective,
1669
+ AXPWidgetColumnCellComponent,
1670
+ ], template: "<article\n class=\"axp-entity-card\"\n role=\"button\"\n tabindex=\"0\"\n [class.axp-entity-card--selected]=\"selected()\"\n [attr.aria-selected]=\"selected()\"\n (click)=\"onCardClick($event)\"\n (dblclick)=\"onCardDblClick($event)\"\n (keydown)=\"onCardKeydown($event)\"\n>\n <div class=\"axp-entity-card__header\">\n <div class=\"axp-entity-card__header-main\">\n <div class=\"axp-entity-card__header-text\">\n <div class=\"axp-entity-card__title-row\">\n @if (iconClass(); as icon) {\n <i [class]=\"icon + ' axp-entity-card__icon'\" aria-hidden=\"true\"></i>\n }\n\n <h3 class=\"axp-entity-card__title\" title=\"{{ titleText() | translate | async }}\">\n {{ titleText() | translate | async }}\n </h3>\n\n @for (field of headerBadgeFields(); track field.name) {\n @if (isStatusBadgeField(field)) {\n <div class=\"axp-entity-card__header-badge\">\n <axp-widget-column-cell [node]=\"field.headerBadgeNode()\" [rowData]=\"row()\" [caption]=\"field.title\" />\n </div>\n } @else if (resolveBadgeText(field)) {\n <ax-badge\n class=\"axp-entity-card__header-badge\"\n [text]=\"resolveBadgeText(field)\"\n [color]=\"resolveBadgeColor(field)\"\n />\n }\n }\n </div>\n\n @if (descriptionText()) {\n <p class=\"axp-entity-card__description\" title=\"{{ descriptionText() | translate | async }}\">\n {{ descriptionText() | translate | async }}\n </p>\n }\n </div>\n </div>\n\n @if (showSelection() || secondaryActions().length) {\n <div class=\"axp-entity-card__header-actions\">\n @if (showSelection()) {\n <ax-check-box\n class=\"axp-entity-card__select-checkbox\"\n [value]=\"selected()\"\n (onValueChanged)=\"onSelectionCheckboxChange($event)\"\n (click)=\"onSelectionCheckboxClick($event)\"\n />\n } @else if (secondaryActions().length) {\n <ax-button [look]=\"'blank'\" [color]=\"'default'\" (onClick)=\"stopClickPropagation($event)\">\n <ax-prefix>\n <i class=\"fa-solid fa-ellipsis\" aria-hidden=\"true\"></i>\n </ax-prefix>\n\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (item of secondaryActions(); track item.name) {\n @if (item.divided) {\n <ax-divider />\n }\n <ax-button-item\n [text]=\"(item.title | translate | async)!\"\n [color]=\"item.color\"\n [disabled]=\"item.disabled\"\n (onClick)=\"onSecondaryActionClick(item, $event)\"\n >\n @if (item.icon) {\n <ax-prefix>\n <ax-icon icon=\"fa-light {{ item.icon }}\"></ax-icon>\n </ax-prefix>\n }\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n }\n </div>\n }\n </div>\n\n @if (showCardContent()) {\n @if (bodyFields().length) {\n <div class=\"axp-entity-card__fields ax-grid ax-grid-cols-12 ax-gap-y-3 ax-gap-x-4\">\n @for (field of bodyFields(); track field.name) {\n <div\n class=\"axp-entity-card__field ax-col-span-12\"\n [axp-grid-layout]=\"field.layout ?? { positions: { sm: { colSpan: 12 } } }\"\n >\n <div class=\"axp-entity-card__field-row\">\n <span class=\"axp-entity-card__field-label\">{{ field.title | translate | async }}</span>\n\n <div class=\"axp-entity-card__field-value\">\n <axp-widget-column-cell [node]=\"field.node()\" [rowData]=\"row()\" [caption]=\"field.title\" />\n </div>\n </div>\n </div>\n }\n </div>\n }\n }\n\n @if (primaryActions().length) {\n <footer class=\"axp-entity-card__footer\">\n @for (action of primaryActions(); track action.name) {\n <ax-button\n class=\"axp-entity-card__primary-action ax-text-xs\"\n [class.ax-flex-1]=\"!primaryActionsIconOnly()\"\n [look]=\"'outline'\"\n [color]=\"action.color\"\n [size]=\"'sm'\"\n [iconOnly]=\"primaryActionsIconOnly()\"\n [disabled]=\"action.disabled\"\n [text]=\"(action.title | translate | async)!\"\n (onClick)=\"onPrimaryActionClick(action.name, $event)\"\n >\n @if (action.icon) {\n <ax-prefix>\n <i class=\"fa-light {{ action.icon }}\"></i>\n </ax-prefix>\n }\n </ax-button>\n }\n </footer>\n }\n</article>\n", styles: [":host{display:block;height:auto;width:100%}.axp-entity-card{display:flex;height:auto;width:100%;flex-direction:column;gap:1rem;border-radius:.75rem;border-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lightest-surface),var(--tw-bg-opacity, 1));padding:1rem;cursor:pointer;transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.axp-entity-card:hover{--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-entity-card:focus-visible{outline-width:2px;outline-offset:2px;outline-color:rgba(var(--ax-sys-color-primary-500),1)}.axp-entity-card--selected{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-primary-500),var(--tw-border-opacity, 1));--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 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);box-shadow:0 0 0 1px rgb(var(--ax-sys-color-primary-500)/.25),0 2px 6px #0000000f}.axp-entity-card__header{display:flex;align-items:center;justify-content:space-between;gap:.5rem}.axp-entity-card__header-main{display:flex;min-width:0px;flex:1 1 0%;flex-wrap:wrap;align-items:center;gap:.5rem}.axp-entity-card__header-text{display:flex;min-width:0px;flex:1 1 0%;flex-direction:column;gap:.125rem}.axp-entity-card__title-row{display:flex;min-width:0px;align-items:center;gap:.5rem}.axp-entity-card__select-checkbox,.axp-entity-card__header-badge{flex-shrink:0}.axp-entity-card__header-actions{display:flex;flex-shrink:0;align-items:center;gap:.125rem}.axp-entity-card__title{min-width:0px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:1.125rem;line-height:1.75rem;font-weight:700;line-height:1.25}.axp-entity-card__icon{flex-shrink:0;font-size:1.125rem;line-height:1.75rem;--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.axp-entity-card__description{min-width:0px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;line-height:1.375;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lightest-surface),var(--tw-text-opacity, 1))}.axp-entity-card__fields{border-top-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));padding-top:1rem}.axp-entity-card__field-row{display:grid;width:100%;align-items:center;gap:.75rem;grid-template-columns:auto minmax(0,1fr)}.axp-entity-card__field-label{flex-shrink:0;font-size:.875rem;line-height:1.25rem;font-weight:600;--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.axp-entity-card__field-value{min-width:0px;max-width:100%;justify-self:end;text-align:end;font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lightest-surface),var(--tw-text-opacity, 1));width:fit-content}.axp-entity-card__field-value axp-widget-column-cell{display:block;max-width:100%}.axp-entity-card__footer{margin-left:-1rem;margin-right:-1rem;margin-top:auto;margin-bottom:-1rem;display:flex;align-items:center;justify-content:flex-end;gap:1rem;border-bottom-right-radius:.75rem;border-bottom-left-radius:.75rem;border-top-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lighter-surface),var(--tw-bg-opacity, 1));padding:.75rem 1rem}.axp-entity-card__primary-action{min-width:0px}\n"] }]
1671
+ }], ctorParameters: () => [], propDecorators: { vm: [{ type: i0.Input, args: [{ isSignal: true, alias: "vm", required: true }] }], row: [{ type: i0.Input, args: [{ isSignal: true, alias: "row", required: true }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }], showSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSelection", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], commandClick: [{ type: i0.Output, args: ["commandClick"] }] } });
1672
+
1673
+ class AXPEntityMasterListCardListComponent {
1674
+ //#endregion
1675
+ //#region ---- Lifecycle ----
1676
+ constructor() {
1677
+ //#region ---- Services & Dependencies ----
1678
+ this.deviceService = inject(AXPDeviceService);
1679
+ //#endregion
1680
+ //#region ---- Inputs & Outputs ----
1681
+ this.vm = input.required(...(ngDevMode ? [{ debugName: "vm" }] : /* istanbul ignore next */ []));
1682
+ this.pageChanged = output();
1683
+ //#endregion
1684
+ //#region ---- State ----
1685
+ this.pagerDisplayMode = computed(() => this.deviceService.isSmall() ? 'compact' : 'full', ...(ngDevMode ? [{ debugName: "pagerDisplayMode" }] : /* istanbul ignore next */ []));
1686
+ this.items = signal([], ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
1687
+ this.loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
1688
+ this.totalCount = signal(0, ...(ngDevMode ? [{ debugName: "totalCount" }] : /* istanbul ignore next */ []));
1689
+ this.pageIndex = signal(0, ...(ngDevMode ? [{ debugName: "pageIndex" }] : /* istanbul ignore next */ []));
1690
+ this.pageSize = signal(10, ...(ngDevMode ? [{ debugName: "pageSize" }] : /* istanbul ignore next */ []));
1691
+ this.showSelection = computed(() => this.vm().selectedItems().length > 0, ...(ngDevMode ? [{ debugName: "showSelection" }] : /* istanbul ignore next */ []));
1692
+ this.rowKey = computed(() => this.vm().dataSource.config?.key ?? 'id', ...(ngDevMode ? [{ debugName: "rowKey" }] : /* istanbul ignore next */ []));
1693
+ this.skeletonCount = computed(() => Math.max(this.pageSize(), 1), ...(ngDevMode ? [{ debugName: "skeletonCount" }] : /* istanbul ignore next */ []));
1694
+ this.skeletonFieldCount = computed(() => {
1695
+ if (!this.vm().cardContentExpanded()) {
1696
+ return 0;
1697
+ }
1698
+ const bodyCount = this.vm()
1699
+ .cardFields()
1700
+ .filter((field) => field.visible !== false && !field.isBadgeDisplay).length;
1701
+ return bodyCount > 0 ? bodyCount : 4;
1702
+ }, ...(ngDevMode ? [{ debugName: "skeletonFieldCount" }] : /* istanbul ignore next */ []));
1703
+ this.skeletonBadgeCount = computed(() => {
1704
+ const count = this.vm()
1705
+ .cardFields()
1706
+ .filter((field) => field.visible !== false && field.isBadgeDisplay).length;
1707
+ return count > 0 ? count : 1;
1708
+ }, ...(ngDevMode ? [{ debugName: "skeletonBadgeCount" }] : /* istanbul ignore next */ []));
1709
+ this.skeletonShowFooter = computed(() => this.vm().primaryRowActions().length > 0, ...(ngDevMode ? [{ debugName: "skeletonShowFooter" }] : /* istanbul ignore next */ []));
1710
+ this.skeletonPlaceholders = computed(() => Array.from({ length: this.skeletonCount() }, (_, index) => index), ...(ngDevMode ? [{ debugName: "skeletonPlaceholders" }] : /* istanbul ignore next */ []));
1711
+ effect((onCleanup) => {
1712
+ const vm = this.vm();
1713
+ const dataSource = vm.dataSource;
1714
+ untracked(() => {
1715
+ this.syncPagingFromDataSource(vm);
1716
+ this.syncFromDataSource();
1717
+ });
1718
+ const changedSub = dataSource.onChanged.subscribe(() => {
1719
+ this.syncFromDataSource();
1720
+ });
1721
+ const loadingSub = dataSource.onLoadingChanged.subscribe((isLoading) => {
1722
+ this.loading.set(isLoading);
1723
+ });
1724
+ onCleanup(() => {
1725
+ changedSub.unsubscribe();
1726
+ loadingSub.unsubscribe();
1727
+ });
1728
+ });
1729
+ }
1730
+ //#endregion
1731
+ //#region ---- Public API ----
1732
+ async reload(resetPagination = false) {
1733
+ if (!resetPagination) {
1734
+ await this.vm().ensureListPagingResolved();
1735
+ this.vm().applyPagingToDataSourceWithoutLoad();
1736
+ }
1737
+ this.vm().dataSource.refresh({ reset: resetPagination });
1738
+ }
1739
+ /** Syncs visible items from the shared data source without triggering a load. */
1740
+ syncFromDataSource() {
1741
+ this.syncItemsFromDataSource();
1742
+ }
1743
+ //#endregion
1744
+ //#region ---- Selection ----
1745
+ trackRow(index, row) {
1746
+ if (!isRowRecord(row)) {
1747
+ return `row-${index}`;
1748
+ }
1749
+ const id = get(row, this.rowKey());
1750
+ return id != null ? String(id) : `row-${index}`;
1751
+ }
1752
+ isRowSelected(row) {
1753
+ const key = this.rowKey();
1754
+ const rowId = get(row, key);
1755
+ return this.vm()
1756
+ .selectedItems()
1757
+ .some((item) => getRowId(item, key) === rowId);
1758
+ }
1759
+ onRowSelectionChange(row, selected) {
1760
+ const key = this.rowKey();
1761
+ const rowId = getRowId(row, key);
1762
+ const current = this.vm().selectedItems();
1763
+ if (selected) {
1764
+ if (!current.some((item) => getRowId(item, key) === rowId)) {
1765
+ this.vm().selectedItems.set([...current, row]);
1766
+ }
1767
+ return;
1768
+ }
1769
+ this.vm().selectedItems.set(current.filter((item) => getRowId(item, key) !== rowId));
1770
+ }
1771
+ //#endregion
1772
+ //#region ---- Commands & Paging ----
1773
+ async onCommandClick(name, row) {
1774
+ await this.vm().executeCommand(name, row);
1775
+ }
1776
+ onPageChanged(event) {
1777
+ if (event.isUserInteraction && !this.vm().skipListPagingPersistence) {
1778
+ this.vm().saveListPaging(event.take, event.skip);
1779
+ }
1780
+ applyDataSourcePagingWithoutLoad(this.vm().dataSource, { take: event.take, skip: event.skip });
1781
+ this.pageChanged.emit(event);
1782
+ void this.reload(false);
1783
+ }
1784
+ //#endregion
1785
+ //#region ---- Private Helpers ----
1786
+ syncItemsFromDataSource() {
1787
+ const ds = this.vm().dataSource;
1788
+ const pageItems = [...ds.items];
1789
+ this.items.set(pageItems.filter(isRowRecord));
1790
+ this.totalCount.set(ds.totalCount ?? this.items().length);
1791
+ this.pageIndex.set(getDataSourcePageIndex(this.vm().dataSource));
1792
+ this.pageSize.set(this.vm().dataSource.config.pageSize ?? 10);
1793
+ }
1794
+ syncPagingFromDataSource(vm) {
1795
+ this.pageIndex.set(getDataSourcePageIndex(vm.dataSource));
1796
+ this.pageSize.set(vm.dataSource.config.pageSize ?? 10);
1797
+ }
1798
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityMasterListCardListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1799
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPEntityMasterListCardListComponent, isStandalone: true, selector: "axp-entity-master-list-card-list", inputs: { vm: { classPropertyName: "vm", publicName: "vm", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { pageChanged: "pageChanged" }, ngImport: i0, template: "<div class=\"axp-entity-card-list\">\n @if (loading()) {\n <div class=\"axp-entity-card-list__grid\" aria-busy=\"true\" aria-live=\"polite\">\n @for (index of skeletonPlaceholders(); track index) {\n <axp-entity-master-list-card-item-skeleton\n [fieldCount]=\"skeletonFieldCount()\"\n [badgeCount]=\"skeletonBadgeCount()\"\n [showContent]=\"vm().cardContentExpanded()\"\n [showFooter]=\"skeletonShowFooter()\"\n />\n }\n </div>\n } @else if (!items().length) {\n <div\n class=\"axp-entity-card-list__empty ax-flex ax-flex-col ax-items-center ax-justify-center ax-flex-1 ax-p-8 ax-text-muted\"\n >\n <i class=\"fa-light fa-grid-2 ax-text-3xl ax-mb-2\" aria-hidden=\"true\"></i>\n <span>{{ '@general:terms.interface.no-items' | translate | async }}</span>\n </div>\n } @else {\n <div class=\"axp-entity-card-list__grid\">\n @for (row of items(); track trackRow($index, row)) {\n @if (row) {\n <axp-entity-master-list-card-item\n [vm]=\"vm()\"\n [row]=\"row\"\n [showSelection]=\"showSelection()\"\n [selected]=\"isRowSelected(row)\"\n (selectionChange)=\"onRowSelectionChange(row, $event)\"\n (commandClick)=\"onCommandClick($event, row)\"\n />\n }\n }\n </div>\n }\n\n <div\n class=\"axp-entity-card-list__pager ax-border-t ax-border-light\"\n [class.axp-entity-card-list__pager--compact]=\"deviceService.isSmall()\"\n >\n <ax-data-pager\n [displayMode]=\"pagerDisplayMode()\"\n [total]=\"totalCount()\"\n [size]=\"pageSize()\"\n [value]=\"pageIndex() + 1\"\n (onChanged)=\"onPageChanged($event)\"\n ></ax-data-pager>\n </div>\n</div>\n", styles: [":host.axp-entity-list-host{display:flex;height:100%;min-height:0px;flex-direction:column;overflow:hidden}.axp-entity-card-list{display:flex;min-height:0px;flex:1 1 0%;flex-direction:column;gap:1rem}.axp-entity-card-list__empty{border-radius:.5rem;border-width:1px;border-style:dashed;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1))}.axp-entity-card-list__grid{display:grid;min-height:0px;flex:1 1 0%;grid-template-columns:repeat(1,minmax(0,1fr));gap:1rem;overflow:auto}@media(min-width:768px){.axp-entity-card-list__grid{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(min-width:1280px){.axp-entity-card-list__grid{grid-template-columns:repeat(3,minmax(0,1fr))}}.axp-entity-card-list__grid{align-content:start;align-items:start;grid-auto-rows:max-content}.axp-entity-card-list__pager{flex-shrink:0;padding-top:.5rem}.axp-entity-card-list__pager ax-data-pager{width:100%}.axp-entity-card-list__pager--compact ::ng-deep ax-data-pager{justify-content:center}.axp-entity-card-list__pager--compact ::ng-deep ax-data-pager .ax-compact-prefix{display:flex;width:100%;justify-content:center}.axp-entity-card-list__pager--compact ::ng-deep ax-data-pager .ax-compact-suffix{display:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXDataPagerModule }, { kind: "component", type: i1$3.AXDataPagerComponent, selector: "ax-data-pager", inputs: ["value", "name", "disabled", "readonly", "isLoading", "size", "total", "displayMode"], outputs: ["valueChange", "onValueChanged", "disabledChange", "readonlyChange", "displayModeChange", "onChanged"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPEntityMasterListCardItemComponent, selector: "axp-entity-master-list-card-item", inputs: ["vm", "row", "selected", "showSelection"], outputs: ["selectionChange", "commandClick"] }, { kind: "component", type: AXPEntityMasterListCardItemSkeletonComponent, selector: "axp-entity-master-list-card-item-skeleton", inputs: ["fieldCount", "badgeCount", "showFooter", "showHeaderMenu", "showContent"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1800
+ }
1801
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityMasterListCardListComponent, decorators: [{
1802
+ type: Component,
1803
+ args: [{ selector: 'axp-entity-master-list-card-list', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
1804
+ CommonModule,
1805
+ AXButtonModule,
1806
+ AXDataPagerModule,
1807
+ AXTranslationModule,
1808
+ AXPEntityMasterListCardItemComponent,
1809
+ AXPEntityMasterListCardItemSkeletonComponent,
1810
+ ], template: "<div class=\"axp-entity-card-list\">\n @if (loading()) {\n <div class=\"axp-entity-card-list__grid\" aria-busy=\"true\" aria-live=\"polite\">\n @for (index of skeletonPlaceholders(); track index) {\n <axp-entity-master-list-card-item-skeleton\n [fieldCount]=\"skeletonFieldCount()\"\n [badgeCount]=\"skeletonBadgeCount()\"\n [showContent]=\"vm().cardContentExpanded()\"\n [showFooter]=\"skeletonShowFooter()\"\n />\n }\n </div>\n } @else if (!items().length) {\n <div\n class=\"axp-entity-card-list__empty ax-flex ax-flex-col ax-items-center ax-justify-center ax-flex-1 ax-p-8 ax-text-muted\"\n >\n <i class=\"fa-light fa-grid-2 ax-text-3xl ax-mb-2\" aria-hidden=\"true\"></i>\n <span>{{ '@general:terms.interface.no-items' | translate | async }}</span>\n </div>\n } @else {\n <div class=\"axp-entity-card-list__grid\">\n @for (row of items(); track trackRow($index, row)) {\n @if (row) {\n <axp-entity-master-list-card-item\n [vm]=\"vm()\"\n [row]=\"row\"\n [showSelection]=\"showSelection()\"\n [selected]=\"isRowSelected(row)\"\n (selectionChange)=\"onRowSelectionChange(row, $event)\"\n (commandClick)=\"onCommandClick($event, row)\"\n />\n }\n }\n </div>\n }\n\n <div\n class=\"axp-entity-card-list__pager ax-border-t ax-border-light\"\n [class.axp-entity-card-list__pager--compact]=\"deviceService.isSmall()\"\n >\n <ax-data-pager\n [displayMode]=\"pagerDisplayMode()\"\n [total]=\"totalCount()\"\n [size]=\"pageSize()\"\n [value]=\"pageIndex() + 1\"\n (onChanged)=\"onPageChanged($event)\"\n ></ax-data-pager>\n </div>\n</div>\n", styles: [":host.axp-entity-list-host{display:flex;height:100%;min-height:0px;flex-direction:column;overflow:hidden}.axp-entity-card-list{display:flex;min-height:0px;flex:1 1 0%;flex-direction:column;gap:1rem}.axp-entity-card-list__empty{border-radius:.5rem;border-width:1px;border-style:dashed;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1))}.axp-entity-card-list__grid{display:grid;min-height:0px;flex:1 1 0%;grid-template-columns:repeat(1,minmax(0,1fr));gap:1rem;overflow:auto}@media(min-width:768px){.axp-entity-card-list__grid{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(min-width:1280px){.axp-entity-card-list__grid{grid-template-columns:repeat(3,minmax(0,1fr))}}.axp-entity-card-list__grid{align-content:start;align-items:start;grid-auto-rows:max-content}.axp-entity-card-list__pager{flex-shrink:0;padding-top:.5rem}.axp-entity-card-list__pager ax-data-pager{width:100%}.axp-entity-card-list__pager--compact ::ng-deep ax-data-pager{justify-content:center}.axp-entity-card-list__pager--compact ::ng-deep ax-data-pager .ax-compact-prefix{display:flex;width:100%;justify-content:center}.axp-entity-card-list__pager--compact ::ng-deep ax-data-pager .ax-compact-suffix{display:none}\n"] }]
1811
+ }], ctorParameters: () => [], propDecorators: { vm: [{ type: i0.Input, args: [{ isSignal: true, alias: "vm", required: true }] }], pageChanged: [{ type: i0.Output, args: ["pageChanged"] }] } });
1812
+ function getRowId(row, key) {
1813
+ if (isRowRecord(row)) {
1814
+ return get(row, key);
1815
+ }
1816
+ return undefined;
1817
+ }
1818
+ function isRowRecord(row) {
1819
+ return row != null && typeof row === 'object' && !Array.isArray(row);
1820
+ }
1821
+
1822
+ class AXPEntityMasterListDataTableComponent {
1823
+ constructor() {
1824
+ //#region ---- Inputs & Outputs ----
1825
+ this.vm = input.required(...(ngDevMode ? [{ debugName: "vm" }] : /* istanbul ignore next */ []));
1826
+ this.pageChanged = output();
1827
+ //#endregion
1828
+ //#region ---- View References ----
1829
+ this.gridRef = viewChild('grid', ...(ngDevMode ? [{ debugName: "gridRef" }] : /* istanbul ignore next */ []));
1830
+ //#endregion
1831
+ //#region ---- Computed ----
1832
+ this.commandRowItems = computed(() => {
1833
+ return this.vm()
1834
+ .primaryRowActions()
1835
+ .map((c) => ({
1836
+ icon: c.icon,
1837
+ name: c.name,
1838
+ text: translateSync(c.title),
1839
+ color: c.color,
1840
+ disabled: c.disabled,
1841
+ default: c.default,
1842
+ }));
1843
+ }, ...(ngDevMode ? [{ debugName: "commandRowItems" }] : /* istanbul ignore next */ []));
1844
+ this.getDropdownRowItems = (rowData) => {
1845
+ return Promise.resolve(this.dropdownRowItems(rowData));
1846
+ };
1847
+ this.getCommandRowItems = () => {
1848
+ return this.commandRowItems();
1849
+ };
1850
+ }
1851
+ /** Exposed for parent refresh and expanded-row persistence. */
1852
+ grid() {
1853
+ return this.gridRef();
1854
+ }
1855
+ //#endregion
1856
+ //#region ---- Table Event Handlers ----
1857
+ onColumnSizeChanged(e) {
1858
+ if (e.isUserInteraction && e.type === 'end') {
1859
+ this.vm().saveSettings('columnSizes', e.data);
1860
+ }
1861
+ }
1862
+ onPageChanged(e) {
1863
+ if (e.isUserInteraction && !this.vm().skipListPagingPersistence) {
1864
+ this.vm().saveListPaging(e.take, e.skip);
1865
+ }
1866
+ this.pageChanged.emit(e);
1867
+ }
1868
+ onColumnsOrderChanged(e) {
1869
+ if (e.isUserInteraction) {
1870
+ this.vm().onColumnsOrderChanged(e.data.event);
1871
+ }
1872
+ }
1873
+ async handleRowDbClick(e) {
1874
+ if (this.grid()?.dataSource.isLoading) {
1875
+ return;
1876
+ }
1877
+ const allItems = [...this.commandRowItems(), ...(await this.dropdownRowItems(e.data))];
1878
+ const defaultAction = allItems.find((c) => {
1879
+ const commandName = c.name.split('&')[0];
1880
+ return (c.default || commandName === 'open-entity') && !c.disabled;
1881
+ });
1882
+ if (!defaultAction) {
1883
+ return;
1884
+ }
1885
+ const d = {
1886
+ component: e.component,
1887
+ name: defaultAction.name,
1888
+ data: e.data,
1889
+ };
1890
+ await this.handleRowCommandClick(d);
1891
+ }
1892
+ async handleRowCommandClick(e) {
1893
+ if (this.grid()?.dataSource.isLoading) {
1894
+ return;
1895
+ }
1896
+ if (e.setLoading) {
1897
+ e.setLoading(true);
1898
+ }
1899
+ await this.vm().executeCommand(e.name, e.data);
1900
+ if (e.setLoading) {
1901
+ e.setLoading(false);
1902
+ }
1903
+ }
1904
+ handleSelectedRowsChange(rows) {
1905
+ this.vm().selectedItems.set(rows);
1906
+ }
1907
+ handleColumnSort(columnName, event) {
1908
+ void this.vm().toggleColumnSort(columnName, event.ctrlKey || event.metaKey);
1909
+ }
1910
+ //#endregion
1911
+ //#region ---- Sort Helpers ----
1912
+ resolveColumnSortDirection(sortedFields, columnName) {
1913
+ const dir = sortedFields.find((s) => s.name === columnName)?.dir;
1914
+ return dir === 'asc' || dir === 'desc' ? dir : undefined;
1915
+ }
1916
+ resolveColumnSortIndex(sortedFields, columnName) {
1917
+ const index = sortedFields.findIndex((s) => s.name === columnName);
1918
+ return index >= 0 ? index + 1 : undefined;
1919
+ }
1920
+ //#endregion
1921
+ //#region ---- Private Helpers ----
1922
+ async dropdownRowItems(rowData) {
1923
+ return (await this.vm().secondaryRowActions(rowData)).map((c) => ({
1924
+ icon: c.icon,
1925
+ name: c.name,
1926
+ text: c.title,
1927
+ color: c.color,
1928
+ disabled: c.disabled,
1929
+ default: c.default,
1930
+ divided: c.separated,
1931
+ }));
1932
+ }
1933
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityMasterListDataTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1934
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPEntityMasterListDataTableComponent, isStandalone: true, selector: "axp-entity-master-list-data-table", inputs: { vm: { classPropertyName: "vm", publicName: "vm", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { pageChanged: "pageChanged" }, host: { styleAttribute: "height: -webkit-fill-available;" }, viewQueries: [{ propertyName: "gridRef", first: true, predicate: ["grid"], descendants: true, isSignal: true }], ngImport: i0, template: "<ax-data-table\n id=\"axp-entity-table\"\n [allowReordering]=\"true\"\n (onColumnsOrderChanged)=\"onColumnsOrderChanged($event)\"\n #grid\n [showFooter]=\"false\"\n class=\"ax-flex-1\"\n [paging]=\"true\"\n [fetchDataMode]=\"'manual'\"\n [parentField]=\"vm().parentKey()\"\n [loading]=\"{ enabled: true, animation: true }\"\n [dataSource]=\"vm().dataSource\"\n (selectedRowsChange)=\"handleSelectedRowsChange($event)\"\n (onRowDbClick)=\"handleRowDbClick($event)\"\n (onColumnSizeChanged)=\"onColumnSizeChanged($event)\"\n (onPageChanged)=\"onPageChanged($event)\"\n>\n @if (vm().showIndexColumn()) {\n <ax-index-column\n id=\"axp-table-col-index\"\n [caption]=\"('@general:terms.common.row-number' | translate | async)!\"\n fixed=\"start\"\n [width]=\"'80px'\"\n [padZero]=\"false\"\n ></ax-index-column>\n }\n @if (vm().selectedScopeActionsCount()) {\n <ax-select-column id=\"axp-table-col-select\" fixed=\"start\" [width]=\"'60px'\"></ax-select-column>\n }\n @for (col of vm().columns(); track col.name) {\n @if (col.visible) {\n <axp-widget-column-renderer\n [attr.id]=\"'axp-table-col-' + col.name\"\n [expandHandler]=\"$index === 0 && vm().parentKey() ? true : false\"\n [caption]=\"(col.title | translate | async)!\"\n [node]=\"col.node()\"\n [customWidth]=\"col.width\"\n [sortEnabled]=\"!!col.sortEnabled\"\n [headerSortDirection]=\"resolveColumnSortDirection(vm().sortedFields(), col.name)\"\n [headerSortPriority]=\"resolveColumnSortIndex(vm().sortedFields(), col.name)\"\n (sortToggle)=\"handleColumnSort(col.name, $event)\"\n ></axp-widget-column-renderer>\n }\n }\n @if (getCommandRowItems().length) {\n <ax-command-column\n id=\"axp-table-col-commands\"\n fixed=\"end\"\n [width]=\"getCommandRowItems().length * 70 + 'px'\"\n [items]=\"getCommandRowItems()\"\n (onItemClick)=\"handleRowCommandClick($event)\"\n ></ax-command-column>\n }\n <ax-dropdown-command-column\n id=\"axp-table-col-dropdown-commands\"\n fixed=\"end\"\n [width]=\"'60px'\"\n [items]=\"getDropdownRowItems\"\n (onItemClick)=\"handleRowCommandClick($event)\"\n ></ax-dropdown-command-column>\n</ax-data-table>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXDataTableModule }, { kind: "component", type: i7.AXDataTableComponent, selector: "ax-data-table", inputs: ["dataSource", "selectedRows", "parentField", "hasChildrenField", "rowDetailsTemplate", "look", "rowTemplate", "emptyTemplate", "noDataTemplate", "alternative", "showHeader", "fixedHeader", "showFooter", "fixedFooter", "itemHeight", "allowReordering", "paging", "fetchDataMode", "loading", "focusedRow"], outputs: ["selectedRowsChange", "focusedRowChange", "onRowClick", "onRowDbClick", "onColumnsOrderChanged", "onColumnSizeChanged", "onPageChanged"] }, { kind: "component", type: i7.AXRowIndexColumnComponent, selector: "ax-index-column", inputs: ["width", "caption", "fixed", "footerTemplate", "padZero"] }, { kind: "component", type: i7.AXRowSelectColumnComponent, selector: "ax-select-column", inputs: ["width", "caption", "fixed"] }, { kind: "component", type: i7.AXRowCommandColumnComponent, selector: "ax-command-column", inputs: ["width", "caption", "fixed", "footerTemplate", "items"], outputs: ["onItemClick"] }, { kind: "component", type: i7.AXRowDropdownCommandColumnComponent, selector: "ax-dropdown-command-column", inputs: ["width", "caption", "fixed", "footerTemplate", "emptyStateTemplate", "emptyStateText", "items"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: i7$1.AXPWidgetColumnRendererComponent, selector: "axp-widget-column-renderer", inputs: ["caption", "customExpandIcon", "customCollapseIcon", "customWidth", "node", "footerTemplate", "expandHandler", "sortEnabled", "headerSortDirection", "headerSortPriority", "columnFixed", "cellTemplate", "headerTemplate"], outputs: ["sortToggle"] }, { kind: "ngmodule", type: AXPWidgetsModule }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1935
+ }
1936
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityMasterListDataTableComponent, decorators: [{
1937
+ type: Component,
1938
+ args: [{ selector: 'axp-entity-master-list-data-table', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, AXDataTableModule, AXTranslationModule, AXPWidgetCoreModule, AXPWidgetsModule], host: {
1939
+ style: 'height: -webkit-fill-available;',
1940
+ }, template: "<ax-data-table\n id=\"axp-entity-table\"\n [allowReordering]=\"true\"\n (onColumnsOrderChanged)=\"onColumnsOrderChanged($event)\"\n #grid\n [showFooter]=\"false\"\n class=\"ax-flex-1\"\n [paging]=\"true\"\n [fetchDataMode]=\"'manual'\"\n [parentField]=\"vm().parentKey()\"\n [loading]=\"{ enabled: true, animation: true }\"\n [dataSource]=\"vm().dataSource\"\n (selectedRowsChange)=\"handleSelectedRowsChange($event)\"\n (onRowDbClick)=\"handleRowDbClick($event)\"\n (onColumnSizeChanged)=\"onColumnSizeChanged($event)\"\n (onPageChanged)=\"onPageChanged($event)\"\n>\n @if (vm().showIndexColumn()) {\n <ax-index-column\n id=\"axp-table-col-index\"\n [caption]=\"('@general:terms.common.row-number' | translate | async)!\"\n fixed=\"start\"\n [width]=\"'80px'\"\n [padZero]=\"false\"\n ></ax-index-column>\n }\n @if (vm().selectedScopeActionsCount()) {\n <ax-select-column id=\"axp-table-col-select\" fixed=\"start\" [width]=\"'60px'\"></ax-select-column>\n }\n @for (col of vm().columns(); track col.name) {\n @if (col.visible) {\n <axp-widget-column-renderer\n [attr.id]=\"'axp-table-col-' + col.name\"\n [expandHandler]=\"$index === 0 && vm().parentKey() ? true : false\"\n [caption]=\"(col.title | translate | async)!\"\n [node]=\"col.node()\"\n [customWidth]=\"col.width\"\n [sortEnabled]=\"!!col.sortEnabled\"\n [headerSortDirection]=\"resolveColumnSortDirection(vm().sortedFields(), col.name)\"\n [headerSortPriority]=\"resolveColumnSortIndex(vm().sortedFields(), col.name)\"\n (sortToggle)=\"handleColumnSort(col.name, $event)\"\n ></axp-widget-column-renderer>\n }\n }\n @if (getCommandRowItems().length) {\n <ax-command-column\n id=\"axp-table-col-commands\"\n fixed=\"end\"\n [width]=\"getCommandRowItems().length * 70 + 'px'\"\n [items]=\"getCommandRowItems()\"\n (onItemClick)=\"handleRowCommandClick($event)\"\n ></ax-command-column>\n }\n <ax-dropdown-command-column\n id=\"axp-table-col-dropdown-commands\"\n fixed=\"end\"\n [width]=\"'60px'\"\n [items]=\"getDropdownRowItems\"\n (onItemClick)=\"handleRowCommandClick($event)\"\n ></ax-dropdown-command-column>\n</ax-data-table>\n" }]
1941
+ }], propDecorators: { vm: [{ type: i0.Input, args: [{ isSignal: true, alias: "vm", required: true }] }], pageChanged: [{ type: i0.Output, args: ["pageChanged"] }], gridRef: [{ type: i0.ViewChild, args: ['grid', { isSignal: true }] }] } });
1942
+
1943
+ class AXPEntityMasterListViewComponent extends AXPPageLayoutBaseComponent {
1944
+ constructor(platform) {
1945
+ super();
1946
+ this.platform = platform;
1947
+ //#region ---- Services & Dependencies ----
1948
+ this.activeRoute = inject(ActivatedRoute);
1949
+ this.router = inject(Router);
1950
+ //#endregion
1951
+ //#region ---- View State ----
1952
+ this.vm = this.activeRoute.snapshot.data['vm'];
1953
+ this.store = inject(AXPLayoutThemeService);
1954
+ this.searchBarShown = signal(true, ...(ngDevMode ? [{ debugName: "searchBarShown" }] : /* istanbul ignore next */ []));
1955
+ this.activeEndSideView = signal('column', ...(ngDevMode ? [{ debugName: "activeEndSideView" }] : /* istanbul ignore next */ []));
1956
+ this.categorySearchValue = signal('', ...(ngDevMode ? [{ debugName: "categorySearchValue" }] : /* istanbul ignore next */ []));
1957
+ //#endregion
1958
+ //#region ---- View References ----
1959
+ this.dataTable = viewChild(AXPEntityMasterListDataTableComponent, ...(ngDevMode ? [{ debugName: "dataTable" }] : /* istanbul ignore next */ []));
1960
+ this.initializedFromRoute = false;
1961
+ this.lastEvaluatedViewName = null;
1962
+ this.componentDestroyed = new Subject();
1963
+ this.isRestoringExpandedRows = false;
1964
+ this.restoreExpandedRowsScheduled = false;
1965
+ /** Blocks deferred `replaceUrl` view sync after destroy or once details navigation has started. */
1966
+ this.listQueryParamSyncDisabled = false;
1967
+ effect(() => {
1968
+ const grid = this.grid();
1969
+ if (grid) {
1970
+ grid.selectedRows = this.vm.selectedItems();
1971
+ }
1972
+ });
1973
+ this.vm.events$.subscribe(async (e) => {
1974
+ const refreshTargetId = e.meta?.refreshTargetId;
1975
+ const resetPagination = e.meta?.resetPagination === true;
1976
+ if (e.action == 'refresh') {
1977
+ if (refreshTargetId) {
1978
+ await this.grid()?.refreshItemChildren(refreshTargetId);
1979
+ this.updateParentHasChildAfterRefresh(refreshTargetId);
1980
+ }
1981
+ else {
1982
+ await this.reloadListData(resetPagination);
1983
+ }
1984
+ }
1985
+ });
1986
+ effect(() => {
1987
+ if (!this.initializedFromRoute) {
1988
+ return;
1989
+ }
1990
+ const currentViewName = this.vm.view().name;
1991
+ const urlView = this.activeRoute.snapshot.queryParamMap.get('view');
1992
+ if (currentViewName && currentViewName !== urlView) {
1993
+ this.syncListViewQueryParam(currentViewName);
1994
+ }
1995
+ });
1996
+ effect(() => {
1997
+ const currentViewName = this.vm.view().name;
1998
+ if (!this.initializedFromRoute) {
1999
+ this.lastEvaluatedViewName = currentViewName;
2000
+ return;
2001
+ }
2002
+ if (this.lastEvaluatedViewName !== currentViewName) {
2003
+ this.lastEvaluatedViewName = currentViewName;
2004
+ this.recompute();
2005
+ this.scheduleRestoreExpandedRows();
2006
+ }
2007
+ });
2008
+ }
2009
+ async ngOnInit() {
2010
+ this.router.events
2011
+ .pipe(filter((event) => event instanceof NavigationStart), takeUntil(this.componentDestroyed))
2012
+ .subscribe((event) => {
2013
+ if (axpIsEntityListRoute(this.router) && !axpIsEntityListPath(event.url)) {
2014
+ this.listQueryParamSyncDisabled = true;
2015
+ }
2016
+ });
2017
+ this.queryParamSub = this.activeRoute.queryParamMap.subscribe(async (qp) => {
2018
+ const viewFromUrl = qp.get('view');
2019
+ await this.vm.setView(viewFromUrl);
2020
+ this.scheduleRestoreExpandedRows();
2021
+ });
2022
+ }
2023
+ async ngAfterViewInit() {
2024
+ const viewFromUrl = this.activeRoute.snapshot.queryParamMap.get('view');
2025
+ await this.vm.setView(viewFromUrl);
2026
+ const resolvedView = this.vm.view().name;
2027
+ const currentUrlView = this.activeRoute.snapshot.queryParamMap.get('view');
2028
+ if (currentUrlView !== resolvedView) {
2029
+ this.syncListViewQueryParam(resolvedView);
2030
+ }
2031
+ this.initializedFromRoute = true;
2032
+ this.bindExpandedRowPersistence();
2033
+ this.scheduleRestoreExpandedRows();
2034
+ this.recompute();
2035
+ }
2036
+ ngOnDestroy() {
2037
+ this.listQueryParamSyncDisabled = true;
2038
+ this.componentDestroyed.next();
2039
+ this.componentDestroyed.complete();
2040
+ this.queryParamSub?.unsubscribe();
2041
+ this.vm.destroy();
2042
+ }
2043
+ //#endregion
2044
+ //#region ---- List Layout Handlers ----
2045
+ onListPageChanged() {
2046
+ this.scheduleRestoreExpandedRows();
2047
+ }
2048
+ handleUnselectAll() {
2049
+ this.vm.selectedItems.set([]);
2050
+ }
2051
+ //#endregion
2052
+ //#region ---- Toolbar & Sidebar Handlers ----
2053
+ makeResponsive(value) {
2054
+ if (this.platform.is('Mobile') || this.platform.is('SM')) {
2055
+ return '';
2056
+ }
2057
+ return value;
2058
+ }
2059
+ toggleSideBar(sideBar) {
2060
+ this.toggleEndSide();
2061
+ if (sideBar) {
2062
+ this.activeEndSideView.set(sideBar);
2063
+ }
2064
+ }
2065
+ toggleSearchBar() {
2066
+ this.searchBarShown.update((v) => !v);
2067
+ }
2068
+ handleResetClick(sideBar) {
2069
+ switch (sideBar) {
2070
+ case 'filter': {
2071
+ this.vm.resetFilters();
2072
+ break;
2073
+ }
2074
+ case 'sort': {
2075
+ this.vm.resetSorts();
2076
+ break;
2077
+ }
2078
+ case 'column': {
2079
+ this.vm.resetColumns();
2080
+ break;
2081
+ }
2082
+ }
2083
+ }
2084
+ handleApplyClick(sideBar) {
2085
+ this.vm.applyFilterAndSort();
2086
+ this.toggleEndSide();
2087
+ }
2088
+ toggleCategoryDrawer() {
2089
+ this.toggleStartSide();
2090
+ }
2091
+ //#endregion
2092
+ //#region ---- Page Layout ----
2093
+ getPageTitle() {
2094
+ return this.vm.title();
2095
+ }
2096
+ async getPageDescription() {
2097
+ const description = this.vm.description();
2098
+ if (description) {
2099
+ return this.translateService.translateAsync(description);
2100
+ }
2101
+ return '';
2102
+ }
2103
+ getPageBreadcrumbs() {
2104
+ return this.vm.beardcrumbs();
2105
+ }
2106
+ async getPrimaryMenuItems() {
2107
+ return (await this.vm.getPrimaryActions())
2108
+ .filter((tr) => !tr.isChild)
2109
+ .map((tr) => ({
2110
+ name: tr.name,
2111
+ title: tr.title,
2112
+ icon: tr.icon,
2113
+ color: tr.color,
2114
+ disabled: tr.disabled,
2115
+ items: tr.items?.map((sub) => ({
2116
+ name: sub.name,
2117
+ title: sub.title,
2118
+ icon: sub.icon,
2119
+ color: sub.color,
2120
+ disabled: sub.disabled,
2121
+ command: {
2122
+ name: sub.name,
2123
+ options: sub.options,
2124
+ metadata: sub.metadata,
2125
+ },
2126
+ })),
2127
+ command: {
2128
+ name: tr.name,
2129
+ options: tr.options,
2130
+ metadata: tr.metadata,
2131
+ },
2132
+ }));
2133
+ }
2134
+ async getSecondaryMenuItems() {
2135
+ return (await this.vm.getSecondaryActions()).map((tr) => ({
2136
+ name: tr.name,
2137
+ title: tr.title,
2138
+ icon: tr.icon,
2139
+ color: tr.color,
2140
+ disabled: tr.disabled,
2141
+ separated: tr.separated,
2142
+ command: {
2143
+ name: tr.name,
2144
+ options: tr.options,
2145
+ metadata: tr.metadata,
2146
+ },
2147
+ }));
2148
+ }
2149
+ async execute(command) {
2150
+ if (command) {
2151
+ this.vm.execute(command);
2152
+ }
2153
+ }
2154
+ //#endregion
2155
+ //#region ---- Grid Helpers ----
2156
+ /**
2157
+ * Syncs the list `view` query param without polluting history.
2158
+ * Re-checks the live URL so a deferred call cannot `replaceUrl` over a details entry.
2159
+ */
2160
+ syncListViewQueryParam(viewName) {
2161
+ if (this.listQueryParamSyncDisabled) {
2162
+ return;
2163
+ }
2164
+ queueMicrotask(() => {
2165
+ if (this.listQueryParamSyncDisabled) {
2166
+ return;
2167
+ }
2168
+ axpReplaceEntityListRouteQueryParams(this.router, { view: viewName });
2169
+ });
2170
+ }
2171
+ async reloadListData(resetPagination = false) {
2172
+ if (!resetPagination) {
2173
+ await this.vm.ensureListPagingResolved();
2174
+ this.vm.applyPagingToDataSourceWithoutLoad();
2175
+ }
2176
+ const grid = this.grid();
2177
+ if (grid) {
2178
+ await grid.refresh({ reset: resetPagination });
2179
+ if (!resetPagination) {
2180
+ this.scheduleSyncGridPagerUi();
2181
+ }
2182
+ this.scheduleRestoreExpandedRows();
2183
+ }
2184
+ else {
2185
+ await this.vm.dataSource.refresh({ reset: resetPagination });
2186
+ }
2187
+ }
2188
+ grid() {
2189
+ return this.dataTable()?.grid();
2190
+ }
2191
+ updateParentHasChildAfterRefresh(parentId) {
2192
+ const gridRef = this.grid();
2193
+ const ds = gridRef?.dataSource;
2194
+ if (!ds?.cachedItems?.length) {
2195
+ return;
2196
+ }
2197
+ const key = ds.config?.key ?? 'id';
2198
+ const parent = this.findItemById(ds.cachedItems, String(parentId), key);
2199
+ if (parent && typeof parent === 'object') {
2200
+ parent['hasChild'] = true;
2201
+ }
2202
+ }
2203
+ findItemById(items, id, key) {
2204
+ for (const item of items) {
2205
+ if (item && typeof item === 'object' && String(item[key]) === id) {
2206
+ return item;
2207
+ }
2208
+ const rec = item;
2209
+ const metaChildren = rec?.['__meta__']?.['children'];
2210
+ const directChildren = rec?.['children'];
2211
+ const childArr = Array.isArray(metaChildren)
2212
+ ? metaChildren
2213
+ : Array.isArray(directChildren)
2214
+ ? directChildren
2215
+ : null;
2216
+ if (childArr?.length) {
2217
+ const found = this.findItemById(childArr, id, key);
2218
+ if (found)
2219
+ return found;
2220
+ }
2221
+ }
2222
+ return null;
2223
+ }
2224
+ bindExpandedRowPersistence() {
2225
+ if (!this.vm.parentKey()) {
2226
+ return;
2227
+ }
2228
+ this.vm.dataSource.onItemExpanded.pipe(takeUntil(this.componentDestroyed)).subscribe((event) => {
2229
+ const expandedItem = event?.expandedItem;
2230
+ if (expandedItem && typeof expandedItem === 'object') {
2231
+ this.vm.handleRowExpandChange(expandedItem);
2232
+ }
2233
+ });
2234
+ }
2235
+ scheduleSyncGridPagerUi() {
2236
+ queueMicrotask(() => {
2237
+ this.syncGridPagerUi();
2238
+ });
2239
+ }
2240
+ syncGridPagerUi() {
2241
+ const gridRef = this.grid();
2242
+ if (!gridRef) {
2243
+ return;
2244
+ }
2245
+ const pageIndex = getDataSourcePageIndex(this.vm.dataSource);
2246
+ const take = this.vm.dataSource.config.pageSize;
2247
+ const pagerPage = pageIndex + 1;
2248
+ const grid = gridRef;
2249
+ this.vm.skipListPagingPersistence = true;
2250
+ try {
2251
+ if (grid.page() !== pageIndex) {
2252
+ grid.page.set(pageIndex);
2253
+ }
2254
+ grid.pageSize.set(take);
2255
+ const pager = grid.dataPager;
2256
+ if (pager && pager.value !== pagerPage) {
2257
+ pager.goToPage(pagerPage);
2258
+ }
2259
+ }
2260
+ finally {
2261
+ this.vm.skipListPagingPersistence = false;
2262
+ }
2263
+ }
2264
+ scheduleRestoreExpandedRows() {
2265
+ if (!this.vm.parentKey() || this.restoreExpandedRowsScheduled) {
2266
+ return;
2267
+ }
2268
+ this.restoreExpandedRowsScheduled = true;
2269
+ queueMicrotask(() => {
2270
+ this.restoreExpandedRowsScheduled = false;
2271
+ void this.restoreExpandedRows();
2272
+ });
2273
+ }
2274
+ async restoreExpandedRows() {
2275
+ if (!this.vm.parentKey() || this.isRestoringExpandedRows) {
2276
+ return;
2277
+ }
2278
+ const expandedRowIds = this.vm.getExpandedRowIds();
2279
+ if (!expandedRowIds.length) {
2280
+ return;
2281
+ }
2282
+ const gridRef = this.grid();
2283
+ if (!gridRef || gridRef.dataSource.isLoading) {
2284
+ return;
2285
+ }
2286
+ const gridWithDisplayedRows = gridRef;
2287
+ const displayedRows = gridWithDisplayedRows.displayedRows?.() ?? [];
2288
+ if (!displayedRows.length) {
2289
+ return;
2290
+ }
2291
+ this.isRestoringExpandedRows = true;
2292
+ this.vm.skipExpandedRowPersistence = true;
2293
+ try {
2294
+ const rowKey = this.vm.dataSource.config?.key ?? 'id';
2295
+ await restoreEntityListExpandedRows({
2296
+ expandedRowIds,
2297
+ rowKey,
2298
+ getDisplayedRows: () => gridWithDisplayedRows.displayedRows?.() ?? [],
2299
+ expandRow: (row) => gridRef.expandRow(row),
2300
+ });
2301
+ }
2302
+ finally {
2303
+ this.vm.skipExpandedRowPersistence = false;
2304
+ this.isRestoringExpandedRows = false;
2305
+ }
2306
+ }
2307
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityMasterListViewComponent, deps: [{ token: i1$4.AXPlatform }], target: i0.ɵɵFactoryTarget.Component }); }
2308
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPEntityMasterListViewComponent, isStandalone: true, selector: "axp-entity-master-list", providers: [
2309
+ {
2310
+ provide: AXPPageLayoutBase,
2311
+ useExisting: AXPEntityMasterListViewComponent,
2312
+ },
2313
+ ], viewQueries: [{ propertyName: "dataTable", first: true, predicate: AXPEntityMasterListDataTableComponent, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<axp-page-layout *translate=\"let t\">\n @if (vm.entityDef.category) {\n <axp-layout-start-side id=\"axp-entity-category-drawer\">\n <axp-entity-category\n id=\"axp-entity-category\"\n class=\"ax-w-80\"\n [vm]=\"vm\"\n [searchValue]=\"categorySearchValue()\"\n ></axp-entity-category>\n </axp-layout-start-side>\n }\n <axp-page-toolbar id=\"axp-entity-toolbar\">\n <axp-entity-master-toolbar-view [viewModel]=\"vm\"></axp-entity-master-toolbar-view>\n </axp-page-toolbar>\n <axp-page-content class=\"ax-overflow-auto ax-pt-0\">\n <div\n class=\"ax-flex ax-items-center ax-justify-between ax-gap-1 ax-pb-1 ax-text-muted ax-text-sm\"\n [class.ax-invisible]=\"!vm.selectedItems().length\"\n >\n <span\n >{{ vm.selectedItems().length }}\n <span>{{ '@general:terms.interface.items-selected' | translate | async }}</span>\n </span>\n <ax-button text=\"@general:terms.interface.unselect-all\" class=\"ax-xs\" (onClick)=\"handleUnselectAll()\"></ax-button>\n </div>\n @if (vm.enabledListLayouts().includes('table')) {\n <axp-entity-master-list-data-table\n class=\"axp-entity-list-host\"\n [class.axp-entity-list-host--hidden]=\"vm.activeListLayout() !== 'table'\"\n [vm]=\"vm\"\n (pageChanged)=\"onListPageChanged()\"\n ></axp-entity-master-list-data-table>\n }\n @if (vm.enabledListLayouts().includes('card')) {\n <axp-entity-master-list-card-list\n class=\"axp-entity-list-host\"\n [class.axp-entity-list-host--hidden]=\"vm.activeListLayout() !== 'card'\"\n [vm]=\"vm\"\n (pageChanged)=\"onListPageChanged()\"\n ></axp-entity-master-list-card-list>\n }\n </axp-page-content>\n</axp-page-layout>\n", styles: ["axp-entity-master-list axp-layout-start-side{min-width:20rem!important;border-inline-end-width:1px}axp-entity-master-list axp-layout-header{padding-bottom:.25rem!important}axp-entity-master-list .axp-entity-list-host{display:flex;height:100%;min-height:0px;flex-direction:column}axp-entity-master-list axp-page-content{display:flex;min-height:0px;flex-direction:column}axp-entity-master-list .axp-entity-list-host--hidden{display:none!important}.cdk-drag-preview{border-radius:.375rem;border-width:1px;--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);background:rgba(var(--ax-color-on-surface));padding:.5rem;height:max-content!important}.collapsed-search-box{margin-top:0;height:0px;opacity:0}.view-drawer{width:85vw}@media(min-width:768px){.view-drawer{width:45vw}}@media(min-width:1024px){.view-drawer{width:35vw}}@media(min-width:1536px){.view-drawer{width:20vw}}.view-drawer{--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lightest-surface),var(--tw-bg-opacity, 1));border-inline-start-width:1px;border-inline-start-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));border-top-width:1px;--tw-border-opacity: 1;border-top-color:rgba(var(--ax-sys-color-primary-600),var(--tw-border-opacity, 1))}.view-drawer ax-header{display:flex;align-items:center;border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lighter-surface),var(--tw-bg-opacity, 1));padding:.5rem 1rem}.view-drawer ax-header h2{font-size:1.25rem;line-height:1.75rem;font-weight:700;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lighter-surface),var(--tw-text-opacity, 1))}.view-drawer ax-footer{position:absolute!important;bottom:0!important;width:100%!important;justify-content:flex-start!important;border-top-width:1px!important;--tw-border-opacity: 1 !important;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1))!important;padding:.5rem 1rem!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "ngmodule", type: AXFormModule }, { kind: "ngmodule", type: AXActionSheetModule }, { kind: "ngmodule", type: AXDrawerModule }, { kind: "ngmodule", type: AXDialogModule }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "ngmodule", type: AXTabsModule }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "ngmodule", type: AXBreadcrumbsModule }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i3$1.AXTranslatorDirective, selector: "[translate]" }, { kind: "ngmodule", type: DragDropModule }, { kind: "ngmodule", type: AXPAuthModule }, { kind: "component", type: AXPEntityMasterToolbarViewComponent, selector: "axp-entity-master-toolbar-view", inputs: ["viewModel"] }, { kind: "component", type: AXPPageLayoutComponent, selector: "axp-page-layout" }, { kind: "component", type: AXPThemeLayoutBlockComponent, selector: " axp-page-content, axp-page-footer-container, axp-page-footer, axp-page-header, axp-page-header-container, axp-page-toolbar, axp-layout-content, axp-layout-page-content, axp-layout-sections, axp-layout-body, axp-layout-page-body, axp-layout-prefix, axp-layout-suffix, axp-layout-title-bar, axp-layout-title, axp-layout-title-actions, axp-layout-nav-button, axp-layout-description, axp-layout-breadcrumbs, axp-layout-list-action, " }, { kind: "component", type: AXPThemeLayoutStartSideComponent, selector: "axp-layout-page-start-side, axp-layout-start-side" }, { kind: "component", type: AXPEntityCategoryComponent, selector: "axp-entity-category", inputs: ["vm", "searchValue", "selectMode", "selectionBehavior", "dragArea", "dragBehavior", "showIcons", "showChildrenBadge", "expandedIcon", "collapsedIcon", "indentSize", "look", "searchWithChildren"] }, { kind: "component", type: AXPEntityMasterListDataTableComponent, selector: "axp-entity-master-list-data-table", inputs: ["vm"], outputs: ["pageChanged"] }, { kind: "component", type: AXPEntityMasterListCardListComponent, selector: "axp-entity-master-list-card-list", inputs: ["vm"], outputs: ["pageChanged"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
2314
+ }
2315
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityMasterListViewComponent, decorators: [{
2316
+ type: Component,
2317
+ args: [{ selector: 'axp-entity-master-list', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
2318
+ CommonModule,
2319
+ FormsModule,
2320
+ RouterModule,
2321
+ AXButtonModule,
2322
+ AXDecoratorModule,
2323
+ AXBadgeModule,
2324
+ AXDropdownModule,
2325
+ AXPopoverModule,
2326
+ AXFormModule,
2327
+ AXActionSheetModule,
2328
+ AXDrawerModule,
2329
+ AXDialogModule,
2330
+ AXLoadingModule,
2331
+ AXTabsModule,
2332
+ AXTooltipModule,
2333
+ AXBreadcrumbsModule,
2334
+ AXDropdownButtonModule,
2335
+ AXSearchBoxModule,
2336
+ AXTranslationModule,
2337
+ DragDropModule,
2338
+ AXPAuthModule,
2339
+ AXPEntityMasterToolbarViewComponent,
2340
+ AXPPageLayoutComponent,
2341
+ AXPThemeLayoutBlockComponent,
2342
+ AXPThemeLayoutStartSideComponent,
2343
+ AXPEntityCategoryComponent,
2344
+ AXPEntityMasterListDataTableComponent,
2345
+ AXPEntityMasterListCardListComponent,
2346
+ ], providers: [
2347
+ {
2348
+ provide: AXPPageLayoutBase,
2349
+ useExisting: AXPEntityMasterListViewComponent,
2350
+ },
2351
+ ], template: "<axp-page-layout *translate=\"let t\">\n @if (vm.entityDef.category) {\n <axp-layout-start-side id=\"axp-entity-category-drawer\">\n <axp-entity-category\n id=\"axp-entity-category\"\n class=\"ax-w-80\"\n [vm]=\"vm\"\n [searchValue]=\"categorySearchValue()\"\n ></axp-entity-category>\n </axp-layout-start-side>\n }\n <axp-page-toolbar id=\"axp-entity-toolbar\">\n <axp-entity-master-toolbar-view [viewModel]=\"vm\"></axp-entity-master-toolbar-view>\n </axp-page-toolbar>\n <axp-page-content class=\"ax-overflow-auto ax-pt-0\">\n <div\n class=\"ax-flex ax-items-center ax-justify-between ax-gap-1 ax-pb-1 ax-text-muted ax-text-sm\"\n [class.ax-invisible]=\"!vm.selectedItems().length\"\n >\n <span\n >{{ vm.selectedItems().length }}\n <span>{{ '@general:terms.interface.items-selected' | translate | async }}</span>\n </span>\n <ax-button text=\"@general:terms.interface.unselect-all\" class=\"ax-xs\" (onClick)=\"handleUnselectAll()\"></ax-button>\n </div>\n @if (vm.enabledListLayouts().includes('table')) {\n <axp-entity-master-list-data-table\n class=\"axp-entity-list-host\"\n [class.axp-entity-list-host--hidden]=\"vm.activeListLayout() !== 'table'\"\n [vm]=\"vm\"\n (pageChanged)=\"onListPageChanged()\"\n ></axp-entity-master-list-data-table>\n }\n @if (vm.enabledListLayouts().includes('card')) {\n <axp-entity-master-list-card-list\n class=\"axp-entity-list-host\"\n [class.axp-entity-list-host--hidden]=\"vm.activeListLayout() !== 'card'\"\n [vm]=\"vm\"\n (pageChanged)=\"onListPageChanged()\"\n ></axp-entity-master-list-card-list>\n }\n </axp-page-content>\n</axp-page-layout>\n", styles: ["axp-entity-master-list axp-layout-start-side{min-width:20rem!important;border-inline-end-width:1px}axp-entity-master-list axp-layout-header{padding-bottom:.25rem!important}axp-entity-master-list .axp-entity-list-host{display:flex;height:100%;min-height:0px;flex-direction:column}axp-entity-master-list axp-page-content{display:flex;min-height:0px;flex-direction:column}axp-entity-master-list .axp-entity-list-host--hidden{display:none!important}.cdk-drag-preview{border-radius:.375rem;border-width:1px;--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);background:rgba(var(--ax-color-on-surface));padding:.5rem;height:max-content!important}.collapsed-search-box{margin-top:0;height:0px;opacity:0}.view-drawer{width:85vw}@media(min-width:768px){.view-drawer{width:45vw}}@media(min-width:1024px){.view-drawer{width:35vw}}@media(min-width:1536px){.view-drawer{width:20vw}}.view-drawer{--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lightest-surface),var(--tw-bg-opacity, 1));border-inline-start-width:1px;border-inline-start-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));border-top-width:1px;--tw-border-opacity: 1;border-top-color:rgba(var(--ax-sys-color-primary-600),var(--tw-border-opacity, 1))}.view-drawer ax-header{display:flex;align-items:center;border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lighter-surface),var(--tw-bg-opacity, 1));padding:.5rem 1rem}.view-drawer ax-header h2{font-size:1.25rem;line-height:1.75rem;font-weight:700;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lighter-surface),var(--tw-text-opacity, 1))}.view-drawer ax-footer{position:absolute!important;bottom:0!important;width:100%!important;justify-content:flex-start!important;border-top-width:1px!important;--tw-border-opacity: 1 !important;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-border-opacity, 1))!important;padding:.5rem 1rem!important}\n"] }]
2352
+ }], ctorParameters: () => [{ type: i1$4.AXPlatform }], propDecorators: { dataTable: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXPEntityMasterListDataTableComponent), { isSignal: true }] }] } });
2353
+
2354
+ var entityMasterListView_component = /*#__PURE__*/Object.freeze({
2355
+ __proto__: null,
2356
+ AXPEntityMasterListViewComponent: AXPEntityMasterListViewComponent
2357
+ });
2358
+
192
2359
  class AXPRootLayoutFooterComponent {
193
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPRootLayoutFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
194
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.12", type: AXPRootLayoutFooterComponent, isStandalone: true, selector: "axp-dashboard-admin-footer", host: { classAttribute: "ax-h-10 ax-flex ax-item-center ax-justify-between ax-bg-lighter ax-border-lighter ax-px-6 ax-border-t" }, providers: [], ngImport: i0, template: "<div class=\"ax-flex ax-items-center ax-justify-start ax-gap-1\">\n <axp-component-slot name=\"root-footer-start\"></axp-component-slot>\n</div>\n<div class=\"ax-flex ax-items-center ax-justify-end ax-gap-1\">\n <axp-component-slot name=\"root-footer-end\"></axp-component-slot>\n</div>\n", dependencies: [{ kind: "ngmodule", type: AXPComponentSlotModule }, { kind: "directive", type: i1$2.AXPComponentSlotDirective, selector: "axp-component-slot", inputs: ["name", "host", "context"], exportAs: ["slot"] }], encapsulation: i0.ViewEncapsulation.None }); }
2360
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootLayoutFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2361
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.9", type: AXPRootLayoutFooterComponent, isStandalone: true, selector: "axp-dashboard-admin-footer", host: { classAttribute: "ax-h-10 ax-flex ax-item-center ax-justify-between ax-bg-lighter ax-border-lighter ax-px-6 ax-border-t" }, providers: [], ngImport: i0, template: "<div class=\"ax-flex ax-items-center ax-justify-start ax-gap-1\">\n <axp-component-slot name=\"root-footer-start\"></axp-component-slot>\n</div>\n<div class=\"ax-flex ax-items-center ax-justify-end ax-gap-1\">\n <axp-component-slot name=\"root-footer-end\"></axp-component-slot>\n</div>\n", dependencies: [{ kind: "ngmodule", type: AXPComponentSlotModule }, { kind: "directive", type: i1$5.AXPComponentSlotDirective, selector: "axp-component-slot", inputs: ["name", "host", "context"], exportAs: ["slot"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
195
2362
  }
196
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPRootLayoutFooterComponent, decorators: [{
2363
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootLayoutFooterComponent, decorators: [{
197
2364
  type: Component,
198
- args: [{ selector: 'axp-dashboard-admin-footer', encapsulation: ViewEncapsulation.None, providers: [], host: {
2365
+ args: [{ selector: 'axp-dashboard-admin-footer', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [], host: {
199
2366
  class: 'ax-h-10 ax-flex ax-item-center ax-justify-between ax-bg-lighter ax-border-lighter ax-px-6 ax-border-t',
200
2367
  }, standalone: true, imports: [
201
2368
  AXPComponentSlotModule
@@ -203,47 +2370,70 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
203
2370
  }] });
204
2371
 
205
2372
  class AXPRootLayoutHeaderComponent {
2373
+ //#endregion
2374
+ //#region ---- Lifecycle Methods ----
206
2375
  constructor() {
2376
+ //#region ---- Services & Dependencies ----
207
2377
  this.config = inject(AXP_PLATFORM_CONFIG_TOKEN);
208
- this.store = inject(AXPLayoutThemeService);
209
2378
  this.router = inject(Router);
2379
+ this.destroyRef = inject(DestroyRef);
2380
+ this.shortcutRegistry = inject(AXPKeyboardShortcutRegistry);
2381
+ this.store = inject(AXPLayoutThemeService);
210
2382
  this.logo = this.config.logo;
2383
+ this.shortcutRegistry.register({
2384
+ owner: this.destroyRef,
2385
+ id: 'root-layout-toggle-side-menu',
2386
+ priority: AXPKeyboardShortcutPriority.Global,
2387
+ group: '@general:keyboard-shortcuts.groups.global',
2388
+ shortcuts: [
2389
+ {
2390
+ keys: ['ctrl+shift+b'],
2391
+ title: '@general:keyboard-shortcuts.actions.toggle-side-menu',
2392
+ allowInEditableFields: true,
2393
+ handler: () => {
2394
+ this.toggleSideMenu();
2395
+ },
2396
+ },
2397
+ ],
2398
+ });
211
2399
  }
2400
+ //#endregion
2401
+ //#region ---- UI Handlers ----
212
2402
  toggleSideMenu() {
213
2403
  this.store.toggleSideMenu();
214
2404
  }
215
2405
  handleLogoClick() {
216
2406
  this.router.navigate(['/']);
217
2407
  }
218
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPRootLayoutHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
219
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXPRootLayoutHeaderComponent, isStandalone: true, selector: "axp-dashboard-admin-header", host: { classAttribute: "ax-w-full ax-flex ax-items-center ax-justify-between ax-bg-primary-surface ax-text-primary-on-surface ax-h-14 ax-px-2 ax-light" }, ngImport: i0, template: "<ax-button id=\"axp-menu-toggle\" (onClick)=\"toggleSideMenu()\" color=\"primary\">\n <ax-icon class=\"rtl:ax-rotate-180\">\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 30 30\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n @if (store.isSideMenuOpen()) {\n <defs>\n <clipPath id=\"clip1382_20239\">\n <rect width=\"30.000000\" height=\"30.000000\" fill=\"white\" fill-opacity=\"0\"></rect>\n </clipPath>\n </defs>\n <rect width=\"30.000000\" height=\"30.000000\" fill=\"#FFFFFF\" fill-opacity=\"0\"></rect>\n <g clip-path=\"url(#clip1382_20239)\">\n <rect\n id=\"rect\"\n x=\"17.420410\"\n y=\"12.316406\"\n rx=\"1.000947\"\n width=\"5.995172\"\n height=\"2.001895\"\n transform=\"rotate(137.159 17.420410 12.316406)\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n ></rect>\n <rect\n id=\"rect\"\n x=\"12.959473\"\n y=\"13.728516\"\n rx=\"0.995190\"\n width=\"6.002943\"\n height=\"1.990380\"\n transform=\"rotate(40.853 12.959473 13.728516)\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n ></rect>\n <path\n id=\"path\"\n d=\"M20.1 25.5L9.9 25.51C9.48 25.51 9.06 25.47 8.65 25.39C8.24 25.3 7.84 25.18 7.45 25.02C7.06 24.86 6.69 24.66 6.34 24.43C5.99 24.19 5.67 23.92 5.37 23.63C5.07 23.33 4.81 23 4.58 22.65C4.34 22.3 4.15 21.93 3.98 21.54C3.82 21.15 3.7 20.75 3.62 20.34C3.54 19.93 3.5 19.51 3.5 19.09L3.5 10.93C3.5 10.51 3.54 10.1 3.62 9.68C3.7 9.27 3.82 8.87 3.98 8.48C4.15 8.09 4.34 7.72 4.58 7.37C4.81 7.02 5.07 6.69 5.37 6.39C5.67 6.1 5.99 5.83 6.34 5.6C6.69 5.36 7.06 5.16 7.45 5C7.84 4.84 8.24 4.72 8.65 4.64C9.06 4.55 9.48 4.51 9.9 4.51L20.1 4.5C20.52 4.5 20.94 4.54 21.35 4.62C21.76 4.7 22.16 4.83 22.55 4.99C22.94 5.15 23.31 5.35 23.66 5.58C24 5.82 24.33 6.08 24.62 6.38C24.92 6.68 25.19 7 25.42 7.35C25.65 7.7 25.85 8.07 26.01 8.46C26.17 8.85 26.3 9.25 26.38 9.67C26.46 10.08 26.5 10.5 26.5 10.92L26.5 19.07C26.5 19.5 26.46 19.91 26.38 20.32C26.3 20.74 26.17 21.14 26.01 21.53C25.85 21.92 25.65 22.29 25.42 22.64C25.19 22.99 24.92 23.31 24.62 23.61C24.33 23.91 24 24.17 23.66 24.41C23.31 24.64 22.94 24.84 22.55 25C22.16 25.16 21.76 25.29 21.35 25.37C20.94 25.45 20.52 25.5 20.1 25.5ZM9.9 6.6C9.61 6.6 9.33 6.63 9.05 6.69C8.78 6.74 8.51 6.82 8.24 6.93C7.98 7.04 7.73 7.18 7.5 7.33C7.26 7.49 7.04 7.67 6.84 7.87C6.64 8.07 6.46 8.29 6.31 8.53C6.15 8.77 6.02 9.01 5.91 9.28C5.8 9.54 5.72 9.81 5.66 10.09C5.61 10.37 5.58 10.65 5.58 10.93L5.58 19.09C5.58 19.37 5.61 19.65 5.66 19.93C5.72 20.21 5.8 20.48 5.91 20.74C6.02 21.01 6.15 21.26 6.31 21.49C6.46 21.73 6.64 21.95 6.84 22.15C7.04 22.35 7.26 22.53 7.5 22.69C7.73 22.85 7.98 22.98 8.24 23.09C8.51 23.2 8.78 23.28 9.05 23.33C9.33 23.39 9.61 23.42 9.9 23.42L20.1 23.41C20.38 23.41 20.67 23.37 20.94 23.32C21.22 23.26 21.49 23.18 21.75 23.07C22.01 22.96 22.26 22.83 22.5 22.67C22.73 22.51 22.95 22.33 23.15 22.13C23.35 21.93 23.53 21.71 23.69 21.48C23.85 21.24 23.98 20.99 24.09 20.73C24.2 20.47 24.28 20.2 24.33 19.92C24.39 19.64 24.42 19.36 24.42 19.07L24.42 10.92C24.42 10.64 24.39 10.35 24.33 10.07C24.28 9.79 24.2 9.52 24.09 9.26C23.98 9 23.85 8.75 23.69 8.51C23.53 8.28 23.35 8.06 23.15 7.86C22.95 7.66 22.73 7.48 22.5 7.32C22.26 7.16 22.01 7.03 21.75 6.92C21.49 6.81 21.22 6.73 20.94 6.67C20.67 6.62 20.38 6.59 20.1 6.59L9.9 6.6Z\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n fill-rule=\"nonzero\"\n ></path>\n <path\n id=\"rect\"\n d=\"M8.5 5.51L10.54 5.51L10.6 24.43L8.55 24.43L8.5 5.51Z\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n fill-rule=\"evenodd\"\n ></path>\n </g>\n } @else {\n <defs>\n <clipPath id=\"clip1381_20236\">\n <rect id=\"\u6253\u5F00\u8FB9\u680F0730\" width=\"30.000000\" height=\"30.000000\" fill=\"white\" fill-opacity=\"0\"></rect>\n </clipPath>\n </defs>\n <rect id=\"\u6253\u5F00\u8FB9\u680F0730\" width=\"30.000000\" height=\"30.000000\" fill=\"#FFFFFF\" fill-opacity=\"0\"></rect>\n <g clip-path=\"url(#clip1381_20236)\">\n <rect\n id=\"rect\"\n x=\"11.572754\"\n y=\"17.683594\"\n rx=\"1.000947\"\n width=\"5.995172\"\n height=\"2.001895\"\n transform=\"rotate(-42.841 11.572754 17.683594)\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n ></rect>\n <rect\n id=\"rect\"\n x=\"16.033691\"\n y=\"16.271484\"\n rx=\"0.995190\"\n width=\"6.002943\"\n height=\"1.990380\"\n transform=\"rotate(-139.147 16.033691 16.271484)\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n ></rect>\n <path\n id=\"path\"\n d=\"M20.09 25.48L9.89 25.5C9.47 25.5 9.05 25.45 8.64 25.37C8.23 25.29 7.83 25.17 7.44 25C7.05 24.84 6.68 24.64 6.33 24.41C5.98 24.18 5.66 23.91 5.36 23.61C5.07 23.31 4.8 22.99 4.57 22.64C4.34 22.29 4.14 21.92 3.98 21.53C3.82 21.14 3.69 20.74 3.61 20.32C3.53 19.91 3.49 19.49 3.49 19.07L3.49 10.92C3.49 10.5 3.53 10.08 3.61 9.67C3.69 9.25 3.82 8.85 3.98 8.46C4.14 8.07 4.34 7.7 4.57 7.35C4.8 7 5.07 6.68 5.36 6.38C5.66 6.08 5.98 5.81 6.33 5.58C6.68 5.35 7.05 5.15 7.44 4.99C7.83 4.82 8.23 4.7 8.64 4.62C9.05 4.54 9.47 4.5 9.89 4.5L20.09 4.48C20.51 4.48 20.93 4.52 21.34 4.6C21.75 4.69 22.15 4.81 22.54 4.97C22.93 5.13 23.3 5.33 23.65 5.57C24 5.8 24.32 6.06 24.62 6.36C24.92 6.66 25.18 6.98 25.41 7.33C25.65 7.69 25.84 8.06 26.01 8.45C26.17 8.84 26.29 9.24 26.37 9.65C26.45 10.06 26.49 10.48 26.5 10.91L26.5 19.06C26.49 19.48 26.45 19.89 26.37 20.31C26.29 20.72 26.17 21.12 26.01 21.51C25.84 21.9 25.65 22.27 25.41 22.62C25.18 22.97 24.92 23.3 24.62 23.6C24.32 23.89 24 24.16 23.65 24.39C23.3 24.63 22.93 24.83 22.54 24.99C22.15 25.15 21.75 25.27 21.34 25.35C20.93 25.44 20.51 25.48 20.09 25.48ZM9.89 6.59C9.61 6.59 9.32 6.62 9.05 6.67C8.77 6.73 8.5 6.81 8.24 6.92C7.98 7.03 7.73 7.16 7.49 7.32C7.26 7.48 7.04 7.66 6.84 7.86C6.64 8.06 6.46 8.28 6.3 8.51C6.14 8.75 6.01 9 5.9 9.26C5.79 9.52 5.71 9.8 5.66 10.07C5.6 10.35 5.57 10.63 5.57 10.92L5.57 19.07C5.57 19.36 5.6 19.64 5.66 19.92C5.71 20.19 5.79 20.47 5.9 20.73C6.01 20.99 6.14 21.24 6.3 21.48C6.46 21.71 6.64 21.93 6.84 22.13C7.04 22.33 7.26 22.51 7.49 22.67C7.73 22.83 7.98 22.96 8.24 23.07C8.5 23.18 8.77 23.26 9.05 23.32C9.32 23.37 9.61 23.4 9.89 23.4L20.09 23.39C20.38 23.39 20.66 23.36 20.94 23.3C21.21 23.25 21.48 23.17 21.75 23.06C22.01 22.95 22.26 22.81 22.49 22.66C22.73 22.5 22.95 22.32 23.15 22.12C23.35 21.91 23.52 21.7 23.68 21.46C23.84 21.22 23.97 20.98 24.08 20.71C24.19 20.45 24.27 20.18 24.33 19.9C24.38 19.62 24.41 19.34 24.41 19.06L24.41 10.91C24.41 10.62 24.38 10.34 24.33 10.06C24.27 9.78 24.19 9.51 24.08 9.25C23.97 8.98 23.84 8.74 23.68 8.5C23.52 8.26 23.35 8.04 23.15 7.84C22.95 7.64 22.73 7.46 22.49 7.3C22.26 7.15 22.01 7.01 21.75 6.9C21.48 6.79 21.21 6.71 20.94 6.66C20.66 6.6 20.38 6.57 20.09 6.57L9.89 6.59Z\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n fill-rule=\"nonzero\"\n ></path>\n <path\n id=\"rect\"\n d=\"M8.49 5.5L10.53 5.5L10.59 24.41L8.54 24.41L8.49 5.5Z\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n fill-rule=\"evenodd\"\n ></path>\n </g>\n }\n </svg>\n </ax-icon>\n</ax-button>\n<div class=\"ax-flex ax-items-center ax-gap-1 ax-justify-between ax-w-full\">\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <axp-component-slot name=\"root-header-start\"></axp-component-slot>\n </div>\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <axp-component-slot name=\"root-header-end\"></axp-component-slot>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: AXPComponentSlotModule }, { kind: "directive", type: i1$2.AXPComponentSlotDirective, selector: "axp-component-slot", inputs: ["name", "host", "context"], exportAs: ["slot"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }], encapsulation: i0.ViewEncapsulation.None }); }
2408
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootLayoutHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2409
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPRootLayoutHeaderComponent, isStandalone: true, selector: "axp-dashboard-admin-header", host: { classAttribute: "ax-w-full ax-flex ax-items-center ax-justify-between ax-bg-primary-surface ax-text-primary-on-surface ax-h-14 ax-px-2 ax-light" }, ngImport: i0, template: "<ax-button id=\"axp-menu-toggle\" (onClick)=\"toggleSideMenu()\" color=\"primary\">\n <ax-icon class=\"rtl:ax-rotate-180\">\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 30 30\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n @if (store.isSideMenuOpen()) {\n <defs>\n <clipPath id=\"clip1382_20239\">\n <rect width=\"30.000000\" height=\"30.000000\" fill=\"white\" fill-opacity=\"0\"></rect>\n </clipPath>\n </defs>\n <rect width=\"30.000000\" height=\"30.000000\" fill=\"#FFFFFF\" fill-opacity=\"0\"></rect>\n <g clip-path=\"url(#clip1382_20239)\">\n <rect\n id=\"rect\"\n x=\"17.420410\"\n y=\"12.316406\"\n rx=\"1.000947\"\n width=\"5.995172\"\n height=\"2.001895\"\n transform=\"rotate(137.159 17.420410 12.316406)\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n ></rect>\n <rect\n id=\"rect\"\n x=\"12.959473\"\n y=\"13.728516\"\n rx=\"0.995190\"\n width=\"6.002943\"\n height=\"1.990380\"\n transform=\"rotate(40.853 12.959473 13.728516)\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n ></rect>\n <path\n id=\"path\"\n d=\"M20.1 25.5L9.9 25.51C9.48 25.51 9.06 25.47 8.65 25.39C8.24 25.3 7.84 25.18 7.45 25.02C7.06 24.86 6.69 24.66 6.34 24.43C5.99 24.19 5.67 23.92 5.37 23.63C5.07 23.33 4.81 23 4.58 22.65C4.34 22.3 4.15 21.93 3.98 21.54C3.82 21.15 3.7 20.75 3.62 20.34C3.54 19.93 3.5 19.51 3.5 19.09L3.5 10.93C3.5 10.51 3.54 10.1 3.62 9.68C3.7 9.27 3.82 8.87 3.98 8.48C4.15 8.09 4.34 7.72 4.58 7.37C4.81 7.02 5.07 6.69 5.37 6.39C5.67 6.1 5.99 5.83 6.34 5.6C6.69 5.36 7.06 5.16 7.45 5C7.84 4.84 8.24 4.72 8.65 4.64C9.06 4.55 9.48 4.51 9.9 4.51L20.1 4.5C20.52 4.5 20.94 4.54 21.35 4.62C21.76 4.7 22.16 4.83 22.55 4.99C22.94 5.15 23.31 5.35 23.66 5.58C24 5.82 24.33 6.08 24.62 6.38C24.92 6.68 25.19 7 25.42 7.35C25.65 7.7 25.85 8.07 26.01 8.46C26.17 8.85 26.3 9.25 26.38 9.67C26.46 10.08 26.5 10.5 26.5 10.92L26.5 19.07C26.5 19.5 26.46 19.91 26.38 20.32C26.3 20.74 26.17 21.14 26.01 21.53C25.85 21.92 25.65 22.29 25.42 22.64C25.19 22.99 24.92 23.31 24.62 23.61C24.33 23.91 24 24.17 23.66 24.41C23.31 24.64 22.94 24.84 22.55 25C22.16 25.16 21.76 25.29 21.35 25.37C20.94 25.45 20.52 25.5 20.1 25.5ZM9.9 6.6C9.61 6.6 9.33 6.63 9.05 6.69C8.78 6.74 8.51 6.82 8.24 6.93C7.98 7.04 7.73 7.18 7.5 7.33C7.26 7.49 7.04 7.67 6.84 7.87C6.64 8.07 6.46 8.29 6.31 8.53C6.15 8.77 6.02 9.01 5.91 9.28C5.8 9.54 5.72 9.81 5.66 10.09C5.61 10.37 5.58 10.65 5.58 10.93L5.58 19.09C5.58 19.37 5.61 19.65 5.66 19.93C5.72 20.21 5.8 20.48 5.91 20.74C6.02 21.01 6.15 21.26 6.31 21.49C6.46 21.73 6.64 21.95 6.84 22.15C7.04 22.35 7.26 22.53 7.5 22.69C7.73 22.85 7.98 22.98 8.24 23.09C8.51 23.2 8.78 23.28 9.05 23.33C9.33 23.39 9.61 23.42 9.9 23.42L20.1 23.41C20.38 23.41 20.67 23.37 20.94 23.32C21.22 23.26 21.49 23.18 21.75 23.07C22.01 22.96 22.26 22.83 22.5 22.67C22.73 22.51 22.95 22.33 23.15 22.13C23.35 21.93 23.53 21.71 23.69 21.48C23.85 21.24 23.98 20.99 24.09 20.73C24.2 20.47 24.28 20.2 24.33 19.92C24.39 19.64 24.42 19.36 24.42 19.07L24.42 10.92C24.42 10.64 24.39 10.35 24.33 10.07C24.28 9.79 24.2 9.52 24.09 9.26C23.98 9 23.85 8.75 23.69 8.51C23.53 8.28 23.35 8.06 23.15 7.86C22.95 7.66 22.73 7.48 22.5 7.32C22.26 7.16 22.01 7.03 21.75 6.92C21.49 6.81 21.22 6.73 20.94 6.67C20.67 6.62 20.38 6.59 20.1 6.59L9.9 6.6Z\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n fill-rule=\"nonzero\"\n ></path>\n <path\n id=\"rect\"\n d=\"M8.5 5.51L10.54 5.51L10.6 24.43L8.55 24.43L8.5 5.51Z\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n fill-rule=\"evenodd\"\n ></path>\n </g>\n } @else {\n <defs>\n <clipPath id=\"clip1381_20236\">\n <rect id=\"\u6253\u5F00\u8FB9\u680F0730\" width=\"30.000000\" height=\"30.000000\" fill=\"white\" fill-opacity=\"0\"></rect>\n </clipPath>\n </defs>\n <rect id=\"\u6253\u5F00\u8FB9\u680F0730\" width=\"30.000000\" height=\"30.000000\" fill=\"#FFFFFF\" fill-opacity=\"0\"></rect>\n <g clip-path=\"url(#clip1381_20236)\">\n <rect\n id=\"rect\"\n x=\"11.572754\"\n y=\"17.683594\"\n rx=\"1.000947\"\n width=\"5.995172\"\n height=\"2.001895\"\n transform=\"rotate(-42.841 11.572754 17.683594)\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n ></rect>\n <rect\n id=\"rect\"\n x=\"16.033691\"\n y=\"16.271484\"\n rx=\"0.995190\"\n width=\"6.002943\"\n height=\"1.990380\"\n transform=\"rotate(-139.147 16.033691 16.271484)\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n ></rect>\n <path\n id=\"path\"\n d=\"M20.09 25.48L9.89 25.5C9.47 25.5 9.05 25.45 8.64 25.37C8.23 25.29 7.83 25.17 7.44 25C7.05 24.84 6.68 24.64 6.33 24.41C5.98 24.18 5.66 23.91 5.36 23.61C5.07 23.31 4.8 22.99 4.57 22.64C4.34 22.29 4.14 21.92 3.98 21.53C3.82 21.14 3.69 20.74 3.61 20.32C3.53 19.91 3.49 19.49 3.49 19.07L3.49 10.92C3.49 10.5 3.53 10.08 3.61 9.67C3.69 9.25 3.82 8.85 3.98 8.46C4.14 8.07 4.34 7.7 4.57 7.35C4.8 7 5.07 6.68 5.36 6.38C5.66 6.08 5.98 5.81 6.33 5.58C6.68 5.35 7.05 5.15 7.44 4.99C7.83 4.82 8.23 4.7 8.64 4.62C9.05 4.54 9.47 4.5 9.89 4.5L20.09 4.48C20.51 4.48 20.93 4.52 21.34 4.6C21.75 4.69 22.15 4.81 22.54 4.97C22.93 5.13 23.3 5.33 23.65 5.57C24 5.8 24.32 6.06 24.62 6.36C24.92 6.66 25.18 6.98 25.41 7.33C25.65 7.69 25.84 8.06 26.01 8.45C26.17 8.84 26.29 9.24 26.37 9.65C26.45 10.06 26.49 10.48 26.5 10.91L26.5 19.06C26.49 19.48 26.45 19.89 26.37 20.31C26.29 20.72 26.17 21.12 26.01 21.51C25.84 21.9 25.65 22.27 25.41 22.62C25.18 22.97 24.92 23.3 24.62 23.6C24.32 23.89 24 24.16 23.65 24.39C23.3 24.63 22.93 24.83 22.54 24.99C22.15 25.15 21.75 25.27 21.34 25.35C20.93 25.44 20.51 25.48 20.09 25.48ZM9.89 6.59C9.61 6.59 9.32 6.62 9.05 6.67C8.77 6.73 8.5 6.81 8.24 6.92C7.98 7.03 7.73 7.16 7.49 7.32C7.26 7.48 7.04 7.66 6.84 7.86C6.64 8.06 6.46 8.28 6.3 8.51C6.14 8.75 6.01 9 5.9 9.26C5.79 9.52 5.71 9.8 5.66 10.07C5.6 10.35 5.57 10.63 5.57 10.92L5.57 19.07C5.57 19.36 5.6 19.64 5.66 19.92C5.71 20.19 5.79 20.47 5.9 20.73C6.01 20.99 6.14 21.24 6.3 21.48C6.46 21.71 6.64 21.93 6.84 22.13C7.04 22.33 7.26 22.51 7.49 22.67C7.73 22.83 7.98 22.96 8.24 23.07C8.5 23.18 8.77 23.26 9.05 23.32C9.32 23.37 9.61 23.4 9.89 23.4L20.09 23.39C20.38 23.39 20.66 23.36 20.94 23.3C21.21 23.25 21.48 23.17 21.75 23.06C22.01 22.95 22.26 22.81 22.49 22.66C22.73 22.5 22.95 22.32 23.15 22.12C23.35 21.91 23.52 21.7 23.68 21.46C23.84 21.22 23.97 20.98 24.08 20.71C24.19 20.45 24.27 20.18 24.33 19.9C24.38 19.62 24.41 19.34 24.41 19.06L24.41 10.91C24.41 10.62 24.38 10.34 24.33 10.06C24.27 9.78 24.19 9.51 24.08 9.25C23.97 8.98 23.84 8.74 23.68 8.5C23.52 8.26 23.35 8.04 23.15 7.84C22.95 7.64 22.73 7.46 22.49 7.3C22.26 7.15 22.01 7.01 21.75 6.9C21.48 6.79 21.21 6.71 20.94 6.66C20.66 6.6 20.38 6.57 20.09 6.57L9.89 6.59Z\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n fill-rule=\"nonzero\"\n ></path>\n <path\n id=\"rect\"\n d=\"M8.49 5.5L10.53 5.5L10.59 24.41L8.54 24.41L8.49 5.5Z\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n fill-rule=\"evenodd\"\n ></path>\n </g>\n }\n </svg>\n </ax-icon>\n</ax-button>\n<div class=\"ax-flex ax-items-center ax-gap-1 ax-justify-between ax-w-full\">\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <axp-component-slot name=\"root-header-start\"></axp-component-slot>\n </div>\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <axp-component-slot name=\"root-header-end\"></axp-component-slot>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: AXPComponentSlotModule }, { kind: "directive", type: i1$5.AXPComponentSlotDirective, selector: "axp-component-slot", inputs: ["name", "host", "context"], exportAs: ["slot"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
220
2410
  }
221
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPRootLayoutHeaderComponent, decorators: [{
2411
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootLayoutHeaderComponent, decorators: [{
222
2412
  type: Component,
223
- args: [{ selector: 'axp-dashboard-admin-header', encapsulation: ViewEncapsulation.None, host: { class: 'ax-w-full ax-flex ax-items-center ax-justify-between ax-bg-primary-surface ax-text-primary-on-surface ax-h-14 ax-px-2 ax-light' }, standalone: true, imports: [
2413
+ args: [{ selector: 'axp-dashboard-admin-header', encapsulation: ViewEncapsulation.None, host: { class: 'ax-w-full ax-flex ax-items-center ax-justify-between ax-bg-primary-surface ax-text-primary-on-surface ax-h-14 ax-px-2 ax-light' }, standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
224
2414
  AXPComponentSlotModule,
225
2415
  AXButtonModule,
226
2416
  AXDecoratorModule
227
2417
  ], template: "<ax-button id=\"axp-menu-toggle\" (onClick)=\"toggleSideMenu()\" color=\"primary\">\n <ax-icon class=\"rtl:ax-rotate-180\">\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 30 30\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n @if (store.isSideMenuOpen()) {\n <defs>\n <clipPath id=\"clip1382_20239\">\n <rect width=\"30.000000\" height=\"30.000000\" fill=\"white\" fill-opacity=\"0\"></rect>\n </clipPath>\n </defs>\n <rect width=\"30.000000\" height=\"30.000000\" fill=\"#FFFFFF\" fill-opacity=\"0\"></rect>\n <g clip-path=\"url(#clip1382_20239)\">\n <rect\n id=\"rect\"\n x=\"17.420410\"\n y=\"12.316406\"\n rx=\"1.000947\"\n width=\"5.995172\"\n height=\"2.001895\"\n transform=\"rotate(137.159 17.420410 12.316406)\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n ></rect>\n <rect\n id=\"rect\"\n x=\"12.959473\"\n y=\"13.728516\"\n rx=\"0.995190\"\n width=\"6.002943\"\n height=\"1.990380\"\n transform=\"rotate(40.853 12.959473 13.728516)\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n ></rect>\n <path\n id=\"path\"\n d=\"M20.1 25.5L9.9 25.51C9.48 25.51 9.06 25.47 8.65 25.39C8.24 25.3 7.84 25.18 7.45 25.02C7.06 24.86 6.69 24.66 6.34 24.43C5.99 24.19 5.67 23.92 5.37 23.63C5.07 23.33 4.81 23 4.58 22.65C4.34 22.3 4.15 21.93 3.98 21.54C3.82 21.15 3.7 20.75 3.62 20.34C3.54 19.93 3.5 19.51 3.5 19.09L3.5 10.93C3.5 10.51 3.54 10.1 3.62 9.68C3.7 9.27 3.82 8.87 3.98 8.48C4.15 8.09 4.34 7.72 4.58 7.37C4.81 7.02 5.07 6.69 5.37 6.39C5.67 6.1 5.99 5.83 6.34 5.6C6.69 5.36 7.06 5.16 7.45 5C7.84 4.84 8.24 4.72 8.65 4.64C9.06 4.55 9.48 4.51 9.9 4.51L20.1 4.5C20.52 4.5 20.94 4.54 21.35 4.62C21.76 4.7 22.16 4.83 22.55 4.99C22.94 5.15 23.31 5.35 23.66 5.58C24 5.82 24.33 6.08 24.62 6.38C24.92 6.68 25.19 7 25.42 7.35C25.65 7.7 25.85 8.07 26.01 8.46C26.17 8.85 26.3 9.25 26.38 9.67C26.46 10.08 26.5 10.5 26.5 10.92L26.5 19.07C26.5 19.5 26.46 19.91 26.38 20.32C26.3 20.74 26.17 21.14 26.01 21.53C25.85 21.92 25.65 22.29 25.42 22.64C25.19 22.99 24.92 23.31 24.62 23.61C24.33 23.91 24 24.17 23.66 24.41C23.31 24.64 22.94 24.84 22.55 25C22.16 25.16 21.76 25.29 21.35 25.37C20.94 25.45 20.52 25.5 20.1 25.5ZM9.9 6.6C9.61 6.6 9.33 6.63 9.05 6.69C8.78 6.74 8.51 6.82 8.24 6.93C7.98 7.04 7.73 7.18 7.5 7.33C7.26 7.49 7.04 7.67 6.84 7.87C6.64 8.07 6.46 8.29 6.31 8.53C6.15 8.77 6.02 9.01 5.91 9.28C5.8 9.54 5.72 9.81 5.66 10.09C5.61 10.37 5.58 10.65 5.58 10.93L5.58 19.09C5.58 19.37 5.61 19.65 5.66 19.93C5.72 20.21 5.8 20.48 5.91 20.74C6.02 21.01 6.15 21.26 6.31 21.49C6.46 21.73 6.64 21.95 6.84 22.15C7.04 22.35 7.26 22.53 7.5 22.69C7.73 22.85 7.98 22.98 8.24 23.09C8.51 23.2 8.78 23.28 9.05 23.33C9.33 23.39 9.61 23.42 9.9 23.42L20.1 23.41C20.38 23.41 20.67 23.37 20.94 23.32C21.22 23.26 21.49 23.18 21.75 23.07C22.01 22.96 22.26 22.83 22.5 22.67C22.73 22.51 22.95 22.33 23.15 22.13C23.35 21.93 23.53 21.71 23.69 21.48C23.85 21.24 23.98 20.99 24.09 20.73C24.2 20.47 24.28 20.2 24.33 19.92C24.39 19.64 24.42 19.36 24.42 19.07L24.42 10.92C24.42 10.64 24.39 10.35 24.33 10.07C24.28 9.79 24.2 9.52 24.09 9.26C23.98 9 23.85 8.75 23.69 8.51C23.53 8.28 23.35 8.06 23.15 7.86C22.95 7.66 22.73 7.48 22.5 7.32C22.26 7.16 22.01 7.03 21.75 6.92C21.49 6.81 21.22 6.73 20.94 6.67C20.67 6.62 20.38 6.59 20.1 6.59L9.9 6.6Z\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n fill-rule=\"nonzero\"\n ></path>\n <path\n id=\"rect\"\n d=\"M8.5 5.51L10.54 5.51L10.6 24.43L8.55 24.43L8.5 5.51Z\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n fill-rule=\"evenodd\"\n ></path>\n </g>\n } @else {\n <defs>\n <clipPath id=\"clip1381_20236\">\n <rect id=\"\u6253\u5F00\u8FB9\u680F0730\" width=\"30.000000\" height=\"30.000000\" fill=\"white\" fill-opacity=\"0\"></rect>\n </clipPath>\n </defs>\n <rect id=\"\u6253\u5F00\u8FB9\u680F0730\" width=\"30.000000\" height=\"30.000000\" fill=\"#FFFFFF\" fill-opacity=\"0\"></rect>\n <g clip-path=\"url(#clip1381_20236)\">\n <rect\n id=\"rect\"\n x=\"11.572754\"\n y=\"17.683594\"\n rx=\"1.000947\"\n width=\"5.995172\"\n height=\"2.001895\"\n transform=\"rotate(-42.841 11.572754 17.683594)\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n ></rect>\n <rect\n id=\"rect\"\n x=\"16.033691\"\n y=\"16.271484\"\n rx=\"0.995190\"\n width=\"6.002943\"\n height=\"1.990380\"\n transform=\"rotate(-139.147 16.033691 16.271484)\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n ></rect>\n <path\n id=\"path\"\n d=\"M20.09 25.48L9.89 25.5C9.47 25.5 9.05 25.45 8.64 25.37C8.23 25.29 7.83 25.17 7.44 25C7.05 24.84 6.68 24.64 6.33 24.41C5.98 24.18 5.66 23.91 5.36 23.61C5.07 23.31 4.8 22.99 4.57 22.64C4.34 22.29 4.14 21.92 3.98 21.53C3.82 21.14 3.69 20.74 3.61 20.32C3.53 19.91 3.49 19.49 3.49 19.07L3.49 10.92C3.49 10.5 3.53 10.08 3.61 9.67C3.69 9.25 3.82 8.85 3.98 8.46C4.14 8.07 4.34 7.7 4.57 7.35C4.8 7 5.07 6.68 5.36 6.38C5.66 6.08 5.98 5.81 6.33 5.58C6.68 5.35 7.05 5.15 7.44 4.99C7.83 4.82 8.23 4.7 8.64 4.62C9.05 4.54 9.47 4.5 9.89 4.5L20.09 4.48C20.51 4.48 20.93 4.52 21.34 4.6C21.75 4.69 22.15 4.81 22.54 4.97C22.93 5.13 23.3 5.33 23.65 5.57C24 5.8 24.32 6.06 24.62 6.36C24.92 6.66 25.18 6.98 25.41 7.33C25.65 7.69 25.84 8.06 26.01 8.45C26.17 8.84 26.29 9.24 26.37 9.65C26.45 10.06 26.49 10.48 26.5 10.91L26.5 19.06C26.49 19.48 26.45 19.89 26.37 20.31C26.29 20.72 26.17 21.12 26.01 21.51C25.84 21.9 25.65 22.27 25.41 22.62C25.18 22.97 24.92 23.3 24.62 23.6C24.32 23.89 24 24.16 23.65 24.39C23.3 24.63 22.93 24.83 22.54 24.99C22.15 25.15 21.75 25.27 21.34 25.35C20.93 25.44 20.51 25.48 20.09 25.48ZM9.89 6.59C9.61 6.59 9.32 6.62 9.05 6.67C8.77 6.73 8.5 6.81 8.24 6.92C7.98 7.03 7.73 7.16 7.49 7.32C7.26 7.48 7.04 7.66 6.84 7.86C6.64 8.06 6.46 8.28 6.3 8.51C6.14 8.75 6.01 9 5.9 9.26C5.79 9.52 5.71 9.8 5.66 10.07C5.6 10.35 5.57 10.63 5.57 10.92L5.57 19.07C5.57 19.36 5.6 19.64 5.66 19.92C5.71 20.19 5.79 20.47 5.9 20.73C6.01 20.99 6.14 21.24 6.3 21.48C6.46 21.71 6.64 21.93 6.84 22.13C7.04 22.33 7.26 22.51 7.49 22.67C7.73 22.83 7.98 22.96 8.24 23.07C8.5 23.18 8.77 23.26 9.05 23.32C9.32 23.37 9.61 23.4 9.89 23.4L20.09 23.39C20.38 23.39 20.66 23.36 20.94 23.3C21.21 23.25 21.48 23.17 21.75 23.06C22.01 22.95 22.26 22.81 22.49 22.66C22.73 22.5 22.95 22.32 23.15 22.12C23.35 21.91 23.52 21.7 23.68 21.46C23.84 21.22 23.97 20.98 24.08 20.71C24.19 20.45 24.27 20.18 24.33 19.9C24.38 19.62 24.41 19.34 24.41 19.06L24.41 10.91C24.41 10.62 24.38 10.34 24.33 10.06C24.27 9.78 24.19 9.51 24.08 9.25C23.97 8.98 23.84 8.74 23.68 8.5C23.52 8.26 23.35 8.04 23.15 7.84C22.95 7.64 22.73 7.46 22.49 7.3C22.26 7.15 22.01 7.01 21.75 6.9C21.48 6.79 21.21 6.71 20.94 6.66C20.66 6.6 20.38 6.57 20.09 6.57L9.89 6.59Z\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n fill-rule=\"nonzero\"\n ></path>\n <path\n id=\"rect\"\n d=\"M8.49 5.5L10.53 5.5L10.59 24.41L8.54 24.41L8.49 5.5Z\"\n fill=\"currentColor\"\n fill-opacity=\"1.000000\"\n fill-rule=\"evenodd\"\n ></path>\n </g>\n }\n </svg>\n </ax-icon>\n</ax-button>\n<div class=\"ax-flex ax-items-center ax-gap-1 ax-justify-between ax-w-full\">\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <axp-component-slot name=\"root-header-start\"></axp-component-slot>\n </div>\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <axp-component-slot name=\"root-header-end\"></axp-component-slot>\n </div>\n</div>\n" }]
228
- }] });
2418
+ }], ctorParameters: () => [] });
229
2419
 
230
2420
  class AXPRootLayoutMenuComponent {
231
2421
  constructor() {
2422
+ //#region ---- Services & Dependencies ----
232
2423
  this.menuStore = inject(AXPMenuService);
233
2424
  this.router = inject(Router);
234
2425
  this.badgeService = inject(AXPTaskBadgeService);
235
2426
  this.settingsService = inject(AXPSettingsService);
236
2427
  this.visibilityService = inject(AXPMenuVisibilityService);
237
- this.badgeVisible = signal(true, ...(ngDevMode ? [{ debugName: "badgeVisible" }] : []));
238
- // Debug: Track menu items changes
239
- // effect(() => {
240
- // const items = this.menuStore.items();
241
- // console.log('🎯 Sidebar menu items updated:', items.map(i => ({ name: i.name, priority: i.priority })));
242
- // });
2428
+ this.themeStore = inject(AXPLayoutThemeService);
2429
+ //#endregion
2430
+ //#region ---- Component State ----
2431
+ this.badgeVisible = signal(true, ...(ngDevMode ? [{ debugName: "badgeVisible" }] : /* istanbul ignore next */ []));
2432
+ this.menuMode = this.themeStore.effectiveMenuVerticalMode;
243
2433
  }
2434
+ //#endregion
244
2435
  async ngOnInit() {
245
- this.badgeVisible.set(await this.settingsService.scope(AXPPlatformScope.User).get(AXPThemeLayoutSetting.MenuBadgeVisible));
246
- //subscribe to changes
2436
+ this.badgeVisible.set(await this.settingsService.get(AXPThemeLayoutSetting.MenuBadgeVisible));
247
2437
  this.settingsService.onChanged.subscribe((setting) => {
248
2438
  if (setting.keys.includes(AXPThemeLayoutSetting.MenuBadgeVisible)) {
249
2439
  this.badgeVisible.set(setting.values[AXPThemeLayoutSetting.MenuBadgeVisible]);
@@ -279,6 +2469,30 @@ class AXPRootLayoutMenuComponent {
279
2469
  shouldRenderMenuItem(item) {
280
2470
  return this.visibilityService.shouldRenderMenuItem(item, (item) => this.getRouterLink(item));
281
2471
  }
2472
+ /**
2473
+ * Checks if an item takes up visual space in the menu (group title or rendered menu item).
2474
+ */
2475
+ isItemRendered(item) {
2476
+ if (item.type === 'break') {
2477
+ return false;
2478
+ }
2479
+ if (item.type === 'group') {
2480
+ return this.isItemVisible(item);
2481
+ }
2482
+ return this.shouldRenderMenuItem(item);
2483
+ }
2484
+ /**
2485
+ * Determines if a divider should be shown. A divider is only shown when there is
2486
+ * visible content on both sides; if before or after is blank, the divider is hidden.
2487
+ */
2488
+ shouldShowDivider(item, items, index) {
2489
+ if (item.type !== 'break' || !items || index < 0) {
2490
+ return false;
2491
+ }
2492
+ const hasVisibleBefore = items.slice(0, index).some((i) => this.isItemRendered(i));
2493
+ const hasVisibleAfter = items.slice(index + 1).some((i) => this.isItemRendered(i));
2494
+ return hasVisibleBefore && hasVisibleAfter;
2495
+ }
282
2496
  //#endregion
283
2497
  //#region ---- Menu Navigation Helpers ----
284
2498
  /**
@@ -380,10 +2594,10 @@ class AXPRootLayoutMenuComponent {
380
2594
  const lowerPath = path.trim().toLowerCase();
381
2595
  return lowerPath.startsWith('http://') || lowerPath.startsWith('https://');
382
2596
  }
383
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPRootLayoutMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
384
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXPRootLayoutMenuComponent, isStandalone: true, selector: "axp-side-menu", ngImport: i0, template: "<ax-side-menu look=\"pills\">\n @for (item of sort(menuStore.items()); track item) {\n <ng-container [ngTemplateOutlet]=\"recursiveMenu\" [ngTemplateOutletContext]=\"{ item: item }\"> </ng-container>\n }\n</ax-side-menu>\n<ng-template #recursiveMenu let-item=\"item\">\n @if (item.type == 'group') {\n @if (isItemVisible(item)) {\n <ax-title>{{ item.text | translate | async }}</ax-title>\n }\n } @else if (item.type == 'break') {\n <ax-divider></ax-divider>\n } @else {\n @if (shouldRenderMenuItem(item)) {\n @let routerLinkValue = getRouterLink(item);\n @if (routerLinkValue) {\n <ax-side-menu-item [attr.id]=\"'axp-menu-item-' + (item.name || item.text)\" (onClick)=\"onMenuItemClick(item, true)\"\n [routerLink]=\"routerLinkValue\" [active]=\"item === menuStore.selectedMenuItem().item\"\n [isCollapsed]=\"!menuStore.isItemOpen(item)\">\n <ax-prefix>\n <ax-icon [class]=\"item.icon\" class=\"fa-fw\"></ax-icon>\n </ax-prefix>\n <span>{{ item.text | translate | async }}</span>\n @if (item.children?.length) {\n <ng-container>\n @for (child of sort(item.children); track $index) {\n <ng-container [ngTemplateOutlet]=\"recursiveMenu\" [ngTemplateOutletContext]=\"{ item: child }\">\n </ng-container>\n }\n </ng-container>\n }\n <ax-suffix>\n @if (badgeVisible()) {\n <ax-badge [axp-task-badge]=\"getMenuBadge(item)()\" color=\"secondary\"></ax-badge>\n }\n </ax-suffix>\n </ax-side-menu-item>\n } @else {\n <ax-side-menu-item [attr.id]=\"'axp-menu-item-' + (item.name || item.text)\" (onClick)=\"onMenuItemClick(item)\"\n [active]=\"item === menuStore.selectedMenuItem().item\" [isCollapsed]=\"!menuStore.isItemOpen(item)\">\n <ax-prefix>\n <ax-icon [class]=\"item.icon\" class=\"fa-fw\"></ax-icon>\n </ax-prefix>\n <span>{{ item.text | translate | async }}</span>\n @if (item.children?.length) {\n <ng-container>\n @for (child of sort(item.children); track $index) {\n <ng-container [ngTemplateOutlet]=\"recursiveMenu\" [ngTemplateOutletContext]=\"{ item: child }\">\n </ng-container>\n }\n </ng-container>\n }\n <ax-suffix>\n @if (badgeVisible()) {\n <ax-badge [axp-task-badge]=\"getMenuBadge(item)()\" color=\"secondary\"></ax-badge>\n }\n </ax-suffix>\n </ax-side-menu-item>\n }\n }\n }\n</ng-template>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: AXSideMenuModule }, { kind: "component", type: i2$2.AXSideMenuComponent, selector: "ax-side-menu", inputs: ["items", "look", "location"], outputs: ["itemsChange"] }, { kind: "component", type: i2$2.AXSideMenuItemComponent, selector: "ax-side-menu-item", inputs: ["disabled", "text", "active", "isLoading", "isCollapsed", "toggleOnClick", "href", "routerLink", "routerLinkActive", "routerLinkActiveOptions", "target"], outputs: ["textChange", "activeChange", "isLoadingChange", "isCollapsedChange", "onClick"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: AXPTaskBadgeDirective, selector: "[axp-task-badge]", inputs: ["badgeKey", "axp-task-badge"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i4.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i10.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
2597
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootLayoutMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2598
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPRootLayoutMenuComponent, isStandalone: true, selector: "axp-side-menu", ngImport: i0, template: "<ax-side-menu look=\"pills\" [mode]=\"menuMode()\">\n @let sortedItems = sort(menuStore.items());\n @for (item of sortedItems; track item; let i = $index) {\n <ng-container\n [ngTemplateOutlet]=\"recursiveMenu\"\n [ngTemplateOutletContext]=\"{ item: item, items: sortedItems, index: i }\"\n >\n </ng-container>\n }\n</ax-side-menu>\n<ng-template #recursiveMenu let-item=\"item\" let-items=\"items\" let-index=\"index\">\n @if (item.type == 'group' && menuMode() === 'full') {\n @if (isItemVisible(item)) {\n <ax-title>{{ item.text | translate | async }}</ax-title>\n }\n } @else if (item.type == 'break') {\n @if (shouldShowDivider(item, items, index)) {\n <ax-divider></ax-divider>\n }\n } @else {\n @if (shouldRenderMenuItem(item)) {\n @let routerLinkValue = getRouterLink(item);\n @if (routerLinkValue) {\n <ax-side-menu-item\n [attr.id]=\"'axp-menu-item-' + (item.name || item.text)\"\n (onClick)=\"onMenuItemClick(item, true)\"\n [routerLink]=\"routerLinkValue\"\n [active]=\"item === menuStore.selectedMenuItem().item\"\n [isCollapsed]=\"!menuStore.isItemOpen(item)\"\n >\n <ax-prefix>\n <ax-icon [class]=\"item.icon\" class=\"fa-fw\"></ax-icon>\n </ax-prefix>\n <span>{{ item.text | translate | async }}</span>\n @if (item.children?.length) {\n <ng-container>\n @let sortedChildren = sort(item.children);\n @for (child of sortedChildren; track child; let childIndex = $index) {\n <ng-container\n [ngTemplateOutlet]=\"recursiveMenu\"\n [ngTemplateOutletContext]=\"{ item: child, items: sortedChildren, index: childIndex }\"\n >\n </ng-container>\n }\n </ng-container>\n }\n <ax-suffix>\n @if (badgeVisible()) {\n <ax-badge [axp-task-badge]=\"getMenuBadge(item)()\" color=\"secondary\"></ax-badge>\n }\n </ax-suffix>\n </ax-side-menu-item>\n } @else {\n <ax-side-menu-item\n [attr.id]=\"'axp-menu-item-' + (item.name || item.text)\"\n (onClick)=\"onMenuItemClick(item)\"\n [active]=\"item === menuStore.selectedMenuItem().item\"\n [isCollapsed]=\"!menuStore.isItemOpen(item)\"\n >\n <ax-prefix>\n <ax-icon [class]=\"item.icon\" class=\"fa-fw\"></ax-icon>\n </ax-prefix>\n <span>{{ item.text | translate | async }}</span>\n @if (item.children?.length) {\n <ng-container>\n @let sortedChildren = sort(item.children);\n @for (child of sortedChildren; track child; let childIndex = $index) {\n <ng-container\n [ngTemplateOutlet]=\"recursiveMenu\"\n [ngTemplateOutletContext]=\"{ item: child, items: sortedChildren, index: childIndex }\"\n >\n </ng-container>\n }\n </ng-container>\n }\n <ax-suffix>\n @if (badgeVisible()) {\n <ax-badge [axp-task-badge]=\"getMenuBadge(item)()\" color=\"secondary\"></ax-badge>\n }\n </ax-suffix>\n </ax-side-menu-item>\n }\n }\n }\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: AXSideMenuModule }, { kind: "component", type: i2$3.AXSideMenuComponent, selector: "ax-side-menu", inputs: ["items", "look", "location", "mode"], outputs: ["itemsChange"] }, { kind: "component", type: i2$3.AXSideMenuItemComponent, selector: "ax-side-menu-item", inputs: ["disabled", "text", "active", "isLoading", "isCollapsed", "toggleOnClick", "href", "routerLink", "routerLinkActive", "routerLinkActiveOptions", "target"], outputs: ["textChange", "activeChange", "isLoadingChange", "isCollapsedChange", "onClick"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: AXPTaskBadgeDirective, selector: "[axp-task-badge]", inputs: ["badgeKey", "axp-task-badge"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i1$2.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
385
2599
  }
386
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPRootLayoutMenuComponent, decorators: [{
2600
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootLayoutMenuComponent, decorators: [{
387
2601
  type: Component,
388
2602
  args: [{ selector: 'axp-side-menu', encapsulation: ViewEncapsulation.None, standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
389
2603
  CommonModule,
@@ -392,8 +2606,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
392
2606
  AXPTaskBadgeDirective,
393
2607
  AXDecoratorModule,
394
2608
  AXBadgeModule,
395
- ], template: "<ax-side-menu look=\"pills\">\n @for (item of sort(menuStore.items()); track item) {\n <ng-container [ngTemplateOutlet]=\"recursiveMenu\" [ngTemplateOutletContext]=\"{ item: item }\"> </ng-container>\n }\n</ax-side-menu>\n<ng-template #recursiveMenu let-item=\"item\">\n @if (item.type == 'group') {\n @if (isItemVisible(item)) {\n <ax-title>{{ item.text | translate | async }}</ax-title>\n }\n } @else if (item.type == 'break') {\n <ax-divider></ax-divider>\n } @else {\n @if (shouldRenderMenuItem(item)) {\n @let routerLinkValue = getRouterLink(item);\n @if (routerLinkValue) {\n <ax-side-menu-item [attr.id]=\"'axp-menu-item-' + (item.name || item.text)\" (onClick)=\"onMenuItemClick(item, true)\"\n [routerLink]=\"routerLinkValue\" [active]=\"item === menuStore.selectedMenuItem().item\"\n [isCollapsed]=\"!menuStore.isItemOpen(item)\">\n <ax-prefix>\n <ax-icon [class]=\"item.icon\" class=\"fa-fw\"></ax-icon>\n </ax-prefix>\n <span>{{ item.text | translate | async }}</span>\n @if (item.children?.length) {\n <ng-container>\n @for (child of sort(item.children); track $index) {\n <ng-container [ngTemplateOutlet]=\"recursiveMenu\" [ngTemplateOutletContext]=\"{ item: child }\">\n </ng-container>\n }\n </ng-container>\n }\n <ax-suffix>\n @if (badgeVisible()) {\n <ax-badge [axp-task-badge]=\"getMenuBadge(item)()\" color=\"secondary\"></ax-badge>\n }\n </ax-suffix>\n </ax-side-menu-item>\n } @else {\n <ax-side-menu-item [attr.id]=\"'axp-menu-item-' + (item.name || item.text)\" (onClick)=\"onMenuItemClick(item)\"\n [active]=\"item === menuStore.selectedMenuItem().item\" [isCollapsed]=\"!menuStore.isItemOpen(item)\">\n <ax-prefix>\n <ax-icon [class]=\"item.icon\" class=\"fa-fw\"></ax-icon>\n </ax-prefix>\n <span>{{ item.text | translate | async }}</span>\n @if (item.children?.length) {\n <ng-container>\n @for (child of sort(item.children); track $index) {\n <ng-container [ngTemplateOutlet]=\"recursiveMenu\" [ngTemplateOutletContext]=\"{ item: child }\">\n </ng-container>\n }\n </ng-container>\n }\n <ax-suffix>\n @if (badgeVisible()) {\n <ax-badge [axp-task-badge]=\"getMenuBadge(item)()\" color=\"secondary\"></ax-badge>\n }\n </ax-suffix>\n </ax-side-menu-item>\n }\n }\n }\n</ng-template>" }]
396
- }], ctorParameters: () => [] });
2609
+ ], template: "<ax-side-menu look=\"pills\" [mode]=\"menuMode()\">\n @let sortedItems = sort(menuStore.items());\n @for (item of sortedItems; track item; let i = $index) {\n <ng-container\n [ngTemplateOutlet]=\"recursiveMenu\"\n [ngTemplateOutletContext]=\"{ item: item, items: sortedItems, index: i }\"\n >\n </ng-container>\n }\n</ax-side-menu>\n<ng-template #recursiveMenu let-item=\"item\" let-items=\"items\" let-index=\"index\">\n @if (item.type == 'group' && menuMode() === 'full') {\n @if (isItemVisible(item)) {\n <ax-title>{{ item.text | translate | async }}</ax-title>\n }\n } @else if (item.type == 'break') {\n @if (shouldShowDivider(item, items, index)) {\n <ax-divider></ax-divider>\n }\n } @else {\n @if (shouldRenderMenuItem(item)) {\n @let routerLinkValue = getRouterLink(item);\n @if (routerLinkValue) {\n <ax-side-menu-item\n [attr.id]=\"'axp-menu-item-' + (item.name || item.text)\"\n (onClick)=\"onMenuItemClick(item, true)\"\n [routerLink]=\"routerLinkValue\"\n [active]=\"item === menuStore.selectedMenuItem().item\"\n [isCollapsed]=\"!menuStore.isItemOpen(item)\"\n >\n <ax-prefix>\n <ax-icon [class]=\"item.icon\" class=\"fa-fw\"></ax-icon>\n </ax-prefix>\n <span>{{ item.text | translate | async }}</span>\n @if (item.children?.length) {\n <ng-container>\n @let sortedChildren = sort(item.children);\n @for (child of sortedChildren; track child; let childIndex = $index) {\n <ng-container\n [ngTemplateOutlet]=\"recursiveMenu\"\n [ngTemplateOutletContext]=\"{ item: child, items: sortedChildren, index: childIndex }\"\n >\n </ng-container>\n }\n </ng-container>\n }\n <ax-suffix>\n @if (badgeVisible()) {\n <ax-badge [axp-task-badge]=\"getMenuBadge(item)()\" color=\"secondary\"></ax-badge>\n }\n </ax-suffix>\n </ax-side-menu-item>\n } @else {\n <ax-side-menu-item\n [attr.id]=\"'axp-menu-item-' + (item.name || item.text)\"\n (onClick)=\"onMenuItemClick(item)\"\n [active]=\"item === menuStore.selectedMenuItem().item\"\n [isCollapsed]=\"!menuStore.isItemOpen(item)\"\n >\n <ax-prefix>\n <ax-icon [class]=\"item.icon\" class=\"fa-fw\"></ax-icon>\n </ax-prefix>\n <span>{{ item.text | translate | async }}</span>\n @if (item.children?.length) {\n <ng-container>\n @let sortedChildren = sort(item.children);\n @for (child of sortedChildren; track child; let childIndex = $index) {\n <ng-container\n [ngTemplateOutlet]=\"recursiveMenu\"\n [ngTemplateOutletContext]=\"{ item: child, items: sortedChildren, index: childIndex }\"\n >\n </ng-container>\n }\n </ng-container>\n }\n <ax-suffix>\n @if (badgeVisible()) {\n <ax-badge [axp-task-badge]=\"getMenuBadge(item)()\" color=\"secondary\"></ax-badge>\n }\n </ax-suffix>\n </ax-side-menu-item>\n }\n }\n }\n</ng-template>\n" }]
2610
+ }] });
397
2611
 
398
2612
  class AXPHorizontalMenuComponent {
399
2613
  constructor() {
@@ -404,10 +2618,10 @@ class AXPHorizontalMenuComponent {
404
2618
  this.badgeService = inject(AXPTaskBadgeService);
405
2619
  this.settingsService = inject(AXPSettingsService);
406
2620
  this.visibilityService = inject(AXPMenuVisibilityService);
407
- this.badgeVisible = signal(true, ...(ngDevMode ? [{ debugName: "badgeVisible" }] : []));
2621
+ this.badgeVisible = signal(true, ...(ngDevMode ? [{ debugName: "badgeVisible" }] : /* istanbul ignore next */ []));
408
2622
  }
409
2623
  async ngOnInit() {
410
- this.badgeVisible.set(await this.settingsService.scope(AXPPlatformScope.User).get(AXPThemeLayoutSetting.MenuBadgeVisible));
2624
+ this.badgeVisible.set(await this.settingsService.get(AXPThemeLayoutSetting.MenuBadgeVisible));
411
2625
  //subscribe to changes
412
2626
  this.settingsService.onChanged.subscribe(setting => {
413
2627
  if (setting.keys.includes(AXPThemeLayoutSetting.MenuBadgeVisible)) {
@@ -443,6 +2657,30 @@ class AXPHorizontalMenuComponent {
443
2657
  shouldRenderMenuItem(item) {
444
2658
  return this.visibilityService.shouldRenderMenuItem(item, (item) => this.getRouterLink(item));
445
2659
  }
2660
+ /**
2661
+ * Checks if an item takes up visual space in the menu (group title or rendered menu item).
2662
+ */
2663
+ isItemRendered(item) {
2664
+ if (item.type === 'break') {
2665
+ return false;
2666
+ }
2667
+ if (item.type === 'group') {
2668
+ return this.isItemVisible(item);
2669
+ }
2670
+ return this.shouldRenderMenuItem(item);
2671
+ }
2672
+ /**
2673
+ * Determines if a divider should be shown. A divider is only shown when there is
2674
+ * visible content on both sides; if before or after is blank, the divider is hidden.
2675
+ */
2676
+ shouldShowDivider(item, items, index) {
2677
+ if (item.type !== 'break' || !items || index < 0) {
2678
+ return false;
2679
+ }
2680
+ const hasVisibleBefore = items.slice(0, index).some((i) => this.isItemRendered(i));
2681
+ const hasVisibleAfter = items.slice(index + 1).some((i) => this.isItemRendered(i));
2682
+ return hasVisibleBefore && hasVisibleAfter;
2683
+ }
446
2684
  //#endregion
447
2685
  //#region ---- Menu Navigation Helpers ----
448
2686
  /**
@@ -544,10 +2782,10 @@ class AXPHorizontalMenuComponent {
544
2782
  const lowerPath = path.trim().toLowerCase();
545
2783
  return lowerPath.startsWith('http://') || lowerPath.startsWith('https://');
546
2784
  }
547
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPHorizontalMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
548
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXPHorizontalMenuComponent, isStandalone: true, selector: "axp-horizontal-menu", host: { classAttribute: "ax-light" }, ngImport: i0, template: "<div\n class=\"ax-w-full ax-flex ax-items-center ax-justify-between ax-gap-1 ax-bg-primary-surface ax-text-primary-on-surface ax-h-14 ax-px-4\"\n>\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <axp-logo\n [source]=\"platformConfig.logo?.full?.dark\"\n [attr.alt]=\"platformConfig.title\"\n class=\"ax-mx-auto ax-text-2xl\"\n ></axp-logo>\n </div>\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <axp-component-slot name=\"root-header-start\"></axp-component-slot>\n <axp-component-slot name=\"root-header-end\"></axp-component-slot>\n </div>\n</div>\n\n<div class=\"__menu-bar\">\n <ax-menu [orientation]=\"'horizontal'\" [class.ax-dark]=\"layoutService.isDarkMode()\" [hasArrow]=\"true\">\n @for (item of sort(menuStore.items()); track item) {\n <ng-container [ngTemplateOutlet]=\"recursiveMenu\" [ngTemplateOutletContext]=\"{ item: item }\"> </ng-container>\n }\n <!-- Item Templates -->\n <ng-template #recursiveMenu let-item=\"item\">\n @if (item.type == 'group') {\n @if (isItemVisible(item)) {\n <ax-title>{{ item.text | translate | async }}</ax-title>\n }\n } @else if (item.type == 'break') {\n <ax-divider></ax-divider>\n } @else {\n @if (shouldRenderMenuItem(item)) {\n <ax-menu-item (onClick)=\"onMenuItemClick(item)\">\n @if (!item.meta?.isRoot) {\n <ax-prefix>\n <ax-icon [class]=\"item.icon\" class=\"fa-fw\"></ax-icon>\n </ax-prefix>\n }\n <ax-text> {{ item.text | translate | async }}</ax-text>\n @if (item.children?.length) {\n <ng-container>\n @for (child of sort(item.children); track child) {\n <ng-container [ngTemplateOutlet]=\"recursiveMenu\" [ngTemplateOutletContext]=\"{ item: child }\">\n </ng-container>\n }\n </ng-container>\n }\n <ax-suffix>\n @if (badgeVisible()) {\n <ax-badge [axp-task-badge]=\"getMenuBadge(item)()\" color=\"secondary\"></ax-badge>\n }\n </ax-suffix>\n </ax-menu-item>\n }\n }\n </ng-template>\n </ax-menu>\n</div>\n<!-- <div class=\"__tab-bar\">\n<div class=\"axp-tabs-item axp-state-active\">\n <span class=\"ax-font-medium\">Account</span>\n <i class=\"fa-light fa-times ax-text-sm\"></i>\n</div>\n<div class=\"axp-tabs-item\">\n <span class=\"ax-font-medium\">Projects</span>\n\n</div>\n</div> -->\n", styles: [".__tab-bar{display:flex;height:3rem;width:100%;align-items:flex-end;gap:.5rem;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-primary-darker-surface),var(--tw-bg-opacity, 1));padding-left:1rem;padding-right:1rem;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-primary-darker-surface),var(--tw-text-opacity, 1))}.__tab-bar .axp-tabs-item{display:flex;height:2.5rem;cursor:pointer;align-items:center;justify-content:space-between;gap:.5rem;border-top-left-radius:.5rem;border-top-right-radius:.5rem;padding-left:1rem;padding-right:1rem;font-size:.875rem;line-height:1.25rem;line-height:1}.__tab-bar .axp-tabs-item:hover,.__tab-bar .axp-tabs-item.axp-state-active{--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lightest-surface),var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lightest-surface),var(--tw-text-opacity, 1))}.__menu-bar{display:flex;width:100%;align-items:flex-end;gap:.5rem;overflow-x:auto;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-primary-dark-surface),var(--tw-bg-opacity, 1));padding:.375rem 1rem;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-primary-dark-surface),var(--tw-text-opacity, 1))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: AXPComponentSlotModule }, { kind: "directive", type: i1$2.AXPComponentSlotDirective, selector: "axp-component-slot", inputs: ["name", "host", "context"], exportAs: ["slot"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "component", type: AXPLogoComponent, selector: "axp-logo", inputs: ["source"] }, { kind: "ngmodule", type: AXMenuModule }, { kind: "component", type: i4$1.AXMenuItemComponent, selector: "ax-menu-item", inputs: ["name", "data", "disabled", "color"], outputs: ["onClick"] }, { kind: "component", type: i4$1.AXMenuComponent, selector: "ax-menu", inputs: ["orientation", "openOn", "closeOn", "items", "hasArrow"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: AXPTaskBadgeDirective, selector: "[axp-task-badge]", inputs: ["badgeKey", "axp-task-badge"] }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i4.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i10.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
2785
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPHorizontalMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2786
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPHorizontalMenuComponent, isStandalone: true, selector: "axp-horizontal-menu", host: { classAttribute: "ax-light" }, ngImport: i0, template: "<div\n class=\"ax-w-full ax-flex ax-items-center ax-justify-between ax-gap-1 ax-bg-primary-surface ax-text-primary-on-surface ax-h-14 ax-px-4\"\n>\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <axp-logo\n [source]=\"platformConfig.logo?.full?.dark\"\n [attr.alt]=\"platformConfig.title\"\n class=\"ax-mx-auto ax-text-2xl\"\n ></axp-logo>\n </div>\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <axp-component-slot name=\"root-header-start\"></axp-component-slot>\n <axp-component-slot name=\"root-header-end\"></axp-component-slot>\n </div>\n</div>\n\n<div class=\"__menu-bar\">\n <ax-menu [orientation]=\"'horizontal'\" [class.ax-dark]=\"layoutService.isDarkMode()\" [hasArrow]=\"true\">\n @let sortedItems = sort(menuStore.items());\n @for (item of sortedItems; track item; let i = $index) {\n <ng-container [ngTemplateOutlet]=\"recursiveMenu\" [ngTemplateOutletContext]=\"{ item: item, items: sortedItems, index: i }\"> </ng-container>\n }\n <!-- Item Templates -->\n <ng-template #recursiveMenu let-item=\"item\" let-items=\"items\" let-index=\"index\">\n @if (item.type == 'group') {\n @if (isItemVisible(item)) {\n <ax-title>{{ item.text | translate | async }}</ax-title>\n }\n } @else if (item.type == 'break') {\n @if (shouldShowDivider(item, items, index)) {\n <ax-divider></ax-divider>\n }\n } @else {\n @if (shouldRenderMenuItem(item)) {\n <ax-menu-item (onClick)=\"onMenuItemClick(item)\">\n @if (!item.meta?.isRoot) {\n <ax-prefix>\n <ax-icon [class]=\"item.icon\" class=\"fa-fw\"></ax-icon>\n </ax-prefix>\n }\n <ax-text> {{ item.text | translate | async }}</ax-text>\n @if (item.children?.length) {\n <ng-container>\n @let sortedChildren = sort(item.children);\n @for (child of sortedChildren; track child; let childIndex = $index) {\n <ng-container [ngTemplateOutlet]=\"recursiveMenu\" [ngTemplateOutletContext]=\"{ item: child, items: sortedChildren, index: childIndex }\">\n </ng-container>\n }\n </ng-container>\n }\n <ax-suffix>\n @if (badgeVisible()) {\n <ax-badge [axp-task-badge]=\"getMenuBadge(item)()\" color=\"secondary\"></ax-badge>\n }\n </ax-suffix>\n </ax-menu-item>\n }\n }\n </ng-template>\n </ax-menu>\n</div>\n<!-- <div class=\"__tab-bar\">\n<div class=\"axp-tabs-item axp-state-active\">\n <span class=\"ax-font-medium\">Account</span>\n <i class=\"fa-light fa-times ax-text-sm\"></i>\n</div>\n<div class=\"axp-tabs-item\">\n <span class=\"ax-font-medium\">Projects</span>\n\n</div>\n</div> -->\n", styles: [".__tab-bar{display:flex;height:3rem;width:100%;align-items:flex-end;gap:.5rem;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-primary-darker-surface),var(--tw-bg-opacity, 1));padding-left:1rem;padding-right:1rem;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-primary-darker-surface),var(--tw-text-opacity, 1))}.__tab-bar .axp-tabs-item{display:flex;height:2.5rem;cursor:pointer;align-items:center;justify-content:space-between;gap:.5rem;border-top-left-radius:.5rem;border-top-right-radius:.5rem;padding-left:1rem;padding-right:1rem;font-size:.875rem;line-height:1.25rem;line-height:1}.__tab-bar .axp-tabs-item:hover,.__tab-bar .axp-tabs-item.axp-state-active{--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lightest-surface),var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lightest-surface),var(--tw-text-opacity, 1))}.__menu-bar{display:flex;width:100%;align-items:flex-end;gap:.5rem;overflow-x:auto;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-primary-dark-surface),var(--tw-bg-opacity, 1));padding:.375rem 1rem;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-primary-dark-surface),var(--tw-text-opacity, 1))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: AXPComponentSlotModule }, { kind: "directive", type: i1$5.AXPComponentSlotDirective, selector: "axp-component-slot", inputs: ["name", "host", "context"], exportAs: ["slot"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "component", type: AXPLogoComponent, selector: "axp-logo", inputs: ["source"] }, { kind: "ngmodule", type: AXMenuModule }, { kind: "component", type: i4.AXMenuItemComponent, selector: "ax-menu-item", inputs: ["name", "data", "disabled", "color"], outputs: ["onClick"] }, { kind: "component", type: i4.AXMenuComponent, selector: "ax-menu", inputs: ["orientation", "openOn", "closeOn", "items", "hasArrow"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: AXPTaskBadgeDirective, selector: "[axp-task-badge]", inputs: ["badgeKey", "axp-task-badge"] }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i1$2.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
549
2787
  }
550
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPHorizontalMenuComponent, decorators: [{
2788
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPHorizontalMenuComponent, decorators: [{
551
2789
  type: Component,
552
2790
  args: [{ selector: 'axp-horizontal-menu', host: { class: 'ax-light' }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
553
2791
  CommonModule,
@@ -558,7 +2796,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
558
2796
  AXTranslationModule,
559
2797
  AXPTaskBadgeDirective,
560
2798
  AXBadgeModule,
561
- ], template: "<div\n class=\"ax-w-full ax-flex ax-items-center ax-justify-between ax-gap-1 ax-bg-primary-surface ax-text-primary-on-surface ax-h-14 ax-px-4\"\n>\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <axp-logo\n [source]=\"platformConfig.logo?.full?.dark\"\n [attr.alt]=\"platformConfig.title\"\n class=\"ax-mx-auto ax-text-2xl\"\n ></axp-logo>\n </div>\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <axp-component-slot name=\"root-header-start\"></axp-component-slot>\n <axp-component-slot name=\"root-header-end\"></axp-component-slot>\n </div>\n</div>\n\n<div class=\"__menu-bar\">\n <ax-menu [orientation]=\"'horizontal'\" [class.ax-dark]=\"layoutService.isDarkMode()\" [hasArrow]=\"true\">\n @for (item of sort(menuStore.items()); track item) {\n <ng-container [ngTemplateOutlet]=\"recursiveMenu\" [ngTemplateOutletContext]=\"{ item: item }\"> </ng-container>\n }\n <!-- Item Templates -->\n <ng-template #recursiveMenu let-item=\"item\">\n @if (item.type == 'group') {\n @if (isItemVisible(item)) {\n <ax-title>{{ item.text | translate | async }}</ax-title>\n }\n } @else if (item.type == 'break') {\n <ax-divider></ax-divider>\n } @else {\n @if (shouldRenderMenuItem(item)) {\n <ax-menu-item (onClick)=\"onMenuItemClick(item)\">\n @if (!item.meta?.isRoot) {\n <ax-prefix>\n <ax-icon [class]=\"item.icon\" class=\"fa-fw\"></ax-icon>\n </ax-prefix>\n }\n <ax-text> {{ item.text | translate | async }}</ax-text>\n @if (item.children?.length) {\n <ng-container>\n @for (child of sort(item.children); track child) {\n <ng-container [ngTemplateOutlet]=\"recursiveMenu\" [ngTemplateOutletContext]=\"{ item: child }\">\n </ng-container>\n }\n </ng-container>\n }\n <ax-suffix>\n @if (badgeVisible()) {\n <ax-badge [axp-task-badge]=\"getMenuBadge(item)()\" color=\"secondary\"></ax-badge>\n }\n </ax-suffix>\n </ax-menu-item>\n }\n }\n </ng-template>\n </ax-menu>\n</div>\n<!-- <div class=\"__tab-bar\">\n<div class=\"axp-tabs-item axp-state-active\">\n <span class=\"ax-font-medium\">Account</span>\n <i class=\"fa-light fa-times ax-text-sm\"></i>\n</div>\n<div class=\"axp-tabs-item\">\n <span class=\"ax-font-medium\">Projects</span>\n\n</div>\n</div> -->\n", styles: [".__tab-bar{display:flex;height:3rem;width:100%;align-items:flex-end;gap:.5rem;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-primary-darker-surface),var(--tw-bg-opacity, 1));padding-left:1rem;padding-right:1rem;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-primary-darker-surface),var(--tw-text-opacity, 1))}.__tab-bar .axp-tabs-item{display:flex;height:2.5rem;cursor:pointer;align-items:center;justify-content:space-between;gap:.5rem;border-top-left-radius:.5rem;border-top-right-radius:.5rem;padding-left:1rem;padding-right:1rem;font-size:.875rem;line-height:1.25rem;line-height:1}.__tab-bar .axp-tabs-item:hover,.__tab-bar .axp-tabs-item.axp-state-active{--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lightest-surface),var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lightest-surface),var(--tw-text-opacity, 1))}.__menu-bar{display:flex;width:100%;align-items:flex-end;gap:.5rem;overflow-x:auto;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-primary-dark-surface),var(--tw-bg-opacity, 1));padding:.375rem 1rem;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-primary-dark-surface),var(--tw-text-opacity, 1))}\n"] }]
2799
+ ], template: "<div\n class=\"ax-w-full ax-flex ax-items-center ax-justify-between ax-gap-1 ax-bg-primary-surface ax-text-primary-on-surface ax-h-14 ax-px-4\"\n>\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <axp-logo\n [source]=\"platformConfig.logo?.full?.dark\"\n [attr.alt]=\"platformConfig.title\"\n class=\"ax-mx-auto ax-text-2xl\"\n ></axp-logo>\n </div>\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <axp-component-slot name=\"root-header-start\"></axp-component-slot>\n <axp-component-slot name=\"root-header-end\"></axp-component-slot>\n </div>\n</div>\n\n<div class=\"__menu-bar\">\n <ax-menu [orientation]=\"'horizontal'\" [class.ax-dark]=\"layoutService.isDarkMode()\" [hasArrow]=\"true\">\n @let sortedItems = sort(menuStore.items());\n @for (item of sortedItems; track item; let i = $index) {\n <ng-container [ngTemplateOutlet]=\"recursiveMenu\" [ngTemplateOutletContext]=\"{ item: item, items: sortedItems, index: i }\"> </ng-container>\n }\n <!-- Item Templates -->\n <ng-template #recursiveMenu let-item=\"item\" let-items=\"items\" let-index=\"index\">\n @if (item.type == 'group') {\n @if (isItemVisible(item)) {\n <ax-title>{{ item.text | translate | async }}</ax-title>\n }\n } @else if (item.type == 'break') {\n @if (shouldShowDivider(item, items, index)) {\n <ax-divider></ax-divider>\n }\n } @else {\n @if (shouldRenderMenuItem(item)) {\n <ax-menu-item (onClick)=\"onMenuItemClick(item)\">\n @if (!item.meta?.isRoot) {\n <ax-prefix>\n <ax-icon [class]=\"item.icon\" class=\"fa-fw\"></ax-icon>\n </ax-prefix>\n }\n <ax-text> {{ item.text | translate | async }}</ax-text>\n @if (item.children?.length) {\n <ng-container>\n @let sortedChildren = sort(item.children);\n @for (child of sortedChildren; track child; let childIndex = $index) {\n <ng-container [ngTemplateOutlet]=\"recursiveMenu\" [ngTemplateOutletContext]=\"{ item: child, items: sortedChildren, index: childIndex }\">\n </ng-container>\n }\n </ng-container>\n }\n <ax-suffix>\n @if (badgeVisible()) {\n <ax-badge [axp-task-badge]=\"getMenuBadge(item)()\" color=\"secondary\"></ax-badge>\n }\n </ax-suffix>\n </ax-menu-item>\n }\n }\n </ng-template>\n </ax-menu>\n</div>\n<!-- <div class=\"__tab-bar\">\n<div class=\"axp-tabs-item axp-state-active\">\n <span class=\"ax-font-medium\">Account</span>\n <i class=\"fa-light fa-times ax-text-sm\"></i>\n</div>\n<div class=\"axp-tabs-item\">\n <span class=\"ax-font-medium\">Projects</span>\n\n</div>\n</div> -->\n", styles: [".__tab-bar{display:flex;height:3rem;width:100%;align-items:flex-end;gap:.5rem;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-primary-darker-surface),var(--tw-bg-opacity, 1));padding-left:1rem;padding-right:1rem;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-primary-darker-surface),var(--tw-text-opacity, 1))}.__tab-bar .axp-tabs-item{display:flex;height:2.5rem;cursor:pointer;align-items:center;justify-content:space-between;gap:.5rem;border-top-left-radius:.5rem;border-top-right-radius:.5rem;padding-left:1rem;padding-right:1rem;font-size:.875rem;line-height:1.25rem;line-height:1}.__tab-bar .axp-tabs-item:hover,.__tab-bar .axp-tabs-item.axp-state-active{--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lightest-surface),var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lightest-surface),var(--tw-text-opacity, 1))}.__menu-bar{display:flex;width:100%;align-items:flex-end;gap:.5rem;overflow-x:auto;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-primary-dark-surface),var(--tw-bg-opacity, 1));padding:.375rem 1rem;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-primary-dark-surface),var(--tw-text-opacity, 1))}\n"] }]
562
2800
  }] });
563
2801
 
564
2802
  class AXPRootHorizontalLayoutComponent {
@@ -577,10 +2815,10 @@ class AXPRootHorizontalLayoutComponent {
577
2815
  this.store.setSideMenuWidth(e.value);
578
2816
  }
579
2817
  }
580
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPRootHorizontalLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
581
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXPRootHorizontalLayoutComponent, isStandalone: true, selector: "axp-root-horizontal-layout", viewQueries: [{ propertyName: "drawer", first: true, predicate: ["drawer"], descendants: true }], ngImport: i0, template: "<div class=\"axp-root-layout\">\n <ax-drawer-container>\n <ax-content class=\"ax-flex ax-flex-col ax-relative ax-bg-lightest dark:ax-bg-lighter\">\n @if(store.isNavigationLoading()) {\n <div class=\"axp-navigating-progress\">\n <div></div>\n </div>\n }\n <axp-horizontal-menu></axp-horizontal-menu>\n <div class=\"ax-flex-1 ax-overflow-auto ax-relative\">\n <router-outlet></router-outlet>\n </div>\n </ax-content>\n </ax-drawer-container>\n <axp-dashboard-admin-footer></axp-dashboard-admin-footer>\n</div>", styles: [".axp-root-layout{display:flex;height:100%;width:100%;flex-direction:column;justify-content:space-between}.axp-navigating-progress{position:absolute;top:0;height:.25rem;width:100%;overflow:hidden;background-color:rgba(var(--ax-sys-color-primary-200),.4)}.axp-navigating-progress>div{height:100%;width:100%;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-primary-500),var(--tw-bg-opacity, 1));animation:indeterminateAnimation 1.5s infinite cubic-bezier(.65,.815,.735,.395);transform-origin:0% 50%}@keyframes indeterminateAnimation{0%{transform:translate(-100%) scaleX(.2)}50%{transform:translate(50%) scaleX(.6)}to{transform:translate(100%) scaleX(.4)}}axp-dashboard-admin-header{--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-primary-500),var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-primary-surface),var(--tw-text-opacity, 1))}axp-dashboard-admin-header ax-button{--ax-comp-button-normal-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-border-width: 0 !important;--ax-comp-button-normal-text-color: var(--axp-on-brand-color) !important;--ax-comp-button-hover-text-color: var(--axp-on-brand-color) !important;--ax-comp-button-focus-text-color: var(--axp-on-brand-color) !important;--ax-comp-button-pressed-text-color: var(--axp-on-brand-color) !important}.resize-handle{background-color:transparent!important}.resize-handle:hover{background-color:rgba(var(--ax-sys-color-primary-surface))!important}\n"], dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$3.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "ngmodule", type: AXAvatarModule }, { kind: "ngmodule", type: AXImageModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "ngmodule", type: AXTabsModule }, { kind: "ngmodule", type: AXDrawerModule }, { kind: "component", type: i3$1.AXDrawerContainerComponent, selector: "ax-drawer-container" }, { kind: "ngmodule", type: AXSideMenuModule }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "ngmodule", type: AXPAuthModule }, { kind: "component", type: AXPRootLayoutFooterComponent, selector: "axp-dashboard-admin-footer" }, { kind: "component", type: AXPHorizontalMenuComponent, selector: "axp-horizontal-menu" }, { kind: "ngmodule", type: AXPComponentSlotModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
2818
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootHorizontalLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2819
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPRootHorizontalLayoutComponent, isStandalone: true, selector: "axp-root-horizontal-layout", viewQueries: [{ propertyName: "drawer", first: true, predicate: ["drawer"], descendants: true }], ngImport: i0, template: "<div class=\"axp-root-layout\">\n <ax-drawer-container>\n <ax-content class=\"ax-flex ax-flex-col ax-relative ax-bg-lightest dark:ax-bg-lighter\">\n @if(store.isNavigationLoading()) {\n <div class=\"axp-navigating-progress\">\n <div></div>\n </div>\n }\n <axp-horizontal-menu></axp-horizontal-menu>\n <div class=\"ax-flex-1 ax-overflow-auto ax-relative\">\n <router-outlet></router-outlet>\n </div>\n </ax-content>\n </ax-drawer-container>\n <axp-dashboard-admin-footer></axp-dashboard-admin-footer>\n</div>", styles: [".axp-root-layout{display:flex;height:100%;width:100%;flex-direction:column;justify-content:space-between}.axp-navigating-progress{position:absolute;top:0;height:.25rem;width:100%;overflow:hidden;background-color:rgba(var(--ax-sys-color-primary-200),.4)}.axp-navigating-progress>div{height:100%;width:100%;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-primary-500),var(--tw-bg-opacity, 1));animation:indeterminateAnimation 1.5s infinite cubic-bezier(.65,.815,.735,.395);transform-origin:0% 50%}@keyframes indeterminateAnimation{0%{transform:translate(-100%) scaleX(.2)}50%{transform:translate(50%) scaleX(.6)}to{transform:translate(100%) scaleX(.4)}}axp-dashboard-admin-header{--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-primary-500),var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-primary-surface),var(--tw-text-opacity, 1))}axp-dashboard-admin-header ax-button{--ax-comp-button-normal-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-border-width: 0 !important;--ax-comp-button-normal-text-color: var(--axp-on-brand-color) !important;--ax-comp-button-hover-text-color: var(--axp-on-brand-color) !important;--ax-comp-button-focus-text-color: var(--axp-on-brand-color) !important;--ax-comp-button-pressed-text-color: var(--axp-on-brand-color) !important}.resize-handle{background-color:transparent!important}.resize-handle:hover{background-color:rgba(var(--ax-sys-color-primary-surface))!important}\n"], dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$6.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "ngmodule", type: AXAvatarModule }, { kind: "ngmodule", type: AXImageModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "ngmodule", type: AXTabsModule }, { kind: "ngmodule", type: AXDrawerModule }, { kind: "component", type: i3$4.AXDrawerContainerComponent, selector: "ax-drawer-container" }, { kind: "ngmodule", type: AXSideMenuModule }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "ngmodule", type: AXPAuthModule }, { kind: "component", type: AXPRootLayoutFooterComponent, selector: "axp-dashboard-admin-footer" }, { kind: "component", type: AXPHorizontalMenuComponent, selector: "axp-horizontal-menu" }, { kind: "ngmodule", type: AXPComponentSlotModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
582
2820
  }
583
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPRootHorizontalLayoutComponent, decorators: [{
2821
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootHorizontalLayoutComponent, decorators: [{
584
2822
  type: Component,
585
2823
  args: [{ selector: 'axp-root-horizontal-layout', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
586
2824
  RouterModule,
@@ -614,22 +2852,23 @@ class AXPRootVerticalLayoutComponent {
614
2852
  this.store = inject(AXPLayoutThemeService);
615
2853
  this.deviceService = inject(AXPDeviceService);
616
2854
  this.router = inject(Router);
2855
+ /** Recreates the drawer when switching overlay ↔ push to reset internal layout sizing. */
2856
+ this.sideMenuDrawerKey = computed(() => this.deviceService.isSmall() || this.deviceService.isMedium() ? 'overlay' : 'push', ...(ngDevMode ? [{ debugName: "sideMenuDrawerKey" }] : /* istanbul ignore next */ []));
617
2857
  this.router.events.pipe(filter((event) => event instanceof NavigationEnd)).subscribe(() => {
618
- if (this.deviceService.isSmall() || this.deviceService.isMedium()) {
2858
+ if (this.sideMenuDrawerKey() === 'overlay') {
619
2859
  this.store.closeSideMenu();
620
2860
  }
621
2861
  });
622
2862
  }
623
2863
  handleResizingEnded(e) {
624
- //console.log('handleResizingEnded', e.value);
625
2864
  if (e.isUserInteraction) {
626
- this.store.setSideMenuWidth(e.value);
2865
+ this.store.setSideMenuDrawerWidth(e.value);
627
2866
  }
628
2867
  }
629
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPRootVerticalLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
630
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXPRootVerticalLayoutComponent, isStandalone: true, selector: "axp-root-vertical-layout", viewQueries: [{ propertyName: "drawer", first: true, predicate: ["drawer"], descendants: true }], ngImport: i0, template: "<div id=\"axp-root-layout\" class=\"axp-root-layout\">\n <ax-drawer-container>\n <ax-drawer id=\"axp-side-menu-drawer\" [axResizable]=\"deviceService.isLarge()\" #drawer\n class=\"ax-w-[75%] lg:ax-w-72 ax-border-lighter ax-bg-lighter dark:ax-border-darkest dark:ax-bg-darkest ax-h-full !ax-flex ax-flex-col\"\n [width]=\"(deviceService.isLarge() ? store.sideMenuWidth() : null)!\" location=\"start\"\n [collapsed]=\"!store.isSideMenuOpen()\" [closeOnBackdropClick]=\"false\" [defaultWidth]=\"288\"\n [mode]=\"deviceService.isSmall() || deviceService.isMedium() ? 'overlay' : 'push'\" [dblClickAction]=\"'fit'\"\n (onResizingEnded)=\"handleResizingEnded($event)\" (onResizingDblClick)=\"handleResizingEnded($event)\"\n (onBackdropClick)=\"store.closeSideMenu()\" backdropClass=\"ax-bg-black/50\">\n <ax-header id=\"axp-side-menu-header\"\n class=\"ax-light ax-h-14 ax-flex ax-items-center ax-justify-center ax-bg-primary-500 ax-text-primary-on-surface ax-border-e ax-border-primary-600\">\n <axp-logo [source]=\"logo?.full?.dark\"></axp-logo>\n </ax-header>\n <ax-content class=\"ax-flex ax-flex-col ax-border-e ax-h-full ax-overflow-auto\">\n <axp-component-slot name=\"root-side-menu-header\"></axp-component-slot>\n <div class=\"ax-overflow-auto ax-flex-1\">\n <axp-side-menu id=\"axp-side-menu\" class=\"ax-p-4 ax-block\"></axp-side-menu>\n </div>\n <axp-component-slot name=\"root-side-menu-footer\"></axp-component-slot>\n </ax-content>\n </ax-drawer>\n <ax-content class=\"ax-flex ax-flex-col ax-relative ax-bg-lightest dark:ax-bg-lighter ax-overflow-auto\">\n @if (store.isNavigationLoading()) {\n <div class=\"axp-navigating-progress\">\n <div></div>\n </div>\n }\n <axp-dashboard-admin-header id=\"axp-main-header\" class=\"ax-light\"></axp-dashboard-admin-header>\n\n <div class=\"ax-flex-1 ax-overflow-auto ax-relative\">\n <router-outlet></router-outlet>\n </div>\n </ax-content>\n </ax-drawer-container>\n <axp-dashboard-admin-footer id=\"axp-main-footer\"></axp-dashboard-admin-footer>\n</div>", styles: [".axp-root-layout{display:flex;height:100%;width:100%;flex-direction:column;justify-content:space-between}.axp-navigating-progress{position:absolute;top:0;height:.25rem;width:100%;overflow:hidden;background-color:rgba(var(--ax-sys-color-primary-200),.4)}.axp-navigating-progress>div{height:100%;width:100%;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-primary-500),var(--tw-bg-opacity, 1));animation:indeterminateAnimation 1.5s infinite cubic-bezier(.65,.815,.735,.395);transform-origin:0% 50%}@keyframes indeterminateAnimation{0%{transform:translate(-100%) scaleX(.2)}50%{transform:translate(50%) scaleX(.6)}to{transform:translate(100%) scaleX(.4)}}axp-dashboard-admin-header{--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-primary-500),var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-primary-surface),var(--tw-text-opacity, 1))}axp-dashboard-admin-header ax-button{--ax-comp-button-normal-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-border-width: 0 !important;--ax-comp-button-normal-text-color: var(--axp-on-brand-color) !important;--ax-comp-button-hover-text-color: var(--axp-on-brand-color) !important;--ax-comp-button-focus-text-color: var(--axp-on-brand-color) !important;--ax-comp-button-pressed-text-color: var(--axp-on-brand-color) !important}.resize-handle{background-color:transparent!important}.resize-handle:hover{background-color:rgba(var(--ax-sys-color-primary-surface))!important}\n"], dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$3.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "ngmodule", type: AXAvatarModule }, { kind: "ngmodule", type: AXImageModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "ngmodule", type: AXTabsModule }, { kind: "ngmodule", type: AXDrawerModule }, { kind: "component", type: i3$1.AXDrawerComponent, selector: "ax-drawer", inputs: ["location", "showBackdrop", "mode", "transition", "closeOnBackdropClick", "backdropClass", "collapsed", "singleOpenMode"], outputs: ["onBackdropClick", "collapsedStateChanged"] }, { kind: "component", type: i3$1.AXDrawerContainerComponent, selector: "ax-drawer-container" }, { kind: "ngmodule", type: AXSideMenuModule }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: AXPLogoComponent, selector: "axp-logo", inputs: ["source"] }, { kind: "ngmodule", type: AXPAuthModule }, { kind: "directive", type: AXResizableDirective, selector: "[axResizable]", inputs: ["axResizable", "minWidth", "maxWidth", "dblClickAction", "width", "defaultWidth"], outputs: ["axResizableChange", "minWidthChange", "maxWidthChange", "dblClickActionChange", "widthChange", "defaultWidthChange", "onResizingStarted", "onResizingEnded", "onResizingDblClick"] }, { kind: "component", type: AXPRootLayoutFooterComponent, selector: "axp-dashboard-admin-footer" }, { kind: "component", type: AXPRootLayoutHeaderComponent, selector: "axp-dashboard-admin-header" }, { kind: "component", type: AXPRootLayoutMenuComponent, selector: "axp-side-menu" }, { kind: "ngmodule", type: AXPComponentSlotModule }, { kind: "directive", type: i1$2.AXPComponentSlotDirective, selector: "axp-component-slot", inputs: ["name", "host", "context"], exportAs: ["slot"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
2868
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootVerticalLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2869
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPRootVerticalLayoutComponent, isStandalone: true, selector: "axp-root-vertical-layout", ngImport: i0, template: "<div id=\"axp-root-layout\" class=\"axp-root-layout\">\n <ax-drawer-container>\n @for (drawerKey of [sideMenuDrawerKey()]; track drawerKey) {\n <ax-drawer\n id=\"axp-side-menu-drawer\"\n [axResizable]=\"drawerKey === 'push'\"\n class=\"ax-border-lighter ax-bg-lighter dark:ax-border-darkest dark:ax-bg-darkest ax-h-full !ax-flex ax-flex-col\"\n [class.ax-w-[75%]]=\"drawerKey === 'overlay'\"\n [width]=\"store.sideMenuDrawerWidth()\"\n location=\"start\"\n [collapsed]=\"!store.isSideMenuOpen()\"\n [closeOnBackdropClick]=\"false\"\n [defaultWidth]=\"store.sideMenuDrawerWidth()\"\n [mode]=\"drawerKey === 'overlay' ? 'overlay' : 'push'\"\n [dblClickAction]=\"'fit'\"\n (onResizingEnded)=\"handleResizingEnded($event)\"\n (onResizingDblClick)=\"handleResizingEnded($event)\"\n (onBackdropClick)=\"store.closeSideMenu()\"\n backdropClass=\"ax-bg-black/50\"\n >\n <ax-header\n id=\"axp-side-menu-header\"\n class=\"ax-light ax-h-14 ax-flex ax-items-center ax-justify-center ax-bg-primary-500 ax-text-primary-on-surface ax-border-e ax-border-primary-600\"\n >\n <axp-logo [source]=\"logo?.full?.dark\"></axp-logo>\n </ax-header>\n <ax-content class=\"ax-flex ax-flex-col ax-border-e ax-h-full ax-overflow-y-auto ax-overflow-x-hidden\">\n <axp-component-slot name=\"root-side-menu-header\"></axp-component-slot>\n <div class=\"ax-flex-1\">\n <axp-side-menu id=\"axp-side-menu\" class=\"ax-p-4 ax-block\"></axp-side-menu>\n </div>\n <axp-component-slot name=\"root-side-menu-footer\"></axp-component-slot>\n </ax-content>\n </ax-drawer>\n }\n <ax-content class=\"ax-flex ax-flex-col ax-relative ax-bg-lightest dark:ax-bg-lighter ax-overflow-auto\">\n @if (store.isNavigationLoading()) {\n <div class=\"axp-navigating-progress\">\n <div></div>\n </div>\n }\n <axp-dashboard-admin-header id=\"axp-main-header\" class=\"ax-light\"></axp-dashboard-admin-header>\n\n <div class=\"ax-flex-1 ax-overflow-auto ax-relative\">\n <router-outlet></router-outlet>\n </div>\n </ax-content>\n </ax-drawer-container>\n <axp-component-slot name=\"root-layout-overlay\"></axp-component-slot>\n <axp-dashboard-admin-footer id=\"axp-main-footer\"></axp-dashboard-admin-footer>\n</div>\n", styles: [".axp-root-layout{display:flex;height:100%;width:100%;flex-direction:column;justify-content:space-between}#axp-side-menu-drawer{box-sizing:border-box}.axp-navigating-progress{position:absolute;top:0;height:.25rem;width:100%;overflow:hidden;background-color:rgba(var(--ax-sys-color-primary-200),.4)}.axp-navigating-progress>div{height:100%;width:100%;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-primary-500),var(--tw-bg-opacity, 1));animation:indeterminateAnimation 1.5s infinite cubic-bezier(.65,.815,.735,.395);transform-origin:0% 50%}@keyframes indeterminateAnimation{0%{transform:translate(-100%) scaleX(.2)}50%{transform:translate(50%) scaleX(.6)}to{transform:translate(100%) scaleX(.4)}}axp-dashboard-admin-header{--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-primary-500),var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-primary-surface),var(--tw-text-opacity, 1))}axp-dashboard-admin-header ax-button{--ax-comp-button-normal-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-border-width: 0 !important;--ax-comp-button-normal-text-color: var(--axp-on-brand-color) !important;--ax-comp-button-hover-text-color: var(--axp-on-brand-color) !important;--ax-comp-button-focus-text-color: var(--axp-on-brand-color) !important;--ax-comp-button-pressed-text-color: var(--axp-on-brand-color) !important}.resize-handle{background-color:transparent!important}.resize-handle:hover{background-color:rgba(var(--ax-sys-color-primary-surface))!important}\n"], dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$6.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "ngmodule", type: AXAvatarModule }, { kind: "ngmodule", type: AXImageModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "ngmodule", type: AXTabsModule }, { kind: "ngmodule", type: AXDrawerModule }, { kind: "component", type: i3$4.AXDrawerComponent, selector: "ax-drawer", inputs: ["location", "showBackdrop", "mode", "transition", "closeOnBackdropClick", "backdropClass", "collapsed", "singleOpenMode"], outputs: ["onBackdropClick", "collapsedStateChanged"] }, { kind: "component", type: i3$4.AXDrawerContainerComponent, selector: "ax-drawer-container" }, { kind: "ngmodule", type: AXSideMenuModule }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: AXPLogoComponent, selector: "axp-logo", inputs: ["source"] }, { kind: "ngmodule", type: AXPAuthModule }, { kind: "directive", type: AXResizableDirective, selector: "[axResizable]", inputs: ["axResizable", "minWidth", "maxWidth", "dblClickAction", "width", "defaultWidth"], outputs: ["axResizableChange", "minWidthChange", "maxWidthChange", "dblClickActionChange", "widthChange", "defaultWidthChange", "onResizingStarted", "onResizingEnded", "onResizingDblClick"] }, { kind: "component", type: AXPRootLayoutFooterComponent, selector: "axp-dashboard-admin-footer" }, { kind: "component", type: AXPRootLayoutHeaderComponent, selector: "axp-dashboard-admin-header" }, { kind: "component", type: AXPRootLayoutMenuComponent, selector: "axp-side-menu" }, { kind: "ngmodule", type: AXPComponentSlotModule }, { kind: "directive", type: i1$5.AXPComponentSlotDirective, selector: "axp-component-slot", inputs: ["name", "host", "context"], exportAs: ["slot"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
631
2870
  }
632
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPRootVerticalLayoutComponent, decorators: [{
2871
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootVerticalLayoutComponent, decorators: [{
633
2872
  type: Component,
634
2873
  args: [{ selector: 'axp-root-vertical-layout', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
635
2874
  RouterModule,
@@ -654,11 +2893,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
654
2893
  AXPRootLayoutHeaderComponent,
655
2894
  AXPRootLayoutMenuComponent,
656
2895
  AXPComponentSlotModule,
657
- ], template: "<div id=\"axp-root-layout\" class=\"axp-root-layout\">\n <ax-drawer-container>\n <ax-drawer id=\"axp-side-menu-drawer\" [axResizable]=\"deviceService.isLarge()\" #drawer\n class=\"ax-w-[75%] lg:ax-w-72 ax-border-lighter ax-bg-lighter dark:ax-border-darkest dark:ax-bg-darkest ax-h-full !ax-flex ax-flex-col\"\n [width]=\"(deviceService.isLarge() ? store.sideMenuWidth() : null)!\" location=\"start\"\n [collapsed]=\"!store.isSideMenuOpen()\" [closeOnBackdropClick]=\"false\" [defaultWidth]=\"288\"\n [mode]=\"deviceService.isSmall() || deviceService.isMedium() ? 'overlay' : 'push'\" [dblClickAction]=\"'fit'\"\n (onResizingEnded)=\"handleResizingEnded($event)\" (onResizingDblClick)=\"handleResizingEnded($event)\"\n (onBackdropClick)=\"store.closeSideMenu()\" backdropClass=\"ax-bg-black/50\">\n <ax-header id=\"axp-side-menu-header\"\n class=\"ax-light ax-h-14 ax-flex ax-items-center ax-justify-center ax-bg-primary-500 ax-text-primary-on-surface ax-border-e ax-border-primary-600\">\n <axp-logo [source]=\"logo?.full?.dark\"></axp-logo>\n </ax-header>\n <ax-content class=\"ax-flex ax-flex-col ax-border-e ax-h-full ax-overflow-auto\">\n <axp-component-slot name=\"root-side-menu-header\"></axp-component-slot>\n <div class=\"ax-overflow-auto ax-flex-1\">\n <axp-side-menu id=\"axp-side-menu\" class=\"ax-p-4 ax-block\"></axp-side-menu>\n </div>\n <axp-component-slot name=\"root-side-menu-footer\"></axp-component-slot>\n </ax-content>\n </ax-drawer>\n <ax-content class=\"ax-flex ax-flex-col ax-relative ax-bg-lightest dark:ax-bg-lighter ax-overflow-auto\">\n @if (store.isNavigationLoading()) {\n <div class=\"axp-navigating-progress\">\n <div></div>\n </div>\n }\n <axp-dashboard-admin-header id=\"axp-main-header\" class=\"ax-light\"></axp-dashboard-admin-header>\n\n <div class=\"ax-flex-1 ax-overflow-auto ax-relative\">\n <router-outlet></router-outlet>\n </div>\n </ax-content>\n </ax-drawer-container>\n <axp-dashboard-admin-footer id=\"axp-main-footer\"></axp-dashboard-admin-footer>\n</div>", styles: [".axp-root-layout{display:flex;height:100%;width:100%;flex-direction:column;justify-content:space-between}.axp-navigating-progress{position:absolute;top:0;height:.25rem;width:100%;overflow:hidden;background-color:rgba(var(--ax-sys-color-primary-200),.4)}.axp-navigating-progress>div{height:100%;width:100%;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-primary-500),var(--tw-bg-opacity, 1));animation:indeterminateAnimation 1.5s infinite cubic-bezier(.65,.815,.735,.395);transform-origin:0% 50%}@keyframes indeterminateAnimation{0%{transform:translate(-100%) scaleX(.2)}50%{transform:translate(50%) scaleX(.6)}to{transform:translate(100%) scaleX(.4)}}axp-dashboard-admin-header{--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-primary-500),var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-primary-surface),var(--tw-text-opacity, 1))}axp-dashboard-admin-header ax-button{--ax-comp-button-normal-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-border-width: 0 !important;--ax-comp-button-normal-text-color: var(--axp-on-brand-color) !important;--ax-comp-button-hover-text-color: var(--axp-on-brand-color) !important;--ax-comp-button-focus-text-color: var(--axp-on-brand-color) !important;--ax-comp-button-pressed-text-color: var(--axp-on-brand-color) !important}.resize-handle{background-color:transparent!important}.resize-handle:hover{background-color:rgba(var(--ax-sys-color-primary-surface))!important}\n"] }]
658
- }], ctorParameters: () => [], propDecorators: { drawer: [{
659
- type: ViewChild,
660
- args: ['drawer']
661
- }] } });
2896
+ ], template: "<div id=\"axp-root-layout\" class=\"axp-root-layout\">\n <ax-drawer-container>\n @for (drawerKey of [sideMenuDrawerKey()]; track drawerKey) {\n <ax-drawer\n id=\"axp-side-menu-drawer\"\n [axResizable]=\"drawerKey === 'push'\"\n class=\"ax-border-lighter ax-bg-lighter dark:ax-border-darkest dark:ax-bg-darkest ax-h-full !ax-flex ax-flex-col\"\n [class.ax-w-[75%]]=\"drawerKey === 'overlay'\"\n [width]=\"store.sideMenuDrawerWidth()\"\n location=\"start\"\n [collapsed]=\"!store.isSideMenuOpen()\"\n [closeOnBackdropClick]=\"false\"\n [defaultWidth]=\"store.sideMenuDrawerWidth()\"\n [mode]=\"drawerKey === 'overlay' ? 'overlay' : 'push'\"\n [dblClickAction]=\"'fit'\"\n (onResizingEnded)=\"handleResizingEnded($event)\"\n (onResizingDblClick)=\"handleResizingEnded($event)\"\n (onBackdropClick)=\"store.closeSideMenu()\"\n backdropClass=\"ax-bg-black/50\"\n >\n <ax-header\n id=\"axp-side-menu-header\"\n class=\"ax-light ax-h-14 ax-flex ax-items-center ax-justify-center ax-bg-primary-500 ax-text-primary-on-surface ax-border-e ax-border-primary-600\"\n >\n <axp-logo [source]=\"logo?.full?.dark\"></axp-logo>\n </ax-header>\n <ax-content class=\"ax-flex ax-flex-col ax-border-e ax-h-full ax-overflow-y-auto ax-overflow-x-hidden\">\n <axp-component-slot name=\"root-side-menu-header\"></axp-component-slot>\n <div class=\"ax-flex-1\">\n <axp-side-menu id=\"axp-side-menu\" class=\"ax-p-4 ax-block\"></axp-side-menu>\n </div>\n <axp-component-slot name=\"root-side-menu-footer\"></axp-component-slot>\n </ax-content>\n </ax-drawer>\n }\n <ax-content class=\"ax-flex ax-flex-col ax-relative ax-bg-lightest dark:ax-bg-lighter ax-overflow-auto\">\n @if (store.isNavigationLoading()) {\n <div class=\"axp-navigating-progress\">\n <div></div>\n </div>\n }\n <axp-dashboard-admin-header id=\"axp-main-header\" class=\"ax-light\"></axp-dashboard-admin-header>\n\n <div class=\"ax-flex-1 ax-overflow-auto ax-relative\">\n <router-outlet></router-outlet>\n </div>\n </ax-content>\n </ax-drawer-container>\n <axp-component-slot name=\"root-layout-overlay\"></axp-component-slot>\n <axp-dashboard-admin-footer id=\"axp-main-footer\"></axp-dashboard-admin-footer>\n</div>\n", styles: [".axp-root-layout{display:flex;height:100%;width:100%;flex-direction:column;justify-content:space-between}#axp-side-menu-drawer{box-sizing:border-box}.axp-navigating-progress{position:absolute;top:0;height:.25rem;width:100%;overflow:hidden;background-color:rgba(var(--ax-sys-color-primary-200),.4)}.axp-navigating-progress>div{height:100%;width:100%;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-primary-500),var(--tw-bg-opacity, 1));animation:indeterminateAnimation 1.5s infinite cubic-bezier(.65,.815,.735,.395);transform-origin:0% 50%}@keyframes indeterminateAnimation{0%{transform:translate(-100%) scaleX(.2)}50%{transform:translate(50%) scaleX(.6)}to{transform:translate(100%) scaleX(.4)}}axp-dashboard-admin-header{--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-primary-500),var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-primary-surface),var(--tw-text-opacity, 1))}axp-dashboard-admin-header ax-button{--ax-comp-button-normal-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-border-width: 0 !important;--ax-comp-button-normal-text-color: var(--axp-on-brand-color) !important;--ax-comp-button-hover-text-color: var(--axp-on-brand-color) !important;--ax-comp-button-focus-text-color: var(--axp-on-brand-color) !important;--ax-comp-button-pressed-text-color: var(--axp-on-brand-color) !important}.resize-handle{background-color:transparent!important}.resize-handle:hover{background-color:rgba(var(--ax-sys-color-primary-surface))!important}\n"] }]
2897
+ }], ctorParameters: () => [] });
662
2898
 
663
2899
  class AXPRootLayoutComponent {
664
2900
  constructor() {
@@ -668,7 +2904,6 @@ class AXPRootLayoutComponent {
668
2904
  this.eventService = inject(AXPBroadcastEventService);
669
2905
  this.sessionService = inject(AXPSessionService);
670
2906
  this.unsubscriber = inject(AXUnsubscriber);
671
- this.workflowService = inject(AXPWorkflowService);
672
2907
  this.contextStore = inject(AXPContextStore);
673
2908
  }
674
2909
  ngOnInit() {
@@ -698,11 +2933,9 @@ class AXPRootLayoutComponent {
698
2933
  this.router.navigate(['/auth/login']);
699
2934
  }
700
2935
  });
701
- //
702
- this.workflowService.execute('check-new-version');
703
2936
  }
704
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPRootLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
705
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXPRootLayoutComponent, isStandalone: true, selector: "ng-component", providers: [AXUnsubscriber], ngImport: i0, template: `
2937
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2938
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPRootLayoutComponent, isStandalone: true, selector: "ng-component", providers: [AXUnsubscriber, AXPContextStore], ngImport: i0, template: `
706
2939
  @if(layout.isMenuHorizontal()){
707
2940
  <axp-root-horizontal-layout></axp-root-horizontal-layout>
708
2941
  }@else{
@@ -710,7 +2943,7 @@ class AXPRootLayoutComponent {
710
2943
  }
711
2944
  `, isInline: true, dependencies: [{ kind: "component", type: AXPRootHorizontalLayoutComponent, selector: "axp-root-horizontal-layout" }, { kind: "component", type: AXPRootVerticalLayoutComponent, selector: "axp-root-vertical-layout" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
712
2945
  }
713
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPRootLayoutComponent, decorators: [{
2946
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootLayoutComponent, decorators: [{
714
2947
  type: Component,
715
2948
  args: [{
716
2949
  template: `
@@ -724,7 +2957,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
724
2957
  changeDetection: ChangeDetectionStrategy.OnPush,
725
2958
  standalone: true,
726
2959
  imports: [AXPRootHorizontalLayoutComponent, AXPRootVerticalLayoutComponent],
727
- providers: [AXUnsubscriber],
2960
+ providers: [AXUnsubscriber, AXPContextStore],
728
2961
  }]
729
2962
  }] });
730
2963
 
@@ -824,7 +3057,7 @@ function routesFacory() {
824
3057
  let routes = [
825
3058
  {
826
3059
  path: ':app/modules/:module/:entity',
827
- canActivate: [AXPAuthGuard],
3060
+ canActivate: [...AXP_PROTECTED_ROUTE_GUARDS],
828
3061
  loadComponent: () => {
829
3062
  return config.viewers.root();
830
3063
  },
@@ -844,25 +3077,35 @@ function routesFacory() {
844
3077
  children: [
845
3078
  {
846
3079
  path: 'offline',
847
- loadComponent: () => import('./acorex-platform-themes-default-error-offline.component-E7SzBcAt.mjs').then((c) => c.AXPErrorOfflineComponent),
3080
+ loadComponent: () => import('./acorex-platform-themes-default-error-offline.component-DR6G8gPC.mjs').then((c) => c.AXPErrorOfflineComponent),
848
3081
  },
849
3082
  {
850
3083
  path: '404',
851
- loadComponent: () => import('./acorex-platform-themes-default-error-404.component-CdCV5ZoA.mjs').then((c) => c.AXPError404Component),
3084
+ loadComponent: () => import('./acorex-platform-themes-default-error-404.component-D4UvRe8u.mjs').then((c) => c.AXPError404Component),
852
3085
  },
853
3086
  {
854
3087
  path: '401',
855
- loadComponent: () => import('./acorex-platform-themes-default-error-401.component-cfREo88K.mjs').then((c) => c.AXPError401Component),
3088
+ loadComponent: () => import('./acorex-platform-themes-default-error-401.component-B1nsdpTY.mjs').then((c) => c.AXPError401Component),
856
3089
  },
857
3090
  ],
858
3091
  },
3092
+ {
3093
+ path: '404',
3094
+ redirectTo: 'error/404',
3095
+ pathMatch: 'full',
3096
+ },
3097
+ {
3098
+ path: '401',
3099
+ redirectTo: 'error/401',
3100
+ pathMatch: 'full',
3101
+ },
859
3102
  ];
860
3103
  return routes;
861
3104
  }
862
3105
  class AXPDefaultThemeModule {
863
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDefaultThemeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
864
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.12", ngImport: i0, type: AXPDefaultThemeModule, imports: [AXPCommonModule, AXPThemesSharedModule] }); }
865
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDefaultThemeModule, providers: [
3106
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDefaultThemeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
3107
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: AXPDefaultThemeModule, imports: [AXPCommonModule, AXPThemesSharedModule] }); }
3108
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDefaultThemeModule, providers: [
866
3109
  {
867
3110
  provide: AXP_ENTITY_CONFIG_TOKEN,
868
3111
  useFactory: () => {
@@ -870,14 +3113,14 @@ class AXPDefaultThemeModule {
870
3113
  viewers: {
871
3114
  root: () => Promise.resolve().then(function () { return rootLayout_component; }).then((c) => c.AXPRootLayoutComponent),
872
3115
  master: {
873
- single: () => import('./acorex-platform-themes-default-entity-master-single-view.component-eMBby9k4.mjs').then((c) => c.AXPEntityMasterSingleViewComponent),
3116
+ single: () => import('./acorex-platform-themes-default-entity-master-single-view.component-Br9p5aXT.mjs').then((c) => c.AXPEntityMasterSingleViewComponent),
874
3117
  details: () => import('@acorex/platform/layout/views').then((c) => c.AXPLayoutDetailsViewComponent),
875
3118
  ///
876
- create: () => import('./acorex-platform-themes-default-entity-master-create-view.component-VIGuU5M4.mjs').then((c) => c.AXPEntityMasterCreateViewComponent),
3119
+ create: () => import('./acorex-platform-themes-default-entity-master-create-view.component-CWLfNqV0.mjs').then((c) => c.AXPEntityMasterCreateViewComponent),
877
3120
  ///
878
- modify: () => import('./acorex-platform-themes-default-entity-master-modify-view.component-Ua3ZA5hk.mjs').then((c) => c.AXPEntityMasterModifyViewComponent),
3121
+ modify: () => import('./acorex-platform-themes-default-entity-master-modify-view.component-C7cT82K2.mjs').then((c) => c.AXPEntityMasterModifyViewComponent),
879
3122
  //
880
- list: () => import('./acorex-platform-themes-default-entity-master-list-view.component-D3qZa5fM.mjs').then((c) => c.AXPEntityMasterListViewComponent),
3123
+ list: () => Promise.resolve().then(function () { return entityMasterListView_component; }).then((c) => c.AXPEntityMasterListViewComponent),
881
3124
  },
882
3125
  },
883
3126
  };
@@ -892,7 +3135,7 @@ class AXPDefaultThemeModule {
892
3135
  },
893
3136
  ], imports: [AXPCommonModule, AXPThemesSharedModule] }); }
894
3137
  }
895
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDefaultThemeModule, decorators: [{
3138
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDefaultThemeModule, decorators: [{
896
3139
  type: NgModule,
897
3140
  args: [{
898
3141
  imports: [AXPCommonModule, AXPThemesSharedModule],
@@ -906,14 +3149,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
906
3149
  viewers: {
907
3150
  root: () => Promise.resolve().then(function () { return rootLayout_component; }).then((c) => c.AXPRootLayoutComponent),
908
3151
  master: {
909
- single: () => import('./acorex-platform-themes-default-entity-master-single-view.component-eMBby9k4.mjs').then((c) => c.AXPEntityMasterSingleViewComponent),
3152
+ single: () => import('./acorex-platform-themes-default-entity-master-single-view.component-Br9p5aXT.mjs').then((c) => c.AXPEntityMasterSingleViewComponent),
910
3153
  details: () => import('@acorex/platform/layout/views').then((c) => c.AXPLayoutDetailsViewComponent),
911
3154
  ///
912
- create: () => import('./acorex-platform-themes-default-entity-master-create-view.component-VIGuU5M4.mjs').then((c) => c.AXPEntityMasterCreateViewComponent),
3155
+ create: () => import('./acorex-platform-themes-default-entity-master-create-view.component-CWLfNqV0.mjs').then((c) => c.AXPEntityMasterCreateViewComponent),
913
3156
  ///
914
- modify: () => import('./acorex-platform-themes-default-entity-master-modify-view.component-Ua3ZA5hk.mjs').then((c) => c.AXPEntityMasterModifyViewComponent),
3157
+ modify: () => import('./acorex-platform-themes-default-entity-master-modify-view.component-C7cT82K2.mjs').then((c) => c.AXPEntityMasterModifyViewComponent),
915
3158
  //
916
- list: () => import('./acorex-platform-themes-default-entity-master-list-view.component-D3qZa5fM.mjs').then((c) => c.AXPEntityMasterListViewComponent),
3159
+ list: () => Promise.resolve().then(function () { return entityMasterListView_component; }).then((c) => c.AXPEntityMasterListViewComponent),
917
3160
  },
918
3161
  },
919
3162
  };
@@ -934,5 +3177,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
934
3177
  * Generated bundle index. Do not edit.
935
3178
  */
936
3179
 
937
- export { AXPDefaultThemeModule, AXPEntityDetailListViewComponent, AXPRootHorizontalLayoutComponent, AXPRootLayoutComponent, AXPRootLayoutFooterComponent, AXPRootLayoutHeaderComponent, AXPRootLayoutMenuComponent, AXPRootVerticalLayoutComponent };
3180
+ export { AXPDefaultThemeModule, AXPEntityDetailListViewComponent, AXPEntityMasterListViewComponent, AXPRootHorizontalLayoutComponent, AXPRootLayoutComponent, AXPRootLayoutFooterComponent, AXPRootLayoutHeaderComponent, AXPRootLayoutMenuComponent, AXPRootVerticalLayoutComponent };
938
3181
  //# sourceMappingURL=acorex-platform-themes-default.mjs.map