@acorex/platform 20.6.0-next.18 → 20.6.0-next.19
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-layout-entity.mjs +1134 -413
- package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-views.mjs +3 -2
- package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widgets.mjs +4 -4
- package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
- package/fesm2022/{acorex-platform-themes-default-entity-master-list-view.component-4nWLEm89.mjs → acorex-platform-themes-default-entity-master-list-view.component-BbACUabi.mjs} +406 -173
- package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-BbACUabi.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-default.mjs +2 -2
- package/layout/entity/index.d.ts +168 -24
- package/layout/views/index.d.ts +1 -0
- package/package.json +1 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-4nWLEm89.mjs.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { AXPSessionService, AXPAuthGuard } from '@acorex/platform/auth';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { inject, Injectable, input, viewChild, signal, ElementRef, ChangeDetectionStrategy, Component, ApplicationRef, EnvironmentInjector, createComponent, InjectionToken, computed, Injector, runInInjectionContext, ChangeDetectorRef, effect, viewChildren, linkedSignal, untracked, HostBinding, ViewChild, NgModule } from '@angular/core';
|
|
3
|
+
import { inject, Injectable, input, viewChild, signal, ElementRef, ChangeDetectionStrategy, Component, ApplicationRef, EnvironmentInjector, createComponent, InjectionToken, computed, Injector, runInInjectionContext, afterNextRender, ViewEncapsulation, ChangeDetectorRef, effect, viewChildren, linkedSignal, untracked, HostBinding, ViewChild, NgModule } from '@angular/core';
|
|
4
4
|
import { Router, RouterModule, ROUTES } from '@angular/router';
|
|
5
5
|
import * as i3 from '@acorex/components/button';
|
|
6
6
|
import { AXButtonModule } from '@acorex/components/button';
|
|
7
|
-
import * as
|
|
7
|
+
import * as i1 from '@acorex/components/loading';
|
|
8
8
|
import { AXLoadingModule } from '@acorex/components/loading';
|
|
9
9
|
import * as i2 from '@acorex/components/popover';
|
|
10
10
|
import { AXPopoverModule } from '@acorex/components/popover';
|
|
@@ -18,9 +18,9 @@ import { CommonModule } from '@angular/common';
|
|
|
18
18
|
import { castArray, get, cloneDeep, set, merge, orderBy, isNil, isEqual, isEmpty, sortBy } from 'lodash-es';
|
|
19
19
|
import { AXDataSource } from '@acorex/cdk/common';
|
|
20
20
|
import { AXFormatService } from '@acorex/core/format';
|
|
21
|
-
import * as i4
|
|
21
|
+
import * as i4 from '@acorex/platform/common';
|
|
22
22
|
import { AXPFilterOperatorMiddlewareService, AXPEntityCommandScope, getEntityInfo, AXPSettingService, AXPRefreshEvent, AXPReloadEvent, AXPCommonSettings, AXPCleanNestedFilters, AXPWorkflowNavigateAction, AXPToastAction, AXP_SEARCH_DEFINITION_PROVIDER } from '@acorex/platform/common';
|
|
23
|
-
import * as i1$
|
|
23
|
+
import * as i1$3 from '@acorex/platform/core';
|
|
24
24
|
import { resolveActionLook, AXPExpressionEvaluatorService, AXPDistributedEventListenerService, AXPBroadcastEventService, AXPPlatformScope, extractValue, setSmart, AXPDeviceService, getChangedPaths, AXPSystemActionType } from '@acorex/platform/core';
|
|
25
25
|
import * as i2$3 from '@acorex/platform/workflow';
|
|
26
26
|
import { AXPWorkflowService, ofType, createWorkFlowEvent, AXPWorkflowAction, AXPWorkflowModule } from '@acorex/platform/workflow';
|
|
@@ -31,30 +31,30 @@ import { AXDialogService } from '@acorex/components/dialog';
|
|
|
31
31
|
import { AXLoadingDialogService } from '@acorex/components/loading-dialog';
|
|
32
32
|
import { AXPopupService } from '@acorex/components/popup';
|
|
33
33
|
import { AXPlatform } from '@acorex/core/platform';
|
|
34
|
-
import * as
|
|
34
|
+
import * as i1$1 from '@acorex/components/decorators';
|
|
35
35
|
import { AXDecoratorModule } from '@acorex/components/decorators';
|
|
36
36
|
import { AXBasePageComponent } from '@acorex/components/page';
|
|
37
|
-
import * as i3$
|
|
37
|
+
import * as i3$2 from '@acorex/components/search-box';
|
|
38
38
|
import { AXSearchBoxModule, AXSearchBoxComponent } from '@acorex/components/search-box';
|
|
39
|
-
import * as i4$
|
|
39
|
+
import * as i4$1 from '@acorex/components/skeleton';
|
|
40
40
|
import { AXSkeletonModule } from '@acorex/components/skeleton';
|
|
41
41
|
import { AXTreeViewComponent } from '@acorex/components/tree-view';
|
|
42
42
|
import * as i2$1 from '@acorex/components/badge';
|
|
43
43
|
import { AXBadgeModule } from '@acorex/components/badge';
|
|
44
44
|
import * as i5$1 from '@acorex/components/form';
|
|
45
45
|
import { AXFormModule } from '@acorex/components/form';
|
|
46
|
-
import * as i7 from '@acorex/components/select-box';
|
|
47
|
-
import { AXSelectBoxModule } from '@acorex/components/select-box';
|
|
48
|
-
import * as i6$1 from '@acorex/components/tag-box';
|
|
49
|
-
import { AXTagBoxModule, AXTagBoxComponent } from '@acorex/components/tag-box';
|
|
50
46
|
import { AXValidationModule } from '@acorex/core/validation';
|
|
51
|
-
import * as i1 from '@angular/forms';
|
|
52
|
-
import { FormsModule } from '@angular/forms';
|
|
53
47
|
import { AXP_DISABLED_PROPERTY, AXP_ALLOW_CLEAR_PROPERTY, AXP_DATA_PATH_PROPERTY, AXP_DATA_PROPERTY_GROUP, AXP_ALLOW_MULTIPLE_PROPERTY, AXP_NAME_PROPERTY, AXPFileUploaderWidgetService } from '@acorex/platform/layout/widgets';
|
|
54
|
-
import * as i4$
|
|
48
|
+
import * as i4$2 from '@acorex/components/dropdown';
|
|
55
49
|
import { AXDropdownModule } from '@acorex/components/dropdown';
|
|
50
|
+
import * as i1$2 from '@angular/forms';
|
|
51
|
+
import { FormsModule } from '@angular/forms';
|
|
52
|
+
import * as i7 from '@acorex/components/select-box';
|
|
53
|
+
import { AXSelectBoxModule } from '@acorex/components/select-box';
|
|
56
54
|
import * as i2$2 from '@acorex/components/text-box';
|
|
57
55
|
import { AXTextBoxModule, AXTextBoxComponent } from '@acorex/components/text-box';
|
|
56
|
+
import * as i6$1 from '@acorex/components/tag-box';
|
|
57
|
+
import { AXTagBoxComponent, AXTagBoxModule } from '@acorex/components/tag-box';
|
|
58
58
|
import { AXPDataSelectorService, AXPWidgetPropertyViewerComponent } from '@acorex/platform/layout/components';
|
|
59
59
|
import { AXPLayoutBuilderService } from '@acorex/platform/layout/builder';
|
|
60
60
|
import { transform, isEqual as isEqual$1 } from 'lodash';
|
|
@@ -391,7 +391,7 @@ class AXPEntityDetailPopoverComponent {
|
|
|
391
391
|
return importantProperties;
|
|
392
392
|
}
|
|
393
393
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPEntityDetailPopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
394
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXPEntityDetailPopoverComponent, isStandalone: true, selector: "axp-entity-detail-popover", inputs: { entity: { classPropertyName: "entity", publicName: "entity", isSignal: true, isRequired: true, transformFunction: null }, entityId: { classPropertyName: "entityId", publicName: "entityId", isSignal: true, isRequired: true, transformFunction: null }, textField: { classPropertyName: "textField", publicName: "textField", isSignal: true, isRequired: false, transformFunction: null }, valueField: { classPropertyName: "valueField", publicName: "valueField", isSignal: true, isRequired: false, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "detailPopover", first: true, predicate: ["detailPopover"], descendants: true, isSignal: true }], ngImport: i0, template: "<ax-popover [openOn]=\"'manual'\" #detailPopover (openChange)=\"onDetailPopoverOpenChange($event)\">\n <div class=\"ax-lightest-surface ax-border ax-rounded-lg ax-shadow-lg ax-p-4 ax-min-w-[400px]\">\n <div class=\"ax-mb-4 ax-border-b ax-pb-2\">\n <h3 class=\"ax-text-base ax-font-semibold ax-text-on-lightest-surface\">\n @if (entityDetails()?.entityData?.[textField()]) {\n {{ entityDetails()?.entityData[textField()] }}\n } @else {\n {{ item()?.[textField()] }}\n }\n </h3>\n </div>\n @if (isLoadingDetails()) {\n <div class=\"ax-flex ax-items-center ax-justify-center ax-py-8\">\n <ax-loading>Loading details...</ax-loading>\n </div>\n } @else if (entityDetails()) {\n <div class=\"ax-space-y-3 ax-mb-4\">\n <!-- Important Entity Data -->\n @if (entityDetails()?.entityData) {\n <axp-widgets-container [context]=\"entityDetails()?.entityData\">\n <div class=\"ax-space-y-2\">\n @for (item of getEntityPropertiesWithWidgets(); track item.name) {\n <div class=\"ax-flex ax-justify-between ax-items-center\">\n <span class=\"ax-text-sm ax-font-medium\">{{ item.title | translate | async }}:</span>\n <div class=\"ax-flex-1 ax-ml-2 ax-max-w-48\">\n <ng-container axp-widget-renderer [node]=\"item.node\" [mode]=\"'view'\"></ng-container>\n </div>\n </div>\n }\n </div>\n </axp-widgets-container>\n }\n </div>\n <div class=\"ax-flex ax-gap-2 ax-justify-end ax-sm\">\n <ax-button [color]=\"'primary'\" [look]=\"'solid'\" text=\"Open Details\" (click)=\"navigateToDetails()\"> </ax-button>\n </div>\n }\n </div>\n</ax-popover>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: AXPopoverModule }, { kind: "component", type: i2.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: i3$1.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i3$1.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged"], exportAs: ["widgetRenderer"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type:
|
|
394
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXPEntityDetailPopoverComponent, isStandalone: true, selector: "axp-entity-detail-popover", inputs: { entity: { classPropertyName: "entity", publicName: "entity", isSignal: true, isRequired: true, transformFunction: null }, entityId: { classPropertyName: "entityId", publicName: "entityId", isSignal: true, isRequired: true, transformFunction: null }, textField: { classPropertyName: "textField", publicName: "textField", isSignal: true, isRequired: false, transformFunction: null }, valueField: { classPropertyName: "valueField", publicName: "valueField", isSignal: true, isRequired: false, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "detailPopover", first: true, predicate: ["detailPopover"], descendants: true, isSignal: true }], ngImport: i0, template: "<ax-popover [openOn]=\"'manual'\" #detailPopover (openChange)=\"onDetailPopoverOpenChange($event)\">\n <div class=\"ax-lightest-surface ax-border ax-rounded-lg ax-shadow-lg ax-p-4 ax-min-w-[400px]\">\n <div class=\"ax-mb-4 ax-border-b ax-pb-2\">\n <h3 class=\"ax-text-base ax-font-semibold ax-text-on-lightest-surface\">\n @if (entityDetails()?.entityData?.[textField()]) {\n {{ entityDetails()?.entityData[textField()] }}\n } @else {\n {{ item()?.[textField()] }}\n }\n </h3>\n </div>\n @if (isLoadingDetails()) {\n <div class=\"ax-flex ax-items-center ax-justify-center ax-py-8\">\n <ax-loading>Loading details...</ax-loading>\n </div>\n } @else if (entityDetails()) {\n <div class=\"ax-space-y-3 ax-mb-4\">\n <!-- Important Entity Data -->\n @if (entityDetails()?.entityData) {\n <axp-widgets-container [context]=\"entityDetails()?.entityData\">\n <div class=\"ax-space-y-2\">\n @for (item of getEntityPropertiesWithWidgets(); track item.name) {\n <div class=\"ax-flex ax-justify-between ax-items-center\">\n <span class=\"ax-text-sm ax-font-medium\">{{ item.title | translate | async }}:</span>\n <div class=\"ax-flex-1 ax-ml-2 ax-max-w-48\">\n <ng-container axp-widget-renderer [node]=\"item.node\" [mode]=\"'view'\"></ng-container>\n </div>\n </div>\n }\n </div>\n </axp-widgets-container>\n }\n </div>\n <div class=\"ax-flex ax-gap-2 ax-justify-end ax-sm\">\n <ax-button [color]=\"'primary'\" [look]=\"'solid'\" text=\"Open Details\" (click)=\"navigateToDetails()\"> </ax-button>\n </div>\n }\n </div>\n</ax-popover>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: AXPopoverModule }, { kind: "component", type: i2.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: i3$1.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i3$1.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged"], exportAs: ["widgetRenderer"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i1.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
395
395
|
}
|
|
396
396
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPEntityDetailPopoverComponent, decorators: [{
|
|
397
397
|
type: Component,
|
|
@@ -3222,6 +3222,16 @@ class AXPPageDetailsConverter extends AXPBaseRelatedEntityConverter {
|
|
|
3222
3222
|
async convert(relatedEntity, context) {
|
|
3223
3223
|
const { entityDef } = await this.getEntityDefinition(relatedEntity, context.entityResolver);
|
|
3224
3224
|
const baseHelpers = this.createEntityHelpers(entityDef);
|
|
3225
|
+
// Get update interface to determine editable properties
|
|
3226
|
+
const updateInterface = entityDef?.interfaces?.master?.update;
|
|
3227
|
+
const editablePropertyNames = new Set(updateInterface?.properties?.map((p) => p.name) ?? []);
|
|
3228
|
+
// Check if page should be readonly (no editable properties or all editable properties are readonly)
|
|
3229
|
+
const isPageReadonly = editablePropertyNames.size === 0 ||
|
|
3230
|
+
(editablePropertyNames.size > 0 &&
|
|
3231
|
+
[...editablePropertyNames].every((propName) => {
|
|
3232
|
+
const prop = entityDef?.properties?.find((p) => p.name === propName);
|
|
3233
|
+
return prop?.schema?.readonly === true;
|
|
3234
|
+
}));
|
|
3225
3235
|
// If referenced strategy with mapping and detail type, exclude mapped properties from UI
|
|
3226
3236
|
const p = relatedEntity?.persistence || {};
|
|
3227
3237
|
const strategy = p.strategy || 'embedded';
|
|
@@ -3258,6 +3268,7 @@ class AXPPageDetailsConverter extends AXPBaseRelatedEntityConverter {
|
|
|
3258
3268
|
title: `${context.rootTitle}`,
|
|
3259
3269
|
label: relatedEntity.title ?? entityDef?.formats.displayName ?? '',
|
|
3260
3270
|
icon: relatedEntity.icon || entityDef.icon,
|
|
3271
|
+
isReadonly: isPageReadonly,
|
|
3261
3272
|
settings: this.createPageSettings(),
|
|
3262
3273
|
load: this.createLoadFunction(entityDef, relatedEntity, evaluateExpressions),
|
|
3263
3274
|
execute: this.createExecuteFunction(entityDef, actions, evaluateExpressions, context),
|
|
@@ -3962,6 +3973,13 @@ class AXPMainEntityContentBuilder {
|
|
|
3962
3973
|
});
|
|
3963
3974
|
const afterSections = sortRelatedSections(afterExtraSections);
|
|
3964
3975
|
const combinedSections = [...beforeSections, ...middleBlock, ...afterSections];
|
|
3976
|
+
// Check if page should be readonly (no editable properties or all editable properties are readonly)
|
|
3977
|
+
const isPageReadonly = editablePropertyNames.size === 0 ||
|
|
3978
|
+
(editablePropertyNames.size > 0 &&
|
|
3979
|
+
[...editablePropertyNames].every((propName) => {
|
|
3980
|
+
const prop = entity?.properties?.find((p) => p.name === propName);
|
|
3981
|
+
return prop?.schema?.readonly === true;
|
|
3982
|
+
}));
|
|
3965
3983
|
// Debug: Log final sorted sections for verification
|
|
3966
3984
|
try {
|
|
3967
3985
|
const beforeEntityOrderMap = new Map(beforeExtraSections.map((e) => [e.section?.id, e.entityOrder ?? Number.MAX_SAFE_INTEGER]));
|
|
@@ -4014,6 +4032,7 @@ class AXPMainEntityContentBuilder {
|
|
|
4014
4032
|
icon: entity?.icon,
|
|
4015
4033
|
actions: await this.buildEvaluatedActions(actions, evaluateExpressions),
|
|
4016
4034
|
isPrimary: true,
|
|
4035
|
+
isReadonly: isPageReadonly,
|
|
4017
4036
|
settings: {
|
|
4018
4037
|
commands: {
|
|
4019
4038
|
reject: {
|
|
@@ -4468,7 +4487,7 @@ class AXPLayoutAdapterFactory {
|
|
|
4468
4487
|
const title = await dependencies.expressionEvaluator.evaluate(entity.interfaces?.master?.single?.title, rootContext);
|
|
4469
4488
|
return title;
|
|
4470
4489
|
}
|
|
4471
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPLayoutAdapterFactory, deps: [{ token: AXPRelatedEntityConverterFactory }, { token: AXPMainEntityContentBuilder }, { token: AXPLayoutAdapterBuilder }, { token: i4
|
|
4490
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPLayoutAdapterFactory, deps: [{ token: AXPRelatedEntityConverterFactory }, { token: AXPMainEntityContentBuilder }, { token: AXPLayoutAdapterBuilder }, { token: i4.AXPFilterOperatorMiddlewareService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
4472
4491
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPLayoutAdapterFactory, providedIn: 'root' }); }
|
|
4473
4492
|
}
|
|
4474
4493
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPLayoutAdapterFactory, decorators: [{
|
|
@@ -4476,7 +4495,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
4476
4495
|
args: [{
|
|
4477
4496
|
providedIn: 'root',
|
|
4478
4497
|
}]
|
|
4479
|
-
}], ctorParameters: () => [{ type: AXPRelatedEntityConverterFactory }, { type: AXPMainEntityContentBuilder }, { type: AXPLayoutAdapterBuilder }, { type: i4
|
|
4498
|
+
}], ctorParameters: () => [{ type: AXPRelatedEntityConverterFactory }, { type: AXPMainEntityContentBuilder }, { type: AXPLayoutAdapterBuilder }, { type: i4.AXPFilterOperatorMiddlewareService }] });
|
|
4480
4499
|
|
|
4481
4500
|
const AXPLayoutDetailsViewRouteResolver = async (route, state, entityResolver = inject(AXPEntityDefinitionRegistryService), expressionEvaluator = inject(AXPExpressionEvaluatorService), session = inject(AXPSessionService), formatService = inject(AXFormatService), workflowService = inject(AXPWorkflowService), commandService = inject(AXPCommandService), layoutAdapterFactory = inject(AXPLayoutAdapterFactory)) => {
|
|
4482
4501
|
const moduleName = route.parent?.paramMap.get('module');
|
|
@@ -4961,25 +4980,25 @@ class AXPCategoryTreeService {
|
|
|
4961
4980
|
const allItemsLabel = await this.translate.translateAsync('@general:terms.interface.selection.all-items');
|
|
4962
4981
|
const rootNode = {
|
|
4963
4982
|
id: 'all',
|
|
4964
|
-
|
|
4983
|
+
title: allItemsLabel,
|
|
4965
4984
|
icon: 'fa-solid fa-folder',
|
|
4966
4985
|
childrenCount: items.length,
|
|
4967
4986
|
expanded: true,
|
|
4968
4987
|
data: { [valueField]: 'all', [textField]: allItemsLabel },
|
|
4969
4988
|
};
|
|
4970
4989
|
const childNodes = items.map((item) => this.convertToTreeNode(item, config));
|
|
4971
|
-
rootNode
|
|
4990
|
+
rootNode['children'] = childNodes;
|
|
4972
4991
|
return rootNode;
|
|
4973
4992
|
}
|
|
4974
4993
|
/**
|
|
4975
|
-
* Convert entity item to
|
|
4994
|
+
* Convert entity item to AXTreeViewNode format
|
|
4976
4995
|
*/
|
|
4977
4996
|
convertToTreeNode(item, config) {
|
|
4978
4997
|
const textField = config.textField ?? 'title';
|
|
4979
4998
|
const valueField = config.valueField ?? 'id';
|
|
4980
4999
|
return {
|
|
4981
5000
|
id: String(item[valueField] ?? ''),
|
|
4982
|
-
|
|
5001
|
+
title: String(item[textField] ?? ''),
|
|
4983
5002
|
icon: 'fa-solid fa-folder',
|
|
4984
5003
|
childrenCount: item['childrenCount'] || item['children']?.length || 0,
|
|
4985
5004
|
expanded: false,
|
|
@@ -5014,7 +5033,7 @@ class AXPCategoryTreeService {
|
|
|
5014
5033
|
...treeData.basicQueryEvent,
|
|
5015
5034
|
filter: {
|
|
5016
5035
|
field: treeData.categoryEntityDef.parentKey,
|
|
5017
|
-
value: node
|
|
5036
|
+
value: node['id'],
|
|
5018
5037
|
operator: { type: 'equal' },
|
|
5019
5038
|
},
|
|
5020
5039
|
};
|
|
@@ -5076,11 +5095,12 @@ class AXPCategoryTreeService {
|
|
|
5076
5095
|
*/
|
|
5077
5096
|
updateChildrenAtPath(nodes, targetId, childNodes) {
|
|
5078
5097
|
return nodes.map((node) => {
|
|
5079
|
-
if (node
|
|
5080
|
-
return { ...node, children: childNodes, childrenCount: childNodes.length };
|
|
5098
|
+
if (node['id'] === targetId) {
|
|
5099
|
+
return { ...node, ['children']: childNodes, childrenCount: childNodes.length };
|
|
5081
5100
|
}
|
|
5082
|
-
|
|
5083
|
-
|
|
5101
|
+
const nodeChildren = node['children'];
|
|
5102
|
+
if (nodeChildren?.length) {
|
|
5103
|
+
return { ...node, ['children']: this.updateChildrenAtPath(nodeChildren, targetId, childNodes) };
|
|
5084
5104
|
}
|
|
5085
5105
|
return node;
|
|
5086
5106
|
});
|
|
@@ -5106,8 +5126,10 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
|
|
|
5106
5126
|
this.textField = signal('title', ...(ngDevMode ? [{ debugName: "textField" }] : []));
|
|
5107
5127
|
this.valueField = signal('id', ...(ngDevMode ? [{ debugName: "valueField" }] : []));
|
|
5108
5128
|
this.allowMultiple = signal(false, ...(ngDevMode ? [{ debugName: "allowMultiple" }] : []));
|
|
5129
|
+
this.selectionBehavior = signal('leaf', ...(ngDevMode ? [{ debugName: "selectionBehavior" }] : []));
|
|
5109
5130
|
this.selectedValues = signal([], ...(ngDevMode ? [{ debugName: "selectedValues" }] : []));
|
|
5110
5131
|
this.searchPlaceholder = signal('@general:terms.interface.category.search.placeholder', ...(ngDevMode ? [{ debugName: "searchPlaceholder" }] : []));
|
|
5132
|
+
this.excludedNodeId = signal(undefined, ...(ngDevMode ? [{ debugName: "excludedNodeId" }] : [])); // Node ID to disable
|
|
5111
5133
|
//#endregion
|
|
5112
5134
|
//#region ---- View Queries ----
|
|
5113
5135
|
this.tree = viewChild('tree', ...(ngDevMode ? [{ debugName: "tree" }] : []));
|
|
@@ -5115,6 +5137,7 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
|
|
|
5115
5137
|
//#region ---- Component State ----
|
|
5116
5138
|
this.loading = signal(true, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
5117
5139
|
this.selectedNodeIds = signal([], ...(ngDevMode ? [{ debugName: "selectedNodeIds" }] : []));
|
|
5140
|
+
this.searchValue = signal('', ...(ngDevMode ? [{ debugName: "searchValue" }] : []));
|
|
5118
5141
|
//#endregion
|
|
5119
5142
|
//#region ---- Private Properties ----
|
|
5120
5143
|
this.treeData = null;
|
|
@@ -5129,10 +5152,31 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
|
|
|
5129
5152
|
// If no id provided, return root nodes (or search results if available)
|
|
5130
5153
|
if (!id) {
|
|
5131
5154
|
// If we have search results, use them
|
|
5132
|
-
if (this.searchResults) {
|
|
5155
|
+
if (this.searchResults && this.searchResults.length > 0) {
|
|
5133
5156
|
const rootNode = await this.categoryTreeService.createRootNode(this.searchResults, this.treeConfig);
|
|
5157
|
+
// Mark excluded node as disabled in root node structure
|
|
5158
|
+
const excludedId = this.excludedNodeId();
|
|
5159
|
+
if (excludedId) {
|
|
5160
|
+
this.markNodeAsDisabled(rootNode, excludedId);
|
|
5161
|
+
}
|
|
5162
|
+
// Mark pre-selected nodes as selected in search results
|
|
5163
|
+
this.markNodesAsSelected(rootNode);
|
|
5164
|
+
// After tree loads, programmatically select pre-selected nodes
|
|
5165
|
+
const treeComponent = this.tree();
|
|
5166
|
+
if (treeComponent) {
|
|
5167
|
+
const selectedIds = this.selectedNodeIds();
|
|
5168
|
+
selectedIds.forEach((selectedId) => {
|
|
5169
|
+
if (selectedId && selectedId !== 'all') {
|
|
5170
|
+
treeComponent.selectNode(selectedId);
|
|
5171
|
+
}
|
|
5172
|
+
});
|
|
5173
|
+
}
|
|
5134
5174
|
return [rootNode];
|
|
5135
5175
|
}
|
|
5176
|
+
// If search was performed but returned no results, return empty array
|
|
5177
|
+
if (this.searchResults !== null && this.searchResults.length === 0) {
|
|
5178
|
+
return [];
|
|
5179
|
+
}
|
|
5136
5180
|
// Otherwise load root categories
|
|
5137
5181
|
const items = await this.categoryTreeService.loadRootCategories(this.treeData, this.treeConfig);
|
|
5138
5182
|
if (!items) {
|
|
@@ -5140,27 +5184,71 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
|
|
|
5140
5184
|
}
|
|
5141
5185
|
// Cache node data for getSelectedItems
|
|
5142
5186
|
items.forEach((item) => {
|
|
5143
|
-
const itemId = item[this.treeConfig.valueField || 'id'];
|
|
5144
|
-
if (itemId) {
|
|
5187
|
+
const itemId = String(item[this.treeConfig.valueField || 'id'] ?? '');
|
|
5188
|
+
if (itemId && typeof item === 'object' && item !== null) {
|
|
5145
5189
|
this.nodeDataCache.set(itemId, item);
|
|
5146
5190
|
}
|
|
5147
5191
|
});
|
|
5148
5192
|
const rootNode = await this.categoryTreeService.createRootNode(items, this.treeConfig);
|
|
5193
|
+
// Mark excluded node as disabled in root node structure
|
|
5194
|
+
const excludedId = this.excludedNodeId();
|
|
5195
|
+
if (excludedId) {
|
|
5196
|
+
this.markNodeAsDisabled(rootNode, excludedId);
|
|
5197
|
+
}
|
|
5198
|
+
// Mark pre-selected nodes as selected in the root node structure
|
|
5199
|
+
this.markNodesAsSelected(rootNode);
|
|
5200
|
+
// After tree loads, programmatically select pre-selected nodes
|
|
5201
|
+
const treeComponent = this.tree();
|
|
5202
|
+
if (treeComponent) {
|
|
5203
|
+
const selectedIds = this.selectedNodeIds();
|
|
5204
|
+
selectedIds.forEach((id) => {
|
|
5205
|
+
if (id && id !== 'all') {
|
|
5206
|
+
treeComponent.selectNode(id);
|
|
5207
|
+
}
|
|
5208
|
+
});
|
|
5209
|
+
}
|
|
5149
5210
|
return [rootNode];
|
|
5150
5211
|
}
|
|
5151
5212
|
// Create a minimal node object with just the id (loadChildren only needs node.id)
|
|
5152
5213
|
const targetNode = {
|
|
5153
5214
|
id,
|
|
5154
|
-
|
|
5215
|
+
title: '',
|
|
5155
5216
|
data: {},
|
|
5156
5217
|
};
|
|
5157
5218
|
const childNodes = await this.categoryTreeService.loadChildren(targetNode, this.treeData, this.treeConfig);
|
|
5158
5219
|
// Cache child node data for getSelectedItems
|
|
5159
5220
|
childNodes.forEach((node) => {
|
|
5160
|
-
|
|
5161
|
-
|
|
5221
|
+
const nodeId = String(node['id'] ?? '');
|
|
5222
|
+
const nodeData = node['data'];
|
|
5223
|
+
if (nodeData && nodeId && typeof nodeData === 'object') {
|
|
5224
|
+
this.nodeDataCache.set(nodeId, nodeData);
|
|
5162
5225
|
}
|
|
5163
5226
|
});
|
|
5227
|
+
// Mark excluded node as disabled
|
|
5228
|
+
const excludedId = this.excludedNodeId();
|
|
5229
|
+
if (excludedId) {
|
|
5230
|
+
childNodes.forEach((node) => {
|
|
5231
|
+
const nodeId = String(node['id'] ?? '');
|
|
5232
|
+
if (nodeId === excludedId) {
|
|
5233
|
+
node['disabled'] = true;
|
|
5234
|
+
}
|
|
5235
|
+
});
|
|
5236
|
+
}
|
|
5237
|
+
// Mark pre-selected nodes as selected in the child nodes
|
|
5238
|
+
childNodes.forEach((node) => {
|
|
5239
|
+
this.markNodeAsSelectedIfNeeded(node);
|
|
5240
|
+
});
|
|
5241
|
+
// After children load, programmatically select pre-selected nodes
|
|
5242
|
+
const treeComponent = this.tree();
|
|
5243
|
+
if (treeComponent) {
|
|
5244
|
+
const selectedIds = this.selectedNodeIds();
|
|
5245
|
+
childNodes.forEach((node) => {
|
|
5246
|
+
const nodeId = String(node['id'] ?? '');
|
|
5247
|
+
if (nodeId && selectedIds.includes(nodeId) && nodeId !== 'all') {
|
|
5248
|
+
treeComponent.selectNode(nodeId);
|
|
5249
|
+
}
|
|
5250
|
+
});
|
|
5251
|
+
}
|
|
5164
5252
|
return childNodes;
|
|
5165
5253
|
};
|
|
5166
5254
|
}
|
|
@@ -5205,94 +5293,125 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
|
|
|
5205
5293
|
}
|
|
5206
5294
|
//#endregion
|
|
5207
5295
|
//#region ---- Public Methods ----
|
|
5208
|
-
|
|
5296
|
+
/**
|
|
5297
|
+
* Handles search input value changes
|
|
5298
|
+
*/
|
|
5299
|
+
async handleSearchChange(event) {
|
|
5209
5300
|
if (!this.treeData || !this.treeConfig) {
|
|
5210
5301
|
return;
|
|
5211
5302
|
}
|
|
5303
|
+
// Only process user interactions to avoid unnecessary updates
|
|
5304
|
+
if (!event.isUserInteraction) {
|
|
5305
|
+
return;
|
|
5306
|
+
}
|
|
5307
|
+
const searchTerm = (event.value ?? '').trim();
|
|
5308
|
+
this.searchValue.set(searchTerm);
|
|
5309
|
+
// If search is cleared, reset to normal tree view
|
|
5310
|
+
if (!searchTerm) {
|
|
5311
|
+
this.resetSearch();
|
|
5312
|
+
return;
|
|
5313
|
+
}
|
|
5212
5314
|
this.loading.set(true);
|
|
5213
5315
|
try {
|
|
5214
|
-
const items = await this.categoryTreeService.searchCategories(
|
|
5215
|
-
if
|
|
5216
|
-
|
|
5217
|
-
return;
|
|
5218
|
-
}
|
|
5219
|
-
// Store search results for datasource callback
|
|
5220
|
-
this.searchResults = items;
|
|
5316
|
+
const items = await this.categoryTreeService.searchCategories(searchTerm, this.treeData, this.treeConfig);
|
|
5317
|
+
// Store search results for datasource callback (even if empty array)
|
|
5318
|
+
this.searchResults = items || null;
|
|
5221
5319
|
// Cache node data for getSelectedItems
|
|
5222
|
-
items.
|
|
5223
|
-
const
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5320
|
+
if (items && items.length > 0) {
|
|
5321
|
+
const valueField = this.treeConfig.valueField || 'id';
|
|
5322
|
+
items.forEach((item) => {
|
|
5323
|
+
const id = String(item[valueField] ?? '');
|
|
5324
|
+
if (id) {
|
|
5325
|
+
this.nodeDataCache.set(id, item);
|
|
5326
|
+
}
|
|
5327
|
+
});
|
|
5328
|
+
}
|
|
5228
5329
|
// Trigger tree refresh
|
|
5229
5330
|
const treeComponent = this.tree();
|
|
5230
5331
|
if (treeComponent) {
|
|
5231
|
-
treeComponent.refresh
|
|
5332
|
+
treeComponent.refresh();
|
|
5232
5333
|
}
|
|
5233
5334
|
}
|
|
5234
5335
|
catch (error) {
|
|
5235
5336
|
console.error('Error searching categories:', error);
|
|
5337
|
+
this.resetSearch();
|
|
5236
5338
|
}
|
|
5237
5339
|
finally {
|
|
5238
5340
|
this.loading.set(false);
|
|
5239
5341
|
}
|
|
5240
5342
|
}
|
|
5343
|
+
/**
|
|
5344
|
+
* Resets search state and refreshes tree to show normal view
|
|
5345
|
+
*/
|
|
5346
|
+
resetSearch() {
|
|
5347
|
+
this.searchResults = null;
|
|
5348
|
+
this.loading.set(false);
|
|
5349
|
+
const treeComponent = this.tree();
|
|
5350
|
+
if (treeComponent) {
|
|
5351
|
+
treeComponent.refresh();
|
|
5352
|
+
}
|
|
5353
|
+
}
|
|
5241
5354
|
async onNodeToggle(event) {
|
|
5242
5355
|
// Tree component handles lazy loading via datasource callback
|
|
5243
5356
|
}
|
|
5244
5357
|
async onNodeSelect(event) {
|
|
5245
5358
|
const node = event.node;
|
|
5246
|
-
|
|
5247
|
-
|
|
5248
|
-
}
|
|
5249
|
-
// Cache node data for getSelectedItems
|
|
5250
|
-
if (node.data) {
|
|
5251
|
-
this.nodeDataCache.set(node.id, node.data);
|
|
5252
|
-
}
|
|
5253
|
-
const currentIds = this.selectedNodeIds();
|
|
5254
|
-
if (node.selected) {
|
|
5255
|
-
// Add to selection if not already selected
|
|
5256
|
-
if (!currentIds.includes(node.id)) {
|
|
5257
|
-
this.selectedNodeIds.set([...currentIds, node.id]);
|
|
5258
|
-
}
|
|
5259
|
-
}
|
|
5260
|
-
else {
|
|
5261
|
-
// Remove from selection
|
|
5262
|
-
this.selectedNodeIds.set(currentIds.filter((id) => id !== node.id));
|
|
5263
|
-
}
|
|
5264
|
-
}
|
|
5265
|
-
handleNodeClick(event) {
|
|
5266
|
-
// Extract node from event - could be { node: AXTreeNode } or just AXTreeNode
|
|
5267
|
-
const node = event?.node || event;
|
|
5268
|
-
if (!node || node.id === 'all') {
|
|
5359
|
+
const nodeId = String(node['id'] ?? '');
|
|
5360
|
+
if (!node || nodeId === 'all') {
|
|
5269
5361
|
return;
|
|
5270
5362
|
}
|
|
5271
5363
|
// Cache node data for getSelectedItems
|
|
5272
|
-
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
|
|
5285
|
-
|
|
5364
|
+
const nodeData = node['data'];
|
|
5365
|
+
if (nodeData && typeof nodeData === 'object' && nodeData !== null && !Array.isArray(nodeData)) {
|
|
5366
|
+
this.nodeDataCache.set(nodeId, nodeData);
|
|
5367
|
+
}
|
|
5368
|
+
}
|
|
5369
|
+
async onSelectionChange(event) {
|
|
5370
|
+
// Update selected node IDs from the tree component's selection state
|
|
5371
|
+
const selectedNodes = event.selectedNodes || [];
|
|
5372
|
+
const selectedIds = selectedNodes.map((node) => String(node['id'] ?? '')).filter((id) => id && id !== 'all');
|
|
5373
|
+
this.selectedNodeIds.set(selectedIds);
|
|
5374
|
+
// Cache node data for all selected nodes
|
|
5375
|
+
selectedNodes.forEach((node) => {
|
|
5376
|
+
const nodeId = String(node['id'] ?? '');
|
|
5377
|
+
const nodeData = node['data'];
|
|
5378
|
+
if (nodeData && nodeId && typeof nodeData === 'object') {
|
|
5379
|
+
this.nodeDataCache.set(nodeId, nodeData);
|
|
5286
5380
|
}
|
|
5287
|
-
}
|
|
5288
|
-
else {
|
|
5289
|
-
// Single selection - auto-confirm on click
|
|
5290
|
-
this.selectedNodeIds.set([node.id]);
|
|
5291
|
-
this.close({ selected: this.getSelectedItems() });
|
|
5292
|
-
}
|
|
5381
|
+
});
|
|
5293
5382
|
}
|
|
5383
|
+
// protected handleNodeClick(event: any): void {
|
|
5384
|
+
// // Extract node from event - could be { node: AXTreeNode } or just AXTreeNode
|
|
5385
|
+
// const node: AXTreeViewNode = event?.node || event;
|
|
5386
|
+
// if (!node || node.id === 'all') {
|
|
5387
|
+
// return;
|
|
5388
|
+
// }
|
|
5389
|
+
// // Cache node data for getSelectedItems
|
|
5390
|
+
// if (node.data) {
|
|
5391
|
+
// this.nodeDataCache.set(node.id, node.data);
|
|
5392
|
+
// }
|
|
5393
|
+
// if (this.allowMultiple()) {
|
|
5394
|
+
// // In multiple mode with checkboxes, clicking the node should toggle the checkbox
|
|
5395
|
+
// // The checkbox state is handled by onNodeSelect event, so we just sync the selection here
|
|
5396
|
+
// const currentIds = this.selectedNodeIds();
|
|
5397
|
+
// const isSelected = currentIds.includes(node.id);
|
|
5398
|
+
// // Toggle selection state
|
|
5399
|
+
// // Note: The actual checkbox toggle is handled by the tree component's onNodeSelect event
|
|
5400
|
+
// if (isSelected) {
|
|
5401
|
+
// this.selectedNodeIds.set(currentIds.filter((id) => id !== node.id));
|
|
5402
|
+
// } else {
|
|
5403
|
+
// this.selectedNodeIds.set([...currentIds, node.id]);
|
|
5404
|
+
// }
|
|
5405
|
+
// } else {
|
|
5406
|
+
// // Single selection - auto-confirm on click
|
|
5407
|
+
// this.selectedNodeIds.set([node.id]);
|
|
5408
|
+
// this.close({ selected: this.getSelectedItems() });
|
|
5409
|
+
// }
|
|
5410
|
+
// }
|
|
5294
5411
|
async onConfirm() {
|
|
5295
|
-
|
|
5412
|
+
// Use internal selectedNodeIds state which is kept in sync via onNodeSelect events
|
|
5413
|
+
const selectedItems = await this.getSelectedItems();
|
|
5414
|
+
this.close({ selected: selectedItems });
|
|
5296
5415
|
}
|
|
5297
5416
|
async onCancel() {
|
|
5298
5417
|
await this.close();
|
|
@@ -5308,9 +5427,9 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
|
|
|
5308
5427
|
// Fetch node data for pre-selected items that aren't in the cache
|
|
5309
5428
|
// This ensures getSelectedItems() can retrieve them even if their branches aren't expanded
|
|
5310
5429
|
await this.loadMissingNodeData(ids);
|
|
5311
|
-
// Note: Selection
|
|
5312
|
-
// The tree component
|
|
5313
|
-
//
|
|
5430
|
+
// Note: Selection state is maintained in selectedNodeIds signal
|
|
5431
|
+
// The tree component will sync selection state when nodes are loaded via datasource
|
|
5432
|
+
// We mark nodes as selected in the datasource callback by setting node.selected = true
|
|
5314
5433
|
}
|
|
5315
5434
|
/**
|
|
5316
5435
|
* Loads node data for IDs that are selected but not yet in the cache.
|
|
@@ -5347,7 +5466,7 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
|
|
|
5347
5466
|
if (res?.items) {
|
|
5348
5467
|
// Cache the fetched node data
|
|
5349
5468
|
res.items.forEach((item) => {
|
|
5350
|
-
const itemId = item[valueField];
|
|
5469
|
+
const itemId = String(item[valueField] ?? '');
|
|
5351
5470
|
if (itemId) {
|
|
5352
5471
|
this.nodeDataCache.set(itemId, item);
|
|
5353
5472
|
}
|
|
@@ -5358,13 +5477,170 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
|
|
|
5358
5477
|
console.error('Error loading missing node data:', error);
|
|
5359
5478
|
}
|
|
5360
5479
|
}
|
|
5361
|
-
|
|
5480
|
+
/**
|
|
5481
|
+
* Marks nodes as selected in the tree structure based on selectedNodeIds.
|
|
5482
|
+
* This ensures pre-selected nodes appear selected when the tree is rendered.
|
|
5483
|
+
*/
|
|
5484
|
+
markNodesAsSelected(node) {
|
|
5485
|
+
const selectedIds = this.selectedNodeIds();
|
|
5486
|
+
if (selectedIds.length === 0) {
|
|
5487
|
+
return;
|
|
5488
|
+
}
|
|
5489
|
+
// Mark the node itself if it's selected
|
|
5490
|
+
this.markNodeAsSelectedIfNeeded(node);
|
|
5491
|
+
// Recursively mark children
|
|
5492
|
+
const nodeChildren = node['children'];
|
|
5493
|
+
if (nodeChildren) {
|
|
5494
|
+
nodeChildren.forEach((child) => {
|
|
5495
|
+
this.markNodesAsSelected(child);
|
|
5496
|
+
});
|
|
5497
|
+
}
|
|
5498
|
+
}
|
|
5499
|
+
/**
|
|
5500
|
+
* Marks a single node as selected if it's in the selectedNodeIds list.
|
|
5501
|
+
*/
|
|
5502
|
+
markNodeAsSelectedIfNeeded(node) {
|
|
5503
|
+
const selectedIds = this.selectedNodeIds();
|
|
5504
|
+
const nodeId = String(node['id'] ?? '');
|
|
5505
|
+
if (nodeId && selectedIds.includes(nodeId)) {
|
|
5506
|
+
node['selected'] = true;
|
|
5507
|
+
}
|
|
5508
|
+
}
|
|
5509
|
+
/**
|
|
5510
|
+
* Marks a node and its children as disabled if the node ID matches the excluded ID.
|
|
5511
|
+
*/
|
|
5512
|
+
markNodeAsDisabled(node, excludedId) {
|
|
5513
|
+
const nodeId = String(node['id'] ?? '');
|
|
5514
|
+
if (nodeId === excludedId) {
|
|
5515
|
+
node['disabled'] = true;
|
|
5516
|
+
}
|
|
5517
|
+
// Recursively mark children
|
|
5518
|
+
const nodeChildren = node['children'];
|
|
5519
|
+
if (nodeChildren) {
|
|
5520
|
+
nodeChildren.forEach((child) => {
|
|
5521
|
+
this.markNodeAsDisabled(child, excludedId);
|
|
5522
|
+
});
|
|
5523
|
+
}
|
|
5524
|
+
}
|
|
5525
|
+
/**
|
|
5526
|
+
* Calculate the full path from root to the selected node.
|
|
5527
|
+
* Returns an array of strings like ["C", "B"] for node B under parent C.
|
|
5528
|
+
*/
|
|
5529
|
+
async calculateNodePath(nodeId, nodeData) {
|
|
5530
|
+
if (!this.treeData || !this.treeConfig) {
|
|
5531
|
+
const title = this.getNodeTitle(nodeData);
|
|
5532
|
+
return title ? [title] : [];
|
|
5533
|
+
}
|
|
5534
|
+
const parentKey = this.treeData.categoryEntityDef?.parentKey;
|
|
5535
|
+
if (!parentKey) {
|
|
5536
|
+
// No parent key means flat structure, return just the node title as array
|
|
5537
|
+
const title = this.getNodeTitle(nodeData);
|
|
5538
|
+
return title ? [title] : [];
|
|
5539
|
+
}
|
|
5540
|
+
const path = [];
|
|
5541
|
+
let currentId = nodeId;
|
|
5542
|
+
let currentData = nodeData;
|
|
5543
|
+
const visitedIds = new Set(); // Prevent infinite loops
|
|
5544
|
+
// Build path by traversing up the parent chain
|
|
5545
|
+
while (currentId && currentData && !visitedIds.has(currentId)) {
|
|
5546
|
+
visitedIds.add(currentId);
|
|
5547
|
+
const title = this.getNodeTitle(currentData);
|
|
5548
|
+
if (title) {
|
|
5549
|
+
path.unshift(title); // Add to beginning to maintain hierarchy order
|
|
5550
|
+
}
|
|
5551
|
+
// Get parent ID from current node data
|
|
5552
|
+
const parentId = currentData[parentKey];
|
|
5553
|
+
if (!parentId || parentId === 'all' || parentId === currentId) {
|
|
5554
|
+
break; // Reached root or invalid parent
|
|
5555
|
+
}
|
|
5556
|
+
// Try to get parent data from cache first
|
|
5557
|
+
let parentData = this.nodeDataCache.get(String(parentId));
|
|
5558
|
+
if (!parentData && this.treeData.categoryEntityQueryFunc) {
|
|
5559
|
+
// Parent not in cache, fetch it
|
|
5560
|
+
try {
|
|
5561
|
+
const valueField = this.treeConfig.valueField || 'id';
|
|
5562
|
+
const event = {
|
|
5563
|
+
...this.treeData.basicQueryEvent,
|
|
5564
|
+
filter: {
|
|
5565
|
+
field: valueField,
|
|
5566
|
+
value: parentId,
|
|
5567
|
+
operator: { type: 'equal' },
|
|
5568
|
+
},
|
|
5569
|
+
};
|
|
5570
|
+
const res = await this.treeData.categoryEntityQueryFunc(event);
|
|
5571
|
+
if (res?.items && res.items.length > 0) {
|
|
5572
|
+
parentData = res.items[0];
|
|
5573
|
+
// Cache the parent data
|
|
5574
|
+
this.nodeDataCache.set(String(parentId), parentData);
|
|
5575
|
+
}
|
|
5576
|
+
}
|
|
5577
|
+
catch (error) {
|
|
5578
|
+
console.error('Error fetching parent node:', error);
|
|
5579
|
+
break;
|
|
5580
|
+
}
|
|
5581
|
+
}
|
|
5582
|
+
if (!parentData) {
|
|
5583
|
+
break; // Parent not found, stop traversal
|
|
5584
|
+
}
|
|
5585
|
+
currentId = String(parentId);
|
|
5586
|
+
currentData = parentData;
|
|
5587
|
+
}
|
|
5588
|
+
// Return path array, or just the node title if no path
|
|
5589
|
+
return path.length > 0 ? path : this.getNodeTitle(nodeData) ? [this.getNodeTitle(nodeData)] : [];
|
|
5590
|
+
}
|
|
5591
|
+
/**
|
|
5592
|
+
* Get the display title for a node.
|
|
5593
|
+
*/
|
|
5594
|
+
getNodeTitle(nodeData) {
|
|
5595
|
+
if (!nodeData || !this.treeConfig) {
|
|
5596
|
+
return '';
|
|
5597
|
+
}
|
|
5598
|
+
const textField = this.treeConfig.textField || 'title';
|
|
5599
|
+
return String(nodeData[textField] ?? '');
|
|
5600
|
+
}
|
|
5601
|
+
async getSelectedItems() {
|
|
5602
|
+
// Use tree component's getSelectedNodes if available for more accurate selection
|
|
5603
|
+
const treeComponent = this.tree();
|
|
5604
|
+
if (treeComponent) {
|
|
5605
|
+
const selectedNodes = treeComponent.getSelectedNodes();
|
|
5606
|
+
const items = await Promise.all(selectedNodes.map(async (node) => {
|
|
5607
|
+
const nodeId = String(node['id'] ?? '');
|
|
5608
|
+
if (nodeId === 'all') {
|
|
5609
|
+
return null;
|
|
5610
|
+
}
|
|
5611
|
+
const nodeData = node['data'] || node;
|
|
5612
|
+
if (!nodeData) {
|
|
5613
|
+
return null;
|
|
5614
|
+
}
|
|
5615
|
+
// Calculate path for this node
|
|
5616
|
+
const path = await this.calculateNodePath(nodeId, nodeData);
|
|
5617
|
+
return {
|
|
5618
|
+
...nodeData,
|
|
5619
|
+
id: nodeId,
|
|
5620
|
+
path: path,
|
|
5621
|
+
};
|
|
5622
|
+
}));
|
|
5623
|
+
return items.filter((item) => item != null);
|
|
5624
|
+
}
|
|
5625
|
+
// Fallback to cached data
|
|
5362
5626
|
const selectedIds = this.selectedNodeIds();
|
|
5363
5627
|
if (selectedIds.length === 0) {
|
|
5364
5628
|
return [];
|
|
5365
5629
|
}
|
|
5366
|
-
// Get node data from cache
|
|
5367
|
-
|
|
5630
|
+
// Get node data from cache and calculate paths
|
|
5631
|
+
const items = await Promise.all(selectedIds.map(async (id) => {
|
|
5632
|
+
const nodeData = this.nodeDataCache.get(id);
|
|
5633
|
+
if (!nodeData) {
|
|
5634
|
+
return null;
|
|
5635
|
+
}
|
|
5636
|
+
const path = await this.calculateNodePath(id, nodeData);
|
|
5637
|
+
return {
|
|
5638
|
+
...nodeData,
|
|
5639
|
+
id: id,
|
|
5640
|
+
path: path,
|
|
5641
|
+
};
|
|
5642
|
+
}));
|
|
5643
|
+
return items.filter((item) => item != null);
|
|
5368
5644
|
}
|
|
5369
5645
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPEntityCategoryTreeSelectorComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
5370
5646
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXPEntityCategoryTreeSelectorComponent, isStandalone: true, selector: "axp-entity-category-tree-selector", viewQueries: [{ propertyName: "tree", first: true, predicate: ["tree"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
|
|
@@ -5380,6 +5656,7 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
|
|
|
5380
5656
|
<div class="ax-p-4 ax-border-b">
|
|
5381
5657
|
<ax-search-box
|
|
5382
5658
|
(onValueChanged)="handleSearchChange($event)"
|
|
5659
|
+
[value]="searchValue()"
|
|
5383
5660
|
[delayTime]="300"
|
|
5384
5661
|
[placeholder]="searchPlaceholder()"
|
|
5385
5662
|
></ax-search-box>
|
|
@@ -5387,11 +5664,15 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
|
|
|
5387
5664
|
<div class="ax-flex-1 ax-overflow-auto ax-p-4">
|
|
5388
5665
|
<ax-tree-view
|
|
5389
5666
|
[datasource]="datasource"
|
|
5390
|
-
[
|
|
5667
|
+
[dragBehavior]="'none'"
|
|
5668
|
+
[selectMode]="allowMultiple() ? 'multiple' : 'single'"
|
|
5669
|
+
[selectionBehavior]="selectionBehavior()"
|
|
5391
5670
|
[showIcons]="true"
|
|
5671
|
+
[titleField]="textField()"
|
|
5672
|
+
[idField]="valueField()"
|
|
5392
5673
|
(onNodeSelect)="onNodeSelect($event)"
|
|
5674
|
+
(onSelectionChange)="onSelectionChange($event)"
|
|
5393
5675
|
(onNodeToggle)="onNodeToggle($event)"
|
|
5394
|
-
(onNodeClick)="handleNodeClick($event)"
|
|
5395
5676
|
#tree
|
|
5396
5677
|
>
|
|
5397
5678
|
</ax-tree-view>
|
|
@@ -5403,24 +5684,22 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
|
|
|
5403
5684
|
</div>
|
|
5404
5685
|
}
|
|
5405
5686
|
</div>
|
|
5406
|
-
|
|
5407
|
-
<ax-
|
|
5408
|
-
<ax-
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
|
|
5414
|
-
|
|
5415
|
-
|
|
5416
|
-
|
|
5417
|
-
|
|
5418
|
-
|
|
5419
|
-
|
|
5420
|
-
|
|
5421
|
-
|
|
5422
|
-
}
|
|
5423
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: i3$2.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: AXSearchBoxModule }, { kind: "component", type: i3$3.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: AXSkeletonModule }, { kind: "component", type: i4$2.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "component", type: AXTreeViewComponent, selector: "ax-tree-view", inputs: ["datasource", "selectMode", "showCheckbox", "checkChildrenOnSelect", "intermediateState", "checkOnClick", "dragMode", "dragOperationType", "showIcons", "showChildrenBadge", "expandedIcon", "collapsedIcon", "indentSize", "nodeHeight", "look", "itemTemplate"], outputs: ["datasourceChange", "onBeforeDrop", "onNodeToggle", "onNodeSelect", "onOrderChange", "onMoveChange", "onItemsChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
5687
|
+
<ax-footer>
|
|
5688
|
+
<ax-suffix>
|
|
5689
|
+
<ax-button
|
|
5690
|
+
look="solid"
|
|
5691
|
+
[text]="'@general:actions.cancel.title' | translate | async"
|
|
5692
|
+
(onClick)="onCancel()"
|
|
5693
|
+
></ax-button>
|
|
5694
|
+
<ax-button
|
|
5695
|
+
look="solid"
|
|
5696
|
+
color="primary"
|
|
5697
|
+
[text]="'@general:actions.ok.title' | translate | async"
|
|
5698
|
+
(onClick)="onConfirm()"
|
|
5699
|
+
></ax-button>
|
|
5700
|
+
</ax-suffix>
|
|
5701
|
+
</ax-footer>
|
|
5702
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: i1$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: AXSearchBoxModule }, { kind: "component", type: i3$2.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: AXSkeletonModule }, { kind: "component", type: i4$1.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "component", type: AXTreeViewComponent, selector: "ax-tree-view", inputs: ["datasource", "selectMode", "showCheckbox", "selectionBehavior", "dragArea", "dragBehavior", "showIcons", "showChildrenBadge", "expandedIcon", "collapsedIcon", "indentSize", "look", "nodeTemplate", "idField", "titleField", "tooltipField", "iconField", "expandedField", "selectedField", "indeterminateField", "disabledField", "hiddenField", "childrenField", "childrenCountField", "dataField"], outputs: ["datasourceChange", "onBeforeDrop", "onNodeToggle", "onNodeSelect", "onSelectionChange", "onOrderChange", "onMoveChange", "onItemsChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
5424
5703
|
}
|
|
5425
5704
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPEntityCategoryTreeSelectorComponent, decorators: [{
|
|
5426
5705
|
type: Component,
|
|
@@ -5439,6 +5718,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
5439
5718
|
<div class="ax-p-4 ax-border-b">
|
|
5440
5719
|
<ax-search-box
|
|
5441
5720
|
(onValueChanged)="handleSearchChange($event)"
|
|
5721
|
+
[value]="searchValue()"
|
|
5442
5722
|
[delayTime]="300"
|
|
5443
5723
|
[placeholder]="searchPlaceholder()"
|
|
5444
5724
|
></ax-search-box>
|
|
@@ -5446,11 +5726,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
5446
5726
|
<div class="ax-flex-1 ax-overflow-auto ax-p-4">
|
|
5447
5727
|
<ax-tree-view
|
|
5448
5728
|
[datasource]="datasource"
|
|
5449
|
-
[
|
|
5729
|
+
[dragBehavior]="'none'"
|
|
5730
|
+
[selectMode]="allowMultiple() ? 'multiple' : 'single'"
|
|
5731
|
+
[selectionBehavior]="selectionBehavior()"
|
|
5450
5732
|
[showIcons]="true"
|
|
5733
|
+
[titleField]="textField()"
|
|
5734
|
+
[idField]="valueField()"
|
|
5451
5735
|
(onNodeSelect)="onNodeSelect($event)"
|
|
5736
|
+
(onSelectionChange)="onSelectionChange($event)"
|
|
5452
5737
|
(onNodeToggle)="onNodeToggle($event)"
|
|
5453
|
-
(onNodeClick)="handleNodeClick($event)"
|
|
5454
5738
|
#tree
|
|
5455
5739
|
>
|
|
5456
5740
|
</ax-tree-view>
|
|
@@ -5462,23 +5746,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
5462
5746
|
</div>
|
|
5463
5747
|
}
|
|
5464
5748
|
</div>
|
|
5465
|
-
|
|
5466
|
-
<ax-
|
|
5467
|
-
<ax-
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
5477
|
-
|
|
5478
|
-
|
|
5479
|
-
|
|
5480
|
-
</ax-footer>
|
|
5481
|
-
}
|
|
5749
|
+
<ax-footer>
|
|
5750
|
+
<ax-suffix>
|
|
5751
|
+
<ax-button
|
|
5752
|
+
look="solid"
|
|
5753
|
+
[text]="'@general:actions.cancel.title' | translate | async"
|
|
5754
|
+
(onClick)="onCancel()"
|
|
5755
|
+
></ax-button>
|
|
5756
|
+
<ax-button
|
|
5757
|
+
look="solid"
|
|
5758
|
+
color="primary"
|
|
5759
|
+
[text]="'@general:actions.ok.title' | translate | async"
|
|
5760
|
+
(onClick)="onConfirm()"
|
|
5761
|
+
></ax-button>
|
|
5762
|
+
</ax-suffix>
|
|
5763
|
+
</ax-footer>
|
|
5482
5764
|
`,
|
|
5483
5765
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
5484
5766
|
imports: [
|
|
@@ -5673,20 +5955,397 @@ var entityCategoryWidgetColumn_component = /*#__PURE__*/Object.freeze({
|
|
|
5673
5955
|
AXPEntityCategoryWidgetColumnComponent: AXPEntityCategoryWidgetColumnComponent
|
|
5674
5956
|
});
|
|
5675
5957
|
|
|
5958
|
+
//#region ---- Constants ----
|
|
5959
|
+
const DEFAULT_CHARACTER_LIMIT = 20;
|
|
5960
|
+
const DEFAULT_SECTION_LIMIT = 2;
|
|
5961
|
+
const ELLIPSIS_ICON = 'fa-solid fa-ellipsis';
|
|
5962
|
+
const SEPARATOR_ICON = 'fa-solid fa-chevron-right';
|
|
5963
|
+
const EYE_ICON = 'fa-solid fa-eye';
|
|
5964
|
+
const SEPARATOR_WIDTH = 16; // Approximate width of separator icon + gap
|
|
5965
|
+
const ELLIPSIS_WIDTH = 24; // Approximate width of ellipsis icon + gaps
|
|
5966
|
+
const MIN_CHAR_WIDTH = 8; // Minimum character width estimate
|
|
5967
|
+
const MAX_CHAR_WIDTH = 12; // Maximum character width estimate
|
|
5968
|
+
//#endregion
|
|
5969
|
+
class AXPTruncatedBreadcrumbComponent {
|
|
5970
|
+
//#endregion
|
|
5971
|
+
//#region ---- Constructor & Lifecycle ----
|
|
5972
|
+
constructor() {
|
|
5973
|
+
//#region ---- Component Inputs ----
|
|
5974
|
+
/**
|
|
5975
|
+
* Array of path sections to display
|
|
5976
|
+
*/
|
|
5977
|
+
this.sections = input([], ...(ngDevMode ? [{ debugName: "sections" }] : []));
|
|
5978
|
+
/**
|
|
5979
|
+
* Maximum number of characters per section.
|
|
5980
|
+
* Can be a number or 'auto' to calculate based on available space.
|
|
5981
|
+
*/
|
|
5982
|
+
this.characterLimit = input(DEFAULT_CHARACTER_LIMIT, ...(ngDevMode ? [{ debugName: "characterLimit" }] : []));
|
|
5983
|
+
/**
|
|
5984
|
+
* Maximum number of sections to display before showing ellipsis.
|
|
5985
|
+
* Can be a number or 'auto' to calculate based on available space.
|
|
5986
|
+
*/
|
|
5987
|
+
this.sectionLimit = input(DEFAULT_SECTION_LIMIT, ...(ngDevMode ? [{ debugName: "sectionLimit" }] : []));
|
|
5988
|
+
/**
|
|
5989
|
+
* Icon class for separator between sections
|
|
5990
|
+
*/
|
|
5991
|
+
this.separatorIcon = input(SEPARATOR_ICON, ...(ngDevMode ? [{ debugName: "separatorIcon" }] : []));
|
|
5992
|
+
/**
|
|
5993
|
+
* Icon class for ellipsis
|
|
5994
|
+
*/
|
|
5995
|
+
this.ellipsisIcon = input(ELLIPSIS_ICON, ...(ngDevMode ? [{ debugName: "ellipsisIcon" }] : []));
|
|
5996
|
+
/**
|
|
5997
|
+
* Icon class for eye icon (collapse button)
|
|
5998
|
+
*/
|
|
5999
|
+
this.eyeIcon = input(EYE_ICON, ...(ngDevMode ? [{ debugName: "eyeIcon" }] : []));
|
|
6000
|
+
//#endregion
|
|
6001
|
+
//#region ---- View Queries ----
|
|
6002
|
+
this.container = viewChild('container', ...(ngDevMode ? [{ debugName: "container" }] : []));
|
|
6003
|
+
//#endregion
|
|
6004
|
+
//#region ---- Component State ----
|
|
6005
|
+
this.isExpanded = signal(false, ...(ngDevMode ? [{ debugName: "isExpanded" }] : []));
|
|
6006
|
+
this.containerWidth = signal(0, ...(ngDevMode ? [{ debugName: "containerWidth" }] : []));
|
|
6007
|
+
this.resizeObserver = null;
|
|
6008
|
+
//#endregion
|
|
6009
|
+
//#region ---- Computed Properties ----
|
|
6010
|
+
/**
|
|
6011
|
+
* Effective character limit (calculated if 'auto', otherwise uses input value)
|
|
6012
|
+
*/
|
|
6013
|
+
this.effectiveCharacterLimit = computed(() => {
|
|
6014
|
+
const limit = this.characterLimit();
|
|
6015
|
+
if (limit === 'auto') {
|
|
6016
|
+
return this.calculateAutoCharacterLimit();
|
|
6017
|
+
}
|
|
6018
|
+
return limit;
|
|
6019
|
+
}, ...(ngDevMode ? [{ debugName: "effectiveCharacterLimit" }] : []));
|
|
6020
|
+
/**
|
|
6021
|
+
* Effective section limit (calculated if 'auto', otherwise uses input value)
|
|
6022
|
+
*/
|
|
6023
|
+
this.effectiveSectionLimit = computed(() => {
|
|
6024
|
+
const limit = this.sectionLimit();
|
|
6025
|
+
if (limit === 'auto') {
|
|
6026
|
+
return this.calculateAutoSectionLimit();
|
|
6027
|
+
}
|
|
6028
|
+
return limit;
|
|
6029
|
+
}, ...(ngDevMode ? [{ debugName: "effectiveSectionLimit" }] : []));
|
|
6030
|
+
/**
|
|
6031
|
+
* All sections with truncated text (for collapsed display)
|
|
6032
|
+
*/
|
|
6033
|
+
this.allSections = computed(() => {
|
|
6034
|
+
if (this.isExpanded()) {
|
|
6035
|
+
return this.sections().map((section) => ({ text: section, original: section }));
|
|
6036
|
+
}
|
|
6037
|
+
const charLimit = this.effectiveCharacterLimit();
|
|
6038
|
+
return this.sections().map((section) => ({
|
|
6039
|
+
text: this.truncateText(section, charLimit),
|
|
6040
|
+
original: section,
|
|
6041
|
+
}));
|
|
6042
|
+
}, ...(ngDevMode ? [{ debugName: "allSections" }] : []));
|
|
6043
|
+
/**
|
|
6044
|
+
* All sections with full text (for expanded display)
|
|
6045
|
+
*/
|
|
6046
|
+
this.allSectionsFull = computed(() => {
|
|
6047
|
+
return this.sections();
|
|
6048
|
+
}, ...(ngDevMode ? [{ debugName: "allSectionsFull" }] : []));
|
|
6049
|
+
/**
|
|
6050
|
+
* Sections to display (first N sections) when collapsed
|
|
6051
|
+
*/
|
|
6052
|
+
this.displayedSections = computed(() => {
|
|
6053
|
+
const limit = this.effectiveSectionLimit();
|
|
6054
|
+
const sections = this.allSections();
|
|
6055
|
+
return sections.slice(0, limit);
|
|
6056
|
+
}, ...(ngDevMode ? [{ debugName: "displayedSections" }] : []));
|
|
6057
|
+
/**
|
|
6058
|
+
* Last section (always shown if there are hidden sections)
|
|
6059
|
+
*/
|
|
6060
|
+
this.lastSection = computed(() => {
|
|
6061
|
+
const sections = this.allSections();
|
|
6062
|
+
return sections[sections.length - 1] || { text: '', original: '' };
|
|
6063
|
+
}, ...(ngDevMode ? [{ debugName: "lastSection" }] : []));
|
|
6064
|
+
/**
|
|
6065
|
+
* Check if there are hidden sections
|
|
6066
|
+
*/
|
|
6067
|
+
this.hasHiddenSections = computed(() => {
|
|
6068
|
+
const totalSections = this.sections().length;
|
|
6069
|
+
const limit = this.effectiveSectionLimit();
|
|
6070
|
+
// If we have more sections than the limit, we need to show ellipsis + last section
|
|
6071
|
+
// Example: total=2, limit=1 -> show [section0, ellipsis, section1]
|
|
6072
|
+
// Example: total=3, limit=1 -> show [section0, ellipsis, section2]
|
|
6073
|
+
// Example: total=2, limit=2 -> show [section0, section1] (no ellipsis)
|
|
6074
|
+
return totalSections > limit;
|
|
6075
|
+
}, ...(ngDevMode ? [{ debugName: "hasHiddenSections" }] : []));
|
|
6076
|
+
afterNextRender(() => {
|
|
6077
|
+
this.initializeResizeObserver();
|
|
6078
|
+
});
|
|
6079
|
+
}
|
|
6080
|
+
ngOnDestroy() {
|
|
6081
|
+
if (this.resizeObserver) {
|
|
6082
|
+
this.resizeObserver.disconnect();
|
|
6083
|
+
this.resizeObserver = null;
|
|
6084
|
+
}
|
|
6085
|
+
}
|
|
6086
|
+
//#endregion
|
|
6087
|
+
//#region ---- Public Methods ----
|
|
6088
|
+
/**
|
|
6089
|
+
* Handles click on separator icon to expand
|
|
6090
|
+
*/
|
|
6091
|
+
handleSeparatorClick(event) {
|
|
6092
|
+
if (!this.hasHiddenSections()) {
|
|
6093
|
+
return;
|
|
6094
|
+
}
|
|
6095
|
+
event.stopPropagation();
|
|
6096
|
+
this.isExpanded.set(true);
|
|
6097
|
+
}
|
|
6098
|
+
/**
|
|
6099
|
+
* Handles click on ellipsis icon to expand
|
|
6100
|
+
*/
|
|
6101
|
+
handleEllipsisClick(event) {
|
|
6102
|
+
event.stopPropagation();
|
|
6103
|
+
this.isExpanded.set(true);
|
|
6104
|
+
}
|
|
6105
|
+
/**
|
|
6106
|
+
* Handles click on eye icon to collapse
|
|
6107
|
+
*/
|
|
6108
|
+
handleCollapseClick(event) {
|
|
6109
|
+
event.stopPropagation();
|
|
6110
|
+
this.isExpanded.set(false);
|
|
6111
|
+
}
|
|
6112
|
+
//#endregion
|
|
6113
|
+
//#region ---- Private Methods ----
|
|
6114
|
+
/**
|
|
6115
|
+
* Initializes ResizeObserver to track container width
|
|
6116
|
+
*/
|
|
6117
|
+
initializeResizeObserver() {
|
|
6118
|
+
const containerElement = this.container()?.nativeElement;
|
|
6119
|
+
if (!containerElement) {
|
|
6120
|
+
return;
|
|
6121
|
+
}
|
|
6122
|
+
// Set initial width
|
|
6123
|
+
this.containerWidth.set(containerElement.offsetWidth);
|
|
6124
|
+
// Create ResizeObserver
|
|
6125
|
+
this.resizeObserver = new ResizeObserver((entries) => {
|
|
6126
|
+
for (const entry of entries) {
|
|
6127
|
+
const width = entry.contentRect.width;
|
|
6128
|
+
this.containerWidth.set(width);
|
|
6129
|
+
}
|
|
6130
|
+
});
|
|
6131
|
+
// Observe container
|
|
6132
|
+
this.resizeObserver.observe(containerElement);
|
|
6133
|
+
}
|
|
6134
|
+
/**
|
|
6135
|
+
* Calculates automatic character limit based on available space
|
|
6136
|
+
*/
|
|
6137
|
+
calculateAutoCharacterLimit() {
|
|
6138
|
+
const width = this.containerWidth();
|
|
6139
|
+
if (width === 0) {
|
|
6140
|
+
return DEFAULT_CHARACTER_LIMIT;
|
|
6141
|
+
}
|
|
6142
|
+
// Estimate: assume average character width
|
|
6143
|
+
const avgCharWidth = (MIN_CHAR_WIDTH + MAX_CHAR_WIDTH) / 2;
|
|
6144
|
+
// Reserve space for separators, ellipsis, and padding
|
|
6145
|
+
const reservedSpace = SEPARATOR_WIDTH * 2 + ELLIPSIS_WIDTH + 32; // Extra padding
|
|
6146
|
+
const availableSpace = width - reservedSpace;
|
|
6147
|
+
// Calculate how many characters can fit
|
|
6148
|
+
const estimatedChars = Math.floor(availableSpace / avgCharWidth);
|
|
6149
|
+
return Math.max(10, Math.min(estimatedChars, 100)); // Clamp between 10 and 100
|
|
6150
|
+
}
|
|
6151
|
+
/**
|
|
6152
|
+
* Calculates automatic section limit based on available space
|
|
6153
|
+
*/
|
|
6154
|
+
calculateAutoSectionLimit() {
|
|
6155
|
+
const width = this.containerWidth();
|
|
6156
|
+
const sections = this.sections();
|
|
6157
|
+
if (width === 0 || sections.length === 0) {
|
|
6158
|
+
return DEFAULT_SECTION_LIMIT;
|
|
6159
|
+
}
|
|
6160
|
+
// Calculate average section length
|
|
6161
|
+
const avgSectionLength = sections.reduce((sum, section) => sum + section.length, 0) / sections.length;
|
|
6162
|
+
const charLimit = this.effectiveCharacterLimit();
|
|
6163
|
+
const truncatedLength = Math.min(avgSectionLength, charLimit);
|
|
6164
|
+
// Estimate section width: text + separator
|
|
6165
|
+
const avgCharWidth = (MIN_CHAR_WIDTH + MAX_CHAR_WIDTH) / 2;
|
|
6166
|
+
const sectionWidth = truncatedLength * avgCharWidth + SEPARATOR_WIDTH;
|
|
6167
|
+
// First, check if all sections can fit without ellipsis
|
|
6168
|
+
const totalWidthNeeded = sections.length * sectionWidth;
|
|
6169
|
+
if (totalWidthNeeded <= width - 32) {
|
|
6170
|
+
// All sections fit, return full length
|
|
6171
|
+
return sections.length;
|
|
6172
|
+
}
|
|
6173
|
+
// Reserve space for ellipsis and last section
|
|
6174
|
+
const lastSectionLength = Math.min(sections[sections.length - 1]?.length || 0, charLimit);
|
|
6175
|
+
const lastSectionWidth = lastSectionLength * avgCharWidth;
|
|
6176
|
+
const reservedSpace = ELLIPSIS_WIDTH + SEPARATOR_WIDTH * 2 + lastSectionWidth + 32; // Extra padding
|
|
6177
|
+
const availableSpace = width - reservedSpace;
|
|
6178
|
+
// Calculate how many sections can fit
|
|
6179
|
+
const estimatedSections = Math.floor(availableSpace / sectionWidth);
|
|
6180
|
+
// At least 1, but can return up to sections.length if all fit
|
|
6181
|
+
return Math.max(1, Math.min(estimatedSections, sections.length));
|
|
6182
|
+
}
|
|
6183
|
+
/**
|
|
6184
|
+
* Truncates text to character limit with ellipsis
|
|
6185
|
+
*/
|
|
6186
|
+
truncateText(text, limit) {
|
|
6187
|
+
if (!text || text.length <= limit) {
|
|
6188
|
+
return text;
|
|
6189
|
+
}
|
|
6190
|
+
return text.substring(0, limit) + '...';
|
|
6191
|
+
}
|
|
6192
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPTruncatedBreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6193
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXPTruncatedBreadcrumbComponent, isStandalone: true, selector: "axp-truncated-breadcrumb", inputs: { sections: { classPropertyName: "sections", publicName: "sections", isSignal: true, isRequired: false, transformFunction: null }, characterLimit: { classPropertyName: "characterLimit", publicName: "characterLimit", isSignal: true, isRequired: false, transformFunction: null }, sectionLimit: { classPropertyName: "sectionLimit", publicName: "sectionLimit", isSignal: true, isRequired: false, transformFunction: null }, separatorIcon: { classPropertyName: "separatorIcon", publicName: "separatorIcon", isSignal: true, isRequired: false, transformFunction: null }, ellipsisIcon: { classPropertyName: "ellipsisIcon", publicName: "ellipsisIcon", isSignal: true, isRequired: false, transformFunction: null }, eyeIcon: { classPropertyName: "eyeIcon", publicName: "eyeIcon", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "ax-block" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
6194
|
+
<div class="ax-flex ax-items-center ax-gap-2 ax-flex-wrap" #container>
|
|
6195
|
+
@if (sections().length === 0) {
|
|
6196
|
+
<span class="ax-text-muted">---</span>
|
|
6197
|
+
} @else {
|
|
6198
|
+
@if (isExpanded()) {
|
|
6199
|
+
<!-- Expanded view with eye icon at the end to collapse -->
|
|
6200
|
+
@for (section of allSectionsFull(); track $index; let isLast = $last) {
|
|
6201
|
+
<span class="ax-text-sm">{{ section }}</span>
|
|
6202
|
+
@if (!isLast) {
|
|
6203
|
+
<ax-icon [class]="separatorIcon()" class="ax-text-muted ax-text-xs"></ax-icon>
|
|
6204
|
+
}
|
|
6205
|
+
}
|
|
6206
|
+
<span
|
|
6207
|
+
class="ax-text-sm ax-text-primary ax-cursor-pointer hover:ax-opacity-75 ax-transition-opacity ax-ml-1"
|
|
6208
|
+
(click)="handleCollapseClick($event)"
|
|
6209
|
+
title="Collapse breadcrumb"
|
|
6210
|
+
>
|
|
6211
|
+
<ax-icon [class]="eyeIcon()" class="ax-text-primary"></ax-icon>
|
|
6212
|
+
</span>
|
|
6213
|
+
} @else {
|
|
6214
|
+
<!-- Collapsed view with limits -->
|
|
6215
|
+
@for (section of displayedSections(); track $index; let isLast = $last) {
|
|
6216
|
+
<span class="ax-text-sm">{{ section.text }}</span>
|
|
6217
|
+
@if (!isLast) {
|
|
6218
|
+
<ax-icon
|
|
6219
|
+
[class]="separatorIcon()"
|
|
6220
|
+
[class.ax-cursor-pointer]="hasHiddenSections()"
|
|
6221
|
+
[class.hover:ax-opacity-75]="hasHiddenSections()"
|
|
6222
|
+
class="ax-text-muted ax-text-xs ax-transition-opacity"
|
|
6223
|
+
(click)="handleSeparatorClick($event)"
|
|
6224
|
+
[title]="hasHiddenSections() ? 'Expand to show full path' : ''"
|
|
6225
|
+
></ax-icon>
|
|
6226
|
+
}
|
|
6227
|
+
}
|
|
6228
|
+
|
|
6229
|
+
@if (hasHiddenSections()) {
|
|
6230
|
+
<ax-icon
|
|
6231
|
+
[class]="separatorIcon()"
|
|
6232
|
+
[class.ax-cursor-pointer]="true"
|
|
6233
|
+
[class.hover:ax-opacity-75]="true"
|
|
6234
|
+
class="ax-text-muted ax-text-xs ax-transition-opacity"
|
|
6235
|
+
(click)="handleSeparatorClick($event)"
|
|
6236
|
+
title="Expand to show full path"
|
|
6237
|
+
></ax-icon>
|
|
6238
|
+
<span
|
|
6239
|
+
class="ax-text-sm ax-text-primary ax-cursor-pointer hover:ax-opacity-75 ax-transition-opacity"
|
|
6240
|
+
(click)="handleEllipsisClick($event)"
|
|
6241
|
+
title="Expand to show full path"
|
|
6242
|
+
>
|
|
6243
|
+
<ax-icon [class]="ellipsisIcon()" class="ax-text-primary"></ax-icon>
|
|
6244
|
+
</span>
|
|
6245
|
+
<ax-icon
|
|
6246
|
+
[class]="separatorIcon()"
|
|
6247
|
+
[class.ax-cursor-pointer]="true"
|
|
6248
|
+
[class.hover:ax-opacity-75]="true"
|
|
6249
|
+
class="ax-text-muted ax-text-xs ax-transition-opacity"
|
|
6250
|
+
(click)="handleSeparatorClick($event)"
|
|
6251
|
+
title="Expand to show full path"
|
|
6252
|
+
></ax-icon>
|
|
6253
|
+
<span class="ax-text-sm">{{ lastSection().text }}</span>
|
|
6254
|
+
}
|
|
6255
|
+
}
|
|
6256
|
+
}
|
|
6257
|
+
</div>
|
|
6258
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
6259
|
+
}
|
|
6260
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPTruncatedBreadcrumbComponent, decorators: [{
|
|
6261
|
+
type: Component,
|
|
6262
|
+
args: [{
|
|
6263
|
+
selector: 'axp-truncated-breadcrumb',
|
|
6264
|
+
standalone: true,
|
|
6265
|
+
encapsulation: ViewEncapsulation.None,
|
|
6266
|
+
host: {
|
|
6267
|
+
class: 'ax-block',
|
|
6268
|
+
},
|
|
6269
|
+
template: `
|
|
6270
|
+
<div class="ax-flex ax-items-center ax-gap-2 ax-flex-wrap" #container>
|
|
6271
|
+
@if (sections().length === 0) {
|
|
6272
|
+
<span class="ax-text-muted">---</span>
|
|
6273
|
+
} @else {
|
|
6274
|
+
@if (isExpanded()) {
|
|
6275
|
+
<!-- Expanded view with eye icon at the end to collapse -->
|
|
6276
|
+
@for (section of allSectionsFull(); track $index; let isLast = $last) {
|
|
6277
|
+
<span class="ax-text-sm">{{ section }}</span>
|
|
6278
|
+
@if (!isLast) {
|
|
6279
|
+
<ax-icon [class]="separatorIcon()" class="ax-text-muted ax-text-xs"></ax-icon>
|
|
6280
|
+
}
|
|
6281
|
+
}
|
|
6282
|
+
<span
|
|
6283
|
+
class="ax-text-sm ax-text-primary ax-cursor-pointer hover:ax-opacity-75 ax-transition-opacity ax-ml-1"
|
|
6284
|
+
(click)="handleCollapseClick($event)"
|
|
6285
|
+
title="Collapse breadcrumb"
|
|
6286
|
+
>
|
|
6287
|
+
<ax-icon [class]="eyeIcon()" class="ax-text-primary"></ax-icon>
|
|
6288
|
+
</span>
|
|
6289
|
+
} @else {
|
|
6290
|
+
<!-- Collapsed view with limits -->
|
|
6291
|
+
@for (section of displayedSections(); track $index; let isLast = $last) {
|
|
6292
|
+
<span class="ax-text-sm">{{ section.text }}</span>
|
|
6293
|
+
@if (!isLast) {
|
|
6294
|
+
<ax-icon
|
|
6295
|
+
[class]="separatorIcon()"
|
|
6296
|
+
[class.ax-cursor-pointer]="hasHiddenSections()"
|
|
6297
|
+
[class.hover:ax-opacity-75]="hasHiddenSections()"
|
|
6298
|
+
class="ax-text-muted ax-text-xs ax-transition-opacity"
|
|
6299
|
+
(click)="handleSeparatorClick($event)"
|
|
6300
|
+
[title]="hasHiddenSections() ? 'Expand to show full path' : ''"
|
|
6301
|
+
></ax-icon>
|
|
6302
|
+
}
|
|
6303
|
+
}
|
|
6304
|
+
|
|
6305
|
+
@if (hasHiddenSections()) {
|
|
6306
|
+
<ax-icon
|
|
6307
|
+
[class]="separatorIcon()"
|
|
6308
|
+
[class.ax-cursor-pointer]="true"
|
|
6309
|
+
[class.hover:ax-opacity-75]="true"
|
|
6310
|
+
class="ax-text-muted ax-text-xs ax-transition-opacity"
|
|
6311
|
+
(click)="handleSeparatorClick($event)"
|
|
6312
|
+
title="Expand to show full path"
|
|
6313
|
+
></ax-icon>
|
|
6314
|
+
<span
|
|
6315
|
+
class="ax-text-sm ax-text-primary ax-cursor-pointer hover:ax-opacity-75 ax-transition-opacity"
|
|
6316
|
+
(click)="handleEllipsisClick($event)"
|
|
6317
|
+
title="Expand to show full path"
|
|
6318
|
+
>
|
|
6319
|
+
<ax-icon [class]="ellipsisIcon()" class="ax-text-primary"></ax-icon>
|
|
6320
|
+
</span>
|
|
6321
|
+
<ax-icon
|
|
6322
|
+
[class]="separatorIcon()"
|
|
6323
|
+
[class.ax-cursor-pointer]="true"
|
|
6324
|
+
[class.hover:ax-opacity-75]="true"
|
|
6325
|
+
class="ax-text-muted ax-text-xs ax-transition-opacity"
|
|
6326
|
+
(click)="handleSeparatorClick($event)"
|
|
6327
|
+
title="Expand to show full path"
|
|
6328
|
+
></ax-icon>
|
|
6329
|
+
<span class="ax-text-sm">{{ lastSection().text }}</span>
|
|
6330
|
+
}
|
|
6331
|
+
}
|
|
6332
|
+
}
|
|
6333
|
+
</div>
|
|
6334
|
+
`,
|
|
6335
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
6336
|
+
imports: [CommonModule, AXDecoratorModule],
|
|
6337
|
+
}]
|
|
6338
|
+
}], ctorParameters: () => [], propDecorators: { sections: [{ type: i0.Input, args: [{ isSignal: true, alias: "sections", required: false }] }], characterLimit: [{ type: i0.Input, args: [{ isSignal: true, alias: "characterLimit", required: false }] }], sectionLimit: [{ type: i0.Input, args: [{ isSignal: true, alias: "sectionLimit", required: false }] }], separatorIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "separatorIcon", required: false }] }], ellipsisIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "ellipsisIcon", required: false }] }], eyeIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "eyeIcon", required: false }] }], container: [{ type: i0.ViewChild, args: ['container', { isSignal: true }] }] } });
|
|
6339
|
+
|
|
5676
6340
|
class AXPEntityCategoryWidgetEditComponent extends AXPValueWidgetComponent {
|
|
5677
6341
|
constructor() {
|
|
5678
6342
|
super(...arguments);
|
|
5679
6343
|
//#region ---- Services & Dependencies ----
|
|
5680
6344
|
this.entityResolver = inject(AXPEntityResolver);
|
|
5681
|
-
this.formatService = inject(AXFormatService);
|
|
5682
6345
|
this.popupService = inject(AXPopupService);
|
|
5683
6346
|
this.translateService = inject(AXTranslationService);
|
|
5684
6347
|
this.cdr = inject(ChangeDetectorRef);
|
|
5685
6348
|
//#endregion
|
|
5686
|
-
//#region ---- View Queries ----
|
|
5687
|
-
this.selectBox = viewChild('selectBox', ...(ngDevMode ? [{ debugName: "selectBox" }] : []));
|
|
5688
|
-
this.tagBox = viewChild('tagBoxComponent', ...(ngDevMode ? [{ debugName: "tagBox" }] : []));
|
|
5689
|
-
//#endregion
|
|
5690
6349
|
//#region ---- Computed Properties ----
|
|
5691
6350
|
this.entity = computed(() => this.options()['entity'] ?? '', ...(ngDevMode ? [{ debugName: "entity" }] : []));
|
|
5692
6351
|
this.multiple = computed(() => (this.options()['multiple'] ?? false), ...(ngDevMode ? [{ debugName: "multiple" }] : []));
|
|
@@ -5695,7 +6354,8 @@ class AXPEntityCategoryWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
5695
6354
|
this.valueField = computed(() => this.options()['valueField'] ?? 'id', ...(ngDevMode ? [{ debugName: "valueField" }] : []));
|
|
5696
6355
|
this.expose = computed(() => this.options()['expose'], ...(ngDevMode ? [{ debugName: "expose" }] : []));
|
|
5697
6356
|
this.allowClear = computed(() => (this.options()['allowClear'] ?? false), ...(ngDevMode ? [{ debugName: "allowClear" }] : []));
|
|
5698
|
-
this.
|
|
6357
|
+
this.characterLimit = computed(() => this.options()['characterLimit'] ?? 'auto', ...(ngDevMode ? [{ debugName: "characterLimit" }] : []));
|
|
6358
|
+
this.sectionLimit = computed(() => this.options()['sectionLimit'] ?? 'auto', ...(ngDevMode ? [{ debugName: "sectionLimit" }] : []));
|
|
5699
6359
|
this.defaultTextField = computed(() => {
|
|
5700
6360
|
const textField = this.entityDef()?.formats.lookup ?? this.entityDef()?.properties.find((c) => c.name != 'id')?.name ?? 'title';
|
|
5701
6361
|
return textField;
|
|
@@ -5712,27 +6372,9 @@ class AXPEntityCategoryWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
5712
6372
|
this.selectedItems = signal([], ...(ngDevMode ? [{ debugName: "selectedItems" }] : []));
|
|
5713
6373
|
this.isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
|
|
5714
6374
|
this.isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
|
|
5715
|
-
this.searchTerm = signal(null, ...(ngDevMode ? [{ debugName: "searchTerm" }] : []));
|
|
5716
6375
|
//#endregion
|
|
5717
6376
|
//#region ---- Private Properties ----
|
|
5718
6377
|
this.entityDef = signal(null, ...(ngDevMode ? [{ debugName: "entityDef" }] : []));
|
|
5719
|
-
this.dataSource = computed(() => {
|
|
5720
|
-
const entity = this.entityDef();
|
|
5721
|
-
if (!entity)
|
|
5722
|
-
return null;
|
|
5723
|
-
return new AXDataSource({
|
|
5724
|
-
byKey: (key) => {
|
|
5725
|
-
const func = entity.queries.byKey.execute;
|
|
5726
|
-
return func();
|
|
5727
|
-
},
|
|
5728
|
-
load: (e) => {
|
|
5729
|
-
const func = entity.queries.list?.execute;
|
|
5730
|
-
return func(e);
|
|
5731
|
-
},
|
|
5732
|
-
pageSize: 10,
|
|
5733
|
-
key: 'id',
|
|
5734
|
-
});
|
|
5735
|
-
}, ...(ngDevMode ? [{ debugName: "dataSource" }] : []));
|
|
5736
6378
|
//#endregion
|
|
5737
6379
|
//#region ---- Effects ----
|
|
5738
6380
|
this.#efEntity = effect(async () => {
|
|
@@ -5743,7 +6385,13 @@ class AXPEntityCategoryWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
5743
6385
|
this.entityDef.set(await this.entityResolver.get(module, entity));
|
|
5744
6386
|
}, ...(ngDevMode ? [{ debugName: "#efEntity" }] : []));
|
|
5745
6387
|
this.#efValue = effect(() => {
|
|
5746
|
-
|
|
6388
|
+
const value = this.getValue();
|
|
6389
|
+
const entity = this.entityDef();
|
|
6390
|
+
// Wait for entity definition to be loaded before processing value
|
|
6391
|
+
if (!entity) {
|
|
6392
|
+
return;
|
|
6393
|
+
}
|
|
6394
|
+
if (value) {
|
|
5747
6395
|
this.findByValue();
|
|
5748
6396
|
}
|
|
5749
6397
|
else {
|
|
@@ -5775,9 +6423,16 @@ class AXPEntityCategoryWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
5775
6423
|
#efSearchPlaceholder;
|
|
5776
6424
|
//#endregion
|
|
5777
6425
|
//#region ---- Public Methods ----
|
|
5778
|
-
|
|
6426
|
+
handleAddClick(e) {
|
|
5779
6427
|
this.showTreeSelector();
|
|
5780
6428
|
}
|
|
6429
|
+
handleRemoveItemClick(event, item) {
|
|
6430
|
+
event.nativeEvent.stopPropagation();
|
|
6431
|
+
this.removeItem(item);
|
|
6432
|
+
}
|
|
6433
|
+
handleClearClick() {
|
|
6434
|
+
this.clear();
|
|
6435
|
+
}
|
|
5781
6436
|
async showTreeSelector() {
|
|
5782
6437
|
this.isOpen.set(true);
|
|
5783
6438
|
const currentValue = this.getValue();
|
|
@@ -5786,21 +6441,61 @@ class AXPEntityCategoryWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
5786
6441
|
.map((v) => String(extractValue(v, this.valueField())))
|
|
5787
6442
|
.filter((id) => id && id !== 'all')
|
|
5788
6443
|
: [];
|
|
6444
|
+
// Get current entity ID from context (if editing an entity)
|
|
6445
|
+
const currentEntityId = this.contextService.getValue('id');
|
|
6446
|
+
const excludedNodeId = currentEntityId ? String(currentEntityId) : undefined;
|
|
5789
6447
|
try {
|
|
5790
6448
|
const result = await this.popupService.open(AXPEntityCategoryTreeSelectorComponent, {
|
|
5791
6449
|
title: `${this.translateService.translateSync('@general:widgets.lookup.search')} ${this.translateService.translateSync(this.entityDef()?.formats.plural ?? '')}`,
|
|
5792
|
-
size: '
|
|
6450
|
+
size: 'md',
|
|
5793
6451
|
data: {
|
|
5794
6452
|
entityKey: signal(this.entity()),
|
|
5795
6453
|
textField: signal(this.textField()),
|
|
5796
6454
|
valueField: signal(this.valueField()),
|
|
5797
|
-
allowMultiple: signal(this.multiple()
|
|
6455
|
+
allowMultiple: signal(this.multiple()),
|
|
5798
6456
|
selectedValues: signal(selectedIds),
|
|
5799
6457
|
searchPlaceholder: signal(this.searchPlaceholderText()),
|
|
6458
|
+
excludedNodeId: signal(excludedNodeId),
|
|
5800
6459
|
},
|
|
5801
6460
|
});
|
|
5802
6461
|
if (result?.data?.selected && Array.isArray(result.data.selected)) {
|
|
5803
|
-
this.
|
|
6462
|
+
if (this.multiple()) {
|
|
6463
|
+
// In multiple mode, merge with existing selection
|
|
6464
|
+
const existingItems = this.selectedItems();
|
|
6465
|
+
const newItems = result.data.selected;
|
|
6466
|
+
// Create a map of existing items by their ID
|
|
6467
|
+
const existingItemsMap = new Map();
|
|
6468
|
+
existingItems.forEach((item) => {
|
|
6469
|
+
const id = String(get(item, this.valueField()) ?? '');
|
|
6470
|
+
if (id) {
|
|
6471
|
+
existingItemsMap.set(id, item);
|
|
6472
|
+
}
|
|
6473
|
+
});
|
|
6474
|
+
// Merge items, preferring new items (with paths) over existing ones
|
|
6475
|
+
const mergedItems = [];
|
|
6476
|
+
const processedIds = new Set();
|
|
6477
|
+
// First, add all new items (they have paths)
|
|
6478
|
+
newItems.forEach((item) => {
|
|
6479
|
+
const id = String(get(item, this.valueField()) ?? '');
|
|
6480
|
+
if (id && !processedIds.has(id)) {
|
|
6481
|
+
mergedItems.push(item);
|
|
6482
|
+
processedIds.add(id);
|
|
6483
|
+
}
|
|
6484
|
+
});
|
|
6485
|
+
// Then, add existing items that weren't in new items (preserve them)
|
|
6486
|
+
existingItems.forEach((item) => {
|
|
6487
|
+
const id = String(get(item, this.valueField()) ?? '');
|
|
6488
|
+
if (id && !processedIds.has(id)) {
|
|
6489
|
+
mergedItems.push(item);
|
|
6490
|
+
processedIds.add(id);
|
|
6491
|
+
}
|
|
6492
|
+
});
|
|
6493
|
+
await this.setItems(mergedItems);
|
|
6494
|
+
}
|
|
6495
|
+
else {
|
|
6496
|
+
// In single mode, replace selection
|
|
6497
|
+
await this.setItems(result.data.selected);
|
|
6498
|
+
}
|
|
5804
6499
|
}
|
|
5805
6500
|
}
|
|
5806
6501
|
catch (error) {
|
|
@@ -5808,77 +6503,98 @@ class AXPEntityCategoryWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
5808
6503
|
}
|
|
5809
6504
|
finally {
|
|
5810
6505
|
this.isOpen.set(false);
|
|
5811
|
-
this.selectBox()?.focus();
|
|
5812
6506
|
}
|
|
5813
6507
|
}
|
|
5814
|
-
|
|
5815
|
-
|
|
5816
|
-
|
|
5817
|
-
}
|
|
5818
|
-
handleValueChange(e) {
|
|
5819
|
-
if (e.isUserInteraction) {
|
|
5820
|
-
if (isNil(e.value) || (Array.isArray(e.value) && e.value.length === 0)) {
|
|
5821
|
-
this.clear();
|
|
5822
|
-
}
|
|
5823
|
-
else {
|
|
5824
|
-
this.setValue(this.singleOrMultiple(e.value));
|
|
5825
|
-
}
|
|
6508
|
+
async removeItem(item) {
|
|
6509
|
+
if (this.disabled()) {
|
|
6510
|
+
return;
|
|
5826
6511
|
}
|
|
5827
|
-
|
|
5828
|
-
|
|
5829
|
-
|
|
5830
|
-
|
|
6512
|
+
const currentItems = this.selectedItems();
|
|
6513
|
+
const itemId = get(item, this.valueField());
|
|
6514
|
+
const filteredItems = currentItems.filter((i) => get(i, this.valueField()) !== itemId);
|
|
6515
|
+
if (filteredItems.length === 0) {
|
|
6516
|
+
this.clear();
|
|
5831
6517
|
}
|
|
5832
|
-
|
|
5833
|
-
|
|
5834
|
-
const keyEvent = e.nativeEvent;
|
|
5835
|
-
if (keyEvent.code == 'ArrowDown') {
|
|
5836
|
-
this.showTreeSelector();
|
|
6518
|
+
else {
|
|
6519
|
+
await this.setItems(filteredItems);
|
|
5837
6520
|
}
|
|
5838
6521
|
}
|
|
5839
|
-
handleOnBlur(e) {
|
|
5840
|
-
setTimeout(() => {
|
|
5841
|
-
if (!this.isOpen()) {
|
|
5842
|
-
this.clearInput();
|
|
5843
|
-
}
|
|
5844
|
-
}, 100);
|
|
5845
|
-
}
|
|
5846
|
-
handleClearClick() {
|
|
5847
|
-
this.clear();
|
|
5848
|
-
}
|
|
5849
6522
|
clear() {
|
|
5850
6523
|
this.setValue(null);
|
|
5851
|
-
this.clearInput();
|
|
5852
6524
|
this.selectedItems.set([]);
|
|
5853
|
-
|
|
5854
|
-
clearInput() {
|
|
5855
|
-
this.tagBox()?.inputValue.set('');
|
|
5856
|
-
this.searchTerm.set('');
|
|
6525
|
+
this.cdr.markForCheck();
|
|
5857
6526
|
}
|
|
5858
6527
|
//#endregion
|
|
5859
6528
|
//#region ---- Private Methods ----
|
|
5860
6529
|
async findByValue() {
|
|
5861
6530
|
this.isLoading.set(true);
|
|
5862
6531
|
const rawValue = this.getValue();
|
|
6532
|
+
// If no value, clear and return
|
|
6533
|
+
if (!rawValue) {
|
|
6534
|
+
this.setItems([]);
|
|
6535
|
+
this.isLoading.set(false);
|
|
6536
|
+
return;
|
|
6537
|
+
}
|
|
5863
6538
|
const values = castArray(rawValue);
|
|
5864
6539
|
const byKey = this.entityDef()?.queries.byKey?.execute;
|
|
5865
|
-
if (byKey
|
|
6540
|
+
if (!byKey) {
|
|
6541
|
+
this.setItems([]);
|
|
6542
|
+
this.isLoading.set(false);
|
|
6543
|
+
return;
|
|
6544
|
+
}
|
|
6545
|
+
if (values.length === 0) {
|
|
6546
|
+
this.setItems([]);
|
|
6547
|
+
this.isLoading.set(false);
|
|
6548
|
+
return;
|
|
6549
|
+
}
|
|
6550
|
+
try {
|
|
5866
6551
|
if (this.multiple()) {
|
|
5867
|
-
|
|
5868
|
-
|
|
6552
|
+
// Filter out null/undefined/empty values
|
|
6553
|
+
const validValues = values.filter((v) => v != null && v !== '' && v !== 'all');
|
|
6554
|
+
if (validValues.length === 0) {
|
|
6555
|
+
this.setItems([]);
|
|
6556
|
+
this.isLoading.set(false);
|
|
6557
|
+
return;
|
|
6558
|
+
}
|
|
6559
|
+
const items = await Promise.all(validValues.map((value) => {
|
|
6560
|
+
const id = extractValue(value, this.valueField());
|
|
6561
|
+
if (!id)
|
|
6562
|
+
return null;
|
|
6563
|
+
return byKey(id);
|
|
6564
|
+
}));
|
|
6565
|
+
// Filter out null results
|
|
6566
|
+
const validItems = items.filter((item) => item != null);
|
|
6567
|
+
// Calculate paths for items loaded from value
|
|
6568
|
+
const itemsWithPaths = await Promise.all(validItems.map((item) => this.calculateItemPath(item)));
|
|
6569
|
+
this.setItems(itemsWithPaths);
|
|
5869
6570
|
}
|
|
5870
6571
|
else {
|
|
5871
6572
|
const id = extractValue(values[0], this.valueField());
|
|
6573
|
+
if (!id || id === 'all') {
|
|
6574
|
+
this.setItems([]);
|
|
6575
|
+
this.isLoading.set(false);
|
|
6576
|
+
return;
|
|
6577
|
+
}
|
|
5872
6578
|
const item = await byKey(id);
|
|
5873
|
-
|
|
6579
|
+
if (!item) {
|
|
6580
|
+
this.setItems([]);
|
|
6581
|
+
this.isLoading.set(false);
|
|
6582
|
+
return;
|
|
6583
|
+
}
|
|
6584
|
+
// Calculate path for item loaded from value
|
|
6585
|
+
const itemWithPath = await this.calculateItemPath(item);
|
|
6586
|
+
this.setItems(itemWithPath);
|
|
5874
6587
|
}
|
|
5875
6588
|
}
|
|
5876
|
-
|
|
6589
|
+
catch (error) {
|
|
6590
|
+
console.error('Error loading category items from value:', error);
|
|
5877
6591
|
this.setItems([]);
|
|
5878
6592
|
}
|
|
5879
|
-
|
|
6593
|
+
finally {
|
|
6594
|
+
this.isLoading.set(false);
|
|
6595
|
+
}
|
|
5880
6596
|
}
|
|
5881
|
-
setItems(items) {
|
|
6597
|
+
async setItems(items) {
|
|
5882
6598
|
if (!items || items.length == 0) {
|
|
5883
6599
|
this.selectedItems.set([]);
|
|
5884
6600
|
this.setValue(null);
|
|
@@ -5886,24 +6602,31 @@ class AXPEntityCategoryWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
5886
6602
|
return;
|
|
5887
6603
|
}
|
|
5888
6604
|
items = castArray(items);
|
|
5889
|
-
|
|
5890
|
-
|
|
5891
|
-
|
|
5892
|
-
|
|
6605
|
+
// Ensure all items have paths
|
|
6606
|
+
const itemsWithPaths = await Promise.all(items.map(async (item) => {
|
|
6607
|
+
// If item already has a path array, return it as is
|
|
6608
|
+
if (item.path && Array.isArray(item.path) && item.path.length > 0) {
|
|
6609
|
+
return item;
|
|
6610
|
+
}
|
|
6611
|
+
// Otherwise, calculate the path
|
|
6612
|
+
return await this.calculateItemPath(item);
|
|
6613
|
+
}));
|
|
6614
|
+
this.selectedItems.set(itemsWithPaths);
|
|
6615
|
+
const keys = itemsWithPaths.map((item) => get(item, this.valueField()));
|
|
5893
6616
|
// Extract data from valueField and set context by expose path
|
|
5894
6617
|
if (this.expose()) {
|
|
5895
6618
|
const exposeValue = castArray(this.expose());
|
|
5896
6619
|
const itemToExpose = {};
|
|
5897
6620
|
exposeValue.forEach((i) => {
|
|
5898
6621
|
if (typeof i == 'string') {
|
|
5899
|
-
const values =
|
|
6622
|
+
const values = itemsWithPaths.map((item) => set({}, i, get(item, i)));
|
|
5900
6623
|
setSmart(itemToExpose, i, this.singleOrMultiple(values));
|
|
5901
6624
|
}
|
|
5902
6625
|
else {
|
|
5903
6626
|
// Extract data from item by source path and set context by target path
|
|
5904
6627
|
const values = this.multiple()
|
|
5905
|
-
?
|
|
5906
|
-
:
|
|
6628
|
+
? itemsWithPaths.map((item) => set({}, i.source, get(item, i.source)))
|
|
6629
|
+
: itemsWithPaths.map((item) => get(item, i.source));
|
|
5907
6630
|
setSmart(itemToExpose, i.target, this.singleOrMultiple(values));
|
|
5908
6631
|
}
|
|
5909
6632
|
});
|
|
@@ -5914,232 +6637,230 @@ class AXPEntityCategoryWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
5914
6637
|
else {
|
|
5915
6638
|
this.setValue(this.singleOrMultiple(keys));
|
|
5916
6639
|
}
|
|
5917
|
-
// Trigger change detection
|
|
6640
|
+
// Trigger change detection
|
|
5918
6641
|
this.cdr.markForCheck();
|
|
5919
6642
|
}
|
|
5920
6643
|
singleOrMultiple(values) {
|
|
5921
6644
|
return this.multiple() ? values : values[0];
|
|
5922
6645
|
}
|
|
5923
|
-
|
|
6646
|
+
getItemLabel(item) {
|
|
5924
6647
|
if (!item) {
|
|
5925
6648
|
return '';
|
|
5926
6649
|
}
|
|
6650
|
+
// If path is available as array, join it with customizable separator
|
|
6651
|
+
if (item.path && Array.isArray(item.path) && item.path.length > 0) {
|
|
6652
|
+
return this.joinPath(item.path);
|
|
6653
|
+
}
|
|
6654
|
+
// Fall back to display field if no path
|
|
5927
6655
|
return get(item, this.displayField()) ?? '';
|
|
5928
6656
|
}
|
|
6657
|
+
/**
|
|
6658
|
+
* Get item path as array for breadcrumb component
|
|
6659
|
+
*/
|
|
6660
|
+
getItemPath(item) {
|
|
6661
|
+
if (!item) {
|
|
6662
|
+
return [];
|
|
6663
|
+
}
|
|
6664
|
+
// If path is available as array, return it
|
|
6665
|
+
if (item.path && Array.isArray(item.path) && item.path.length > 0) {
|
|
6666
|
+
return item.path;
|
|
6667
|
+
}
|
|
6668
|
+
// Fall back to display field if no path
|
|
6669
|
+
const displayValue = get(item, this.displayField());
|
|
6670
|
+
return displayValue ? [String(displayValue)] : [];
|
|
6671
|
+
}
|
|
6672
|
+
/**
|
|
6673
|
+
* Join path array with separator.
|
|
6674
|
+
* Override this method to customize the separator (e.g., " > ", " -> ", " / ")
|
|
6675
|
+
*/
|
|
6676
|
+
joinPath(path) {
|
|
6677
|
+
return path.join(' > ');
|
|
6678
|
+
}
|
|
6679
|
+
getItemId(item) {
|
|
6680
|
+
if (!item) {
|
|
6681
|
+
return '';
|
|
6682
|
+
}
|
|
6683
|
+
return String(get(item, this.valueField()) ?? '');
|
|
6684
|
+
}
|
|
6685
|
+
/**
|
|
6686
|
+
* Calculate the full path from root to the item.
|
|
6687
|
+
* Returns an array of strings like ["C", "B"] for item B under parent C.
|
|
6688
|
+
*/
|
|
6689
|
+
async calculateItemPath(item) {
|
|
6690
|
+
if (!item || !this.entityDef()) {
|
|
6691
|
+
return item;
|
|
6692
|
+
}
|
|
6693
|
+
// If item already has a path array, return it as is
|
|
6694
|
+
if (item.path && Array.isArray(item.path) && item.path.length > 0) {
|
|
6695
|
+
return item;
|
|
6696
|
+
}
|
|
6697
|
+
const parentKey = this.entityDef()?.parentKey;
|
|
6698
|
+
if (!parentKey) {
|
|
6699
|
+
// No parent key means flat structure, return item with just its title as path array
|
|
6700
|
+
const title = get(item, this.displayField()) ?? '';
|
|
6701
|
+
return { ...item, path: title ? [title] : [] };
|
|
6702
|
+
}
|
|
6703
|
+
const valueField = this.valueField();
|
|
6704
|
+
const textField = this.displayField();
|
|
6705
|
+
const byKey = this.entityDef()?.queries.byKey?.execute;
|
|
6706
|
+
if (!byKey) {
|
|
6707
|
+
return item;
|
|
6708
|
+
}
|
|
6709
|
+
const path = [];
|
|
6710
|
+
let currentItem = item;
|
|
6711
|
+
const visitedIds = new Set(); // Prevent infinite loops
|
|
6712
|
+
// Build path by traversing up the parent chain
|
|
6713
|
+
while (currentItem) {
|
|
6714
|
+
const currentId = String(get(currentItem, valueField) ?? '');
|
|
6715
|
+
if (!currentId || visitedIds.has(currentId)) {
|
|
6716
|
+
break; // Prevent infinite loops
|
|
6717
|
+
}
|
|
6718
|
+
visitedIds.add(currentId);
|
|
6719
|
+
const title = String(get(currentItem, textField) ?? '');
|
|
6720
|
+
if (title) {
|
|
6721
|
+
path.unshift(title); // Add to beginning to maintain hierarchy order
|
|
6722
|
+
}
|
|
6723
|
+
// Get parent ID from current item
|
|
6724
|
+
const parentId = get(currentItem, parentKey);
|
|
6725
|
+
if (!parentId || parentId === 'all' || parentId === currentId) {
|
|
6726
|
+
break; // Reached root or invalid parent
|
|
6727
|
+
}
|
|
6728
|
+
try {
|
|
6729
|
+
// Fetch parent item
|
|
6730
|
+
const parentItem = await byKey(parentId);
|
|
6731
|
+
if (!parentItem) {
|
|
6732
|
+
break; // Parent not found, stop traversal
|
|
6733
|
+
}
|
|
6734
|
+
currentItem = parentItem;
|
|
6735
|
+
}
|
|
6736
|
+
catch (error) {
|
|
6737
|
+
console.error('Error fetching parent item:', error);
|
|
6738
|
+
break;
|
|
6739
|
+
}
|
|
6740
|
+
}
|
|
6741
|
+
// Return item with path array, or just the item title if no path
|
|
6742
|
+
const pathArray = path.length > 0 ? path : get(item, textField) ? [String(get(item, textField))] : [];
|
|
6743
|
+
return { ...item, path: pathArray };
|
|
6744
|
+
}
|
|
5929
6745
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPEntityCategoryWidgetEditComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
5930
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXPEntityCategoryWidgetEditComponent, isStandalone: true, selector: "axp-entity-category-widget-edit",
|
|
5931
|
-
|
|
5932
|
-
@if (
|
|
5933
|
-
<ax-
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
|
|
5941
|
-
|
|
5942
|
-
|
|
5943
|
-
|
|
5944
|
-
|
|
5945
|
-
|
|
5946
|
-
>
|
|
5947
|
-
<ax-clear-button></ax-clear-button>
|
|
5948
|
-
</ax-search-box>
|
|
5949
|
-
@for (validation of validationRules(); track $index) {
|
|
5950
|
-
<ax-validation-rule
|
|
5951
|
-
[rule]="validation.rule"
|
|
5952
|
-
[message]="validation.options?.message"
|
|
5953
|
-
[options]="validation.options"
|
|
5954
|
-
></ax-validation-rule>
|
|
6746
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXPEntityCategoryWidgetEditComponent, isStandalone: true, selector: "axp-entity-category-widget-edit", usesInheritance: true, ngImport: i0, template: `
|
|
6747
|
+
<div class="ax-flex ax-flex-col ax-gap-3">
|
|
6748
|
+
@if (selectedItems().length > 0) {
|
|
6749
|
+
<div class="ax-flex ax-flex-col ax-gap-2">
|
|
6750
|
+
@for (item of selectedItems(); track getItemId(item)) {
|
|
6751
|
+
<div class="ax-flex ax-items-center ax-gap-2 ax-p-2 ax-border ax-primary-lightest ax-rounded-xl">
|
|
6752
|
+
<axp-truncated-breadcrumb
|
|
6753
|
+
[sections]="getItemPath(item)"
|
|
6754
|
+
[characterLimit]="characterLimit()"
|
|
6755
|
+
[sectionLimit]="sectionLimit()"
|
|
6756
|
+
class="ax-flex-1"
|
|
6757
|
+
></axp-truncated-breadcrumb>
|
|
6758
|
+
<ax-button color="ghost" look="blank" class="ax-xs" (onClick)="handleRemoveItemClick($event, item)">
|
|
6759
|
+
<ax-icon icon="ax-icon ax-icon-close"></ax-icon>
|
|
6760
|
+
</ax-button>
|
|
6761
|
+
</div>
|
|
5955
6762
|
}
|
|
5956
|
-
|
|
5957
|
-
|
|
5958
|
-
|
|
5959
|
-
|
|
5960
|
-
|
|
5961
|
-
|
|
5962
|
-
|
|
5963
|
-
|
|
5964
|
-
|
|
5965
|
-
>
|
|
5966
|
-
@if (isLoading()) {
|
|
5967
|
-
<ax-loading></ax-loading>
|
|
5968
|
-
} @else {
|
|
5969
|
-
<ax-icon icon="far fa-search"></ax-icon>
|
|
5970
|
-
}
|
|
5971
|
-
</ax-button>
|
|
5972
|
-
</ax-suffix>
|
|
5973
|
-
</ax-select-box>
|
|
5974
|
-
} @else {
|
|
5975
|
-
<ax-tag-box
|
|
5976
|
-
#tagBoxComponent
|
|
5977
|
-
[tagTemplate]="tagTemplate"
|
|
5978
|
-
[ngModel]="selectedItems()"
|
|
5979
|
-
[textField]="displayField()"
|
|
5980
|
-
[valueField]="valueField()"
|
|
5981
|
-
(onValueChanged)="handleValueChange($event)"
|
|
5982
|
-
[placeholder]="selectedItems().length ? '' : searchPlaceholderText()"
|
|
5983
|
-
[addOnEnter]="false"
|
|
5984
|
-
[addOnComma]="false"
|
|
5985
|
-
[disabled]="disabled()"
|
|
5986
|
-
(onKeyUp)="handleKeyUp($event)"
|
|
5987
|
-
(onBlur)="handleOnBlur($event)"
|
|
6763
|
+
</div>
|
|
6764
|
+
}
|
|
6765
|
+
|
|
6766
|
+
<div class="ax-flex ax-items-center ax-gap-2">
|
|
6767
|
+
<ax-button
|
|
6768
|
+
[text]="'@general:actions.add.title' | translate | async"
|
|
6769
|
+
color="primary"
|
|
6770
|
+
[disabled]="isLoading() || disabled()"
|
|
6771
|
+
(onClick)="handleAddClick($event)"
|
|
5988
6772
|
>
|
|
5989
|
-
@
|
|
5990
|
-
<ax-
|
|
5991
|
-
|
|
5992
|
-
|
|
5993
|
-
[options]="validation.options"
|
|
5994
|
-
></ax-validation-rule>
|
|
5995
|
-
}
|
|
5996
|
-
@if (selectedItems().length > 1 || allowClear()) {
|
|
5997
|
-
<ax-clear-button (click)="handleClearClick()"></ax-clear-button>
|
|
6773
|
+
@if (isLoading()) {
|
|
6774
|
+
<ax-loading></ax-loading>
|
|
6775
|
+
} @else {
|
|
6776
|
+
<ax-icon icon="far fa-plus"></ax-icon>
|
|
5998
6777
|
}
|
|
6778
|
+
</ax-button>
|
|
5999
6779
|
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
|
|
6011
|
-
|
|
6012
|
-
|
|
6013
|
-
</ax-suffix>
|
|
6014
|
-
</ax-tag-box>
|
|
6015
|
-
<ng-template #tagTemplate let-item let-index="index">
|
|
6016
|
-
<div class="ax-inline-flex ax-items-center ax-gap-1.5 ax-rounded-md ax-px-3 ax-py-1 ax-text-sm ax-surface">
|
|
6017
|
-
<span>{{ getTagLabel(item) }}</span>
|
|
6018
|
-
<button type="button" (click)="tagBoxComponent.removeItem(index)">
|
|
6019
|
-
<ax-icon class="ax-icon ax-icon-close"></ax-icon>
|
|
6020
|
-
</button>
|
|
6021
|
-
</div>
|
|
6022
|
-
</ng-template>
|
|
6780
|
+
@if (allowClear() && selectedItems().length > 0) {
|
|
6781
|
+
<ax-button color="ghost" look="outline" [disabled]="disabled()" (onClick)="handleClearClick()">
|
|
6782
|
+
Clear All
|
|
6783
|
+
</ax-button>
|
|
6784
|
+
}
|
|
6785
|
+
</div>
|
|
6786
|
+
|
|
6787
|
+
@for (validation of validationRules(); track $index) {
|
|
6788
|
+
<ax-validation-rule
|
|
6789
|
+
[rule]="validation.rule"
|
|
6790
|
+
[message]="validation.options?.message"
|
|
6791
|
+
[options]="validation.options"
|
|
6792
|
+
></ax-validation-rule>
|
|
6023
6793
|
}
|
|
6024
|
-
|
|
6025
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type:
|
|
6794
|
+
</div>
|
|
6795
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: i1$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i1.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXValidationModule }, { kind: "ngmodule", type: AXFormModule }, { kind: "directive", type: i5$1.AXValidationRuleDirective, selector: "ax-validation-rule", inputs: ["rule", "options", "message", "disabled"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPTruncatedBreadcrumbComponent, selector: "axp-truncated-breadcrumb", inputs: ["sections", "characterLimit", "sectionLimit", "separatorIcon", "ellipsisIcon", "eyeIcon"] }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
6026
6796
|
}
|
|
6027
6797
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPEntityCategoryWidgetEditComponent, decorators: [{
|
|
6028
6798
|
type: Component,
|
|
6029
6799
|
args: [{
|
|
6030
6800
|
selector: 'axp-entity-category-widget-edit',
|
|
6031
6801
|
template: `
|
|
6032
|
-
|
|
6033
|
-
@if (
|
|
6034
|
-
<ax-
|
|
6035
|
-
|
|
6036
|
-
|
|
6037
|
-
|
|
6038
|
-
|
|
6039
|
-
|
|
6040
|
-
|
|
6041
|
-
|
|
6042
|
-
|
|
6043
|
-
|
|
6044
|
-
|
|
6045
|
-
|
|
6046
|
-
|
|
6047
|
-
>
|
|
6048
|
-
<ax-clear-button></ax-clear-button>
|
|
6049
|
-
</ax-search-box>
|
|
6050
|
-
@for (validation of validationRules(); track $index) {
|
|
6051
|
-
<ax-validation-rule
|
|
6052
|
-
[rule]="validation.rule"
|
|
6053
|
-
[message]="validation.options?.message"
|
|
6054
|
-
[options]="validation.options"
|
|
6055
|
-
></ax-validation-rule>
|
|
6802
|
+
<div class="ax-flex ax-flex-col ax-gap-3">
|
|
6803
|
+
@if (selectedItems().length > 0) {
|
|
6804
|
+
<div class="ax-flex ax-flex-col ax-gap-2">
|
|
6805
|
+
@for (item of selectedItems(); track getItemId(item)) {
|
|
6806
|
+
<div class="ax-flex ax-items-center ax-gap-2 ax-p-2 ax-border ax-primary-lightest ax-rounded-xl">
|
|
6807
|
+
<axp-truncated-breadcrumb
|
|
6808
|
+
[sections]="getItemPath(item)"
|
|
6809
|
+
[characterLimit]="characterLimit()"
|
|
6810
|
+
[sectionLimit]="sectionLimit()"
|
|
6811
|
+
class="ax-flex-1"
|
|
6812
|
+
></axp-truncated-breadcrumb>
|
|
6813
|
+
<ax-button color="ghost" look="blank" class="ax-xs" (onClick)="handleRemoveItemClick($event, item)">
|
|
6814
|
+
<ax-icon icon="ax-icon ax-icon-close"></ax-icon>
|
|
6815
|
+
</ax-button>
|
|
6816
|
+
</div>
|
|
6056
6817
|
}
|
|
6057
|
-
|
|
6058
|
-
|
|
6059
|
-
|
|
6060
|
-
|
|
6061
|
-
|
|
6062
|
-
|
|
6063
|
-
|
|
6064
|
-
|
|
6065
|
-
|
|
6066
|
-
>
|
|
6067
|
-
@if (isLoading()) {
|
|
6068
|
-
<ax-loading></ax-loading>
|
|
6069
|
-
} @else {
|
|
6070
|
-
<ax-icon icon="far fa-search"></ax-icon>
|
|
6071
|
-
}
|
|
6072
|
-
</ax-button>
|
|
6073
|
-
</ax-suffix>
|
|
6074
|
-
</ax-select-box>
|
|
6075
|
-
} @else {
|
|
6076
|
-
<ax-tag-box
|
|
6077
|
-
#tagBoxComponent
|
|
6078
|
-
[tagTemplate]="tagTemplate"
|
|
6079
|
-
[ngModel]="selectedItems()"
|
|
6080
|
-
[textField]="displayField()"
|
|
6081
|
-
[valueField]="valueField()"
|
|
6082
|
-
(onValueChanged)="handleValueChange($event)"
|
|
6083
|
-
[placeholder]="selectedItems().length ? '' : searchPlaceholderText()"
|
|
6084
|
-
[addOnEnter]="false"
|
|
6085
|
-
[addOnComma]="false"
|
|
6086
|
-
[disabled]="disabled()"
|
|
6087
|
-
(onKeyUp)="handleKeyUp($event)"
|
|
6088
|
-
(onBlur)="handleOnBlur($event)"
|
|
6818
|
+
</div>
|
|
6819
|
+
}
|
|
6820
|
+
|
|
6821
|
+
<div class="ax-flex ax-items-center ax-gap-2">
|
|
6822
|
+
<ax-button
|
|
6823
|
+
[text]="'@general:actions.add.title' | translate | async"
|
|
6824
|
+
color="primary"
|
|
6825
|
+
[disabled]="isLoading() || disabled()"
|
|
6826
|
+
(onClick)="handleAddClick($event)"
|
|
6089
6827
|
>
|
|
6090
|
-
@
|
|
6091
|
-
<ax-
|
|
6092
|
-
|
|
6093
|
-
|
|
6094
|
-
[options]="validation.options"
|
|
6095
|
-
></ax-validation-rule>
|
|
6096
|
-
}
|
|
6097
|
-
@if (selectedItems().length > 1 || allowClear()) {
|
|
6098
|
-
<ax-clear-button (click)="handleClearClick()"></ax-clear-button>
|
|
6828
|
+
@if (isLoading()) {
|
|
6829
|
+
<ax-loading></ax-loading>
|
|
6830
|
+
} @else {
|
|
6831
|
+
<ax-icon icon="far fa-plus"></ax-icon>
|
|
6099
6832
|
}
|
|
6833
|
+
</ax-button>
|
|
6100
6834
|
|
|
6101
|
-
|
|
6102
|
-
|
|
6103
|
-
|
|
6104
|
-
|
|
6105
|
-
|
|
6106
|
-
|
|
6107
|
-
|
|
6108
|
-
|
|
6109
|
-
|
|
6110
|
-
|
|
6111
|
-
|
|
6112
|
-
|
|
6113
|
-
|
|
6114
|
-
</ax-suffix>
|
|
6115
|
-
</ax-tag-box>
|
|
6116
|
-
<ng-template #tagTemplate let-item let-index="index">
|
|
6117
|
-
<div class="ax-inline-flex ax-items-center ax-gap-1.5 ax-rounded-md ax-px-3 ax-py-1 ax-text-sm ax-surface">
|
|
6118
|
-
<span>{{ getTagLabel(item) }}</span>
|
|
6119
|
-
<button type="button" (click)="tagBoxComponent.removeItem(index)">
|
|
6120
|
-
<ax-icon class="ax-icon ax-icon-close"></ax-icon>
|
|
6121
|
-
</button>
|
|
6122
|
-
</div>
|
|
6123
|
-
</ng-template>
|
|
6835
|
+
@if (allowClear() && selectedItems().length > 0) {
|
|
6836
|
+
<ax-button color="ghost" look="outline" [disabled]="disabled()" (onClick)="handleClearClick()">
|
|
6837
|
+
Clear All
|
|
6838
|
+
</ax-button>
|
|
6839
|
+
}
|
|
6840
|
+
</div>
|
|
6841
|
+
|
|
6842
|
+
@for (validation of validationRules(); track $index) {
|
|
6843
|
+
<ax-validation-rule
|
|
6844
|
+
[rule]="validation.rule"
|
|
6845
|
+
[message]="validation.options?.message"
|
|
6846
|
+
[options]="validation.options"
|
|
6847
|
+
></ax-validation-rule>
|
|
6124
6848
|
}
|
|
6125
|
-
|
|
6849
|
+
</div>
|
|
6126
6850
|
`,
|
|
6127
6851
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
6128
6852
|
imports: [
|
|
6129
6853
|
CommonModule,
|
|
6130
|
-
FormsModule,
|
|
6131
6854
|
AXButtonModule,
|
|
6132
6855
|
AXDecoratorModule,
|
|
6133
6856
|
AXLoadingModule,
|
|
6134
6857
|
AXValidationModule,
|
|
6135
6858
|
AXFormModule,
|
|
6136
|
-
AXTagBoxModule,
|
|
6137
6859
|
AXTranslationModule,
|
|
6138
|
-
|
|
6139
|
-
AXSearchBoxComponent,
|
|
6860
|
+
AXPTruncatedBreadcrumbComponent,
|
|
6140
6861
|
],
|
|
6141
6862
|
}]
|
|
6142
|
-
}]
|
|
6863
|
+
}] });
|
|
6143
6864
|
|
|
6144
6865
|
var entityCategoryWidgetEdit_component = /*#__PURE__*/Object.freeze({
|
|
6145
6866
|
__proto__: null,
|
|
@@ -6241,7 +6962,7 @@ class AXPEntityCategoryWidgetViewComponent extends AXPValueWidgetComponent {
|
|
|
6241
6962
|
<span class="ax-text-muted">---</span>
|
|
6242
6963
|
}
|
|
6243
6964
|
}
|
|
6244
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type:
|
|
6965
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i1.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i2$1.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
6245
6966
|
}
|
|
6246
6967
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPEntityCategoryWidgetViewComponent, decorators: [{
|
|
6247
6968
|
type: Component,
|
|
@@ -7137,7 +7858,7 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
|
|
|
7137
7858
|
></ng-container>
|
|
7138
7859
|
}
|
|
7139
7860
|
</div>
|
|
7140
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type:
|
|
7861
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i1$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: AXPWidgetCoreModule }, { kind: "directive", type: i3$1.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged"], exportAs: ["widgetRenderer"] }, { 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: i4$2.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
7141
7862
|
}
|
|
7142
7863
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPEntityListWidgetViewComponent, decorators: [{
|
|
7143
7864
|
type: Component,
|
|
@@ -7708,7 +8429,7 @@ class AXPLookupWidgetViewComponent extends AXPValueWidgetComponent {
|
|
|
7708
8429
|
<span class="ax-text-muted">---</span>
|
|
7709
8430
|
}
|
|
7710
8431
|
}
|
|
7711
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type:
|
|
8432
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i1.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i2$1.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
7712
8433
|
}
|
|
7713
8434
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPLookupWidgetViewComponent, decorators: [{
|
|
7714
8435
|
type: Component,
|
|
@@ -8424,9 +9145,9 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
8424
9145
|
</ng-template>
|
|
8425
9146
|
}
|
|
8426
9147
|
}
|
|
8427
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type:
|
|
9148
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type:
|
|
8428
9149
|
//
|
|
8429
|
-
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:
|
|
9150
|
+
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: i1$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i1$1.AXDecoratorClearButtonComponent, selector: "ax-clear-button", inputs: ["icon"] }, { kind: "component", type: i1$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: AXLoadingModule }, { kind: "component", type: i1.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXValidationModule }, { kind: "ngmodule", type: AXFormModule }, { kind: "directive", type: i5$1.AXValidationRuleDirective, selector: "ax-validation-rule", inputs: ["rule", "options", "message", "disabled"] }, { kind: "ngmodule", type: AXTagBoxModule }, { kind: "component", type: i6$1.AXTagBoxComponent, selector: "ax-tag-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "allowNull", "type", "look", "addOnComma", "addOnEnter", "valueField", "textField", "readonlyField", "allowDuplicateValues", "tagTemplate"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress", "onTagClick", "onTagDblClick", "onTagContextMenu"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXSelectBoxModule }, { kind: "component", type: i7.AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "isItemTruncated", "showItemTooltip", "itemHeight", "maxVisibleItems", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed", "onItemSelected", "onItemClick"] }, { kind: "component", type: 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
8430
9151
|
}
|
|
8431
9152
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPLookupWidgetEditComponent, decorators: [{
|
|
8432
9153
|
type: Component,
|
|
@@ -8799,7 +9520,7 @@ class AXPWidgetSelectorWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
8799
9520
|
<axp-widget-property-viewer [widget]="selectedWidgetNode()!" (onChanged)="handleChangeWidget($event)">
|
|
8800
9521
|
</axp-widget-property-viewer>
|
|
8801
9522
|
}
|
|
8802
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXSelectBoxModule }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "component", type: i2$2.AXTextBoxComponent, selector: "ax-text-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "maxLength", "allowNull", "type", "autoComplete", "look", "mask-options", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { 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:
|
|
9523
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXSelectBoxModule }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "component", type: i2$2.AXTextBoxComponent, selector: "ax-text-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "maxLength", "allowNull", "type", "autoComplete", "look", "mask-options", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { 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: i1$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i1$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: AXLoadingModule }, { kind: "ngmodule", type: AXValidationModule }, { kind: "ngmodule", type: AXFormModule }, { kind: "directive", type: i5$1.AXValidationRuleDirective, selector: "ax-validation-rule", inputs: ["rule", "options", "message", "disabled"] }, { kind: "component", type: AXPWidgetPropertyViewerComponent, selector: "axp-widget-property-viewer", inputs: ["widget", "mode"], outputs: ["onChanged"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
8803
9524
|
}
|
|
8804
9525
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPWidgetSelectorWidgetEditComponent, decorators: [{
|
|
8805
9526
|
type: Component,
|
|
@@ -9318,7 +10039,7 @@ class AXPEntityModule {
|
|
|
9318
10039
|
},
|
|
9319
10040
|
});
|
|
9320
10041
|
}
|
|
9321
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPEntityModule, deps: [{ token: i1$
|
|
10042
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPEntityModule, deps: [{ token: i1$3.AXPAppStartUpService }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
9322
10043
|
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.12", ngImport: i0, type: AXPEntityModule, imports: [RouterModule, i2$3.AXPWorkflowModule, i3$1.AXPWidgetCoreModule] }); }
|
|
9323
10044
|
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPEntityModule, providers: [
|
|
9324
10045
|
{
|
|
@@ -9494,7 +10215,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
9494
10215
|
]),
|
|
9495
10216
|
],
|
|
9496
10217
|
}]
|
|
9497
|
-
}], ctorParameters: () => [{ type: i1$
|
|
10218
|
+
}], ctorParameters: () => [{ type: i1$3.AXPAppStartUpService }, { type: i0.Injector }] });
|
|
9498
10219
|
|
|
9499
10220
|
//#endregion
|
|
9500
10221
|
//#region ---- Get Entity Details Query ----
|
|
@@ -10051,5 +10772,5 @@ function detectEntityChanges(oldObj, newObj) {
|
|
|
10051
10772
|
* Generated bundle index. Do not edit.
|
|
10052
10773
|
*/
|
|
10053
10774
|
|
|
10054
|
-
export { AXMEntityCrudService, AXMEntityCrudServiceImpl, AXPCategoryTreeService, AXPCreateEntityWorkflow, AXPDataSeederService, AXPDeleteEntityWorkflow, AXPEntityApplyUpdatesAction, AXPEntityCategoryTreeSelectorComponent, AXPEntityCategoryWidget, AXPEntityCategoryWidgetColumnComponent, AXPEntityCategoryWidgetEditComponent, AXPEntityCategoryWidgetViewComponent, AXPEntityCommandTriggerViewModel, AXPEntityCreateEvent, AXPEntityCreatePopupAction, AXPEntityCreateSubmittedAction, AXPEntityCreateViewElementViewModel, AXPEntityCreateViewModelFactory, AXPEntityCreateViewSectionViewModel, AXPEntityDataProvider, AXPEntityDataProviderImpl, AXPEntityDataSelectorService, AXPEntityDefinitionRegistryService, AXPEntityDeletedEvent, AXPEntityDetailListViewModel, AXPEntityDetailPopoverComponent, AXPEntityDetailPopoverService, AXPEntityDetailViewModelFactory, AXPEntityDetailViewModelResolver, AXPEntityDynamicDialogService, AXPEntityEventDispatcherService, AXPEntityListTableService, AXPEntityListViewColumnViewModel, AXPEntityListViewModelFactory, AXPEntityListViewModelResolver, AXPEntityListWidget, AXPEntityListWidgetViewComponent, AXPEntityMasterCreateViewModel, AXPEntityMasterListViewModel, AXPEntityMasterListViewQueryViewModel, AXPEntityMasterSingleElementViewModel, AXPEntityMasterSingleViewGroupViewModel, AXPEntityMasterSingleViewModel, AXPEntityMasterUpdateElementViewModel, AXPEntityMasterUpdateViewModel, AXPEntityMasterUpdateViewModelFactory, AXPEntityMiddleware, AXPEntityModifyConfirmedAction, AXPEntityModifyEvent, AXPEntityModifySectionPopupAction, AXPEntityModule, AXPEntityPerformDeleteAction, AXPEntityReferenceWidget, AXPEntityReferenceWidgetColumnComponent, AXPEntityReferenceWidgetDesignerComponent, AXPEntityReferenceWidgetEditComponent, AXPEntityReferenceWidgetPrintComponent, AXPEntityReferenceWidgetViewComponent, AXPEntityResolver, AXPEntityService, AXPEntityStorageService, AXPEntityUpdateViewSectionViewModel, AXPGetEntityDetailsQuery, AXPLookupFilterWidget, AXPLookupFilterWidgetEditComponent, AXPLookupWidget, AXPLookupWidgetColumnComponent, AXPLookupWidgetEditComponent, AXPLookupWidgetViewComponent, AXPMiddlewareAbortError, AXPMiddlewareEntityStorageService, AXPModifyEntitySectionWorkflow, AXPOpenEntityDetailsCommand, AXPQuickEntityModifyPopupAction, AXPQuickModifyEntityWorkflow, AXPShowDetailViewAction, AXPShowDetailsViewWorkflow, AXPShowListViewAction, AXPShowListViewWorkflow, AXPWidgetSelectorWidget, AXPWidgetSelectorWidgetEditComponent, AXPWidgetSelectorWidgetViewComponent, AXP_DATA_SEEDER_TOKEN, AXP_ENTITY_ACTION_PLUGIN, AXP_ENTITY_CONFIG_TOKEN, AXP_ENTITY_DEFINITION_LOADER, AXP_ENTITY_MODIFIER, AXP_ENTITY_STORAGE_BACKEND, AXP_ENTITY_STORAGE_MIDDLEWARE, DEFAULT_COLUMN_WIDTHS, DEFAULT_PROPERTY_ORDER, DEFAULT_SECTION_ORDER, actionExists, columnWidthMiddlewareFactory, columnWidthMiddlewareProvider, createColumnWidthMiddlewareProvider, createLayoutOrderingMiddlewareProvider, createModifierContext, detectEntityChanges, ensureListActions, entityDetailsCreateActions, entityDetailsCrudActions, entityDetailsEditAction, entityDetailsReferenceCondition, entityDetailsReferenceCreateActions, entityDetailsSimpleCondition, entityMasterBulkDeleteAction, entityMasterCreateAction, entityMasterCrudActions, entityMasterDeleteAction, entityMasterRecordActions, entityMasterViewAction, entityOverrideDetailsViewAction, eventDispatchMiddleware, isAXPMiddlewareAbortError, layoutOrderingMiddlewareFactory, layoutOrderingMiddlewareProvider };
|
|
10775
|
+
export { AXMEntityCrudService, AXMEntityCrudServiceImpl, AXPCategoryTreeService, AXPCreateEntityWorkflow, AXPDataSeederService, AXPDeleteEntityWorkflow, AXPEntityApplyUpdatesAction, AXPEntityCategoryTreeSelectorComponent, AXPEntityCategoryWidget, AXPEntityCategoryWidgetColumnComponent, AXPEntityCategoryWidgetEditComponent, AXPEntityCategoryWidgetViewComponent, AXPEntityCommandTriggerViewModel, AXPEntityCreateEvent, AXPEntityCreatePopupAction, AXPEntityCreateSubmittedAction, AXPEntityCreateViewElementViewModel, AXPEntityCreateViewModelFactory, AXPEntityCreateViewSectionViewModel, AXPEntityDataProvider, AXPEntityDataProviderImpl, AXPEntityDataSelectorService, AXPEntityDefinitionRegistryService, AXPEntityDeletedEvent, AXPEntityDetailListViewModel, AXPEntityDetailPopoverComponent, AXPEntityDetailPopoverService, AXPEntityDetailViewModelFactory, AXPEntityDetailViewModelResolver, AXPEntityDynamicDialogService, AXPEntityEventDispatcherService, AXPEntityListTableService, AXPEntityListViewColumnViewModel, AXPEntityListViewModelFactory, AXPEntityListViewModelResolver, AXPEntityListWidget, AXPEntityListWidgetViewComponent, AXPEntityMasterCreateViewModel, AXPEntityMasterListViewModel, AXPEntityMasterListViewQueryViewModel, AXPEntityMasterSingleElementViewModel, AXPEntityMasterSingleViewGroupViewModel, AXPEntityMasterSingleViewModel, AXPEntityMasterUpdateElementViewModel, AXPEntityMasterUpdateViewModel, AXPEntityMasterUpdateViewModelFactory, AXPEntityMiddleware, AXPEntityModifyConfirmedAction, AXPEntityModifyEvent, AXPEntityModifySectionPopupAction, AXPEntityModule, AXPEntityPerformDeleteAction, AXPEntityReferenceWidget, AXPEntityReferenceWidgetColumnComponent, AXPEntityReferenceWidgetDesignerComponent, AXPEntityReferenceWidgetEditComponent, AXPEntityReferenceWidgetPrintComponent, AXPEntityReferenceWidgetViewComponent, AXPEntityResolver, AXPEntityService, AXPEntityStorageService, AXPEntityUpdateViewSectionViewModel, AXPGetEntityDetailsQuery, AXPLookupFilterWidget, AXPLookupFilterWidgetEditComponent, AXPLookupWidget, AXPLookupWidgetColumnComponent, AXPLookupWidgetEditComponent, AXPLookupWidgetViewComponent, AXPMiddlewareAbortError, AXPMiddlewareEntityStorageService, AXPModifyEntitySectionWorkflow, AXPOpenEntityDetailsCommand, AXPQuickEntityModifyPopupAction, AXPQuickModifyEntityWorkflow, AXPShowDetailViewAction, AXPShowDetailsViewWorkflow, AXPShowListViewAction, AXPShowListViewWorkflow, AXPTruncatedBreadcrumbComponent, AXPWidgetSelectorWidget, AXPWidgetSelectorWidgetEditComponent, AXPWidgetSelectorWidgetViewComponent, AXP_DATA_SEEDER_TOKEN, AXP_ENTITY_ACTION_PLUGIN, AXP_ENTITY_CONFIG_TOKEN, AXP_ENTITY_DEFINITION_LOADER, AXP_ENTITY_MODIFIER, AXP_ENTITY_STORAGE_BACKEND, AXP_ENTITY_STORAGE_MIDDLEWARE, DEFAULT_COLUMN_WIDTHS, DEFAULT_PROPERTY_ORDER, DEFAULT_SECTION_ORDER, actionExists, columnWidthMiddlewareFactory, columnWidthMiddlewareProvider, createColumnWidthMiddlewareProvider, createLayoutOrderingMiddlewareProvider, createModifierContext, detectEntityChanges, ensureListActions, entityDetailsCreateActions, entityDetailsCrudActions, entityDetailsEditAction, entityDetailsReferenceCondition, entityDetailsReferenceCreateActions, entityDetailsSimpleCondition, entityMasterBulkDeleteAction, entityMasterCreateAction, entityMasterCrudActions, entityMasterDeleteAction, entityMasterRecordActions, entityMasterViewAction, entityOverrideDetailsViewAction, eventDispatchMiddleware, isAXPMiddlewareAbortError, layoutOrderingMiddlewareFactory, layoutOrderingMiddlewareProvider };
|
|
10055
10776
|
//# sourceMappingURL=acorex-platform-layout-entity.mjs.map
|