@acorex/platform 21.0.0-next.7 → 21.0.0-next.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/acorex-platform-auth.mjs +281 -23
- package/fesm2022/acorex-platform-auth.mjs.map +1 -1
- package/fesm2022/acorex-platform-common-common-settings.provider-Bi1RYif5.mjs +163 -0
- package/fesm2022/acorex-platform-common-common-settings.provider-Bi1RYif5.mjs.map +1 -0
- package/fesm2022/acorex-platform-common.mjs +1381 -276
- package/fesm2022/acorex-platform-common.mjs.map +1 -1
- package/fesm2022/acorex-platform-core.mjs +1538 -611
- package/fesm2022/acorex-platform-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-domain.mjs +557 -826
- package/fesm2022/acorex-platform-domain.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-builder.mjs +1372 -210
- package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-CXEdvDTf.mjs +121 -0
- package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-CXEdvDTf.mjs.map +1 -0
- package/fesm2022/acorex-platform-layout-components.mjs +6298 -1929
- package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-designer.mjs +456 -204
- package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity-attachments-page.component-D8iQnT-R.mjs +371 -0
- package/fesm2022/acorex-platform-layout-entity-attachments-page.component-D8iQnT-R.mjs.map +1 -0
- package/fesm2022/acorex-platform-layout-entity-file-list-popup.component-_yrP5SQe.mjs +100 -0
- package/fesm2022/acorex-platform-layout-entity-file-list-popup.component-_yrP5SQe.mjs.map +1 -0
- package/fesm2022/acorex-platform-layout-entity.mjs +22537 -9975
- package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-views.mjs +865 -218
- package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widget-core.mjs +2138 -487
- package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -1
- 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
- package/fesm2022/acorex-platform-layout-widgets-button-widget-designer.component-Dy7jF-oD.mjs.map +1 -0
- package/fesm2022/{acorex-platform-layout-widgets-image-preview.popup-V31OpYah.mjs → acorex-platform-layout-widgets-image-preview.popup-C_EPAvCU.mjs} +6 -7
- package/fesm2022/acorex-platform-layout-widgets-image-preview.popup-C_EPAvCU.mjs.map +1 -0
- package/fesm2022/{acorex-platform-layout-widgets-page-widget-designer.component-BtZMBxYp.mjs → acorex-platform-layout-widgets-page-widget-designer.component-D10yO28c.mjs} +12 -12
- package/fesm2022/acorex-platform-layout-widgets-page-widget-designer.component-D10yO28c.mjs.map +1 -0
- package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-J0zcGKBX.mjs +116 -0
- package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-J0zcGKBX.mjs.map +1 -0
- package/fesm2022/{acorex-platform-layout-widgets-tabular-data-edit-popup.component-Ck7-wpT2.mjs → acorex-platform-layout-widgets-tabular-data-edit-popup.component-BcpRkpJp.mjs} +6 -6
- package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-BcpRkpJp.mjs.map +1 -0
- package/fesm2022/{acorex-platform-layout-widgets-tabular-data-view-popup.component-y8vjUiVs.mjs → acorex-platform-layout-widgets-tabular-data-view-popup.component-DQtK4lxl.mjs} +5 -5
- package/fesm2022/acorex-platform-layout-widgets-tabular-data-view-popup.component-DQtK4lxl.mjs.map +1 -0
- 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
- package/fesm2022/acorex-platform-layout-widgets-text-block-widget-designer.component-Vo4fWHtX.mjs.map +1 -0
- package/fesm2022/acorex-platform-layout-widgets.mjs +10434 -7982
- package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
- package/fesm2022/acorex-platform-native.mjs +8 -7
- package/fesm2022/acorex-platform-native.mjs.map +1 -1
- package/fesm2022/acorex-platform-runtime.mjs +391 -166
- package/fesm2022/acorex-platform-runtime.mjs.map +1 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-CWLfNqV0.mjs +160 -0
- package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-CWLfNqV0.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-C7cT82K2.mjs +120 -0
- package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-C7cT82K2.mjs.map +1 -0
- 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
- package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-Br9p5aXT.mjs.map +1 -0
- package/fesm2022/{acorex-platform-themes-default-error-401.component-cfREo88K.mjs → acorex-platform-themes-default-error-401.component-C7EYJzSr.mjs} +4 -4
- package/fesm2022/acorex-platform-themes-default-error-401.component-C7EYJzSr.mjs.map +1 -0
- package/fesm2022/{acorex-platform-themes-default-error-404.component-CdCV5ZoA.mjs → acorex-platform-themes-default-error-404.component-7MVLMwIa.mjs} +4 -4
- package/fesm2022/acorex-platform-themes-default-error-404.component-7MVLMwIa.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-default-error-offline.component-DR6G8gPC.mjs +19 -0
- package/fesm2022/acorex-platform-themes-default-error-offline.component-DR6G8gPC.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-default.mjs +2289 -90
- package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
- package/fesm2022/{acorex-platform-themes-shared-icon-chooser-column.component-C0EpfU2k.mjs → acorex-platform-themes-shared-icon-chooser-column.component-CqkWJYdv.mjs} +6 -6
- package/fesm2022/acorex-platform-themes-shared-icon-chooser-column.component-CqkWJYdv.mjs.map +1 -0
- package/fesm2022/{acorex-platform-themes-shared-icon-chooser-view.component-9W52W6Nu.mjs → acorex-platform-themes-shared-icon-chooser-view.component-BOTuLdWN.mjs} +6 -6
- package/fesm2022/acorex-platform-themes-shared-icon-chooser-view.component-BOTuLdWN.mjs.map +1 -0
- package/fesm2022/{acorex-platform-themes-shared-settings.provider-DSs1o1M6.mjs → acorex-platform-themes-shared-settings.provider-BjuzSe0T.mjs} +52 -33
- package/fesm2022/acorex-platform-themes-shared-settings.provider-BjuzSe0T.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-D566Kdvy.mjs +94 -0
- package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-D566Kdvy.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-D7-rCGl7.mjs +86 -0
- package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-D7-rCGl7.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-shared.mjs +790 -612
- package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
- package/fesm2022/acorex-platform-workflow.mjs +978 -238
- package/fesm2022/acorex-platform-workflow.mjs.map +1 -1
- package/fesm2022/acorex-platform.mjs.map +1 -1
- package/package.json +40 -38
- package/{auth/index.d.ts → types/acorex-platform-auth.d.ts} +241 -4
- package/{common/index.d.ts → types/acorex-platform-common.d.ts} +833 -89
- package/{core/index.d.ts → types/acorex-platform-core.d.ts} +779 -164
- package/{domain/index.d.ts → types/acorex-platform-domain.d.ts} +744 -412
- package/{layout/builder/index.d.ts → types/acorex-platform-layout-builder.d.ts} +277 -55
- package/types/acorex-platform-layout-components.d.ts +3257 -0
- package/{layout/designer/index.d.ts → types/acorex-platform-layout-designer.d.ts} +96 -18
- package/types/acorex-platform-layout-entity.d.ts +4492 -0
- package/{layout/views/index.d.ts → types/acorex-platform-layout-views.d.ts} +247 -62
- package/{layout/widget-core/index.d.ts → types/acorex-platform-layout-widget-core.d.ts} +437 -131
- package/{layout/widgets/index.d.ts → types/acorex-platform-layout-widgets.d.ts} +1140 -506
- package/{native/index.d.ts → types/acorex-platform-native.d.ts} +0 -7
- package/types/acorex-platform-runtime.d.ts +571 -0
- package/{themes/default/index.d.ts → types/acorex-platform-themes-default.d.ts} +254 -7
- package/{themes/shared/index.d.ts → types/acorex-platform-themes-shared.d.ts} +30 -2
- package/{workflow/index.d.ts → types/acorex-platform-workflow.d.ts} +620 -617
- package/fesm2022/acorex-platform-common-common-settings.provider-zhqNP3xb.mjs +0 -71
- package/fesm2022/acorex-platform-common-common-settings.provider-zhqNP3xb.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-button-widget-designer.component-C3VoBb_b.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-CxrsI6Hn.mjs +0 -135
- package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-CxrsI6Hn.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-image-preview.popup-V31OpYah.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-page-widget-designer.component-BtZMBxYp.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-Ck7-wpT2.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-tabular-data-view-popup.component-y8vjUiVs.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-text-block-widget-designer.component-Df1BFkSa.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-VIGuU5M4.mjs +0 -157
- package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-VIGuU5M4.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-DfJEx_bs.mjs +0 -1542
- package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-DfJEx_bs.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-Ua3ZA5hk.mjs +0 -101
- package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-Ua3ZA5hk.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-eMBby9k4.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-error-401.component-cfREo88K.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-error-404.component-CdCV5ZoA.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-error-offline.component-E7SzBcAt.mjs +0 -19
- package/fesm2022/acorex-platform-themes-default-error-offline.component-E7SzBcAt.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-shared-icon-chooser-column.component-C0EpfU2k.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-shared-icon-chooser-view.component-9W52W6Nu.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-shared-settings.provider-DSs1o1M6.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-DTnfRy5f.mjs +0 -65
- package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-DTnfRy5f.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-DY0JtT1v.mjs +0 -64
- package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-DY0JtT1v.mjs.map +0 -1
- package/layout/components/index.d.ts +0 -1669
- package/layout/entity/index.d.ts +0 -2287
- package/runtime/index.d.ts +0 -307
- /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
|
|
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$
|
|
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
|
|
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
29
|
import { AXPAuthModule, AXPSessionService, AXPSessionStatus, AXPAuthGuard } from '@acorex/platform/auth';
|
|
29
|
-
import { AXPRefreshEvent, AXP_PLATFORM_CONFIG_TOKEN, AXPMenuService,
|
|
30
|
-
import
|
|
31
|
-
import {
|
|
30
|
+
import { AXPRefreshEvent, AXPSettingsService, AXPCommonSettings, AXP_PLATFORM_CONFIG_TOKEN, AXPMenuService, AXPMenuVisibilityService, AXPCommonModule } from '@acorex/platform/common';
|
|
31
|
+
import * as i1$5 from '@acorex/platform/core';
|
|
32
|
+
import { AXPDeviceService, AXHighlightService, AXPGridLayoutDirective, AXPComponentSlotModule, 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, NgModule } from '@angular/core';
|
|
41
43
|
import { FormsModule } from '@angular/forms';
|
|
42
|
-
import * as i1$
|
|
43
|
-
import { RouterModule, Router, NavigationEnd, RouteReuseStrategy, ROUTES } from '@angular/router';
|
|
44
|
+
import * as i1$6 from '@angular/router';
|
|
45
|
+
import { RouterModule, Router, ActivatedRoute, NavigationEnd, RouteReuseStrategy, ROUTES } from '@angular/router';
|
|
44
46
|
import { Subject, takeUntil, filter, firstValueFrom } from 'rxjs';
|
|
45
|
-
import * as i1$
|
|
46
|
-
import {
|
|
47
|
-
import
|
|
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
|
|
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: "
|
|
153
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
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", "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:
|
|
170
|
+
AXPWidgetCoreModule }, { kind: "component", type: i7$1.AXPWidgetColumnRendererComponent, selector: "axp-widget-column-renderer", inputs: ["caption", "customExpandIcon", "customCollapseIcon", "customWidth", "node", "footerTemplate", "expandHandler", "sortEnabled", "headerSortDirection", "headerSortPriority", "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: "
|
|
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\"
|
|
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,2154 @@ 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"], outputs: ["datasourceChange", "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
|
+
// Sync query param immediately on tab change
|
|
1350
|
+
this.router.navigate([], {
|
|
1351
|
+
relativeTo: this.activeRoute,
|
|
1352
|
+
queryParams: { view: view.name },
|
|
1353
|
+
queryParamsHandling: 'merge',
|
|
1354
|
+
replaceUrl: true,
|
|
1355
|
+
});
|
|
1356
|
+
this.isInitializing = true;
|
|
1357
|
+
this.pendingInitialFilters = true;
|
|
1358
|
+
this.pendingInitialSorts = true;
|
|
1359
|
+
this.setInitialFiltersFromSettingsOrView();
|
|
1360
|
+
// Ensure initial load after view change
|
|
1361
|
+
setTimeout(() => {
|
|
1362
|
+
this.isInitializing = false;
|
|
1363
|
+
this.scheduleApply();
|
|
1364
|
+
}, 0);
|
|
1365
|
+
}
|
|
1366
|
+
#effect;
|
|
1367
|
+
setInitialFiltersFromSettingsOrView() {
|
|
1368
|
+
const saved = this.vm.filterQueries();
|
|
1369
|
+
this.previousFilterQueries.set(saved);
|
|
1370
|
+
const viewConditions = this.vm.view().conditions.map((c) => c.name);
|
|
1371
|
+
if (saved && saved.length) {
|
|
1372
|
+
this.initialFilters.set(saved.map((s) => ({ ...s, hidden: viewConditions.includes(s.field) })));
|
|
1373
|
+
return;
|
|
1374
|
+
}
|
|
1375
|
+
this.initialFilters.set(this.vm.view().conditions.map((c) => ({
|
|
1376
|
+
field: c.name,
|
|
1377
|
+
operator: c.operator,
|
|
1378
|
+
value: c.value,
|
|
1379
|
+
hidden: true,
|
|
1380
|
+
})));
|
|
1381
|
+
}
|
|
1382
|
+
onFiltersChanged(filters) {
|
|
1383
|
+
if (this.isInitializing || this.pendingInitialFilters) {
|
|
1384
|
+
this.pendingInitialFilters = false;
|
|
1385
|
+
return;
|
|
1386
|
+
}
|
|
1387
|
+
this.vm.filterQueries.set(filters);
|
|
1388
|
+
if (this.filterTriggerMode === 'auto') {
|
|
1389
|
+
this.applyFilters();
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
applyFilters() {
|
|
1393
|
+
this.previousFilterQueries.set(this.vm.filterQueries());
|
|
1394
|
+
this.vm.saveSettings('filters', this.vm.filterQueries());
|
|
1395
|
+
this.scheduleApply();
|
|
1396
|
+
}
|
|
1397
|
+
onSortQueriesChange(e) {
|
|
1398
|
+
if (this.isInitializing || this.pendingInitialSorts) {
|
|
1399
|
+
this.pendingInitialSorts = false;
|
|
1400
|
+
return;
|
|
1401
|
+
}
|
|
1402
|
+
const sortableByName = new Map(this.vm.sortableFields().map((f) => [f.name, f]));
|
|
1403
|
+
const nextSortedFields = e
|
|
1404
|
+
.filter((s) => s.dir && sortableByName.has(s.name))
|
|
1405
|
+
.map((s) => ({
|
|
1406
|
+
name: s.name,
|
|
1407
|
+
title: sortableByName.get(s.name).title,
|
|
1408
|
+
dir: s.dir,
|
|
1409
|
+
}));
|
|
1410
|
+
const sortSignature = (fields) => fields.map((s) => `${s.name}:${s.dir ?? ''}`).join('|');
|
|
1411
|
+
if (sortSignature(nextSortedFields) === sortSignature(this.vm.sortedFields())) {
|
|
1412
|
+
return;
|
|
1413
|
+
}
|
|
1414
|
+
this.vm.sortedFields.set(nextSortedFields);
|
|
1415
|
+
this.vm.saveSettings('sorts', e);
|
|
1416
|
+
this.scheduleApply();
|
|
1417
|
+
}
|
|
1418
|
+
onColumnsChange(columns) {
|
|
1419
|
+
const keyOf = (c) => c.column?.options?.dataPath ?? c.name;
|
|
1420
|
+
this.vm.columns.update((prev) => {
|
|
1421
|
+
const byKey = new Map(prev.map((c) => [keyOf(c), c]));
|
|
1422
|
+
return columns
|
|
1423
|
+
.map((newColumn) => {
|
|
1424
|
+
const existing = byKey.get(keyOf(newColumn));
|
|
1425
|
+
if (!existing) {
|
|
1426
|
+
return null;
|
|
1427
|
+
}
|
|
1428
|
+
return new AXPEntityListViewColumnViewModel(existing.property, {
|
|
1429
|
+
...existing.column,
|
|
1430
|
+
options: {
|
|
1431
|
+
...existing.column.options,
|
|
1432
|
+
visible: newColumn.visible,
|
|
1433
|
+
},
|
|
1434
|
+
});
|
|
1435
|
+
})
|
|
1436
|
+
.filter((c) => c != null);
|
|
1437
|
+
});
|
|
1438
|
+
// Persist column order/visibility
|
|
1439
|
+
this.vm.onColumnsChanged(this.vm.columns());
|
|
1440
|
+
// Use debounced apply to avoid triple refresh when combined with sorts/filters
|
|
1441
|
+
// this.scheduleApply();
|
|
1442
|
+
}
|
|
1443
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityMasterToolbarViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1444
|
+
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 }); }
|
|
1445
|
+
}
|
|
1446
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityMasterToolbarViewComponent, decorators: [{
|
|
1447
|
+
type: Component,
|
|
1448
|
+
args: [{ selector: 'axp-entity-master-toolbar-view', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
|
|
1449
|
+
AsyncPipe,
|
|
1450
|
+
AXButtonModule,
|
|
1451
|
+
AXDecoratorModule,
|
|
1452
|
+
AXDropdownModule,
|
|
1453
|
+
AXTranslationModule,
|
|
1454
|
+
AXPQueryFiltersComponent,
|
|
1455
|
+
AXPopoverModule,
|
|
1456
|
+
AXPQuerySortsComponent,
|
|
1457
|
+
AXPQueryViewsComponent,
|
|
1458
|
+
AXPQueryColumnsComponent,
|
|
1459
|
+
], host: {
|
|
1460
|
+
class: 'ax-w-full',
|
|
1461
|
+
}, 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" }]
|
|
1462
|
+
}], propDecorators: { vm: [{
|
|
1463
|
+
type: Input,
|
|
1464
|
+
args: ['viewModel']
|
|
1465
|
+
}], listDisplayModePopover: [{ type: i0.ViewChild, args: ['listDisplayModePopover', { isSignal: true }] }] } });
|
|
1466
|
+
|
|
1467
|
+
class AXPEntityMasterListCardItemSkeletonComponent {
|
|
1468
|
+
constructor() {
|
|
1469
|
+
//#region ---- Inputs ----
|
|
1470
|
+
this.fieldCount = input(4, ...(ngDevMode ? [{ debugName: "fieldCount" }] : /* istanbul ignore next */ []));
|
|
1471
|
+
this.badgeCount = input(1, ...(ngDevMode ? [{ debugName: "badgeCount" }] : /* istanbul ignore next */ []));
|
|
1472
|
+
this.showFooter = input(true, ...(ngDevMode ? [{ debugName: "showFooter" }] : /* istanbul ignore next */ []));
|
|
1473
|
+
this.showHeaderMenu = input(false, ...(ngDevMode ? [{ debugName: "showHeaderMenu" }] : /* istanbul ignore next */ []));
|
|
1474
|
+
this.showContent = input(true, ...(ngDevMode ? [{ debugName: "showContent" }] : /* istanbul ignore next */ []));
|
|
1475
|
+
//#endregion
|
|
1476
|
+
//#region ---- Computed ----
|
|
1477
|
+
this.fieldPlaceholders = computed(() => Array.from({ length: Math.max(this.fieldCount(), 0) }, (_, index) => index), ...(ngDevMode ? [{ debugName: "fieldPlaceholders" }] : /* istanbul ignore next */ []));
|
|
1478
|
+
this.badgePlaceholders = computed(() => Array.from({ length: Math.max(this.badgeCount(), 0) }, (_, index) => index), ...(ngDevMode ? [{ debugName: "badgePlaceholders" }] : /* istanbul ignore next */ []));
|
|
1479
|
+
}
|
|
1480
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityMasterListCardItemSkeletonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1481
|
+
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 }); }
|
|
1482
|
+
}
|
|
1483
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityMasterListCardItemSkeletonComponent, decorators: [{
|
|
1484
|
+
type: Component,
|
|
1485
|
+
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"] }]
|
|
1486
|
+
}], 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 }] }] } });
|
|
1487
|
+
|
|
1488
|
+
class AXPEntityMasterListCardItemComponent {
|
|
1489
|
+
//#endregion
|
|
1490
|
+
//#region ---- Lifecycle ----
|
|
1491
|
+
constructor() {
|
|
1492
|
+
this.translation = inject(AXTranslationService);
|
|
1493
|
+
//#region ---- Inputs & Outputs ----
|
|
1494
|
+
this.vm = input.required(...(ngDevMode ? [{ debugName: "vm" }] : /* istanbul ignore next */ []));
|
|
1495
|
+
this.row = input.required(...(ngDevMode ? [{ debugName: "row" }] : /* istanbul ignore next */ []));
|
|
1496
|
+
this.selected = input(false, ...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
|
|
1497
|
+
this.showSelection = input(false, ...(ngDevMode ? [{ debugName: "showSelection" }] : /* istanbul ignore next */ []));
|
|
1498
|
+
this.selectionChange = output();
|
|
1499
|
+
this.commandClick = output();
|
|
1500
|
+
//#endregion
|
|
1501
|
+
//#region ---- Computed ----
|
|
1502
|
+
this.header = computed(() => this.vm().cardLayout()?.header, ...(ngDevMode ? [{ debugName: "header" }] : /* istanbul ignore next */ []));
|
|
1503
|
+
this.showCardContent = computed(() => this.vm().cardContentExpanded(), ...(ngDevMode ? [{ debugName: "showCardContent" }] : /* istanbul ignore next */ []));
|
|
1504
|
+
this.headerBadgeFields = computed(() => this.vm()
|
|
1505
|
+
.cardFields()
|
|
1506
|
+
.filter((field) => field.visible !== false && field.isBadgeDisplay), ...(ngDevMode ? [{ debugName: "headerBadgeFields" }] : /* istanbul ignore next */ []));
|
|
1507
|
+
/** Column name to omit from body when `header.title` is a simple property path (not an expression). */
|
|
1508
|
+
this.headerTitleColumnName = computed(() => {
|
|
1509
|
+
const title = this.header()?.title;
|
|
1510
|
+
if (!title || title.includes('{{')) {
|
|
1511
|
+
return undefined;
|
|
1512
|
+
}
|
|
1513
|
+
return title;
|
|
1514
|
+
}, ...(ngDevMode ? [{ debugName: "headerTitleColumnName" }] : /* istanbul ignore next */ []));
|
|
1515
|
+
this.bodyFields = computed(() => {
|
|
1516
|
+
const titleColumn = this.headerTitleColumnName();
|
|
1517
|
+
return this.vm()
|
|
1518
|
+
.cardFields()
|
|
1519
|
+
.filter((field) => field.visible !== false && !field.isBadgeDisplay && field.name !== titleColumn);
|
|
1520
|
+
}, ...(ngDevMode ? [{ debugName: "bodyFields" }] : /* istanbul ignore next */ []));
|
|
1521
|
+
this.badgeColorByField = signal({}, ...(ngDevMode ? [{ debugName: "badgeColorByField" }] : /* istanbul ignore next */ []));
|
|
1522
|
+
this.titleText = signal('', ...(ngDevMode ? [{ debugName: "titleText" }] : /* istanbul ignore next */ []));
|
|
1523
|
+
this.descriptionText = signal('', ...(ngDevMode ? [{ debugName: "descriptionText" }] : /* istanbul ignore next */ []));
|
|
1524
|
+
this.iconClass = signal(null, ...(ngDevMode ? [{ debugName: "iconClass" }] : /* istanbul ignore next */ []));
|
|
1525
|
+
this.primaryActions = computed(() => this.vm().primaryRowActions(), ...(ngDevMode ? [{ debugName: "primaryActions" }] : /* istanbul ignore next */ []));
|
|
1526
|
+
this.primaryActionsIconOnly = computed(() => !this.vm().cardContentExpanded(), ...(ngDevMode ? [{ debugName: "primaryActionsIconOnly" }] : /* istanbul ignore next */ []));
|
|
1527
|
+
this.secondaryActions = signal([], ...(ngDevMode ? [{ debugName: "secondaryActions" }] : /* istanbul ignore next */ []));
|
|
1528
|
+
effect(() => {
|
|
1529
|
+
const row = this.row();
|
|
1530
|
+
const header = this.header();
|
|
1531
|
+
const badgeFields = this.headerBadgeFields().filter((field) => !this.isStatusBadgeField(field));
|
|
1532
|
+
untracked(() => {
|
|
1533
|
+
void this.loadSecondaryActions(row);
|
|
1534
|
+
void this.resolveHeaderFields(row, header);
|
|
1535
|
+
void this.resolveBadgeColors(row, badgeFields);
|
|
1536
|
+
});
|
|
1537
|
+
});
|
|
1538
|
+
}
|
|
1539
|
+
//#endregion
|
|
1540
|
+
//#region ---- Row Actions ----
|
|
1541
|
+
async loadSecondaryActions(row) {
|
|
1542
|
+
const actions = await this.vm().cardSecondaryRowActions(row);
|
|
1543
|
+
this.secondaryActions.set(actions);
|
|
1544
|
+
}
|
|
1545
|
+
//#endregion
|
|
1546
|
+
//#region ---- UI Handlers ----
|
|
1547
|
+
onCardClick(event) {
|
|
1548
|
+
if (event.ctrlKey || event.metaKey) {
|
|
1549
|
+
event.preventDefault();
|
|
1550
|
+
this.selectionChange.emit(!this.selected());
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
onCardDblClick(event) {
|
|
1554
|
+
event.preventDefault();
|
|
1555
|
+
void this.runDefaultAction();
|
|
1556
|
+
}
|
|
1557
|
+
onCardKeydown(event) {
|
|
1558
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
1559
|
+
event.preventDefault();
|
|
1560
|
+
void this.runDefaultAction();
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1563
|
+
onPrimaryActionClick(actionName, event) {
|
|
1564
|
+
event.nativeEvent?.stopPropagation();
|
|
1565
|
+
const action = this.primaryActions().find((a) => a.name === actionName);
|
|
1566
|
+
if (action && !action.disabled) {
|
|
1567
|
+
this.commandClick.emit(action.name);
|
|
1568
|
+
}
|
|
1569
|
+
}
|
|
1570
|
+
onSecondaryActionClick(item, event) {
|
|
1571
|
+
event.nativeEvent?.stopPropagation();
|
|
1572
|
+
if (item.isCardSelect || item.name === AXPEntityMasterListCardSelectActionName) {
|
|
1573
|
+
if (!this.selected()) {
|
|
1574
|
+
this.selectionChange.emit(true);
|
|
1575
|
+
}
|
|
1576
|
+
return;
|
|
1577
|
+
}
|
|
1578
|
+
this.commandClick.emit(item.name);
|
|
1579
|
+
}
|
|
1580
|
+
onSelectionCheckboxChange(event) {
|
|
1581
|
+
this.selectionChange.emit(!!event.value);
|
|
1582
|
+
}
|
|
1583
|
+
onSelectionCheckboxClick(event) {
|
|
1584
|
+
event.stopPropagation();
|
|
1585
|
+
}
|
|
1586
|
+
stopClickPropagation(event) {
|
|
1587
|
+
event.nativeEvent?.stopPropagation();
|
|
1588
|
+
}
|
|
1589
|
+
isStatusBadgeField(field) {
|
|
1590
|
+
return field.isStatusWidget;
|
|
1591
|
+
}
|
|
1592
|
+
resolveBadgeText(field) {
|
|
1593
|
+
const path = field.node().path ?? field.name;
|
|
1594
|
+
const value = get(this.row(), path);
|
|
1595
|
+
if (value == null) {
|
|
1596
|
+
return '';
|
|
1597
|
+
}
|
|
1598
|
+
if (typeof value === 'object') {
|
|
1599
|
+
const record = value;
|
|
1600
|
+
const label = record['title'] ?? record['name'] ?? record['label'];
|
|
1601
|
+
return label == null ? '' : String(label);
|
|
1602
|
+
}
|
|
1603
|
+
return String(value);
|
|
1604
|
+
}
|
|
1605
|
+
resolveBadgeColor(field) {
|
|
1606
|
+
return this.badgeColorByField()[field.name] ?? 'default';
|
|
1607
|
+
}
|
|
1608
|
+
//#endregion
|
|
1609
|
+
//#region ---- Private Helpers ----
|
|
1610
|
+
async resolveBadgeColors(row, fields) {
|
|
1611
|
+
const vm = this.vm();
|
|
1612
|
+
const entries = await Promise.all(fields.map(async (field) => [field.name, await vm.resolveCardBadgeColor(field, row)]));
|
|
1613
|
+
this.badgeColorByField.set(Object.fromEntries(entries));
|
|
1614
|
+
}
|
|
1615
|
+
async resolveHeaderFields(row, header) {
|
|
1616
|
+
const vm = this.vm();
|
|
1617
|
+
const [title, description, icon] = await Promise.all([
|
|
1618
|
+
vm.resolveCardHeaderValue(header?.title, row),
|
|
1619
|
+
vm.resolveCardHeaderValue(header?.description, row),
|
|
1620
|
+
vm.resolveCardHeaderValue(header?.icon, row),
|
|
1621
|
+
]);
|
|
1622
|
+
this.titleText.set(title);
|
|
1623
|
+
this.descriptionText.set(description);
|
|
1624
|
+
this.iconClass.set(this.toIconClass(this.toIconString(icon)));
|
|
1625
|
+
}
|
|
1626
|
+
toIconString(value) {
|
|
1627
|
+
if (!value) {
|
|
1628
|
+
return '';
|
|
1629
|
+
}
|
|
1630
|
+
if (typeof value === 'string') {
|
|
1631
|
+
return value;
|
|
1632
|
+
}
|
|
1633
|
+
if (this.translation.isValidMultiLanguageObject(value)) {
|
|
1634
|
+
return this.translation.resolve(value);
|
|
1635
|
+
}
|
|
1636
|
+
return '';
|
|
1637
|
+
}
|
|
1638
|
+
toIconClass(value) {
|
|
1639
|
+
if (!value) {
|
|
1640
|
+
return null;
|
|
1641
|
+
}
|
|
1642
|
+
return value.includes('fa-') ? value : `fa-light fa-${value}`;
|
|
1643
|
+
}
|
|
1644
|
+
async runDefaultAction() {
|
|
1645
|
+
const primary = this.primaryActions();
|
|
1646
|
+
const secondary = this.secondaryActions().filter((a) => !a.isCardSelect);
|
|
1647
|
+
const all = [...primary, ...secondary].filter(Boolean);
|
|
1648
|
+
const defaultAction = all.find((a) => {
|
|
1649
|
+
if (!a) {
|
|
1650
|
+
return false;
|
|
1651
|
+
}
|
|
1652
|
+
const commandName = a.name.split('&')[0];
|
|
1653
|
+
return (a.default || commandName === 'open-entity') && !a.disabled;
|
|
1654
|
+
});
|
|
1655
|
+
if (defaultAction) {
|
|
1656
|
+
this.commandClick.emit(defaultAction.name);
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityMasterListCardItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1660
|
+
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 }); }
|
|
1661
|
+
}
|
|
1662
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityMasterListCardItemComponent, decorators: [{
|
|
1663
|
+
type: Component,
|
|
1664
|
+
args: [{ selector: 'axp-entity-master-list-card-item', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
1665
|
+
CommonModule,
|
|
1666
|
+
AXBadgeModule,
|
|
1667
|
+
AXButtonModule,
|
|
1668
|
+
AXCheckBoxModule,
|
|
1669
|
+
AXDecoratorModule,
|
|
1670
|
+
AXDropdownModule,
|
|
1671
|
+
AXTranslationModule,
|
|
1672
|
+
AXPGridLayoutDirective,
|
|
1673
|
+
AXPWidgetColumnCellComponent,
|
|
1674
|
+
], 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"] }]
|
|
1675
|
+
}], 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"] }] } });
|
|
1676
|
+
|
|
1677
|
+
class AXPEntityMasterListCardListComponent {
|
|
1678
|
+
//#endregion
|
|
1679
|
+
//#region ---- Lifecycle ----
|
|
1680
|
+
constructor() {
|
|
1681
|
+
//#region ---- Services & Dependencies ----
|
|
1682
|
+
this.deviceService = inject(AXPDeviceService);
|
|
1683
|
+
//#endregion
|
|
1684
|
+
//#region ---- Inputs & Outputs ----
|
|
1685
|
+
this.vm = input.required(...(ngDevMode ? [{ debugName: "vm" }] : /* istanbul ignore next */ []));
|
|
1686
|
+
this.pageChanged = output();
|
|
1687
|
+
//#endregion
|
|
1688
|
+
//#region ---- State ----
|
|
1689
|
+
this.pagerDisplayMode = computed(() => this.deviceService.isSmall() ? 'compact' : 'full', ...(ngDevMode ? [{ debugName: "pagerDisplayMode" }] : /* istanbul ignore next */ []));
|
|
1690
|
+
this.items = signal([], ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
1691
|
+
this.loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
1692
|
+
this.totalCount = signal(0, ...(ngDevMode ? [{ debugName: "totalCount" }] : /* istanbul ignore next */ []));
|
|
1693
|
+
this.pageIndex = signal(0, ...(ngDevMode ? [{ debugName: "pageIndex" }] : /* istanbul ignore next */ []));
|
|
1694
|
+
this.pageSize = signal(10, ...(ngDevMode ? [{ debugName: "pageSize" }] : /* istanbul ignore next */ []));
|
|
1695
|
+
this.showSelection = computed(() => this.vm().selectedItems().length > 0, ...(ngDevMode ? [{ debugName: "showSelection" }] : /* istanbul ignore next */ []));
|
|
1696
|
+
this.rowKey = computed(() => this.vm().dataSource.config?.key ?? 'id', ...(ngDevMode ? [{ debugName: "rowKey" }] : /* istanbul ignore next */ []));
|
|
1697
|
+
this.skeletonCount = computed(() => Math.max(this.pageSize(), 1), ...(ngDevMode ? [{ debugName: "skeletonCount" }] : /* istanbul ignore next */ []));
|
|
1698
|
+
this.skeletonFieldCount = computed(() => {
|
|
1699
|
+
if (!this.vm().cardContentExpanded()) {
|
|
1700
|
+
return 0;
|
|
1701
|
+
}
|
|
1702
|
+
const bodyCount = this.vm()
|
|
1703
|
+
.cardFields()
|
|
1704
|
+
.filter((field) => field.visible !== false && !field.isBadgeDisplay).length;
|
|
1705
|
+
return bodyCount > 0 ? bodyCount : 4;
|
|
1706
|
+
}, ...(ngDevMode ? [{ debugName: "skeletonFieldCount" }] : /* istanbul ignore next */ []));
|
|
1707
|
+
this.skeletonBadgeCount = computed(() => {
|
|
1708
|
+
const count = this.vm()
|
|
1709
|
+
.cardFields()
|
|
1710
|
+
.filter((field) => field.visible !== false && field.isBadgeDisplay).length;
|
|
1711
|
+
return count > 0 ? count : 1;
|
|
1712
|
+
}, ...(ngDevMode ? [{ debugName: "skeletonBadgeCount" }] : /* istanbul ignore next */ []));
|
|
1713
|
+
this.skeletonShowFooter = computed(() => this.vm().primaryRowActions().length > 0, ...(ngDevMode ? [{ debugName: "skeletonShowFooter" }] : /* istanbul ignore next */ []));
|
|
1714
|
+
this.skeletonPlaceholders = computed(() => Array.from({ length: this.skeletonCount() }, (_, index) => index), ...(ngDevMode ? [{ debugName: "skeletonPlaceholders" }] : /* istanbul ignore next */ []));
|
|
1715
|
+
effect((onCleanup) => {
|
|
1716
|
+
const vm = this.vm();
|
|
1717
|
+
const dataSource = vm.dataSource;
|
|
1718
|
+
untracked(() => {
|
|
1719
|
+
this.syncPagingFromDataSource(vm);
|
|
1720
|
+
this.syncFromDataSource();
|
|
1721
|
+
});
|
|
1722
|
+
const changedSub = dataSource.onChanged.subscribe(() => {
|
|
1723
|
+
this.syncFromDataSource();
|
|
1724
|
+
});
|
|
1725
|
+
const loadingSub = dataSource.onLoadingChanged.subscribe((isLoading) => {
|
|
1726
|
+
this.loading.set(isLoading);
|
|
1727
|
+
});
|
|
1728
|
+
onCleanup(() => {
|
|
1729
|
+
changedSub.unsubscribe();
|
|
1730
|
+
loadingSub.unsubscribe();
|
|
1731
|
+
});
|
|
1732
|
+
});
|
|
1733
|
+
}
|
|
1734
|
+
//#endregion
|
|
1735
|
+
//#region ---- Public API ----
|
|
1736
|
+
async reload(resetPagination = false) {
|
|
1737
|
+
if (!resetPagination) {
|
|
1738
|
+
await this.vm().ensureListPagingResolved();
|
|
1739
|
+
this.vm().applyPagingToDataSourceWithoutLoad();
|
|
1740
|
+
}
|
|
1741
|
+
this.vm().dataSource.refresh({ reset: resetPagination });
|
|
1742
|
+
}
|
|
1743
|
+
/** Syncs visible items from the shared data source without triggering a load. */
|
|
1744
|
+
syncFromDataSource() {
|
|
1745
|
+
this.syncItemsFromDataSource();
|
|
1746
|
+
}
|
|
1747
|
+
//#endregion
|
|
1748
|
+
//#region ---- Selection ----
|
|
1749
|
+
trackRow(index, row) {
|
|
1750
|
+
if (!isRowRecord(row)) {
|
|
1751
|
+
return `row-${index}`;
|
|
1752
|
+
}
|
|
1753
|
+
const id = get(row, this.rowKey());
|
|
1754
|
+
return id != null ? String(id) : `row-${index}`;
|
|
1755
|
+
}
|
|
1756
|
+
isRowSelected(row) {
|
|
1757
|
+
const key = this.rowKey();
|
|
1758
|
+
const rowId = get(row, key);
|
|
1759
|
+
return this.vm()
|
|
1760
|
+
.selectedItems()
|
|
1761
|
+
.some((item) => getRowId(item, key) === rowId);
|
|
1762
|
+
}
|
|
1763
|
+
onRowSelectionChange(row, selected) {
|
|
1764
|
+
const key = this.rowKey();
|
|
1765
|
+
const rowId = getRowId(row, key);
|
|
1766
|
+
const current = this.vm().selectedItems();
|
|
1767
|
+
if (selected) {
|
|
1768
|
+
if (!current.some((item) => getRowId(item, key) === rowId)) {
|
|
1769
|
+
this.vm().selectedItems.set([...current, row]);
|
|
1770
|
+
}
|
|
1771
|
+
return;
|
|
1772
|
+
}
|
|
1773
|
+
this.vm().selectedItems.set(current.filter((item) => getRowId(item, key) !== rowId));
|
|
1774
|
+
}
|
|
1775
|
+
//#endregion
|
|
1776
|
+
//#region ---- Commands & Paging ----
|
|
1777
|
+
async onCommandClick(name, row) {
|
|
1778
|
+
await this.vm().executeCommand(name, row);
|
|
1779
|
+
}
|
|
1780
|
+
onPageChanged(event) {
|
|
1781
|
+
if (event.isUserInteraction && !this.vm().skipListPagingPersistence) {
|
|
1782
|
+
this.vm().saveListPaging(event.take, event.skip);
|
|
1783
|
+
}
|
|
1784
|
+
applyDataSourcePagingWithoutLoad(this.vm().dataSource, { take: event.take, skip: event.skip });
|
|
1785
|
+
this.pageChanged.emit(event);
|
|
1786
|
+
void this.reload(false);
|
|
1787
|
+
}
|
|
1788
|
+
//#endregion
|
|
1789
|
+
//#region ---- Private Helpers ----
|
|
1790
|
+
syncItemsFromDataSource() {
|
|
1791
|
+
const ds = this.vm().dataSource;
|
|
1792
|
+
const pageItems = [...ds.items];
|
|
1793
|
+
this.items.set(pageItems.filter(isRowRecord));
|
|
1794
|
+
this.totalCount.set(ds.totalCount ?? this.items().length);
|
|
1795
|
+
this.pageIndex.set(getDataSourcePageIndex(this.vm().dataSource));
|
|
1796
|
+
this.pageSize.set(this.vm().dataSource.config.pageSize ?? 10);
|
|
1797
|
+
}
|
|
1798
|
+
syncPagingFromDataSource(vm) {
|
|
1799
|
+
this.pageIndex.set(getDataSourcePageIndex(vm.dataSource));
|
|
1800
|
+
this.pageSize.set(vm.dataSource.config.pageSize ?? 10);
|
|
1801
|
+
}
|
|
1802
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityMasterListCardListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1803
|
+
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 }); }
|
|
1804
|
+
}
|
|
1805
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityMasterListCardListComponent, decorators: [{
|
|
1806
|
+
type: Component,
|
|
1807
|
+
args: [{ selector: 'axp-entity-master-list-card-list', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
1808
|
+
CommonModule,
|
|
1809
|
+
AXButtonModule,
|
|
1810
|
+
AXDataPagerModule,
|
|
1811
|
+
AXTranslationModule,
|
|
1812
|
+
AXPEntityMasterListCardItemComponent,
|
|
1813
|
+
AXPEntityMasterListCardItemSkeletonComponent,
|
|
1814
|
+
], 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"] }]
|
|
1815
|
+
}], ctorParameters: () => [], propDecorators: { vm: [{ type: i0.Input, args: [{ isSignal: true, alias: "vm", required: true }] }], pageChanged: [{ type: i0.Output, args: ["pageChanged"] }] } });
|
|
1816
|
+
function getRowId(row, key) {
|
|
1817
|
+
if (isRowRecord(row)) {
|
|
1818
|
+
return get(row, key);
|
|
1819
|
+
}
|
|
1820
|
+
return undefined;
|
|
1821
|
+
}
|
|
1822
|
+
function isRowRecord(row) {
|
|
1823
|
+
return row != null && typeof row === 'object' && !Array.isArray(row);
|
|
1824
|
+
}
|
|
1825
|
+
|
|
1826
|
+
class AXPEntityMasterListDataTableComponent {
|
|
1827
|
+
constructor() {
|
|
1828
|
+
//#region ---- Inputs & Outputs ----
|
|
1829
|
+
this.vm = input.required(...(ngDevMode ? [{ debugName: "vm" }] : /* istanbul ignore next */ []));
|
|
1830
|
+
this.pageChanged = output();
|
|
1831
|
+
//#endregion
|
|
1832
|
+
//#region ---- View References ----
|
|
1833
|
+
this.gridRef = viewChild('grid', ...(ngDevMode ? [{ debugName: "gridRef" }] : /* istanbul ignore next */ []));
|
|
1834
|
+
//#endregion
|
|
1835
|
+
//#region ---- Computed ----
|
|
1836
|
+
this.commandRowItems = computed(() => {
|
|
1837
|
+
return this.vm()
|
|
1838
|
+
.primaryRowActions()
|
|
1839
|
+
.map((c) => ({
|
|
1840
|
+
icon: c.icon,
|
|
1841
|
+
name: c.name,
|
|
1842
|
+
text: translateSync(c.title),
|
|
1843
|
+
color: c.color,
|
|
1844
|
+
disabled: c.disabled,
|
|
1845
|
+
default: c.default,
|
|
1846
|
+
}));
|
|
1847
|
+
}, ...(ngDevMode ? [{ debugName: "commandRowItems" }] : /* istanbul ignore next */ []));
|
|
1848
|
+
this.getDropdownRowItems = (rowData) => {
|
|
1849
|
+
return Promise.resolve(this.dropdownRowItems(rowData));
|
|
1850
|
+
};
|
|
1851
|
+
this.getCommandRowItems = () => {
|
|
1852
|
+
return this.commandRowItems();
|
|
1853
|
+
};
|
|
1854
|
+
}
|
|
1855
|
+
/** Exposed for parent refresh and expanded-row persistence. */
|
|
1856
|
+
grid() {
|
|
1857
|
+
return this.gridRef();
|
|
1858
|
+
}
|
|
1859
|
+
//#endregion
|
|
1860
|
+
//#region ---- Table Event Handlers ----
|
|
1861
|
+
onColumnSizeChanged(e) {
|
|
1862
|
+
if (e.isUserInteraction && e.type === 'end') {
|
|
1863
|
+
this.vm().saveSettings('columnSizes', e.data);
|
|
1864
|
+
}
|
|
1865
|
+
}
|
|
1866
|
+
onPageChanged(e) {
|
|
1867
|
+
if (e.isUserInteraction && !this.vm().skipListPagingPersistence) {
|
|
1868
|
+
this.vm().saveListPaging(e.take, e.skip);
|
|
1869
|
+
}
|
|
1870
|
+
this.pageChanged.emit(e);
|
|
1871
|
+
}
|
|
1872
|
+
onColumnsOrderChanged(e) {
|
|
1873
|
+
if (e.isUserInteraction) {
|
|
1874
|
+
this.vm().onColumnsOrderChanged(e.data.event);
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1877
|
+
async handleRowDbClick(e) {
|
|
1878
|
+
if (this.grid()?.dataSource.isLoading) {
|
|
1879
|
+
return;
|
|
1880
|
+
}
|
|
1881
|
+
const allItems = [...this.commandRowItems(), ...(await this.dropdownRowItems(e.data))];
|
|
1882
|
+
const defaultAction = allItems.find((c) => {
|
|
1883
|
+
const commandName = c.name.split('&')[0];
|
|
1884
|
+
return (c.default || commandName === 'open-entity') && !c.disabled;
|
|
1885
|
+
});
|
|
1886
|
+
if (!defaultAction) {
|
|
1887
|
+
return;
|
|
1888
|
+
}
|
|
1889
|
+
const d = {
|
|
1890
|
+
component: e.component,
|
|
1891
|
+
name: defaultAction.name,
|
|
1892
|
+
data: e.data,
|
|
1893
|
+
};
|
|
1894
|
+
await this.handleRowCommandClick(d);
|
|
1895
|
+
}
|
|
1896
|
+
async handleRowCommandClick(e) {
|
|
1897
|
+
if (this.grid()?.dataSource.isLoading) {
|
|
1898
|
+
return;
|
|
1899
|
+
}
|
|
1900
|
+
if (e.setLoading) {
|
|
1901
|
+
e.setLoading(true);
|
|
1902
|
+
}
|
|
1903
|
+
await this.vm().executeCommand(e.name, e.data);
|
|
1904
|
+
if (e.setLoading) {
|
|
1905
|
+
e.setLoading(false);
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
handleSelectedRowsChange(rows) {
|
|
1909
|
+
this.vm().selectedItems.set(rows);
|
|
1910
|
+
}
|
|
1911
|
+
handleColumnSort(columnName, event) {
|
|
1912
|
+
void this.vm().toggleColumnSort(columnName, event.ctrlKey || event.metaKey);
|
|
1913
|
+
}
|
|
1914
|
+
//#endregion
|
|
1915
|
+
//#region ---- Sort Helpers ----
|
|
1916
|
+
resolveColumnSortDirection(sortedFields, columnName) {
|
|
1917
|
+
const dir = sortedFields.find((s) => s.name === columnName)?.dir;
|
|
1918
|
+
return dir === 'asc' || dir === 'desc' ? dir : undefined;
|
|
1919
|
+
}
|
|
1920
|
+
resolveColumnSortIndex(sortedFields, columnName) {
|
|
1921
|
+
const index = sortedFields.findIndex((s) => s.name === columnName);
|
|
1922
|
+
return index >= 0 ? index + 1 : undefined;
|
|
1923
|
+
}
|
|
1924
|
+
//#endregion
|
|
1925
|
+
//#region ---- Private Helpers ----
|
|
1926
|
+
async dropdownRowItems(rowData) {
|
|
1927
|
+
return (await this.vm().secondaryRowActions(rowData)).map((c) => ({
|
|
1928
|
+
icon: c.icon,
|
|
1929
|
+
name: c.name,
|
|
1930
|
+
text: c.title,
|
|
1931
|
+
color: c.color,
|
|
1932
|
+
disabled: c.disabled,
|
|
1933
|
+
default: c.default,
|
|
1934
|
+
divided: c.separated,
|
|
1935
|
+
}));
|
|
1936
|
+
}
|
|
1937
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityMasterListDataTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1938
|
+
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", "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", "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 }); }
|
|
1939
|
+
}
|
|
1940
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityMasterListDataTableComponent, decorators: [{
|
|
1941
|
+
type: Component,
|
|
1942
|
+
args: [{ selector: 'axp-entity-master-list-data-table', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, AXDataTableModule, AXTranslationModule, AXPWidgetCoreModule, AXPWidgetsModule], host: {
|
|
1943
|
+
style: 'height: -webkit-fill-available;',
|
|
1944
|
+
}, 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" }]
|
|
1945
|
+
}], 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 }] }] } });
|
|
1946
|
+
|
|
1947
|
+
class AXPEntityMasterListViewComponent extends AXPPageLayoutBaseComponent {
|
|
1948
|
+
constructor(platform) {
|
|
1949
|
+
super();
|
|
1950
|
+
this.platform = platform;
|
|
1951
|
+
//#region ---- Services & Dependencies ----
|
|
1952
|
+
this.activeRoute = inject(ActivatedRoute);
|
|
1953
|
+
this.router = inject(Router);
|
|
1954
|
+
//#endregion
|
|
1955
|
+
//#region ---- View State ----
|
|
1956
|
+
this.vm = this.activeRoute.snapshot.data['vm'];
|
|
1957
|
+
this.store = inject(AXPLayoutThemeService);
|
|
1958
|
+
this.searchBarShown = signal(true, ...(ngDevMode ? [{ debugName: "searchBarShown" }] : /* istanbul ignore next */ []));
|
|
1959
|
+
this.activeEndSideView = signal('column', ...(ngDevMode ? [{ debugName: "activeEndSideView" }] : /* istanbul ignore next */ []));
|
|
1960
|
+
this.categorySearchValue = signal('', ...(ngDevMode ? [{ debugName: "categorySearchValue" }] : /* istanbul ignore next */ []));
|
|
1961
|
+
//#endregion
|
|
1962
|
+
//#region ---- View References ----
|
|
1963
|
+
this.dataTable = viewChild(AXPEntityMasterListDataTableComponent, ...(ngDevMode ? [{ debugName: "dataTable" }] : /* istanbul ignore next */ []));
|
|
1964
|
+
this.initializedFromRoute = false;
|
|
1965
|
+
this.lastEvaluatedViewName = null;
|
|
1966
|
+
this.componentDestroyed = new Subject();
|
|
1967
|
+
this.isRestoringExpandedRows = false;
|
|
1968
|
+
this.restoreExpandedRowsScheduled = false;
|
|
1969
|
+
effect(() => {
|
|
1970
|
+
const grid = this.grid();
|
|
1971
|
+
if (grid) {
|
|
1972
|
+
grid.selectedRows = this.vm.selectedItems();
|
|
1973
|
+
}
|
|
1974
|
+
});
|
|
1975
|
+
this.vm.events$.subscribe(async (e) => {
|
|
1976
|
+
const refreshTargetId = e.meta?.refreshTargetId;
|
|
1977
|
+
const resetPagination = e.meta?.resetPagination === true;
|
|
1978
|
+
if (e.action == 'refresh') {
|
|
1979
|
+
if (refreshTargetId) {
|
|
1980
|
+
await this.grid()?.refreshItemChildren(refreshTargetId);
|
|
1981
|
+
this.updateParentHasChildAfterRefresh(refreshTargetId);
|
|
1982
|
+
}
|
|
1983
|
+
else {
|
|
1984
|
+
await this.reloadListData(resetPagination);
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
1987
|
+
});
|
|
1988
|
+
effect(() => {
|
|
1989
|
+
if (!this.initializedFromRoute) {
|
|
1990
|
+
return;
|
|
1991
|
+
}
|
|
1992
|
+
const currentViewName = this.vm.view().name;
|
|
1993
|
+
const urlView = this.activeRoute.snapshot.queryParamMap.get('view');
|
|
1994
|
+
if (currentViewName && currentViewName !== urlView) {
|
|
1995
|
+
this.router.navigate([], {
|
|
1996
|
+
relativeTo: this.activeRoute,
|
|
1997
|
+
queryParams: { view: currentViewName },
|
|
1998
|
+
queryParamsHandling: 'merge',
|
|
1999
|
+
replaceUrl: true,
|
|
2000
|
+
});
|
|
2001
|
+
}
|
|
2002
|
+
});
|
|
2003
|
+
effect(() => {
|
|
2004
|
+
const currentViewName = this.vm.view().name;
|
|
2005
|
+
if (!this.initializedFromRoute) {
|
|
2006
|
+
this.lastEvaluatedViewName = currentViewName;
|
|
2007
|
+
return;
|
|
2008
|
+
}
|
|
2009
|
+
if (this.lastEvaluatedViewName !== currentViewName) {
|
|
2010
|
+
this.lastEvaluatedViewName = currentViewName;
|
|
2011
|
+
this.recompute();
|
|
2012
|
+
this.scheduleRestoreExpandedRows();
|
|
2013
|
+
}
|
|
2014
|
+
});
|
|
2015
|
+
}
|
|
2016
|
+
async ngOnInit() {
|
|
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.router.navigate([], {
|
|
2030
|
+
relativeTo: this.activeRoute,
|
|
2031
|
+
queryParams: { view: resolvedView },
|
|
2032
|
+
queryParamsHandling: 'merge',
|
|
2033
|
+
replaceUrl: true,
|
|
2034
|
+
});
|
|
2035
|
+
}
|
|
2036
|
+
this.initializedFromRoute = true;
|
|
2037
|
+
this.bindExpandedRowPersistence();
|
|
2038
|
+
this.scheduleRestoreExpandedRows();
|
|
2039
|
+
this.recompute();
|
|
2040
|
+
}
|
|
2041
|
+
ngOnDestroy() {
|
|
2042
|
+
this.componentDestroyed.next();
|
|
2043
|
+
this.componentDestroyed.complete();
|
|
2044
|
+
this.queryParamSub?.unsubscribe();
|
|
2045
|
+
this.vm.destroy();
|
|
2046
|
+
}
|
|
2047
|
+
//#endregion
|
|
2048
|
+
//#region ---- List Layout Handlers ----
|
|
2049
|
+
onListPageChanged() {
|
|
2050
|
+
this.scheduleRestoreExpandedRows();
|
|
2051
|
+
}
|
|
2052
|
+
handleUnselectAll() {
|
|
2053
|
+
this.vm.selectedItems.set([]);
|
|
2054
|
+
}
|
|
2055
|
+
//#endregion
|
|
2056
|
+
//#region ---- Toolbar & Sidebar Handlers ----
|
|
2057
|
+
makeResponsive(value) {
|
|
2058
|
+
if (this.platform.is('Mobile') || this.platform.is('SM')) {
|
|
2059
|
+
return '';
|
|
2060
|
+
}
|
|
2061
|
+
return value;
|
|
2062
|
+
}
|
|
2063
|
+
toggleSideBar(sideBar) {
|
|
2064
|
+
this.toggleEndSide();
|
|
2065
|
+
if (sideBar) {
|
|
2066
|
+
this.activeEndSideView.set(sideBar);
|
|
2067
|
+
}
|
|
2068
|
+
}
|
|
2069
|
+
toggleSearchBar() {
|
|
2070
|
+
this.searchBarShown.update((v) => !v);
|
|
2071
|
+
}
|
|
2072
|
+
handleResetClick(sideBar) {
|
|
2073
|
+
switch (sideBar) {
|
|
2074
|
+
case 'filter': {
|
|
2075
|
+
this.vm.resetFilters();
|
|
2076
|
+
break;
|
|
2077
|
+
}
|
|
2078
|
+
case 'sort': {
|
|
2079
|
+
this.vm.resetSorts();
|
|
2080
|
+
break;
|
|
2081
|
+
}
|
|
2082
|
+
case 'column': {
|
|
2083
|
+
this.vm.resetColumns();
|
|
2084
|
+
break;
|
|
2085
|
+
}
|
|
2086
|
+
}
|
|
2087
|
+
}
|
|
2088
|
+
handleApplyClick(sideBar) {
|
|
2089
|
+
this.vm.applyFilterAndSort();
|
|
2090
|
+
this.toggleEndSide();
|
|
2091
|
+
}
|
|
2092
|
+
toggleCategoryDrawer() {
|
|
2093
|
+
this.toggleStartSide();
|
|
2094
|
+
}
|
|
2095
|
+
//#endregion
|
|
2096
|
+
//#region ---- Page Layout ----
|
|
2097
|
+
getPageTitle() {
|
|
2098
|
+
return this.vm.title();
|
|
2099
|
+
}
|
|
2100
|
+
async getPageDescription() {
|
|
2101
|
+
const description = this.vm.description();
|
|
2102
|
+
if (description) {
|
|
2103
|
+
return this.translateService.translateAsync(description);
|
|
2104
|
+
}
|
|
2105
|
+
return '';
|
|
2106
|
+
}
|
|
2107
|
+
getPageBreadcrumbs() {
|
|
2108
|
+
return this.vm.beardcrumbs();
|
|
2109
|
+
}
|
|
2110
|
+
async getPrimaryMenuItems() {
|
|
2111
|
+
return (await this.vm.getPrimaryActions())
|
|
2112
|
+
.filter((tr) => !tr.isChild)
|
|
2113
|
+
.map((tr) => ({
|
|
2114
|
+
name: tr.name,
|
|
2115
|
+
title: tr.title,
|
|
2116
|
+
icon: tr.icon,
|
|
2117
|
+
color: tr.color,
|
|
2118
|
+
disabled: tr.disabled,
|
|
2119
|
+
items: tr.items?.map((sub) => ({
|
|
2120
|
+
name: sub.name,
|
|
2121
|
+
title: sub.title,
|
|
2122
|
+
icon: sub.icon,
|
|
2123
|
+
color: sub.color,
|
|
2124
|
+
disabled: sub.disabled,
|
|
2125
|
+
command: {
|
|
2126
|
+
name: sub.name,
|
|
2127
|
+
options: sub.options,
|
|
2128
|
+
metadata: sub.metadata,
|
|
2129
|
+
},
|
|
2130
|
+
})),
|
|
2131
|
+
command: {
|
|
2132
|
+
name: tr.name,
|
|
2133
|
+
options: tr.options,
|
|
2134
|
+
metadata: tr.metadata,
|
|
2135
|
+
},
|
|
2136
|
+
}));
|
|
2137
|
+
}
|
|
2138
|
+
async getSecondaryMenuItems() {
|
|
2139
|
+
return (await this.vm.getSecondaryActions()).map((tr) => ({
|
|
2140
|
+
name: tr.name,
|
|
2141
|
+
title: tr.title,
|
|
2142
|
+
icon: tr.icon,
|
|
2143
|
+
color: tr.color,
|
|
2144
|
+
disabled: tr.disabled,
|
|
2145
|
+
separated: tr.separated,
|
|
2146
|
+
command: {
|
|
2147
|
+
name: tr.name,
|
|
2148
|
+
options: tr.options,
|
|
2149
|
+
metadata: tr.metadata,
|
|
2150
|
+
},
|
|
2151
|
+
}));
|
|
2152
|
+
}
|
|
2153
|
+
async execute(command) {
|
|
2154
|
+
if (command) {
|
|
2155
|
+
this.vm.execute(command);
|
|
2156
|
+
}
|
|
2157
|
+
}
|
|
2158
|
+
//#endregion
|
|
2159
|
+
//#region ---- Grid Helpers ----
|
|
2160
|
+
async reloadListData(resetPagination = false) {
|
|
2161
|
+
if (!resetPagination) {
|
|
2162
|
+
await this.vm.ensureListPagingResolved();
|
|
2163
|
+
this.vm.applyPagingToDataSourceWithoutLoad();
|
|
2164
|
+
}
|
|
2165
|
+
const grid = this.grid();
|
|
2166
|
+
if (grid) {
|
|
2167
|
+
await grid.refresh({ reset: resetPagination });
|
|
2168
|
+
if (!resetPagination) {
|
|
2169
|
+
this.scheduleSyncGridPagerUi();
|
|
2170
|
+
}
|
|
2171
|
+
this.scheduleRestoreExpandedRows();
|
|
2172
|
+
}
|
|
2173
|
+
else {
|
|
2174
|
+
await this.vm.dataSource.refresh({ reset: resetPagination });
|
|
2175
|
+
}
|
|
2176
|
+
}
|
|
2177
|
+
grid() {
|
|
2178
|
+
return this.dataTable()?.grid();
|
|
2179
|
+
}
|
|
2180
|
+
updateParentHasChildAfterRefresh(parentId) {
|
|
2181
|
+
const gridRef = this.grid();
|
|
2182
|
+
const ds = gridRef?.dataSource;
|
|
2183
|
+
if (!ds?.cachedItems?.length) {
|
|
2184
|
+
return;
|
|
2185
|
+
}
|
|
2186
|
+
const key = ds.config?.key ?? 'id';
|
|
2187
|
+
const parent = this.findItemById(ds.cachedItems, String(parentId), key);
|
|
2188
|
+
if (parent && typeof parent === 'object') {
|
|
2189
|
+
parent['hasChild'] = true;
|
|
2190
|
+
}
|
|
2191
|
+
}
|
|
2192
|
+
findItemById(items, id, key) {
|
|
2193
|
+
for (const item of items) {
|
|
2194
|
+
if (item && typeof item === 'object' && String(item[key]) === id) {
|
|
2195
|
+
return item;
|
|
2196
|
+
}
|
|
2197
|
+
const rec = item;
|
|
2198
|
+
const metaChildren = rec?.['__meta__']?.['children'];
|
|
2199
|
+
const directChildren = rec?.['children'];
|
|
2200
|
+
const childArr = Array.isArray(metaChildren)
|
|
2201
|
+
? metaChildren
|
|
2202
|
+
: Array.isArray(directChildren)
|
|
2203
|
+
? directChildren
|
|
2204
|
+
: null;
|
|
2205
|
+
if (childArr?.length) {
|
|
2206
|
+
const found = this.findItemById(childArr, id, key);
|
|
2207
|
+
if (found)
|
|
2208
|
+
return found;
|
|
2209
|
+
}
|
|
2210
|
+
}
|
|
2211
|
+
return null;
|
|
2212
|
+
}
|
|
2213
|
+
bindExpandedRowPersistence() {
|
|
2214
|
+
if (!this.vm.parentKey()) {
|
|
2215
|
+
return;
|
|
2216
|
+
}
|
|
2217
|
+
this.vm.dataSource.onItemExpanded.pipe(takeUntil(this.componentDestroyed)).subscribe((event) => {
|
|
2218
|
+
const expandedItem = event?.expandedItem;
|
|
2219
|
+
if (expandedItem && typeof expandedItem === 'object') {
|
|
2220
|
+
this.vm.handleRowExpandChange(expandedItem);
|
|
2221
|
+
}
|
|
2222
|
+
});
|
|
2223
|
+
}
|
|
2224
|
+
scheduleSyncGridPagerUi() {
|
|
2225
|
+
queueMicrotask(() => {
|
|
2226
|
+
this.syncGridPagerUi();
|
|
2227
|
+
});
|
|
2228
|
+
}
|
|
2229
|
+
syncGridPagerUi() {
|
|
2230
|
+
const gridRef = this.grid();
|
|
2231
|
+
if (!gridRef) {
|
|
2232
|
+
return;
|
|
2233
|
+
}
|
|
2234
|
+
const pageIndex = getDataSourcePageIndex(this.vm.dataSource);
|
|
2235
|
+
const take = this.vm.dataSource.config.pageSize;
|
|
2236
|
+
const pagerPage = pageIndex + 1;
|
|
2237
|
+
const grid = gridRef;
|
|
2238
|
+
this.vm.skipListPagingPersistence = true;
|
|
2239
|
+
try {
|
|
2240
|
+
if (grid.page() !== pageIndex) {
|
|
2241
|
+
grid.page.set(pageIndex);
|
|
2242
|
+
}
|
|
2243
|
+
grid.pageSize.set(take);
|
|
2244
|
+
const pager = grid.dataPager;
|
|
2245
|
+
if (pager && pager.value !== pagerPage) {
|
|
2246
|
+
pager.goToPage(pagerPage);
|
|
2247
|
+
}
|
|
2248
|
+
}
|
|
2249
|
+
finally {
|
|
2250
|
+
this.vm.skipListPagingPersistence = false;
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
scheduleRestoreExpandedRows() {
|
|
2254
|
+
if (!this.vm.parentKey() || this.restoreExpandedRowsScheduled) {
|
|
2255
|
+
return;
|
|
2256
|
+
}
|
|
2257
|
+
this.restoreExpandedRowsScheduled = true;
|
|
2258
|
+
queueMicrotask(() => {
|
|
2259
|
+
this.restoreExpandedRowsScheduled = false;
|
|
2260
|
+
void this.restoreExpandedRows();
|
|
2261
|
+
});
|
|
2262
|
+
}
|
|
2263
|
+
async restoreExpandedRows() {
|
|
2264
|
+
if (!this.vm.parentKey() || this.isRestoringExpandedRows) {
|
|
2265
|
+
return;
|
|
2266
|
+
}
|
|
2267
|
+
const expandedRowIds = this.vm.getExpandedRowIds();
|
|
2268
|
+
if (!expandedRowIds.length) {
|
|
2269
|
+
return;
|
|
2270
|
+
}
|
|
2271
|
+
const gridRef = this.grid();
|
|
2272
|
+
if (!gridRef || gridRef.dataSource.isLoading) {
|
|
2273
|
+
return;
|
|
2274
|
+
}
|
|
2275
|
+
const gridWithDisplayedRows = gridRef;
|
|
2276
|
+
const displayedRows = gridWithDisplayedRows.displayedRows?.() ?? [];
|
|
2277
|
+
if (!displayedRows.length) {
|
|
2278
|
+
return;
|
|
2279
|
+
}
|
|
2280
|
+
this.isRestoringExpandedRows = true;
|
|
2281
|
+
this.vm.skipExpandedRowPersistence = true;
|
|
2282
|
+
try {
|
|
2283
|
+
const rowKey = this.vm.dataSource.config?.key ?? 'id';
|
|
2284
|
+
await restoreEntityListExpandedRows({
|
|
2285
|
+
expandedRowIds,
|
|
2286
|
+
rowKey,
|
|
2287
|
+
getDisplayedRows: () => gridWithDisplayedRows.displayedRows?.() ?? [],
|
|
2288
|
+
expandRow: (row) => gridRef.expandRow(row),
|
|
2289
|
+
});
|
|
2290
|
+
}
|
|
2291
|
+
finally {
|
|
2292
|
+
this.vm.skipExpandedRowPersistence = false;
|
|
2293
|
+
this.isRestoringExpandedRows = false;
|
|
2294
|
+
}
|
|
2295
|
+
}
|
|
2296
|
+
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 }); }
|
|
2297
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPEntityMasterListViewComponent, isStandalone: true, selector: "axp-entity-master-list", providers: [
|
|
2298
|
+
{
|
|
2299
|
+
provide: AXPPageLayoutBase,
|
|
2300
|
+
useExisting: AXPEntityMasterListViewComponent,
|
|
2301
|
+
},
|
|
2302
|
+
], 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 }); }
|
|
2303
|
+
}
|
|
2304
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityMasterListViewComponent, decorators: [{
|
|
2305
|
+
type: Component,
|
|
2306
|
+
args: [{ selector: 'axp-entity-master-list', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
2307
|
+
CommonModule,
|
|
2308
|
+
FormsModule,
|
|
2309
|
+
RouterModule,
|
|
2310
|
+
AXButtonModule,
|
|
2311
|
+
AXDecoratorModule,
|
|
2312
|
+
AXBadgeModule,
|
|
2313
|
+
AXDropdownModule,
|
|
2314
|
+
AXPopoverModule,
|
|
2315
|
+
AXFormModule,
|
|
2316
|
+
AXActionSheetModule,
|
|
2317
|
+
AXDrawerModule,
|
|
2318
|
+
AXDialogModule,
|
|
2319
|
+
AXLoadingModule,
|
|
2320
|
+
AXTabsModule,
|
|
2321
|
+
AXTooltipModule,
|
|
2322
|
+
AXBreadcrumbsModule,
|
|
2323
|
+
AXDropdownButtonModule,
|
|
2324
|
+
AXSearchBoxModule,
|
|
2325
|
+
AXTranslationModule,
|
|
2326
|
+
DragDropModule,
|
|
2327
|
+
AXPAuthModule,
|
|
2328
|
+
AXPEntityMasterToolbarViewComponent,
|
|
2329
|
+
AXPPageLayoutComponent,
|
|
2330
|
+
AXPThemeLayoutBlockComponent,
|
|
2331
|
+
AXPThemeLayoutStartSideComponent,
|
|
2332
|
+
AXPEntityCategoryComponent,
|
|
2333
|
+
AXPEntityMasterListDataTableComponent,
|
|
2334
|
+
AXPEntityMasterListCardListComponent,
|
|
2335
|
+
], providers: [
|
|
2336
|
+
{
|
|
2337
|
+
provide: AXPPageLayoutBase,
|
|
2338
|
+
useExisting: AXPEntityMasterListViewComponent,
|
|
2339
|
+
},
|
|
2340
|
+
], 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"] }]
|
|
2341
|
+
}], ctorParameters: () => [{ type: i1$4.AXPlatform }], propDecorators: { dataTable: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXPEntityMasterListDataTableComponent), { isSignal: true }] }] } });
|
|
2342
|
+
|
|
2343
|
+
var entityMasterListView_component = /*#__PURE__*/Object.freeze({
|
|
2344
|
+
__proto__: null,
|
|
2345
|
+
AXPEntityMasterListViewComponent: AXPEntityMasterListViewComponent
|
|
2346
|
+
});
|
|
2347
|
+
|
|
192
2348
|
class AXPRootLayoutFooterComponent {
|
|
193
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
194
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
2349
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootLayoutFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2350
|
+
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
2351
|
}
|
|
196
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2352
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootLayoutFooterComponent, decorators: [{
|
|
197
2353
|
type: Component,
|
|
198
|
-
args: [{ selector: 'axp-dashboard-admin-footer', encapsulation: ViewEncapsulation.None, providers: [], host: {
|
|
2354
|
+
args: [{ selector: 'axp-dashboard-admin-footer', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [], host: {
|
|
199
2355
|
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
2356
|
}, standalone: true, imports: [
|
|
201
2357
|
AXPComponentSlotModule
|
|
@@ -215,12 +2371,12 @@ class AXPRootLayoutHeaderComponent {
|
|
|
215
2371
|
handleLogoClick() {
|
|
216
2372
|
this.router.navigate(['/']);
|
|
217
2373
|
}
|
|
218
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
219
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2374
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootLayoutHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2375
|
+
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
2376
|
}
|
|
221
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2377
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootLayoutHeaderComponent, decorators: [{
|
|
222
2378
|
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: [
|
|
2379
|
+
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
2380
|
AXPComponentSlotModule,
|
|
225
2381
|
AXButtonModule,
|
|
226
2382
|
AXDecoratorModule
|
|
@@ -229,21 +2385,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
229
2385
|
|
|
230
2386
|
class AXPRootLayoutMenuComponent {
|
|
231
2387
|
constructor() {
|
|
2388
|
+
//#region ---- Services & Dependencies ----
|
|
232
2389
|
this.menuStore = inject(AXPMenuService);
|
|
233
2390
|
this.router = inject(Router);
|
|
234
2391
|
this.badgeService = inject(AXPTaskBadgeService);
|
|
235
2392
|
this.settingsService = inject(AXPSettingsService);
|
|
236
2393
|
this.visibilityService = inject(AXPMenuVisibilityService);
|
|
237
|
-
this.
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
// });
|
|
2394
|
+
this.themeStore = inject(AXPLayoutThemeService);
|
|
2395
|
+
//#endregion
|
|
2396
|
+
//#region ---- Component State ----
|
|
2397
|
+
this.badgeVisible = signal(true, ...(ngDevMode ? [{ debugName: "badgeVisible" }] : /* istanbul ignore next */ []));
|
|
2398
|
+
this.menuMode = this.themeStore.effectiveMenuVerticalMode;
|
|
243
2399
|
}
|
|
2400
|
+
//#endregion
|
|
244
2401
|
async ngOnInit() {
|
|
245
|
-
this.badgeVisible.set(await this.settingsService.
|
|
246
|
-
//subscribe to changes
|
|
2402
|
+
this.badgeVisible.set(await this.settingsService.get(AXPThemeLayoutSetting.MenuBadgeVisible));
|
|
247
2403
|
this.settingsService.onChanged.subscribe((setting) => {
|
|
248
2404
|
if (setting.keys.includes(AXPThemeLayoutSetting.MenuBadgeVisible)) {
|
|
249
2405
|
this.badgeVisible.set(setting.values[AXPThemeLayoutSetting.MenuBadgeVisible]);
|
|
@@ -279,6 +2435,30 @@ class AXPRootLayoutMenuComponent {
|
|
|
279
2435
|
shouldRenderMenuItem(item) {
|
|
280
2436
|
return this.visibilityService.shouldRenderMenuItem(item, (item) => this.getRouterLink(item));
|
|
281
2437
|
}
|
|
2438
|
+
/**
|
|
2439
|
+
* Checks if an item takes up visual space in the menu (group title or rendered menu item).
|
|
2440
|
+
*/
|
|
2441
|
+
isItemRendered(item) {
|
|
2442
|
+
if (item.type === 'break') {
|
|
2443
|
+
return false;
|
|
2444
|
+
}
|
|
2445
|
+
if (item.type === 'group') {
|
|
2446
|
+
return this.isItemVisible(item);
|
|
2447
|
+
}
|
|
2448
|
+
return this.shouldRenderMenuItem(item);
|
|
2449
|
+
}
|
|
2450
|
+
/**
|
|
2451
|
+
* Determines if a divider should be shown. A divider is only shown when there is
|
|
2452
|
+
* visible content on both sides; if before or after is blank, the divider is hidden.
|
|
2453
|
+
*/
|
|
2454
|
+
shouldShowDivider(item, items, index) {
|
|
2455
|
+
if (item.type !== 'break' || !items || index < 0) {
|
|
2456
|
+
return false;
|
|
2457
|
+
}
|
|
2458
|
+
const hasVisibleBefore = items.slice(0, index).some((i) => this.isItemRendered(i));
|
|
2459
|
+
const hasVisibleAfter = items.slice(index + 1).some((i) => this.isItemRendered(i));
|
|
2460
|
+
return hasVisibleBefore && hasVisibleAfter;
|
|
2461
|
+
}
|
|
282
2462
|
//#endregion
|
|
283
2463
|
//#region ---- Menu Navigation Helpers ----
|
|
284
2464
|
/**
|
|
@@ -380,10 +2560,10 @@ class AXPRootLayoutMenuComponent {
|
|
|
380
2560
|
const lowerPath = path.trim().toLowerCase();
|
|
381
2561
|
return lowerPath.startsWith('http://') || lowerPath.startsWith('https://');
|
|
382
2562
|
}
|
|
383
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
384
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2563
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootLayoutMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2564
|
+
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
2565
|
}
|
|
386
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2566
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootLayoutMenuComponent, decorators: [{
|
|
387
2567
|
type: Component,
|
|
388
2568
|
args: [{ selector: 'axp-side-menu', encapsulation: ViewEncapsulation.None, standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
389
2569
|
CommonModule,
|
|
@@ -392,8 +2572,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
392
2572
|
AXPTaskBadgeDirective,
|
|
393
2573
|
AXDecoratorModule,
|
|
394
2574
|
AXBadgeModule,
|
|
395
|
-
], template: "<ax-side-menu look=\"pills\">\n @
|
|
396
|
-
}]
|
|
2575
|
+
], 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" }]
|
|
2576
|
+
}] });
|
|
397
2577
|
|
|
398
2578
|
class AXPHorizontalMenuComponent {
|
|
399
2579
|
constructor() {
|
|
@@ -404,10 +2584,10 @@ class AXPHorizontalMenuComponent {
|
|
|
404
2584
|
this.badgeService = inject(AXPTaskBadgeService);
|
|
405
2585
|
this.settingsService = inject(AXPSettingsService);
|
|
406
2586
|
this.visibilityService = inject(AXPMenuVisibilityService);
|
|
407
|
-
this.badgeVisible = signal(true, ...(ngDevMode ? [{ debugName: "badgeVisible" }] : []));
|
|
2587
|
+
this.badgeVisible = signal(true, ...(ngDevMode ? [{ debugName: "badgeVisible" }] : /* istanbul ignore next */ []));
|
|
408
2588
|
}
|
|
409
2589
|
async ngOnInit() {
|
|
410
|
-
this.badgeVisible.set(await this.settingsService.
|
|
2590
|
+
this.badgeVisible.set(await this.settingsService.get(AXPThemeLayoutSetting.MenuBadgeVisible));
|
|
411
2591
|
//subscribe to changes
|
|
412
2592
|
this.settingsService.onChanged.subscribe(setting => {
|
|
413
2593
|
if (setting.keys.includes(AXPThemeLayoutSetting.MenuBadgeVisible)) {
|
|
@@ -443,6 +2623,30 @@ class AXPHorizontalMenuComponent {
|
|
|
443
2623
|
shouldRenderMenuItem(item) {
|
|
444
2624
|
return this.visibilityService.shouldRenderMenuItem(item, (item) => this.getRouterLink(item));
|
|
445
2625
|
}
|
|
2626
|
+
/**
|
|
2627
|
+
* Checks if an item takes up visual space in the menu (group title or rendered menu item).
|
|
2628
|
+
*/
|
|
2629
|
+
isItemRendered(item) {
|
|
2630
|
+
if (item.type === 'break') {
|
|
2631
|
+
return false;
|
|
2632
|
+
}
|
|
2633
|
+
if (item.type === 'group') {
|
|
2634
|
+
return this.isItemVisible(item);
|
|
2635
|
+
}
|
|
2636
|
+
return this.shouldRenderMenuItem(item);
|
|
2637
|
+
}
|
|
2638
|
+
/**
|
|
2639
|
+
* Determines if a divider should be shown. A divider is only shown when there is
|
|
2640
|
+
* visible content on both sides; if before or after is blank, the divider is hidden.
|
|
2641
|
+
*/
|
|
2642
|
+
shouldShowDivider(item, items, index) {
|
|
2643
|
+
if (item.type !== 'break' || !items || index < 0) {
|
|
2644
|
+
return false;
|
|
2645
|
+
}
|
|
2646
|
+
const hasVisibleBefore = items.slice(0, index).some((i) => this.isItemRendered(i));
|
|
2647
|
+
const hasVisibleAfter = items.slice(index + 1).some((i) => this.isItemRendered(i));
|
|
2648
|
+
return hasVisibleBefore && hasVisibleAfter;
|
|
2649
|
+
}
|
|
446
2650
|
//#endregion
|
|
447
2651
|
//#region ---- Menu Navigation Helpers ----
|
|
448
2652
|
/**
|
|
@@ -544,10 +2748,10 @@ class AXPHorizontalMenuComponent {
|
|
|
544
2748
|
const lowerPath = path.trim().toLowerCase();
|
|
545
2749
|
return lowerPath.startsWith('http://') || lowerPath.startsWith('https://');
|
|
546
2750
|
}
|
|
547
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
548
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2751
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPHorizontalMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2752
|
+
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
2753
|
}
|
|
550
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2754
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPHorizontalMenuComponent, decorators: [{
|
|
551
2755
|
type: Component,
|
|
552
2756
|
args: [{ selector: 'axp-horizontal-menu', host: { class: 'ax-light' }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
553
2757
|
CommonModule,
|
|
@@ -558,7 +2762,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
558
2762
|
AXTranslationModule,
|
|
559
2763
|
AXPTaskBadgeDirective,
|
|
560
2764
|
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 @
|
|
2765
|
+
], 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
2766
|
}] });
|
|
563
2767
|
|
|
564
2768
|
class AXPRootHorizontalLayoutComponent {
|
|
@@ -577,10 +2781,10 @@ class AXPRootHorizontalLayoutComponent {
|
|
|
577
2781
|
this.store.setSideMenuWidth(e.value);
|
|
578
2782
|
}
|
|
579
2783
|
}
|
|
580
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
581
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2784
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootHorizontalLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2785
|
+
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
2786
|
}
|
|
583
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2787
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootHorizontalLayoutComponent, decorators: [{
|
|
584
2788
|
type: Component,
|
|
585
2789
|
args: [{ selector: 'axp-root-horizontal-layout', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
|
|
586
2790
|
RouterModule,
|
|
@@ -614,22 +2818,23 @@ class AXPRootVerticalLayoutComponent {
|
|
|
614
2818
|
this.store = inject(AXPLayoutThemeService);
|
|
615
2819
|
this.deviceService = inject(AXPDeviceService);
|
|
616
2820
|
this.router = inject(Router);
|
|
2821
|
+
/** Recreates the drawer when switching overlay ↔ push to reset internal layout sizing. */
|
|
2822
|
+
this.sideMenuDrawerKey = computed(() => this.deviceService.isSmall() || this.deviceService.isMedium() ? 'overlay' : 'push', ...(ngDevMode ? [{ debugName: "sideMenuDrawerKey" }] : /* istanbul ignore next */ []));
|
|
617
2823
|
this.router.events.pipe(filter((event) => event instanceof NavigationEnd)).subscribe(() => {
|
|
618
|
-
if (this.
|
|
2824
|
+
if (this.sideMenuDrawerKey() === 'overlay') {
|
|
619
2825
|
this.store.closeSideMenu();
|
|
620
2826
|
}
|
|
621
2827
|
});
|
|
622
2828
|
}
|
|
623
2829
|
handleResizingEnded(e) {
|
|
624
|
-
//console.log('handleResizingEnded', e.value);
|
|
625
2830
|
if (e.isUserInteraction) {
|
|
626
|
-
this.store.
|
|
2831
|
+
this.store.setSideMenuDrawerWidth(e.value);
|
|
627
2832
|
}
|
|
628
2833
|
}
|
|
629
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
630
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2834
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootVerticalLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2835
|
+
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-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
2836
|
}
|
|
632
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2837
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootVerticalLayoutComponent, decorators: [{
|
|
633
2838
|
type: Component,
|
|
634
2839
|
args: [{ selector: 'axp-root-vertical-layout', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
|
|
635
2840
|
RouterModule,
|
|
@@ -654,11 +2859,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
654
2859
|
AXPRootLayoutHeaderComponent,
|
|
655
2860
|
AXPRootLayoutMenuComponent,
|
|
656
2861
|
AXPComponentSlotModule,
|
|
657
|
-
], template: "<div id=\"axp-root-layout\" class=\"axp-root-layout\">\n <ax-drawer-container>\n <ax-drawer
|
|
658
|
-
}], ctorParameters: () => []
|
|
659
|
-
type: ViewChild,
|
|
660
|
-
args: ['drawer']
|
|
661
|
-
}] } });
|
|
2862
|
+
], 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-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"] }]
|
|
2863
|
+
}], ctorParameters: () => [] });
|
|
662
2864
|
|
|
663
2865
|
class AXPRootLayoutComponent {
|
|
664
2866
|
constructor() {
|
|
@@ -668,7 +2870,6 @@ class AXPRootLayoutComponent {
|
|
|
668
2870
|
this.eventService = inject(AXPBroadcastEventService);
|
|
669
2871
|
this.sessionService = inject(AXPSessionService);
|
|
670
2872
|
this.unsubscriber = inject(AXUnsubscriber);
|
|
671
|
-
this.workflowService = inject(AXPWorkflowService);
|
|
672
2873
|
this.contextStore = inject(AXPContextStore);
|
|
673
2874
|
}
|
|
674
2875
|
ngOnInit() {
|
|
@@ -698,11 +2899,9 @@ class AXPRootLayoutComponent {
|
|
|
698
2899
|
this.router.navigate(['/auth/login']);
|
|
699
2900
|
}
|
|
700
2901
|
});
|
|
701
|
-
//
|
|
702
|
-
this.workflowService.execute('check-new-version');
|
|
703
2902
|
}
|
|
704
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
705
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2903
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2904
|
+
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
2905
|
@if(layout.isMenuHorizontal()){
|
|
707
2906
|
<axp-root-horizontal-layout></axp-root-horizontal-layout>
|
|
708
2907
|
}@else{
|
|
@@ -710,7 +2909,7 @@ class AXPRootLayoutComponent {
|
|
|
710
2909
|
}
|
|
711
2910
|
`, 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
2911
|
}
|
|
713
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2912
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPRootLayoutComponent, decorators: [{
|
|
714
2913
|
type: Component,
|
|
715
2914
|
args: [{
|
|
716
2915
|
template: `
|
|
@@ -724,7 +2923,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
724
2923
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
725
2924
|
standalone: true,
|
|
726
2925
|
imports: [AXPRootHorizontalLayoutComponent, AXPRootVerticalLayoutComponent],
|
|
727
|
-
providers: [AXUnsubscriber],
|
|
2926
|
+
providers: [AXUnsubscriber, AXPContextStore],
|
|
728
2927
|
}]
|
|
729
2928
|
}] });
|
|
730
2929
|
|
|
@@ -844,15 +3043,15 @@ function routesFacory() {
|
|
|
844
3043
|
children: [
|
|
845
3044
|
{
|
|
846
3045
|
path: 'offline',
|
|
847
|
-
loadComponent: () => import('./acorex-platform-themes-default-error-offline.component-
|
|
3046
|
+
loadComponent: () => import('./acorex-platform-themes-default-error-offline.component-DR6G8gPC.mjs').then((c) => c.AXPErrorOfflineComponent),
|
|
848
3047
|
},
|
|
849
3048
|
{
|
|
850
3049
|
path: '404',
|
|
851
|
-
loadComponent: () => import('./acorex-platform-themes-default-error-404.component-
|
|
3050
|
+
loadComponent: () => import('./acorex-platform-themes-default-error-404.component-7MVLMwIa.mjs').then((c) => c.AXPError404Component),
|
|
852
3051
|
},
|
|
853
3052
|
{
|
|
854
3053
|
path: '401',
|
|
855
|
-
loadComponent: () => import('./acorex-platform-themes-default-error-401.component-
|
|
3054
|
+
loadComponent: () => import('./acorex-platform-themes-default-error-401.component-C7EYJzSr.mjs').then((c) => c.AXPError401Component),
|
|
856
3055
|
},
|
|
857
3056
|
],
|
|
858
3057
|
},
|
|
@@ -860,9 +3059,9 @@ function routesFacory() {
|
|
|
860
3059
|
return routes;
|
|
861
3060
|
}
|
|
862
3061
|
class AXPDefaultThemeModule {
|
|
863
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
864
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "
|
|
865
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "
|
|
3062
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDefaultThemeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
3063
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: AXPDefaultThemeModule, imports: [AXPCommonModule, AXPThemesSharedModule] }); }
|
|
3064
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDefaultThemeModule, providers: [
|
|
866
3065
|
{
|
|
867
3066
|
provide: AXP_ENTITY_CONFIG_TOKEN,
|
|
868
3067
|
useFactory: () => {
|
|
@@ -870,14 +3069,14 @@ class AXPDefaultThemeModule {
|
|
|
870
3069
|
viewers: {
|
|
871
3070
|
root: () => Promise.resolve().then(function () { return rootLayout_component; }).then((c) => c.AXPRootLayoutComponent),
|
|
872
3071
|
master: {
|
|
873
|
-
single: () => import('./acorex-platform-themes-default-entity-master-single-view.component-
|
|
3072
|
+
single: () => import('./acorex-platform-themes-default-entity-master-single-view.component-Br9p5aXT.mjs').then((c) => c.AXPEntityMasterSingleViewComponent),
|
|
874
3073
|
details: () => import('@acorex/platform/layout/views').then((c) => c.AXPLayoutDetailsViewComponent),
|
|
875
3074
|
///
|
|
876
|
-
create: () => import('./acorex-platform-themes-default-entity-master-create-view.component-
|
|
3075
|
+
create: () => import('./acorex-platform-themes-default-entity-master-create-view.component-CWLfNqV0.mjs').then((c) => c.AXPEntityMasterCreateViewComponent),
|
|
877
3076
|
///
|
|
878
|
-
modify: () => import('./acorex-platform-themes-default-entity-master-modify-view.component-
|
|
3077
|
+
modify: () => import('./acorex-platform-themes-default-entity-master-modify-view.component-C7cT82K2.mjs').then((c) => c.AXPEntityMasterModifyViewComponent),
|
|
879
3078
|
//
|
|
880
|
-
list: () =>
|
|
3079
|
+
list: () => Promise.resolve().then(function () { return entityMasterListView_component; }).then((c) => c.AXPEntityMasterListViewComponent),
|
|
881
3080
|
},
|
|
882
3081
|
},
|
|
883
3082
|
};
|
|
@@ -892,7 +3091,7 @@ class AXPDefaultThemeModule {
|
|
|
892
3091
|
},
|
|
893
3092
|
], imports: [AXPCommonModule, AXPThemesSharedModule] }); }
|
|
894
3093
|
}
|
|
895
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3094
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDefaultThemeModule, decorators: [{
|
|
896
3095
|
type: NgModule,
|
|
897
3096
|
args: [{
|
|
898
3097
|
imports: [AXPCommonModule, AXPThemesSharedModule],
|
|
@@ -906,14 +3105,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
906
3105
|
viewers: {
|
|
907
3106
|
root: () => Promise.resolve().then(function () { return rootLayout_component; }).then((c) => c.AXPRootLayoutComponent),
|
|
908
3107
|
master: {
|
|
909
|
-
single: () => import('./acorex-platform-themes-default-entity-master-single-view.component-
|
|
3108
|
+
single: () => import('./acorex-platform-themes-default-entity-master-single-view.component-Br9p5aXT.mjs').then((c) => c.AXPEntityMasterSingleViewComponent),
|
|
910
3109
|
details: () => import('@acorex/platform/layout/views').then((c) => c.AXPLayoutDetailsViewComponent),
|
|
911
3110
|
///
|
|
912
|
-
create: () => import('./acorex-platform-themes-default-entity-master-create-view.component-
|
|
3111
|
+
create: () => import('./acorex-platform-themes-default-entity-master-create-view.component-CWLfNqV0.mjs').then((c) => c.AXPEntityMasterCreateViewComponent),
|
|
913
3112
|
///
|
|
914
|
-
modify: () => import('./acorex-platform-themes-default-entity-master-modify-view.component-
|
|
3113
|
+
modify: () => import('./acorex-platform-themes-default-entity-master-modify-view.component-C7cT82K2.mjs').then((c) => c.AXPEntityMasterModifyViewComponent),
|
|
915
3114
|
//
|
|
916
|
-
list: () =>
|
|
3115
|
+
list: () => Promise.resolve().then(function () { return entityMasterListView_component; }).then((c) => c.AXPEntityMasterListViewComponent),
|
|
917
3116
|
},
|
|
918
3117
|
},
|
|
919
3118
|
};
|
|
@@ -934,5 +3133,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
934
3133
|
* Generated bundle index. Do not edit.
|
|
935
3134
|
*/
|
|
936
3135
|
|
|
937
|
-
export { AXPDefaultThemeModule, AXPEntityDetailListViewComponent, AXPRootHorizontalLayoutComponent, AXPRootLayoutComponent, AXPRootLayoutFooterComponent, AXPRootLayoutHeaderComponent, AXPRootLayoutMenuComponent, AXPRootVerticalLayoutComponent };
|
|
3136
|
+
export { AXPDefaultThemeModule, AXPEntityDetailListViewComponent, AXPEntityMasterListViewComponent, AXPRootHorizontalLayoutComponent, AXPRootLayoutComponent, AXPRootLayoutFooterComponent, AXPRootLayoutHeaderComponent, AXPRootLayoutMenuComponent, AXPRootVerticalLayoutComponent };
|
|
938
3137
|
//# sourceMappingURL=acorex-platform-themes-default.mjs.map
|