@acorex/platform 21.0.0-next.83 → 21.0.0-next.88
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/acorex-platform-auth.mjs +1 -1
- package/fesm2022/acorex-platform-auth.mjs.map +1 -1
- package/fesm2022/{acorex-platform-common-common-settings.provider-Ytey9uhY.mjs → acorex-platform-common-common-settings.provider-VfmZct9H.mjs} +43 -3
- package/fesm2022/acorex-platform-common-common-settings.provider-VfmZct9H.mjs.map +1 -0
- package/fesm2022/acorex-platform-common.mjs +1709 -870
- package/fesm2022/acorex-platform-common.mjs.map +1 -1
- package/fesm2022/acorex-platform-contracts.mjs +1160 -9
- package/fesm2022/acorex-platform-contracts.mjs.map +1 -1
- package/fesm2022/acorex-platform-core.mjs +210 -131
- package/fesm2022/acorex-platform-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-domain-contracts.mjs +58 -0
- package/fesm2022/acorex-platform-domain-contracts.mjs.map +1 -0
- package/fesm2022/acorex-platform-domain.mjs +2 -50
- package/fesm2022/acorex-platform-domain.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-components.mjs +61 -23
- package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-designer.mjs +3 -2
- package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity-attachments-page.component-CwG6n_Yb.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity-contracts.mjs +1114 -0
- package/fesm2022/acorex-platform-layout-entity-contracts.mjs.map +1 -0
- package/fesm2022/acorex-platform-layout-entity-file-list-popup.component--IeMZLIr.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity.mjs +661 -742
- package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-views.mjs +376 -176
- package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widget-core.mjs +11 -105
- package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-CFyfix31.mjs +513 -0
- package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-CFyfix31.mjs.map +1 -0
- package/fesm2022/{acorex-platform-layout-widgets-tabular-data-edit-popup.component-DjpZU6gz.mjs → acorex-platform-layout-widgets-tabular-data-edit-popup.component-D4MOHEpI.mjs} +4 -4
- package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-D4MOHEpI.mjs.map +1 -0
- package/fesm2022/acorex-platform-layout-widgets.mjs +871 -59
- package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
- package/fesm2022/acorex-platform-runtime.mjs.map +1 -1
- package/fesm2022/{acorex-platform-themes-default-entity-master-single-view.component-Br9p5aXT.mjs → acorex-platform-themes-default-entity-master-single-view.component-DrUwqKKA.mjs} +2 -3
- package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-DrUwqKKA.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-default.mjs +740 -96
- package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
- package/fesm2022/{acorex-platform-themes-shared-settings.provider-BjuzSe0T.mjs → acorex-platform-themes-shared-settings.provider-BUwPqwUS.mjs} +3 -3
- package/fesm2022/acorex-platform-themes-shared-settings.provider-BUwPqwUS.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-shared.mjs +4 -3
- package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
- package/fesm2022/acorex-platform-workflow.mjs +6 -8
- package/fesm2022/acorex-platform-workflow.mjs.map +1 -1
- package/package.json +9 -5
- package/types/acorex-platform-auth.d.ts +2 -1
- package/types/acorex-platform-common.d.ts +419 -1083
- package/types/acorex-platform-contracts.d.ts +1791 -260
- package/types/acorex-platform-core.d.ts +2153 -2806
- package/types/acorex-platform-domain-contracts.d.ts +416 -0
- package/types/acorex-platform-domain.d.ts +4 -415
- package/types/acorex-platform-layout-builder.d.ts +2 -1
- package/types/acorex-platform-layout-components.d.ts +15 -4
- package/types/acorex-platform-layout-designer.d.ts +2 -1
- package/types/acorex-platform-layout-entity-contracts.d.ts +864 -0
- package/types/acorex-platform-layout-entity.d.ts +88 -269
- package/types/acorex-platform-layout-views.d.ts +48 -14
- package/types/acorex-platform-layout-widget-core.d.ts +9 -5
- package/types/acorex-platform-layout-widgets.d.ts +89 -13
- package/types/acorex-platform-runtime.d.ts +1 -1
- package/types/acorex-platform-themes-default.d.ts +173 -70
- package/types/acorex-platform-workflow.d.ts +5 -18
- package/fesm2022/acorex-platform-common-common-settings.provider-Ytey9uhY.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-J0zcGKBX.mjs +0 -116
- package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-J0zcGKBX.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-DjpZU6gz.mjs.map +0 -1
- package/fesm2022/acorex-platform-native.mjs +0 -155
- package/fesm2022/acorex-platform-native.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-Br9p5aXT.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-shared-settings.provider-BjuzSe0T.mjs.map +0 -1
- package/native/README.md +0 -4
- package/types/acorex-platform-native.d.ts +0 -28
|
@@ -1,25 +1,29 @@
|
|
|
1
1
|
import { AXToastService } from '@acorex/components/toast';
|
|
2
2
|
import * as i3$1 from '@acorex/core/translation';
|
|
3
|
-
import { AXTranslationService,
|
|
3
|
+
import { AXTranslationService, resolveMultiLanguageString, AXTranslationModule, translateSync } from '@acorex/core/translation';
|
|
4
4
|
import * as i4$2 from '@acorex/platform/common';
|
|
5
|
-
import { AXPNotFoundError, AXPEntityCommandScope, axpNavigateAppPath, AXPSettingsService, AXPCommonSettings,
|
|
5
|
+
import { AXPNotFoundError, AXPEntityCommandScope, axpNavigateAppPath, AXPSettingsService, AXPCommonSettings, resolveEntityModifyPopupTitle, resolveSearchableText, evaluateEntityDisplayTemplate, AXPFilterOperatorMiddlewareService, isCardFieldBadgeDisplay, resolveCardFieldBadgeColor, getEntityInfo, resolveEnabledMasterListLayouts, resolveDefaultMasterListLayout, AXPRefreshEvent, AXPReloadEvent, axpRedirectToNotFound, AXPCleanNestedFilters, AXPFileTypeProviderService, AXPFileStorageService, resolveEntityRowDisplayTitle, AXPFileActionsService, axpIsEntityRecordNotFound, AXPDefaultMultiLanguageConfigService, withDefaultMultiLanguageOnWidgetNodeTree, AXPEntityQueryType, AXPWorkflowNavigateAction, AXP_NOT_FOUND_ROUTE, AXP_PROTECTED_ROUTE_GUARDS, AXPToastAction, AXP_SEARCH_DEFINITION_PROVIDER, AXP_SEARCH_DEFINITION_LAZY_RESOLVER, AXPMenuItemsDataSourceDefinition } from '@acorex/platform/common';
|
|
6
6
|
import * as i0 from '@angular/core';
|
|
7
|
-
import { InjectionToken, inject, Injector, runInInjectionContext, Injectable, ChangeDetectorRef, input, signal, computed, ChangeDetectionStrategy, Component, ElementRef, NgModule, viewChild,
|
|
7
|
+
import { InjectionToken, inject, Injector, runInInjectionContext, Injectable, ChangeDetectorRef, input, signal, computed, effect, ChangeDetectionStrategy, Component, ElementRef, NgModule, viewChild, Input, afterNextRender, untracked, ViewEncapsulation, viewChildren, linkedSignal, HostBinding, output, EnvironmentInjector, makeEnvironmentProviders } from '@angular/core';
|
|
8
|
+
import { cloneDeep, merge, get, castArray, set, orderBy, isNil, isEmpty, isEqual as isEqual$1, isArray, isString } from 'lodash-es';
|
|
8
9
|
import { Subject, filter, takeUntil } from 'rxjs';
|
|
9
10
|
import { AXPLayoutBuilderService, LayoutBuilderModule } from '@acorex/platform/layout/builder';
|
|
10
|
-
import
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
|
|
11
|
+
import { AXPWidgetsCatalog, AXPPlatformScope, AXPDataGenerator, AXPSystemActionType } from '@acorex/platform/contracts';
|
|
12
|
+
import { AXPDeviceService, AXPExpressionEvaluatorService, AXPContextEvalFactory, AXPBroadcastEventService, applyFilterArray, applySortArray, resolveActionLook, AXPDistributedEventListenerService, AXHighlightService, extractValue, setSmart, getChangedPaths, objectKeyValueTransforms, AXPHookService, AXPComponentSlotModule, AXPContextStore, AXPColumnWidthService, AXPModuleManifestRegistry, defaultColumnWidthProvider, AXP_COLUMN_WIDTH_PROVIDER, AXP_DATASOURCE_DEFINITION_PROVIDER, AXPModuleManifestsDataSourceDefinition } from '@acorex/platform/core';
|
|
13
|
+
import { mergeForeignKeyFieldIntoCreateActions, collectNestedCreateHiddenProperties, normalizeEntityDisplayTemplate, sanitizeResolvedEntityDisplayTitle, isUnresolvedEntityDisplayTemplate, AXPEntityDataSourceKeys, AXPEntityEventsKeys, collectEntityListFilterDefinitions, ENTITY_ROW_POPUP_TITLE_OPTION, buildEntitySearchTitleContext } from '@acorex/platform/layout/entity-contracts';
|
|
14
|
+
export * from '@acorex/platform/layout/entity-contracts';
|
|
15
|
+
export { collectNestedCreateHiddenProperties, entityDetailsCreateActions, entityDetailsCreateActionsDeferredParent, entityDetailsCrudActions, entityDetailsEditAction, entityDetailsNewEditAction, entityDetailsReferenceCondition, entityDetailsReferenceCreateActions, entityDetailsSimpleCondition, entityMasterBulkDeleteAction, entityMasterCreateAction, entityMasterCrudActions, entityMasterDeleteAction, entityMasterEditAction, entityMasterRecordActions, entityMasterViewAction, entityOverrideDetailsViewAction, mergeForeignKeyFieldIntoCreateActions } from '@acorex/platform/layout/entity-contracts';
|
|
14
16
|
import { transform, isEqual } from 'lodash';
|
|
15
17
|
import { AXPSessionService, AXPPermissionDefinitionsDataSourceDefinition } from '@acorex/platform/auth';
|
|
16
18
|
import { Router, NavigationStart, ActivatedRoute, RouterModule, ROUTES } from '@angular/router';
|
|
17
19
|
import { defineCommand, AXP_COMMAND_DEFINITION_CATEGORY_ENTITY, AXPCommandService, AXPQueryService, AXPQueryExecutor, AXPCommandExecutor, provideCommandSetups, provideQuerySetups, AXPCommandRegistry, AXPQueryRegistry } from '@acorex/platform/runtime';
|
|
20
|
+
import { AXFormatService } from '@acorex/core/format';
|
|
18
21
|
import * as i1 from '@acorex/components/button';
|
|
19
22
|
import { AXButtonModule } from '@acorex/components/button';
|
|
20
23
|
import * as i3 from '@acorex/components/skeleton';
|
|
21
24
|
import { AXSkeletonModule } from '@acorex/components/skeleton';
|
|
22
|
-
import
|
|
25
|
+
import * as i2 from '@acorex/platform/layout/widget-core';
|
|
26
|
+
import { AXPWidgetCoreModule, AXPPageStatus, AXPWidgetRegistryService, AXPColumnWidgetComponent, AXPValueWidgetComponent, AXPWidgetGroupEnum, createBooleanProperty, AXPWidgetRendererDirective, AXPBaseWidgetComponent, AXPWidgetStatus, createStringProperty, createNumberProperty, AXP_WIDGETS_ADVANCE_SUB_MEDIA, AXP_WIDGETS_ADVANCE_CATEGORY, createSelectProperty, AXP_WIDGETS_EDITOR_CATEGORY, AXP_WIDGET_DEFINITION_PROVIDER } from '@acorex/platform/layout/widget-core';
|
|
23
27
|
import * as i5 from '@angular/common';
|
|
24
28
|
import { CommonModule, DOCUMENT, AsyncPipe, NgClass } from '@angular/common';
|
|
25
29
|
import { AXOverlayService } from '@acorex/cdk/overlay';
|
|
@@ -37,6 +41,7 @@ import { moveItemInArray } from '@angular/cdk/drag-drop';
|
|
|
37
41
|
import { AXDialogService } from '@acorex/components/dialog';
|
|
38
42
|
import { AXLoadingDialogService } from '@acorex/components/loading-dialog';
|
|
39
43
|
import { AXPopupService } from '@acorex/components/popup';
|
|
44
|
+
import { AXP_DISABLED_PROPERTY, AXP_ALLOW_CLEAR_PROPERTY, AXP_DATA_PATH_PROPERTY, AXP_DATA_PROPERTY_GROUP, AXP_ALLOW_MULTIPLE_PROPERTY, AXP_NAME_PROPERTY, AXP_READONLY_PROPERTY, AXP_PLACEHOLDER_PROPERTY, AXP_BEHAVIOR_PROPERTY_GROUP, AXPProviderSelectWidgetEditBase, AXP_ROW_EXPR_PREFIX, AXP_DOWNLOADABLE_PROPERTY, AXP_DESCRIPTION_PROPERTY, AXP_REPEATER_ENTITY_BY_KEY_LOOKUP } from '@acorex/platform/layout/widgets';
|
|
40
45
|
import * as i2$1 from '@acorex/components/badge';
|
|
41
46
|
import { AXBadgeModule } from '@acorex/components/badge';
|
|
42
47
|
import { AXCheckBoxModule } from '@acorex/components/check-box';
|
|
@@ -57,7 +62,6 @@ import { AXLoadingModule } from '@acorex/components/loading';
|
|
|
57
62
|
import * as i6 from '@acorex/components/tag-box';
|
|
58
63
|
import { AXTagBoxModule } from '@acorex/components/tag-box';
|
|
59
64
|
import { AXValidationModule } from '@acorex/core/validation';
|
|
60
|
-
import { AXP_DISABLED_PROPERTY, AXP_ALLOW_CLEAR_PROPERTY, AXP_DATA_PATH_PROPERTY, AXP_DATA_PROPERTY_GROUP, AXP_ALLOW_MULTIPLE_PROPERTY, AXP_NAME_PROPERTY, AXP_READONLY_PROPERTY, AXP_PLACEHOLDER_PROPERTY, AXP_BEHAVIOR_PROPERTY_GROUP, AXPProviderSelectWidgetEditBase, AXP_ROW_EXPR_PREFIX, AXP_DOWNLOADABLE_PROPERTY, AXP_DESCRIPTION_PROPERTY } from '@acorex/platform/layout/widgets';
|
|
61
65
|
import * as i2$2 from '@acorex/components/select-box';
|
|
62
66
|
import { AXSelectBoxModule } from '@acorex/components/select-box';
|
|
63
67
|
import * as i3$4 from '@acorex/components/dropdown';
|
|
@@ -854,276 +858,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
854
858
|
}]
|
|
855
859
|
}] });
|
|
856
860
|
|
|
857
|
-
// #region Master
|
|
858
|
-
function entityMasterCreateAction() {
|
|
859
|
-
return {
|
|
860
|
-
title: '@general:actions.create.title',
|
|
861
|
-
command: {
|
|
862
|
-
name: 'Entity:Create',
|
|
863
|
-
},
|
|
864
|
-
priority: 'primary',
|
|
865
|
-
type: AXPSystemActionType.Create,
|
|
866
|
-
scope: AXPEntityCommandScope.TypeLevel,
|
|
867
|
-
};
|
|
868
|
-
}
|
|
869
|
-
function entityMasterEditAction() {
|
|
870
|
-
return {
|
|
871
|
-
title: '@general:actions.edit.title',
|
|
872
|
-
command: 'Entity:Update',
|
|
873
|
-
priority: 'secondary',
|
|
874
|
-
type: AXPSystemActionType.Update,
|
|
875
|
-
scope: AXPEntityCommandScope.Individual,
|
|
876
|
-
default: true,
|
|
877
|
-
};
|
|
878
|
-
}
|
|
879
|
-
function entityMasterBulkDeleteAction() {
|
|
880
|
-
return {
|
|
881
|
-
title: '@general:actions.delete-items.title',
|
|
882
|
-
command: 'delete-entity',
|
|
883
|
-
priority: 'primary',
|
|
884
|
-
type: AXPSystemActionType.Delete,
|
|
885
|
-
scope: AXPEntityCommandScope.Selected,
|
|
886
|
-
order: 100,
|
|
887
|
-
};
|
|
888
|
-
}
|
|
889
|
-
function entityMasterViewAction() {
|
|
890
|
-
return {
|
|
891
|
-
title: '@general:actions.view.title',
|
|
892
|
-
command: 'open-entity',
|
|
893
|
-
priority: 'secondary',
|
|
894
|
-
type: AXPSystemActionType.View,
|
|
895
|
-
scope: AXPEntityCommandScope.Individual,
|
|
896
|
-
default: true,
|
|
897
|
-
};
|
|
898
|
-
}
|
|
899
|
-
function entityMasterDeleteAction() {
|
|
900
|
-
return {
|
|
901
|
-
title: '@general:actions.delete.title',
|
|
902
|
-
command: 'delete-entity',
|
|
903
|
-
priority: 'secondary',
|
|
904
|
-
type: AXPSystemActionType.Delete,
|
|
905
|
-
scope: AXPEntityCommandScope.Individual,
|
|
906
|
-
order: 100,
|
|
907
|
-
shortcuts: ['ctrl+shift+delete'],
|
|
908
|
-
};
|
|
909
|
-
}
|
|
910
|
-
function entityMasterCrudActions(options) {
|
|
911
|
-
const opts = {
|
|
912
|
-
create: true,
|
|
913
|
-
delete: true,
|
|
914
|
-
view: true,
|
|
915
|
-
edit: false,
|
|
916
|
-
...options,
|
|
917
|
-
};
|
|
918
|
-
const actions = [];
|
|
919
|
-
if (opts.create) {
|
|
920
|
-
actions.push(entityMasterCreateAction());
|
|
921
|
-
}
|
|
922
|
-
if (opts.delete) {
|
|
923
|
-
actions.push(entityMasterBulkDeleteAction());
|
|
924
|
-
actions.push(entityMasterDeleteAction());
|
|
925
|
-
}
|
|
926
|
-
if (opts.view) {
|
|
927
|
-
actions.push(entityMasterViewAction());
|
|
928
|
-
}
|
|
929
|
-
if (opts.edit) {
|
|
930
|
-
actions.push(entityMasterEditAction());
|
|
931
|
-
}
|
|
932
|
-
return actions;
|
|
933
|
-
}
|
|
934
|
-
function entityMasterRecordActions() {
|
|
935
|
-
return [entityMasterDeleteAction()];
|
|
936
|
-
}
|
|
937
|
-
// #endregion
|
|
938
|
-
// #region Details
|
|
939
|
-
function entityDetailsCreateActions(parentId) {
|
|
940
|
-
return {
|
|
941
|
-
title: '@general:actions.create.title',
|
|
942
|
-
command: {
|
|
943
|
-
name: 'Entity:Create',
|
|
944
|
-
options: {
|
|
945
|
-
process: {
|
|
946
|
-
redirect: false,
|
|
947
|
-
canCreateNewOne: true,
|
|
948
|
-
data: {
|
|
949
|
-
[parentId]: '{{context.eval("id")}}',
|
|
950
|
-
},
|
|
951
|
-
},
|
|
952
|
-
},
|
|
953
|
-
},
|
|
954
|
-
priority: 'primary',
|
|
955
|
-
type: AXPSystemActionType.Create,
|
|
956
|
-
scope: AXPEntityCommandScope.TypeLevel,
|
|
957
|
-
};
|
|
958
|
-
}
|
|
959
|
-
/**
|
|
960
|
-
* Type-level Create with empty `process.data`; the FK is supplied from `relatedEntity.persistence.foreignKeyField`
|
|
961
|
-
* when the related list is built (see `mergeForeignKeyFieldIntoCreateActions`).
|
|
962
|
-
*/
|
|
963
|
-
function entityDetailsCreateActionsDeferredParent() {
|
|
964
|
-
return {
|
|
965
|
-
title: '@general:actions.create.title',
|
|
966
|
-
command: {
|
|
967
|
-
name: 'Entity:Create',
|
|
968
|
-
options: {
|
|
969
|
-
process: {
|
|
970
|
-
redirect: false,
|
|
971
|
-
canCreateNewOne: true,
|
|
972
|
-
data: {},
|
|
973
|
-
},
|
|
974
|
-
},
|
|
975
|
-
},
|
|
976
|
-
priority: 'primary',
|
|
977
|
-
type: AXPSystemActionType.Create,
|
|
978
|
-
scope: AXPEntityCommandScope.TypeLevel,
|
|
979
|
-
};
|
|
980
|
-
}
|
|
981
|
-
/**
|
|
982
|
-
* Ensures each type-level `Entity:Create` action includes `process.data[foreignKeyField]` bound to the parent row id.
|
|
983
|
-
*/
|
|
984
|
-
function mergeForeignKeyFieldIntoCreateActions(foreignKeyField, actions) {
|
|
985
|
-
if (!foreignKeyField || !actions?.length) {
|
|
986
|
-
return actions ?? [];
|
|
987
|
-
}
|
|
988
|
-
return actions.map((a) => {
|
|
989
|
-
const cmd = a.command;
|
|
990
|
-
if (typeof cmd !== 'object' ||
|
|
991
|
-
!cmd ||
|
|
992
|
-
cmd.name !== 'Entity:Create' ||
|
|
993
|
-
a.scope !== AXPEntityCommandScope.TypeLevel) {
|
|
994
|
-
return a;
|
|
995
|
-
}
|
|
996
|
-
const opts = (cmd.options ?? {});
|
|
997
|
-
const proc = (opts['process'] ?? {});
|
|
998
|
-
const data = { ...(proc['data'] ?? {}) };
|
|
999
|
-
if (data[foreignKeyField] === undefined || data[foreignKeyField] === null || data[foreignKeyField] === '') {
|
|
1000
|
-
data[foreignKeyField] = '{{ context.eval("id") }}';
|
|
1001
|
-
}
|
|
1002
|
-
return {
|
|
1003
|
-
...a,
|
|
1004
|
-
command: {
|
|
1005
|
-
...cmd,
|
|
1006
|
-
options: { ...opts, process: { ...proc, data } },
|
|
1007
|
-
},
|
|
1008
|
-
};
|
|
1009
|
-
});
|
|
1010
|
-
}
|
|
1011
|
-
/** Property names hidden on nested Create from a related list (`excludeProperties` plus `foreignKeyField` when set). */
|
|
1012
|
-
function collectNestedCreateHiddenProperties(relatedEntity) {
|
|
1013
|
-
const fk = relatedEntity.persistence?.foreignKeyField;
|
|
1014
|
-
const merged = [...(relatedEntity.excludeProperties ?? [])];
|
|
1015
|
-
if (fk) {
|
|
1016
|
-
merged.push(fk);
|
|
1017
|
-
}
|
|
1018
|
-
const unique = [...new Set(merged)];
|
|
1019
|
-
return unique.length ? unique : undefined;
|
|
1020
|
-
}
|
|
1021
|
-
function entityDetailsSimpleCondition(fk) {
|
|
1022
|
-
return {
|
|
1023
|
-
name: fk,
|
|
1024
|
-
operator: { type: 'equal' },
|
|
1025
|
-
value: '{{context.eval("id")}}',
|
|
1026
|
-
};
|
|
1027
|
-
}
|
|
1028
|
-
function entityDetailsReferenceCondition(type) {
|
|
1029
|
-
return [
|
|
1030
|
-
{
|
|
1031
|
-
name: 'reference.id',
|
|
1032
|
-
operator: { type: 'equal' },
|
|
1033
|
-
value: '{{context.eval("id")}}',
|
|
1034
|
-
},
|
|
1035
|
-
{
|
|
1036
|
-
name: 'reference.type',
|
|
1037
|
-
operator: { type: 'equal' },
|
|
1038
|
-
value: type,
|
|
1039
|
-
},
|
|
1040
|
-
];
|
|
1041
|
-
}
|
|
1042
|
-
function entityDetailsEditAction() {
|
|
1043
|
-
return {
|
|
1044
|
-
title: '@general:actions.edit.title',
|
|
1045
|
-
// command: 'quick-modify-entity',
|
|
1046
|
-
command: 'Entity:Update',
|
|
1047
|
-
priority: 'secondary',
|
|
1048
|
-
type: AXPSystemActionType.Update,
|
|
1049
|
-
default: true,
|
|
1050
|
-
scope: AXPEntityCommandScope.Individual,
|
|
1051
|
-
};
|
|
1052
|
-
}
|
|
1053
|
-
function entityDetailsNewEditAction() {
|
|
1054
|
-
return {
|
|
1055
|
-
title: 'New Edit',
|
|
1056
|
-
command: {
|
|
1057
|
-
name: 'Entity:Update',
|
|
1058
|
-
},
|
|
1059
|
-
priority: 'secondary',
|
|
1060
|
-
type: AXPSystemActionType.Update,
|
|
1061
|
-
default: true,
|
|
1062
|
-
scope: AXPEntityCommandScope.Individual,
|
|
1063
|
-
};
|
|
1064
|
-
}
|
|
1065
|
-
function entityOverrideDetailsViewAction() {
|
|
1066
|
-
return {
|
|
1067
|
-
title: '@general:actions.view.title',
|
|
1068
|
-
command: 'open-entity',
|
|
1069
|
-
priority: 'secondary',
|
|
1070
|
-
hidden: true,
|
|
1071
|
-
type: AXPSystemActionType.View,
|
|
1072
|
-
scope: AXPEntityCommandScope.Individual,
|
|
1073
|
-
};
|
|
1074
|
-
}
|
|
1075
|
-
function entityDetailsCrudActions(parentId, options) {
|
|
1076
|
-
const opts = {
|
|
1077
|
-
create: true,
|
|
1078
|
-
delete: true,
|
|
1079
|
-
view: true,
|
|
1080
|
-
edit: true,
|
|
1081
|
-
...options,
|
|
1082
|
-
};
|
|
1083
|
-
const actions = [];
|
|
1084
|
-
if (opts.create) {
|
|
1085
|
-
if (parentId) {
|
|
1086
|
-
actions.push(entityDetailsCreateActions(parentId));
|
|
1087
|
-
}
|
|
1088
|
-
else {
|
|
1089
|
-
actions.push(entityDetailsCreateActionsDeferredParent());
|
|
1090
|
-
}
|
|
1091
|
-
}
|
|
1092
|
-
if (opts.edit) {
|
|
1093
|
-
actions.push(entityDetailsEditAction());
|
|
1094
|
-
}
|
|
1095
|
-
if (opts.view) {
|
|
1096
|
-
actions.push(entityOverrideDetailsViewAction());
|
|
1097
|
-
}
|
|
1098
|
-
return actions;
|
|
1099
|
-
}
|
|
1100
|
-
function entityDetailsReferenceCreateActions(type) {
|
|
1101
|
-
return [
|
|
1102
|
-
{
|
|
1103
|
-
title: '@general:actions.create.title',
|
|
1104
|
-
command: {
|
|
1105
|
-
name: 'Entity:Create',
|
|
1106
|
-
options: {
|
|
1107
|
-
process: {
|
|
1108
|
-
redirect: false,
|
|
1109
|
-
canCreateNewOne: true,
|
|
1110
|
-
data: {
|
|
1111
|
-
reference: {
|
|
1112
|
-
id: '{{context.eval("id")}}',
|
|
1113
|
-
type: type,
|
|
1114
|
-
},
|
|
1115
|
-
},
|
|
1116
|
-
},
|
|
1117
|
-
},
|
|
1118
|
-
},
|
|
1119
|
-
priority: 'primary',
|
|
1120
|
-
type: AXPSystemActionType.Create,
|
|
1121
|
-
scope: AXPEntityCommandScope.TypeLevel,
|
|
1122
|
-
},
|
|
1123
|
-
entityDetailsEditAction(),
|
|
1124
|
-
entityOverrideDetailsViewAction(),
|
|
1125
|
-
];
|
|
1126
|
-
}
|
|
1127
861
|
/**
|
|
1128
862
|
* Computes a diff between two plain objects with array-aware semantics.
|
|
1129
863
|
* - For arrays of objects with an id field, computes added/removed by id.
|
|
@@ -1481,7 +1215,7 @@ class PropertyFilter {
|
|
|
1481
1215
|
const viewLayout = mainViewLayoutMap.get(prop.name);
|
|
1482
1216
|
const mergedProp = {
|
|
1483
1217
|
...prop,
|
|
1484
|
-
__layout: viewLayout?.layout,
|
|
1218
|
+
__layout: viewLayout?.layout ? cloneDeep(viewLayout.layout) : undefined,
|
|
1485
1219
|
__order: viewLayout?.layout?.order,
|
|
1486
1220
|
};
|
|
1487
1221
|
if (this.readonlyList?.has(prop.name)) {
|
|
@@ -1544,7 +1278,7 @@ class PropertyFilter {
|
|
|
1544
1278
|
const mergedProp = {
|
|
1545
1279
|
...prop,
|
|
1546
1280
|
__dataPath: dataPath,
|
|
1547
|
-
__layout: viewLayout?.layout,
|
|
1281
|
+
__layout: viewLayout?.layout ? cloneDeep(viewLayout.layout) : undefined,
|
|
1548
1282
|
__order: viewLayout?.layout?.order,
|
|
1549
1283
|
};
|
|
1550
1284
|
// Apply generic propertyOverrides extension (e.g. for identifier defaultValue on nested paths)
|
|
@@ -2053,6 +1787,9 @@ const GRID_COLUMNS = 12;
|
|
|
2053
1787
|
function getColSpanAt(layout, breakpoint) {
|
|
2054
1788
|
return layout?.positions?.[breakpoint]?.colSpan ?? GRID_COLUMNS;
|
|
2055
1789
|
}
|
|
1790
|
+
function getColStartAt(layout, breakpoint) {
|
|
1791
|
+
return layout?.positions?.[breakpoint]?.colStart;
|
|
1792
|
+
}
|
|
2056
1793
|
function setColSpanAt(layout, breakpoint, colSpan) {
|
|
2057
1794
|
if (!layout)
|
|
2058
1795
|
return;
|
|
@@ -2077,23 +1814,56 @@ function normalizeLayoutFillRowGaps(items, getLayout, getItemId) {
|
|
|
2077
1814
|
if (items.length === 0)
|
|
2078
1815
|
return scaleFactors;
|
|
2079
1816
|
for (const breakpoint of LAYOUT_BREAKPOINTS) {
|
|
2080
|
-
const colSpans = items.map((item) => getColSpanAt(getLayout(item), breakpoint));
|
|
2081
1817
|
let i = 0;
|
|
2082
|
-
while (i <
|
|
2083
|
-
let rowSum = 0;
|
|
1818
|
+
while (i < items.length) {
|
|
2084
1819
|
const rowStart = i;
|
|
2085
|
-
|
|
2086
|
-
|
|
1820
|
+
let rowHasExplicitColStart = false;
|
|
1821
|
+
let sequentialRowSum = 0;
|
|
1822
|
+
let explicitRowEnd = 0;
|
|
1823
|
+
while (i < items.length) {
|
|
1824
|
+
const layout = getLayout(items[i]);
|
|
1825
|
+
const colStart = getColStartAt(layout, breakpoint);
|
|
1826
|
+
const colSpan = getColSpanAt(layout, breakpoint);
|
|
1827
|
+
// colStart: 1 begins a new row (except for the first item in the current row)
|
|
1828
|
+
if (colStart === 1 && i > rowStart) {
|
|
1829
|
+
break;
|
|
1830
|
+
}
|
|
1831
|
+
if (colStart != null) {
|
|
1832
|
+
rowHasExplicitColStart = true;
|
|
1833
|
+
const end = colStart + colSpan;
|
|
1834
|
+
if (end - 1 > GRID_COLUMNS) {
|
|
1835
|
+
i++;
|
|
1836
|
+
break;
|
|
1837
|
+
}
|
|
1838
|
+
explicitRowEnd = Math.max(explicitRowEnd, end);
|
|
1839
|
+
i++;
|
|
1840
|
+
if (explicitRowEnd >= GRID_COLUMNS) {
|
|
1841
|
+
break;
|
|
1842
|
+
}
|
|
1843
|
+
continue;
|
|
1844
|
+
}
|
|
1845
|
+
if (sequentialRowSum + colSpan > GRID_COLUMNS && i > rowStart) {
|
|
1846
|
+
break;
|
|
1847
|
+
}
|
|
1848
|
+
if (sequentialRowSum + colSpan > GRID_COLUMNS && i === rowStart) {
|
|
1849
|
+
sequentialRowSum = colSpan;
|
|
1850
|
+
i++;
|
|
1851
|
+
break;
|
|
1852
|
+
}
|
|
1853
|
+
sequentialRowSum += colSpan;
|
|
2087
1854
|
i++;
|
|
1855
|
+
if (sequentialRowSum >= GRID_COLUMNS) {
|
|
1856
|
+
break;
|
|
1857
|
+
}
|
|
2088
1858
|
}
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
1859
|
+
// Rows with explicit colStart (e.g. 4+4+4 at columns 1/5/9) keep intentional gaps
|
|
1860
|
+
if (rowHasExplicitColStart) {
|
|
1861
|
+
continue;
|
|
2092
1862
|
}
|
|
2093
|
-
if (
|
|
1863
|
+
if (sequentialRowSum < GRID_COLUMNS && sequentialRowSum > 0 && i > rowStart) {
|
|
2094
1864
|
const lastIdx = i - 1;
|
|
2095
|
-
const oldColSpan =
|
|
2096
|
-
const fill = GRID_COLUMNS -
|
|
1865
|
+
const oldColSpan = getColSpanAt(getLayout(items[lastIdx]), breakpoint);
|
|
1866
|
+
const fill = GRID_COLUMNS - sequentialRowSum;
|
|
2097
1867
|
const newColSpan = Math.min(GRID_COLUMNS, oldColSpan + fill);
|
|
2098
1868
|
const layout = getLayout(items[lastIdx]);
|
|
2099
1869
|
if (layout) {
|
|
@@ -2588,7 +2358,7 @@ class AXPCreateEntityCommand {
|
|
|
2588
2358
|
}
|
|
2589
2359
|
const createFn = entityRef.commands?.create?.execute;
|
|
2590
2360
|
const updateFn = entityRef.commands?.update?.execute;
|
|
2591
|
-
const context = dialogRef.context();
|
|
2361
|
+
const context = merge({}, data, dialogRef.context());
|
|
2592
2362
|
console.log('context', context);
|
|
2593
2363
|
const hasPersistedId = hasPersistedRootId(context);
|
|
2594
2364
|
const persistFn = hasPersistedId ? updateFn : createFn;
|
|
@@ -2744,6 +2514,9 @@ class AXPUpdateEntityCommand {
|
|
|
2744
2514
|
this.entityService = inject(AXPEntityDefinitionRegistryService);
|
|
2745
2515
|
this.toastService = inject(AXToastService);
|
|
2746
2516
|
this.translationService = inject(AXTranslationService);
|
|
2517
|
+
this.formatService = inject(AXFormatService);
|
|
2518
|
+
this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
|
|
2519
|
+
this.contextEvalFactory = inject(AXPContextEvalFactory);
|
|
2747
2520
|
this.eventService = inject(AXPBroadcastEventService);
|
|
2748
2521
|
}
|
|
2749
2522
|
//#endregion
|
|
@@ -2751,7 +2524,7 @@ class AXPUpdateEntityCommand {
|
|
|
2751
2524
|
async execute(input) {
|
|
2752
2525
|
const enableOperationToasts = await this.settingsService.get(AXPCommonSettings.EnableOperationToasts);
|
|
2753
2526
|
const dialogSize = input['dialogSize'];
|
|
2754
|
-
const { entity,
|
|
2527
|
+
const { entity, data, options } = input.__context__;
|
|
2755
2528
|
const excludeProperties = options?.excludeProperties;
|
|
2756
2529
|
const includeProperties = options?.includeProperties;
|
|
2757
2530
|
const decoration = options?.['decoration'];
|
|
@@ -2790,10 +2563,17 @@ class AXPUpdateEntityCommand {
|
|
|
2790
2563
|
if (headerTitle) {
|
|
2791
2564
|
chain = chain.title(headerTitle);
|
|
2792
2565
|
}
|
|
2793
|
-
else
|
|
2794
|
-
|
|
2795
|
-
const
|
|
2796
|
-
|
|
2566
|
+
else {
|
|
2567
|
+
let recordData = {};
|
|
2568
|
+
const recordId = typeof data === 'string' ? data : (data?.id ?? data?._id);
|
|
2569
|
+
if (recordId) {
|
|
2570
|
+
recordData = await this.entityForm.getRecordById(`${moduleName}.${entityName}`, String(recordId));
|
|
2571
|
+
}
|
|
2572
|
+
else if (typeof data === 'object' && data != null) {
|
|
2573
|
+
recordData = data;
|
|
2574
|
+
}
|
|
2575
|
+
const title = await resolveEntityModifyPopupTitle(entityRef, recordData, this.translationService, this.formatService, this.expressionEvaluator, this.contextEvalFactory, '@general:actions.edit.title');
|
|
2576
|
+
chain = chain.title(title);
|
|
2797
2577
|
}
|
|
2798
2578
|
const finalSize = layoutSize || dialogSize;
|
|
2799
2579
|
if (finalSize) {
|
|
@@ -2887,15 +2667,19 @@ var updateEntity_command = /*#__PURE__*/Object.freeze({
|
|
|
2887
2667
|
|
|
2888
2668
|
class AXPViewEntityDetailsCommand {
|
|
2889
2669
|
constructor() {
|
|
2890
|
-
//#region ----
|
|
2670
|
+
//#region ---- Services & Dependencies ----
|
|
2891
2671
|
this.entityForm = inject(AXPEntityFormBuilderService);
|
|
2892
2672
|
this.entityService = inject(AXPEntityDefinitionRegistryService);
|
|
2893
2673
|
this.translationService = inject(AXTranslationService);
|
|
2674
|
+
this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
|
|
2675
|
+
this.contextEvalFactory = inject(AXPContextEvalFactory);
|
|
2894
2676
|
}
|
|
2895
2677
|
//#endregion
|
|
2896
|
-
//#region ----
|
|
2678
|
+
//#region ---- Command Execution ----
|
|
2897
2679
|
async execute(input) {
|
|
2898
|
-
const excludeProperties = input['excludeProperties']
|
|
2680
|
+
const excludeProperties = input['excludeProperties'] ??
|
|
2681
|
+
input?.options?.excludeProperties ??
|
|
2682
|
+
input?.__context__?.options?.excludeProperties;
|
|
2899
2683
|
const { entity, entityInfo, data } = input.__context__;
|
|
2900
2684
|
const [moduleName, entityName] = (entity || '').split('.');
|
|
2901
2685
|
if (!moduleName || !entityName) {
|
|
@@ -2906,10 +2690,9 @@ class AXPViewEntityDetailsCommand {
|
|
|
2906
2690
|
},
|
|
2907
2691
|
};
|
|
2908
2692
|
}
|
|
2909
|
-
await this.entityService.resolve(moduleName, entityName);
|
|
2693
|
+
const entityDef = await this.entityService.resolve(moduleName, entityName);
|
|
2910
2694
|
let dialogRef;
|
|
2911
2695
|
try {
|
|
2912
|
-
// Validate data type
|
|
2913
2696
|
if (!data || (typeof data !== 'string' && typeof data !== 'object')) {
|
|
2914
2697
|
return {
|
|
2915
2698
|
success: false,
|
|
@@ -2918,22 +2701,18 @@ class AXPViewEntityDetailsCommand {
|
|
|
2918
2701
|
},
|
|
2919
2702
|
};
|
|
2920
2703
|
}
|
|
2921
|
-
// Pass data directly to single() - it handles string | object internally
|
|
2922
2704
|
let chain = this.entityForm.entity(`${moduleName}.${entityName}`).single(data);
|
|
2923
2705
|
if (excludeProperties && excludeProperties.length > 0) {
|
|
2924
2706
|
chain = chain.exclude(...excludeProperties);
|
|
2925
2707
|
}
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
chain = chain.title(`${detailText}`);
|
|
2708
|
+
const dialogTitle = await this.resolveDialogTitle(entityDef, data);
|
|
2709
|
+
if (dialogTitle) {
|
|
2710
|
+
chain = chain.title(dialogTitle);
|
|
2930
2711
|
}
|
|
2931
2712
|
chain = chain.actions((actions) => {
|
|
2932
2713
|
actions.submit('@general:actions.ok.title');
|
|
2933
2714
|
});
|
|
2934
2715
|
dialogRef = await chain.show();
|
|
2935
|
-
// For single/view mode, only close action is available
|
|
2936
|
-
// No need to show any message when closing a read-only view
|
|
2937
2716
|
dialogRef.close();
|
|
2938
2717
|
return {
|
|
2939
2718
|
success: true,
|
|
@@ -2953,11 +2732,62 @@ class AXPViewEntityDetailsCommand {
|
|
|
2953
2732
|
};
|
|
2954
2733
|
}
|
|
2955
2734
|
finally {
|
|
2956
|
-
if (dialogRef) {
|
|
2735
|
+
if (dialogRef && typeof dialogRef === 'object' && dialogRef !== null && 'setLoading' in dialogRef) {
|
|
2957
2736
|
dialogRef.setLoading(false);
|
|
2958
2737
|
}
|
|
2959
2738
|
}
|
|
2960
2739
|
}
|
|
2740
|
+
//#endregion
|
|
2741
|
+
//#region ---- Title resolution ----
|
|
2742
|
+
async resolveDialogTitle(entityDef, data) {
|
|
2743
|
+
const titleTemplate = entityDef.interfaces?.master?.single?.title ??
|
|
2744
|
+
entityDef.formats?.searchResult?.title ??
|
|
2745
|
+
entityDef.formats?.individual;
|
|
2746
|
+
if (!titleTemplate || typeof titleTemplate !== 'string') {
|
|
2747
|
+
return this.translationService.translateAsync('@general:actions.detail.title');
|
|
2748
|
+
}
|
|
2749
|
+
if (!titleTemplate.includes('{{')) {
|
|
2750
|
+
const translated = await this.translationService.translateAsync(titleTemplate);
|
|
2751
|
+
return resolveMultiLanguageString(translated, this.translationService.getActiveLang()).trim() || translated;
|
|
2752
|
+
}
|
|
2753
|
+
const recordContext = await this.loadRecordContext(`${entityDef.module}.${entityDef.name}`, data);
|
|
2754
|
+
const scope = {
|
|
2755
|
+
context: this.contextEvalFactory.createScope(recordContext),
|
|
2756
|
+
};
|
|
2757
|
+
const evaluated = await this.expressionEvaluator.evaluate(titleTemplate, scope);
|
|
2758
|
+
const locale = this.translationService.getActiveLang();
|
|
2759
|
+
const text = resolveMultiLanguageString(evaluated, locale).trim() || String(evaluated ?? '').trim();
|
|
2760
|
+
if (text) {
|
|
2761
|
+
return text;
|
|
2762
|
+
}
|
|
2763
|
+
return this.translationService.translateAsync('@general:actions.detail.title');
|
|
2764
|
+
}
|
|
2765
|
+
async loadRecordContext(entityFullName, data) {
|
|
2766
|
+
if (typeof data === 'object' && data !== null && !Array.isArray(data)) {
|
|
2767
|
+
const hasNestedFields = get(data, 'subject.title') != null ||
|
|
2768
|
+
get(data, 'recordType.title') != null ||
|
|
2769
|
+
get(data, 'occurredDate') != null;
|
|
2770
|
+
if (hasNestedFields) {
|
|
2771
|
+
return data;
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2774
|
+
const recordId = typeof data === 'string' ? data : String(get(data, 'id') ?? '');
|
|
2775
|
+
if (!recordId) {
|
|
2776
|
+
return typeof data === 'object' && data !== null ? data : {};
|
|
2777
|
+
}
|
|
2778
|
+
try {
|
|
2779
|
+
const [moduleName, entityName] = entityFullName.split('.');
|
|
2780
|
+
const entity = await this.entityService.resolve(moduleName, entityName);
|
|
2781
|
+
const byKeyFn = entity?.queries?.byKey?.execute;
|
|
2782
|
+
if (typeof byKeyFn === 'function') {
|
|
2783
|
+
return (await byKeyFn(recordId)) ?? {};
|
|
2784
|
+
}
|
|
2785
|
+
}
|
|
2786
|
+
catch {
|
|
2787
|
+
// Fall back to list row payload below.
|
|
2788
|
+
}
|
|
2789
|
+
return typeof data === 'object' && data !== null ? data : {};
|
|
2790
|
+
}
|
|
2961
2791
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPViewEntityDetailsCommand, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2962
2792
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPViewEntityDetailsCommand, providedIn: 'root' }); }
|
|
2963
2793
|
}
|
|
@@ -2973,55 +2803,39 @@ var viewEntityDetails_command = /*#__PURE__*/Object.freeze({
|
|
|
2973
2803
|
AXPViewEntityDetailsCommand: AXPViewEntityDetailsCommand
|
|
2974
2804
|
});
|
|
2975
2805
|
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
const AXP_RECORD_WORKFLOW_INFO_CORRELATION_ID_FIELD = 'workflowInfo.correlationId';
|
|
2994
|
-
/** Entity query filter field for {@link AXPRecordWorkflowInfo.definitionId}. */
|
|
2995
|
-
const AXP_RECORD_WORKFLOW_INFO_DEFINITION_ID_FIELD = 'workflowInfo.definitionId';
|
|
2996
|
-
/** Returns a trimmed workflow instance id from a record, if present. */
|
|
2997
|
-
function getRecordWorkflowInstanceId(record) {
|
|
2998
|
-
const id = record?.workflowInfo?.instanceId?.trim();
|
|
2999
|
-
return id && id.length > 0 ? id : null;
|
|
3000
|
-
}
|
|
3001
|
-
/** Returns a trimmed workflow correlation id from a record, if present. */
|
|
3002
|
-
function getRecordWorkflowCorrelationId(record) {
|
|
3003
|
-
const id = record?.workflowInfo?.correlationId?.trim();
|
|
3004
|
-
return id && id.length > 0 ? id : null;
|
|
2806
|
+
/** Common keys on denormalized expose stubs (e.g. `{ id, displayName }` from lookup expose). */
|
|
2807
|
+
const LOOKUP_EXPOSE_STUB_DISPLAY_FIELDS = ['displayName', 'title', 'name', 'fullName', 'code'];
|
|
2808
|
+
function resolveLookupItemFieldValue(item, field) {
|
|
2809
|
+
const direct = get(item, field);
|
|
2810
|
+
if (direct != null && direct !== '') {
|
|
2811
|
+
return direct;
|
|
2812
|
+
}
|
|
2813
|
+
if (!field.includes('.')) {
|
|
2814
|
+
return direct;
|
|
2815
|
+
}
|
|
2816
|
+
for (const fallback of LOOKUP_EXPOSE_STUB_DISPLAY_FIELDS) {
|
|
2817
|
+
const candidate = get(item, fallback);
|
|
2818
|
+
if (candidate != null && candidate !== '') {
|
|
2819
|
+
return candidate;
|
|
2820
|
+
}
|
|
2821
|
+
}
|
|
2822
|
+
return direct;
|
|
3005
2823
|
}
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
if (!instanceId) {
|
|
3010
|
-
return {};
|
|
2824
|
+
function formatLookupFieldValue(raw, locale, translationService, resolveMultiLanguage) {
|
|
2825
|
+
if (raw == null || raw === '') {
|
|
2826
|
+
return '';
|
|
3011
2827
|
}
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
2828
|
+
if (typeof raw === 'string' || typeof raw === 'number' || typeof raw === 'boolean') {
|
|
2829
|
+
return String(raw);
|
|
2830
|
+
}
|
|
2831
|
+
if (typeof raw === 'object' && !Array.isArray(raw)) {
|
|
2832
|
+
if (resolveMultiLanguage) {
|
|
2833
|
+
return resolveMultiLanguage(raw);
|
|
2834
|
+
}
|
|
2835
|
+
return resolveSearchableText(raw, locale, translationService);
|
|
2836
|
+
}
|
|
2837
|
+
return String(raw);
|
|
3020
2838
|
}
|
|
3021
|
-
|
|
3022
|
-
//#region ---- Contracts barrel ----
|
|
3023
|
-
//#endregion
|
|
3024
|
-
|
|
3025
2839
|
//#region ---- Template resolution ----
|
|
3026
2840
|
/**
|
|
3027
2841
|
* Resolves the display template for a lookup item.
|
|
@@ -3063,9 +2877,9 @@ function resolveLookupDisplayField(entity, options) {
|
|
|
3063
2877
|
return found ?? 'title';
|
|
3064
2878
|
}
|
|
3065
2879
|
/**
|
|
3066
|
-
* Formats a lookup row for display using template and/or field resolution.
|
|
2880
|
+
* Formats a lookup row for display using template and/or field resolution (display tier).
|
|
3067
2881
|
*/
|
|
3068
|
-
function
|
|
2882
|
+
async function formatLookupItemDisplayAsync(item, entity, options, formatService, displayDeps, resolveMultiLanguage) {
|
|
3069
2883
|
if (item == null) {
|
|
3070
2884
|
return '';
|
|
3071
2885
|
}
|
|
@@ -3080,6 +2894,45 @@ function formatLookupItemDisplay(item, entity, options, formatService, resolveMu
|
|
|
3080
2894
|
}
|
|
3081
2895
|
const template = resolveLookupDisplayTemplate(entity, options);
|
|
3082
2896
|
if (template) {
|
|
2897
|
+
if (template.includes('{{') || template.includes('context.eval')) {
|
|
2898
|
+
const evaluated = await evaluateEntityDisplayTemplate(template, item, displayDeps.expressionEvaluator, displayDeps.locale, displayDeps.translationService, displayDeps.contextEvalFactory);
|
|
2899
|
+
const text = sanitizeResolvedEntityDisplayTitle(resolveSearchableText(evaluated, displayDeps.locale, displayDeps.translationService));
|
|
2900
|
+
if (text && !isUnresolvedEntityDisplayTemplate(text)) {
|
|
2901
|
+
return text;
|
|
2902
|
+
}
|
|
2903
|
+
}
|
|
2904
|
+
else {
|
|
2905
|
+
const formatted = formatService.format(template, 'string', item);
|
|
2906
|
+
if (formatted) {
|
|
2907
|
+
const text = String(formatted);
|
|
2908
|
+
if (!isUnresolvedEntityDisplayTemplate(text)) {
|
|
2909
|
+
return text;
|
|
2910
|
+
}
|
|
2911
|
+
}
|
|
2912
|
+
}
|
|
2913
|
+
}
|
|
2914
|
+
const field = resolveLookupDisplayField(entity, options);
|
|
2915
|
+
const raw = typeof item === 'object' && item != null ? resolveLookupItemFieldValue(item, field) : undefined;
|
|
2916
|
+
return formatLookupFieldValue(raw, displayDeps.locale, displayDeps.translationService, resolveMultiLanguage);
|
|
2917
|
+
}
|
|
2918
|
+
/**
|
|
2919
|
+
* @deprecated Prefer {@link formatLookupItemDisplayAsync} for expression templates with `context.eval`.
|
|
2920
|
+
*/
|
|
2921
|
+
function formatLookupItemDisplay(item, entity, options, formatService, resolveMultiLanguage) {
|
|
2922
|
+
if (item == null) {
|
|
2923
|
+
return '';
|
|
2924
|
+
}
|
|
2925
|
+
if (typeof item === 'string' || typeof item === 'number' || typeof item === 'boolean') {
|
|
2926
|
+
return String(item);
|
|
2927
|
+
}
|
|
2928
|
+
if (typeof item !== 'object') {
|
|
2929
|
+
return '';
|
|
2930
|
+
}
|
|
2931
|
+
if (options.isMultiLanguage?.(item) && resolveMultiLanguage) {
|
|
2932
|
+
return resolveMultiLanguage(item);
|
|
2933
|
+
}
|
|
2934
|
+
const template = resolveLookupDisplayTemplate(entity, options);
|
|
2935
|
+
if (template && !template.includes('context.eval') && !template.includes('{{')) {
|
|
3083
2936
|
const formatted = formatService.format(template, 'string', item);
|
|
3084
2937
|
if (formatted) {
|
|
3085
2938
|
const text = String(formatted);
|
|
@@ -3089,8 +2942,8 @@ function formatLookupItemDisplay(item, entity, options, formatService, resolveMu
|
|
|
3089
2942
|
}
|
|
3090
2943
|
}
|
|
3091
2944
|
const field = resolveLookupDisplayField(entity, options);
|
|
3092
|
-
const raw =
|
|
3093
|
-
if (raw == null) {
|
|
2945
|
+
const raw = typeof item === 'object' && item != null ? resolveLookupItemFieldValue(item, field) : undefined;
|
|
2946
|
+
if (raw == null || raw === '') {
|
|
3094
2947
|
return '';
|
|
3095
2948
|
}
|
|
3096
2949
|
if (typeof raw === 'string' || typeof raw === 'number' || typeof raw === 'boolean') {
|
|
@@ -3113,6 +2966,8 @@ class AXPEntityDetailPopoverComponent {
|
|
|
3113
2966
|
this.queryService = inject(AXPQueryService);
|
|
3114
2967
|
this.formatService = inject(AXFormatService);
|
|
3115
2968
|
this.translation = inject(AXTranslationService);
|
|
2969
|
+
this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
|
|
2970
|
+
this.contextEvalFactory = inject(AXPContextEvalFactory);
|
|
3116
2971
|
this.changeDetectorRef = inject(ChangeDetectorRef);
|
|
3117
2972
|
//#endregion
|
|
3118
2973
|
//#region ---- Inputs ----
|
|
@@ -3128,31 +2983,10 @@ class AXPEntityDetailPopoverComponent {
|
|
|
3128
2983
|
//#region ---- Signals ----
|
|
3129
2984
|
this.entityDetails = signal(null, ...(ngDevMode ? [{ debugName: "entityDetails" }] : /* istanbul ignore next */ []));
|
|
3130
2985
|
this.isLoadingDetails = signal(false, ...(ngDevMode ? [{ debugName: "isLoadingDetails" }] : /* istanbul ignore next */ []));
|
|
2986
|
+
this.headerTitleVersion = 0;
|
|
3131
2987
|
/** Placeholder rows for the loading skeleton (matches typical property count). */
|
|
3132
2988
|
this.loadingSkeletonRows = [1, 2, 3, 4, 5];
|
|
3133
|
-
this.headerTitle =
|
|
3134
|
-
const details = this.entityDetails();
|
|
3135
|
-
const entityDefinition = details?.entityDefinition;
|
|
3136
|
-
const data = details?.entityData;
|
|
3137
|
-
if (data && entityDefinition) {
|
|
3138
|
-
const fromDetails = this.resolveLookupDisplayLabel(data, entityDefinition);
|
|
3139
|
-
if (fromDetails) {
|
|
3140
|
-
return fromDetails;
|
|
3141
|
-
}
|
|
3142
|
-
}
|
|
3143
|
-
const preset = this.displayTitle()?.trim();
|
|
3144
|
-
if (preset && !isUnresolvedEntityDisplayTemplate(preset)) {
|
|
3145
|
-
return preset;
|
|
3146
|
-
}
|
|
3147
|
-
const fallbackItem = this.item();
|
|
3148
|
-
if (fallbackItem) {
|
|
3149
|
-
const fromItem = this.resolveLookupDisplayLabel(fallbackItem, entityDefinition);
|
|
3150
|
-
if (fromItem) {
|
|
3151
|
-
return fromItem;
|
|
3152
|
-
}
|
|
3153
|
-
}
|
|
3154
|
-
return preset ?? '';
|
|
3155
|
-
}, ...(ngDevMode ? [{ debugName: "headerTitle" }] : /* istanbul ignore next */ []));
|
|
2989
|
+
this.headerTitle = signal('', ...(ngDevMode ? [{ debugName: "headerTitle" }] : /* istanbul ignore next */ []));
|
|
3156
2990
|
/**
|
|
3157
2991
|
* Stable list of property widgets for the template. Must be a signal (computed), not a method:
|
|
3158
2992
|
* calling a method from the template rebuilds nodes every CD cycle and can make the widget renderer loop.
|
|
@@ -3165,6 +2999,18 @@ class AXPEntityDetailPopoverComponent {
|
|
|
3165
2999
|
return [];
|
|
3166
3000
|
return this.buildEntityPropertiesWithWidgets(data, entityDefinition, this.textField(), this.valueField());
|
|
3167
3001
|
}, ...(ngDevMode ? [{ debugName: "entityPropertiesWithWidgets" }] : /* istanbul ignore next */ []));
|
|
3002
|
+
effect(() => {
|
|
3003
|
+
void this.translation.getActiveLang();
|
|
3004
|
+
const details = this.entityDetails();
|
|
3005
|
+
const preset = this.displayTitle();
|
|
3006
|
+
const fallbackItem = this.item();
|
|
3007
|
+
const version = ++this.headerTitleVersion;
|
|
3008
|
+
void this.resolveHeaderTitle(details?.entityDefinition, details?.entityData, preset, fallbackItem).then((title) => {
|
|
3009
|
+
if (version === this.headerTitleVersion) {
|
|
3010
|
+
this.headerTitle.set(title);
|
|
3011
|
+
}
|
|
3012
|
+
});
|
|
3013
|
+
});
|
|
3168
3014
|
}
|
|
3169
3015
|
//#endregion
|
|
3170
3016
|
//#region ---- Public Methods ----
|
|
@@ -3201,10 +3047,34 @@ class AXPEntityDetailPopoverComponent {
|
|
|
3201
3047
|
}
|
|
3202
3048
|
//#endregion
|
|
3203
3049
|
//#region ---- Helper Methods ----
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3050
|
+
async resolveHeaderTitle(entityDefinition, data, preset, fallbackItem) {
|
|
3051
|
+
if (data && entityDefinition) {
|
|
3052
|
+
const fromDetails = await this.resolveLookupDisplayLabelAsync(data, entityDefinition);
|
|
3053
|
+
if (fromDetails) {
|
|
3054
|
+
return fromDetails;
|
|
3055
|
+
}
|
|
3056
|
+
}
|
|
3057
|
+
const presetTrimmed = preset?.trim();
|
|
3058
|
+
if (presetTrimmed && !isUnresolvedEntityDisplayTemplate(presetTrimmed)) {
|
|
3059
|
+
return presetTrimmed;
|
|
3060
|
+
}
|
|
3061
|
+
if (fallbackItem) {
|
|
3062
|
+
const fromItem = await this.resolveLookupDisplayLabelAsync(fallbackItem, entityDefinition);
|
|
3063
|
+
if (fromItem) {
|
|
3064
|
+
return fromItem;
|
|
3065
|
+
}
|
|
3066
|
+
}
|
|
3067
|
+
return presetTrimmed ?? '';
|
|
3068
|
+
}
|
|
3069
|
+
async resolveLookupDisplayLabelAsync(item, entityDefinition) {
|
|
3070
|
+
const locale = this.translation.getActiveLang() ?? 'en-US';
|
|
3071
|
+
const label = await formatLookupItemDisplayAsync(item, entityDefinition ?? null, { textField: this.textField() }, this.formatService, {
|
|
3072
|
+
expressionEvaluator: this.expressionEvaluator,
|
|
3073
|
+
contextEvalFactory: this.contextEvalFactory,
|
|
3074
|
+
translationService: this.translation,
|
|
3075
|
+
locale,
|
|
3076
|
+
}, (value) => this.translation.resolve(value));
|
|
3077
|
+
return label && !isUnresolvedEntityDisplayTemplate(label) ? label : '';
|
|
3208
3078
|
}
|
|
3209
3079
|
/**
|
|
3210
3080
|
* Returns true if a value is meaningful for display (non-empty/non-null).
|
|
@@ -3369,14 +3239,24 @@ class AXPEntityDetailPopoverComponent {
|
|
|
3369
3239
|
resolveDataPath(prop, data) {
|
|
3370
3240
|
const iface = prop.schema?.interface;
|
|
3371
3241
|
const expose = iface?.options?.['expose'];
|
|
3242
|
+
const textField = iface?.options?.['textField']?.trim();
|
|
3372
3243
|
if (expose?.length) {
|
|
3373
|
-
// Try expanded path first (e.g. personTitle for personTitle.title)
|
|
3374
3244
|
const textTarget = expose.find((e) => e.source !== 'id');
|
|
3375
3245
|
if (textTarget) {
|
|
3376
3246
|
const expandedPath = textTarget.target.split('.')[0];
|
|
3377
3247
|
const expandedValue = get(data, expandedPath);
|
|
3378
3248
|
if (expandedValue != null && typeof expandedValue === 'object') {
|
|
3379
|
-
|
|
3249
|
+
if (textField) {
|
|
3250
|
+
if (this.hasMeaningfulValue(get(expandedValue, textField))) {
|
|
3251
|
+
return expandedPath;
|
|
3252
|
+
}
|
|
3253
|
+
}
|
|
3254
|
+
else {
|
|
3255
|
+
const leaf = textTarget.target.split('.').pop();
|
|
3256
|
+
if (leaf && this.hasMeaningfulValue(get(expandedValue, leaf))) {
|
|
3257
|
+
return expandedPath;
|
|
3258
|
+
}
|
|
3259
|
+
}
|
|
3380
3260
|
}
|
|
3381
3261
|
}
|
|
3382
3262
|
}
|
|
@@ -3388,7 +3268,7 @@ class AXPEntityDetailPopoverComponent {
|
|
|
3388
3268
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityDetailPopoverComponent, decorators: [{
|
|
3389
3269
|
type: Component,
|
|
3390
3270
|
args: [{ selector: 'axp-entity-detail-popover', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, AXButtonModule, AXPWidgetCoreModule, AXTranslationModule, AXSkeletonModule], template: "<div\n class=\"ax-lightest-surface dark:ax-dark-surface ax-p-4 ax-w-[min(600px,calc(100vw-2rem))] ax-rounded-lg ax-shadow-lg\"\n>\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 {{ headerTitle() }}\n </h3>\n @if (breadcrumb()) {\n <div class=\"ax-text-xs ax-text-neutral-500 ax-mt-1\">{{ breadcrumb() }}</div>\n }\n </div>\n @if (isLoadingDetails()) {\n <div class=\"ax-space-y-2 ax-mb-4\">\n @for (row of loadingSkeletonRows; track row) {\n <div class=\"ax-grid ax-grid-cols-[minmax(7rem,35%)_1fr] ax-gap-x-4 ax-items-start\">\n <ax-skeleton [animated]=\"true\" class=\"ax-h-4 ax-w-2/3 ax-rounded\"></ax-skeleton>\n @if (row === 2) {\n <ax-skeleton [animated]=\"true\" class=\"ax-h-16 ax-w-full ax-rounded\"></ax-skeleton>\n } @else {\n <ax-skeleton [animated]=\"true\" class=\"ax-h-4 ax-w-full ax-rounded\"></ax-skeleton>\n }\n </div>\n }\n </div>\n <div class=\"ax-flex ax-justify-end\">\n <ax-skeleton [animated]=\"true\" class=\"ax-h-9 ax-w-28 ax-rounded\"></ax-skeleton>\n </div>\n } @else if (entityDetails()) {\n <div class=\"ax-space-y-3 ax-mb-4\">\n @if (entityDetails()?.entityData) {\n <axp-widgets-container [context]=\"entityDetails()?.entityData\">\n <div class=\"ax-space-y-2\">\n @for (item of entityPropertiesWithWidgets(); track item.name) {\n <div class=\"ax-grid ax-grid-cols-[minmax(7rem,35%)_1fr] ax-gap-x-4 ax-gap-y-1 ax-items-start\">\n <span class=\"ax-text-sm ax-font-medium ax-shrink-0\">{{ item.title | translate | async }}:</span>\n <div class=\"ax-min-w-0 ax-text-sm\">\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\n [color]=\"'primary'\"\n [look]=\"'solid'\"\n [text]=\"'@general:actions.open-details.title' | translate | async\"\n (click)=\"navigateToDetails()\"\n >\n </ax-button>\n </div>\n }\n</div>\n" }]
|
|
3391
|
-
}], propDecorators: { entity: [{ type: i0.Input, args: [{ isSignal: true, alias: "entity", required: true }] }], entityId: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityId", required: true }] }], textField: [{ type: i0.Input, args: [{ isSignal: true, alias: "textField", required: false }] }], valueField: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueField", required: false }] }], displayTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayTitle", required: false }] }], item: [{ type: i0.Input, args: [{ isSignal: true, alias: "item", required: false }] }], breadcrumb: [{ type: i0.Input, args: [{ isSignal: true, alias: "breadcrumb", required: false }] }], requestClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "requestClose", required: false }] }] } });
|
|
3271
|
+
}], ctorParameters: () => [], propDecorators: { entity: [{ type: i0.Input, args: [{ isSignal: true, alias: "entity", required: true }] }], entityId: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityId", required: true }] }], textField: [{ type: i0.Input, args: [{ isSignal: true, alias: "textField", required: false }] }], valueField: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueField", required: false }] }], displayTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayTitle", required: false }] }], item: [{ type: i0.Input, args: [{ isSignal: true, alias: "item", required: false }] }], breadcrumb: [{ type: i0.Input, args: [{ isSignal: true, alias: "breadcrumb", required: false }] }], requestClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "requestClose", required: false }] }] } });
|
|
3392
3272
|
|
|
3393
3273
|
class AXPEntityDetailPopoverService {
|
|
3394
3274
|
constructor() {
|
|
@@ -3402,6 +3282,7 @@ class AXPEntityDetailPopoverService {
|
|
|
3402
3282
|
//#region ---- Private Properties ----
|
|
3403
3283
|
this.overlayRef = null;
|
|
3404
3284
|
this.componentRef = null;
|
|
3285
|
+
this.anchorElement = null;
|
|
3405
3286
|
this.outsideClickHandler = null;
|
|
3406
3287
|
this.keydownHandler = null;
|
|
3407
3288
|
this.routerSubscription = null;
|
|
@@ -3458,6 +3339,7 @@ class AXPEntityDetailPopoverService {
|
|
|
3458
3339
|
});
|
|
3459
3340
|
this.overlayRef = ref;
|
|
3460
3341
|
this.componentRef = ref.instance;
|
|
3342
|
+
this.anchorElement = anchorElement;
|
|
3461
3343
|
setTimeout(() => {
|
|
3462
3344
|
ref.updatePosition();
|
|
3463
3345
|
this.bindDismissHandlers(ref.overlayElement, anchorElement);
|
|
@@ -3559,6 +3441,7 @@ class AXPEntityDetailPopoverService {
|
|
|
3559
3441
|
this.removeDismissHandlers();
|
|
3560
3442
|
this.overlayRef = null;
|
|
3561
3443
|
this.componentRef = null;
|
|
3444
|
+
this.anchorElement = null;
|
|
3562
3445
|
}
|
|
3563
3446
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityDetailPopoverService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
3564
3447
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityDetailPopoverService, providedIn: 'root' }); }
|
|
@@ -4055,7 +3938,6 @@ class AXPEntityPreloadFiltersContainerComponent extends AXPPageLayoutBaseCompone
|
|
|
4055
3938
|
super(...arguments);
|
|
4056
3939
|
//#region ---- Services & Dependencies ----
|
|
4057
3940
|
this.route = inject(ActivatedRoute);
|
|
4058
|
-
this.router = inject(Router);
|
|
4059
3941
|
this.entityService = inject(AXPEntityService);
|
|
4060
3942
|
this.filterOperatorMiddleware = inject(AXPFilterOperatorMiddlewareService);
|
|
4061
3943
|
//#endregion
|
|
@@ -4474,7 +4356,7 @@ class AXPEntityCommandTriggerViewModel {
|
|
|
4474
4356
|
this.priority = action.priority;
|
|
4475
4357
|
this.title = action.title;
|
|
4476
4358
|
this.separated = action.separated ?? false;
|
|
4477
|
-
this.color = action.color ?? resolvedLook.color;
|
|
4359
|
+
this.color = (action.color ?? resolvedLook.color);
|
|
4478
4360
|
this.icon = action.icon ?? resolvedLook.icon;
|
|
4479
4361
|
this.hidden = action.hidden ?? false;
|
|
4480
4362
|
this.disabled = action.disabled ?? false;
|
|
@@ -4566,6 +4448,7 @@ class AXPEntityDetailListViewModel {
|
|
|
4566
4448
|
this.settingsService = this.injector.get(AXPSettingsService);
|
|
4567
4449
|
this.destroyed = new Subject();
|
|
4568
4450
|
this.showRowIndexColumnEnabled = signal(false, ...(ngDevMode ? [{ debugName: "showRowIndexColumnEnabled" }] : /* istanbul ignore next */ []));
|
|
4451
|
+
this.lastAppliedFilterKey = null;
|
|
4569
4452
|
/** Whether the row index column is shown (user setting). */
|
|
4570
4453
|
this.showIndexColumn = computed(() => this.showRowIndexColumnEnabled(), ...(ngDevMode ? [{ debugName: "showIndexColumn" }] : /* istanbul ignore next */ []));
|
|
4571
4454
|
this.dataSource = new AXDataSource({
|
|
@@ -4759,10 +4642,6 @@ class AXPEntityDetailListViewModel {
|
|
|
4759
4642
|
this.applyFilterAndSort();
|
|
4760
4643
|
}
|
|
4761
4644
|
async applyFilterAndSort() {
|
|
4762
|
-
this.dataSource.clearFilter();
|
|
4763
|
-
//
|
|
4764
|
-
//this.dataSource.sort(...this.detailEntity.().map(s => ({ dir: s.dir, field: s.name } as AXDataSourceSortOption)));
|
|
4765
|
-
//
|
|
4766
4645
|
const parentFilters = (await Promise.all(this.detailEntityConfig.conditions?.map(async (c) => {
|
|
4767
4646
|
return {
|
|
4768
4647
|
field: c.name,
|
|
@@ -4780,22 +4659,30 @@ class AXPEntityDetailListViewModel {
|
|
|
4780
4659
|
//
|
|
4781
4660
|
const inline = this.inlineFilters.filters?.length ?? 0;
|
|
4782
4661
|
const parent = parentFilterWrapper.filters?.length ?? 0;
|
|
4783
|
-
|
|
4784
|
-
if (inline) {
|
|
4785
|
-
this.
|
|
4786
|
-
}
|
|
4787
|
-
else if (!inline && parent) {
|
|
4788
|
-
this.dataSource.filter(this.filterOperatorMiddleware.transformFilter(parentFilterWrapper));
|
|
4789
|
-
}
|
|
4790
|
-
else if (inline && parent) {
|
|
4791
|
-
this.dataSource.filter(this.filterOperatorMiddleware.transformFilter({
|
|
4662
|
+
let effectiveFilter;
|
|
4663
|
+
if (inline && parent) {
|
|
4664
|
+
effectiveFilter = this.filterOperatorMiddleware.transformFilter({
|
|
4792
4665
|
field: null,
|
|
4793
4666
|
logic: 'and',
|
|
4794
4667
|
operator: null,
|
|
4795
4668
|
filters: [this.inlineFilters, parentFilterWrapper],
|
|
4796
|
-
})
|
|
4669
|
+
});
|
|
4670
|
+
}
|
|
4671
|
+
else if (inline) {
|
|
4672
|
+
effectiveFilter = this.filterOperatorMiddleware.transformFilter(this.inlineFilters);
|
|
4673
|
+
}
|
|
4674
|
+
else if (parent) {
|
|
4675
|
+
effectiveFilter = this.filterOperatorMiddleware.transformFilter(parentFilterWrapper);
|
|
4676
|
+
}
|
|
4677
|
+
const filterKey = JSON.stringify(effectiveFilter ?? null);
|
|
4678
|
+
if (filterKey === this.lastAppliedFilterKey) {
|
|
4679
|
+
return;
|
|
4680
|
+
}
|
|
4681
|
+
this.lastAppliedFilterKey = filterKey;
|
|
4682
|
+
this.dataSource.clearFilter();
|
|
4683
|
+
if (effectiveFilter) {
|
|
4684
|
+
this.dataSource.filter(effectiveFilter);
|
|
4797
4685
|
}
|
|
4798
|
-
//
|
|
4799
4686
|
this.dataSource.refresh();
|
|
4800
4687
|
}
|
|
4801
4688
|
//****************** Commands ******************//
|
|
@@ -5344,7 +5231,7 @@ class AXPEntityMasterListViewModel {
|
|
|
5344
5231
|
}
|
|
5345
5232
|
}
|
|
5346
5233
|
//#endregion
|
|
5347
|
-
|
|
5234
|
+
createLogicExpressionScope(data) {
|
|
5348
5235
|
return {
|
|
5349
5236
|
context: {
|
|
5350
5237
|
eval: (path) => get(data, path),
|
|
@@ -5355,11 +5242,20 @@ class AXPEntityMasterListViewModel {
|
|
|
5355
5242
|
},
|
|
5356
5243
|
};
|
|
5357
5244
|
}
|
|
5245
|
+
createDisplayExpressionScope(data) {
|
|
5246
|
+
return {
|
|
5247
|
+
context: this.contextEvalFactory.createScope((data ?? {})),
|
|
5248
|
+
list: {
|
|
5249
|
+
view: () => this.view().name,
|
|
5250
|
+
views: () => this.views().map((v) => ({ name: v.name, title: v.title })),
|
|
5251
|
+
},
|
|
5252
|
+
};
|
|
5253
|
+
}
|
|
5358
5254
|
async resolveCommandNameExpression(commandName, data) {
|
|
5359
5255
|
if (!commandName || !commandName.includes('{{')) {
|
|
5360
5256
|
return commandName;
|
|
5361
5257
|
}
|
|
5362
|
-
const scope = this.
|
|
5258
|
+
const scope = this.createLogicExpressionScope(data);
|
|
5363
5259
|
const result = await this.expressionEvaluator.evaluate({ value: commandName }, scope);
|
|
5364
5260
|
const resolved = result?.value;
|
|
5365
5261
|
return typeof resolved === 'string' && resolved.trim() !== '' ? resolved : commandName;
|
|
@@ -5368,7 +5264,7 @@ class AXPEntityMasterListViewModel {
|
|
|
5368
5264
|
if (!title || !title.includes('{{')) {
|
|
5369
5265
|
return title;
|
|
5370
5266
|
}
|
|
5371
|
-
const scope = this.
|
|
5267
|
+
const scope = this.createDisplayExpressionScope(data);
|
|
5372
5268
|
const result = await this.expressionEvaluator.evaluate({ value: title }, scope);
|
|
5373
5269
|
const resolved = result?.value;
|
|
5374
5270
|
return typeof resolved === 'string' && resolved.trim() !== '' ? resolved : title;
|
|
@@ -5383,7 +5279,7 @@ class AXPEntityMasterListViewModel {
|
|
|
5383
5279
|
return '';
|
|
5384
5280
|
}
|
|
5385
5281
|
if (value.includes('{{')) {
|
|
5386
|
-
const scope = this.
|
|
5282
|
+
const scope = this.createDisplayExpressionScope(rowData);
|
|
5387
5283
|
const result = await this.expressionEvaluator.evaluate(value, scope);
|
|
5388
5284
|
if (result === false) {
|
|
5389
5285
|
return '';
|
|
@@ -5421,7 +5317,7 @@ class AXPEntityMasterListViewModel {
|
|
|
5421
5317
|
if (color == null || color === '') {
|
|
5422
5318
|
return 'default';
|
|
5423
5319
|
}
|
|
5424
|
-
const scope = this.
|
|
5320
|
+
const scope = this.createLogicExpressionScope(rowData);
|
|
5425
5321
|
const result = await this.expressionEvaluator.evaluate(color, scope);
|
|
5426
5322
|
if (result === false || result == null) {
|
|
5427
5323
|
return 'default';
|
|
@@ -5469,6 +5365,7 @@ class AXPEntityMasterListViewModel {
|
|
|
5469
5365
|
this.settings = this.injector.get(AXPSettingsService);
|
|
5470
5366
|
this.widgetResolver = this.injector.get(AXPWidgetRegistryService);
|
|
5471
5367
|
this.expressionEvaluator = this.injector.get(AXPExpressionEvaluatorService);
|
|
5368
|
+
this.contextEvalFactory = this.injector.get(AXPContextEvalFactory);
|
|
5472
5369
|
this.translation = this.injector.get(AXTranslationService);
|
|
5473
5370
|
this.commandService = this.injector.get(AXPCommandService);
|
|
5474
5371
|
this.eventService = this.injector.get(AXPBroadcastEventService);
|
|
@@ -5582,8 +5479,11 @@ class AXPEntityMasterListViewModel {
|
|
|
5582
5479
|
return this._viewDef.description ?? null;
|
|
5583
5480
|
}, ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
|
|
5584
5481
|
//****************** Inline filter ******************//
|
|
5482
|
+
this.filterDefinitions = signal([], ...(ngDevMode ? [{ debugName: "filterDefinitions" }] : /* istanbul ignore next */ []));
|
|
5585
5483
|
this.inlineFiltersPlaceholders = computed(() => {
|
|
5586
|
-
return this.
|
|
5484
|
+
return this.filterDefinitions()
|
|
5485
|
+
.filter((f) => f.filterType.inline)
|
|
5486
|
+
.map((c) => c.title ?? c.field);
|
|
5587
5487
|
}, ...(ngDevMode ? [{ debugName: "inlineFiltersPlaceholders" }] : /* istanbul ignore next */ []));
|
|
5588
5488
|
this.hasInlineFilters = computed(() => {
|
|
5589
5489
|
return this.inlineFiltersPlaceholders().length > 0;
|
|
@@ -5691,7 +5591,7 @@ class AXPEntityMasterListViewModel {
|
|
|
5691
5591
|
this.sortedFields = signal([], ...(ngDevMode ? [{ debugName: "sortedFields" }] : /* istanbul ignore next */ []));
|
|
5692
5592
|
//#endregion
|
|
5693
5593
|
this.evaluateExpressions = async (options, data) => {
|
|
5694
|
-
const scope = this.
|
|
5594
|
+
const scope = this.createLogicExpressionScope(data);
|
|
5695
5595
|
return await this.expressionEvaluator.evaluate(options, scope);
|
|
5696
5596
|
};
|
|
5697
5597
|
this.workflow.events$
|
|
@@ -6081,7 +5981,7 @@ class AXPEntityMasterListViewModel {
|
|
|
6081
5981
|
this.selectedCategory.set(category);
|
|
6082
5982
|
}
|
|
6083
5983
|
async getPrimaryActions() {
|
|
6084
|
-
const scope = this.
|
|
5984
|
+
const scope = this.createLogicExpressionScope(null);
|
|
6085
5985
|
const actions = await Promise.all(this.allActions()
|
|
6086
5986
|
.filter((a) => a.priority == 'primary' &&
|
|
6087
5987
|
((a.scope == AXPEntityCommandScope.Selected && this.hasSelectedItems()) ||
|
|
@@ -6098,7 +5998,7 @@ class AXPEntityMasterListViewModel {
|
|
|
6098
5998
|
return actions.filter(Boolean);
|
|
6099
5999
|
}
|
|
6100
6000
|
async getSecondaryActions() {
|
|
6101
|
-
const scope = this.
|
|
6001
|
+
const scope = this.createLogicExpressionScope(null);
|
|
6102
6002
|
const actions = await Promise.all(this.allActions()
|
|
6103
6003
|
.filter((a) => a.priority == 'secondary' &&
|
|
6104
6004
|
((a.scope == AXPEntityCommandScope.Selected && this.hasSelectedItems()) ||
|
|
@@ -6115,7 +6015,7 @@ class AXPEntityMasterListViewModel {
|
|
|
6115
6015
|
return actions.filter(Boolean);
|
|
6116
6016
|
}
|
|
6117
6017
|
async secondaryRowActions(rowData) {
|
|
6118
|
-
const scope = this.
|
|
6018
|
+
const scope = this.createLogicExpressionScope(rowData);
|
|
6119
6019
|
const actions = await Promise.all(this.allActions()
|
|
6120
6020
|
.filter((a) => a.scope === AXPEntityCommandScope.Individual && a.priority === 'secondary')
|
|
6121
6021
|
.map(async (a) => {
|
|
@@ -6276,38 +6176,20 @@ class AXPEntityMasterListViewModel {
|
|
|
6276
6176
|
}
|
|
6277
6177
|
return false;
|
|
6278
6178
|
}
|
|
6279
|
-
|
|
6280
|
-
|
|
6281
|
-
|
|
6282
|
-
|
|
6283
|
-
|
|
6284
|
-
|
|
6285
|
-
const type = (e.options?.filter?.advance?.widgetType ||
|
|
6286
|
-
widgetConfig?.defaultFilterWidgetName ||
|
|
6287
|
-
e.schema.interface?.type);
|
|
6288
|
-
const iface = e.schema.interface ?? {};
|
|
6289
|
-
return {
|
|
6290
|
-
title: e.title,
|
|
6291
|
-
field: e.name,
|
|
6292
|
-
operator: {
|
|
6293
|
-
type: 'contains',
|
|
6294
|
-
},
|
|
6295
|
-
widget: { ...omit(iface, 'triggers'), path: e.name, type },
|
|
6296
|
-
filters: [],
|
|
6297
|
-
isParametric: false,
|
|
6298
|
-
icon: widgetConfig?.icon,
|
|
6299
|
-
filterType: {
|
|
6300
|
-
advance: e.options?.filter?.advance?.enabled ?? false,
|
|
6301
|
-
inline: e.options?.filter?.inline?.enabled ?? false,
|
|
6302
|
-
preload: e.options?.filter?.preload,
|
|
6303
|
-
},
|
|
6304
|
-
// `interface.options.disabled` is for edit forms only; do not gray out advance filters.
|
|
6305
|
-
triggers: e.schema.interface?.triggers,
|
|
6306
|
-
};
|
|
6179
|
+
/**
|
|
6180
|
+
* Loads host and merge-detail related filter definitions (async registry resolution).
|
|
6181
|
+
*/
|
|
6182
|
+
async loadFilterDefinitions() {
|
|
6183
|
+
const definitions = await collectEntityListFilterDefinitions(this.entityDef, (moduleName, entityName) => this.entityDefinitionRegistry.resolve(moduleName, entityName).catch(() => null), {
|
|
6184
|
+
resolveWidget: (type) => this.widgetResolver.resolve(type),
|
|
6307
6185
|
});
|
|
6186
|
+
this.filterDefinitions.set(definitions);
|
|
6187
|
+
}
|
|
6188
|
+
get filtersDef() {
|
|
6189
|
+
return this.filterDefinitions();
|
|
6308
6190
|
}
|
|
6309
6191
|
get preloadFiltersDef() {
|
|
6310
|
-
return this.
|
|
6192
|
+
return this.filterDefinitions().filter((f) => f.filterType.preload?.enabled);
|
|
6311
6193
|
}
|
|
6312
6194
|
// const viewFilters = this.view().conditions.map((f) => ({
|
|
6313
6195
|
// field: f.name,
|
|
@@ -6337,7 +6219,13 @@ class AXPEntityMasterListViewModel {
|
|
|
6337
6219
|
.map((s) => ({ name: s.name, dir: s.dir }));
|
|
6338
6220
|
const filters = this.filterQueries();
|
|
6339
6221
|
const sortKey = JSON.stringify(sorts);
|
|
6340
|
-
const
|
|
6222
|
+
const transformedFilter = this.filterOperatorMiddleware.transformFilter({
|
|
6223
|
+
field: null,
|
|
6224
|
+
logic: 'and',
|
|
6225
|
+
operator: null,
|
|
6226
|
+
filters: filters,
|
|
6227
|
+
});
|
|
6228
|
+
const filterKey = JSON.stringify(transformedFilter);
|
|
6341
6229
|
if (sortKey === this.lastAppliedSortKey && filterKey === this.lastAppliedFilterKey) {
|
|
6342
6230
|
return; // No effective change; avoid redundant refresh
|
|
6343
6231
|
}
|
|
@@ -6349,12 +6237,7 @@ class AXPEntityMasterListViewModel {
|
|
|
6349
6237
|
}
|
|
6350
6238
|
this.dataSource.clearFilter();
|
|
6351
6239
|
this.dataSource.sort(...sorts.map((s) => ({ dir: s.dir, field: s.name })));
|
|
6352
|
-
this.dataSource.filter(
|
|
6353
|
-
field: null,
|
|
6354
|
-
logic: 'and',
|
|
6355
|
-
operator: null,
|
|
6356
|
-
filters: filters,
|
|
6357
|
-
}));
|
|
6240
|
+
this.dataSource.filter(transformedFilter);
|
|
6358
6241
|
this.events$.next({ action: 'refresh', meta: { resetPagination: filtersChanged } });
|
|
6359
6242
|
}
|
|
6360
6243
|
resetColumns() {
|
|
@@ -6751,6 +6634,7 @@ class AXPEntityListViewModelFactory {
|
|
|
6751
6634
|
const config = await this.entityService.resolve(moduleName, entityName);
|
|
6752
6635
|
this.layout.setNavigationLoading(false);
|
|
6753
6636
|
const vm = new AXPEntityMasterListViewModel(this.injector, config);
|
|
6637
|
+
await vm.loadFilterDefinitions();
|
|
6754
6638
|
await vm.initializeListPersistence();
|
|
6755
6639
|
return vm;
|
|
6756
6640
|
}
|
|
@@ -7138,6 +7022,9 @@ class AXPEntityModifySectionPopupAction extends AXPWorkflowAction {
|
|
|
7138
7022
|
this.popupService = inject(AXPopupService);
|
|
7139
7023
|
this.platform = inject(AXPlatform);
|
|
7140
7024
|
this.translateService = inject(AXTranslationService);
|
|
7025
|
+
this.formatService = inject(AXFormatService);
|
|
7026
|
+
this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
|
|
7027
|
+
this.contextEvalFactory = inject(AXPContextEvalFactory);
|
|
7141
7028
|
this.entityRegistery = inject(AXPEntityDefinitionRegistryService);
|
|
7142
7029
|
this.config = inject(AXP_ENTITY_CONFIG_TOKEN);
|
|
7143
7030
|
this.factory = inject(AXPEntityMasterUpdateViewModelFactory);
|
|
@@ -7155,7 +7042,7 @@ class AXPEntityModifySectionPopupAction extends AXPWorkflowAction {
|
|
|
7155
7042
|
title: headerTitle
|
|
7156
7043
|
? headerTitle
|
|
7157
7044
|
: title ??
|
|
7158
|
-
|
|
7045
|
+
(await resolveEntityModifyPopupTitle(entityRef, vm.context(), this.translateService, this.formatService, this.expressionEvaluator, this.contextEvalFactory)),
|
|
7159
7046
|
size: this.platform.is('Mobile') || this.platform.is('SM') ? 'full' : 'md',
|
|
7160
7047
|
data: {
|
|
7161
7048
|
vm,
|
|
@@ -7516,6 +7403,8 @@ class AXPEntityPreloadFiltersViewModel {
|
|
|
7516
7403
|
this.config = config;
|
|
7517
7404
|
this.entityDef = cloneDeep(this.config);
|
|
7518
7405
|
this.widgetResolver = this.injector.get(AXPWidgetRegistryService);
|
|
7406
|
+
this.entityRegistry = this.injector.get(AXPEntityDefinitionRegistryService);
|
|
7407
|
+
this.filterDefinitions = signal([], ...(ngDevMode ? [{ debugName: "filterDefinitions" }] : /* istanbul ignore next */ []));
|
|
7519
7408
|
//#endregion
|
|
7520
7409
|
//#region ---- Computed Properties ----
|
|
7521
7410
|
/**
|
|
@@ -7534,46 +7423,7 @@ class AXPEntityPreloadFiltersViewModel {
|
|
|
7534
7423
|
* All filter definitions for properties with preload enabled
|
|
7535
7424
|
*/
|
|
7536
7425
|
this.preloadFiltersDef = computed(() => {
|
|
7537
|
-
|
|
7538
|
-
return props.map((e) => {
|
|
7539
|
-
const widgetConfig = this.widgetResolver.resolve(e.schema.interface?.type);
|
|
7540
|
-
const type = e.schema.interface?.type;
|
|
7541
|
-
// Merge validations with existing options
|
|
7542
|
-
const validations = e.options?.filter?.preload?.required
|
|
7543
|
-
? [
|
|
7544
|
-
{
|
|
7545
|
-
rule: 'required',
|
|
7546
|
-
message: 'This field is required',
|
|
7547
|
-
options: {},
|
|
7548
|
-
},
|
|
7549
|
-
]
|
|
7550
|
-
: [];
|
|
7551
|
-
const mergedOptions = {
|
|
7552
|
-
...e.schema.interface?.options,
|
|
7553
|
-
validations,
|
|
7554
|
-
};
|
|
7555
|
-
return {
|
|
7556
|
-
title: e.title,
|
|
7557
|
-
field: e.name,
|
|
7558
|
-
operator: {
|
|
7559
|
-
type: 'contains',
|
|
7560
|
-
},
|
|
7561
|
-
widget: {
|
|
7562
|
-
...e.schema.interface,
|
|
7563
|
-
path: e.name,
|
|
7564
|
-
type,
|
|
7565
|
-
options: mergedOptions,
|
|
7566
|
-
},
|
|
7567
|
-
filters: [],
|
|
7568
|
-
isParametric: false,
|
|
7569
|
-
icon: widgetConfig?.icon,
|
|
7570
|
-
filterType: {
|
|
7571
|
-
advance: false,
|
|
7572
|
-
inline: false,
|
|
7573
|
-
preload: e.options?.filter?.preload,
|
|
7574
|
-
},
|
|
7575
|
-
};
|
|
7576
|
-
});
|
|
7426
|
+
return this.filterDefinitions().filter((definition) => definition.filterType.preload?.enabled);
|
|
7577
7427
|
}, ...(ngDevMode ? [{ debugName: "preloadFiltersDef" }] : /* istanbul ignore next */ []));
|
|
7578
7428
|
/**
|
|
7579
7429
|
* Required filter definitions only
|
|
@@ -7582,7 +7432,14 @@ class AXPEntityPreloadFiltersViewModel {
|
|
|
7582
7432
|
return this.preloadFiltersDef().filter((c) => c.filterType.preload?.required);
|
|
7583
7433
|
}, ...(ngDevMode ? [{ debugName: "requiredFiltersDef" }] : /* istanbul ignore next */ []));
|
|
7584
7434
|
}
|
|
7435
|
+
//#endregion
|
|
7585
7436
|
//#region ---- Methods ----
|
|
7437
|
+
async loadFilterDefinitions() {
|
|
7438
|
+
const definitions = await collectEntityListFilterDefinitions(this.entityDef, (moduleName, entityName) => this.entityRegistry.resolve(moduleName, entityName).catch(() => null), {
|
|
7439
|
+
resolveWidget: (type) => this.widgetResolver.resolve(type),
|
|
7440
|
+
});
|
|
7441
|
+
this.filterDefinitions.set(definitions);
|
|
7442
|
+
}
|
|
7586
7443
|
/**
|
|
7587
7444
|
* Serialize filter values to plain objects (remove signals, functions, etc.)
|
|
7588
7445
|
*/
|
|
@@ -7599,7 +7456,9 @@ const AXPEntityPreloadFiltersViewModelResolver = async (route, state) => {
|
|
|
7599
7456
|
const entityName = route.paramMap.get('entity');
|
|
7600
7457
|
try {
|
|
7601
7458
|
const entity = await entityRegistry.resolve(moduleName, entityName);
|
|
7602
|
-
|
|
7459
|
+
const vm = new AXPEntityPreloadFiltersViewModel(injector, entity);
|
|
7460
|
+
await vm.loadFilterDefinitions();
|
|
7461
|
+
return vm;
|
|
7603
7462
|
}
|
|
7604
7463
|
catch (error) {
|
|
7605
7464
|
if (error instanceof AXPNotFoundError) {
|
|
@@ -7610,150 +7469,6 @@ const AXPEntityPreloadFiltersViewModelResolver = async (route, state) => {
|
|
|
7610
7469
|
};
|
|
7611
7470
|
//#endregion
|
|
7612
7471
|
|
|
7613
|
-
//#endregion
|
|
7614
|
-
//#region ---- Quick search: schema-driven field paths ----
|
|
7615
|
-
const NON_TEXT_DATATYPES = new Set([
|
|
7616
|
-
'number',
|
|
7617
|
-
'integer',
|
|
7618
|
-
'int',
|
|
7619
|
-
'long',
|
|
7620
|
-
'float',
|
|
7621
|
-
'double',
|
|
7622
|
-
'decimal',
|
|
7623
|
-
'money',
|
|
7624
|
-
'currency',
|
|
7625
|
-
'boolean',
|
|
7626
|
-
'bool',
|
|
7627
|
-
'date',
|
|
7628
|
-
'datetime',
|
|
7629
|
-
'time',
|
|
7630
|
-
'object',
|
|
7631
|
-
'array',
|
|
7632
|
-
'json',
|
|
7633
|
-
'image',
|
|
7634
|
-
'file',
|
|
7635
|
-
'binary',
|
|
7636
|
-
]);
|
|
7637
|
-
/**
|
|
7638
|
-
* Whether an entity property likely stores free text worth a `contains` quick-search clause.
|
|
7639
|
-
*/
|
|
7640
|
-
function isTextLikeDataType(dataType) {
|
|
7641
|
-
const dt = (dataType ?? 'string').toLowerCase().trim();
|
|
7642
|
-
if (!dt || NON_TEXT_DATATYPES.has(dt)) {
|
|
7643
|
-
return false;
|
|
7644
|
-
}
|
|
7645
|
-
return true;
|
|
7646
|
-
}
|
|
7647
|
-
/**
|
|
7648
|
-
* Lodash-get paths for quick search from a single entity definition: string-like property names
|
|
7649
|
-
* plus lookup `expose[].target` paths (e.g. `brand.title`).
|
|
7650
|
-
*/
|
|
7651
|
-
function collectQuickSearchPathsFromSingleEntityDefinition(entity) {
|
|
7652
|
-
if (!entity?.properties?.length) {
|
|
7653
|
-
return [];
|
|
7654
|
-
}
|
|
7655
|
-
const paths = new Set();
|
|
7656
|
-
for (const p of entity.properties) {
|
|
7657
|
-
if (isTextLikeDataType(p.schema?.dataType)) {
|
|
7658
|
-
paths.add(p.name);
|
|
7659
|
-
}
|
|
7660
|
-
const opts = p.schema?.interface?.options;
|
|
7661
|
-
const expose = opts?.['expose'];
|
|
7662
|
-
if (!Array.isArray(expose)) {
|
|
7663
|
-
continue;
|
|
7664
|
-
}
|
|
7665
|
-
for (const row of expose) {
|
|
7666
|
-
if (row && typeof row === 'object' && typeof row.target === 'string') {
|
|
7667
|
-
const t = (row.target).trim();
|
|
7668
|
-
if (t) {
|
|
7669
|
-
paths.add(t);
|
|
7670
|
-
}
|
|
7671
|
-
}
|
|
7672
|
-
}
|
|
7673
|
-
}
|
|
7674
|
-
return [...paths];
|
|
7675
|
-
}
|
|
7676
|
-
//#endregion
|
|
7677
|
-
//#region ---- Column-derived nested paths ----
|
|
7678
|
-
/**
|
|
7679
|
-
* Adds dotted paths from master columns (`name` or `options.dataPath`), e.g. `person.fullName`, `jobDefinition.title`.
|
|
7680
|
-
*/
|
|
7681
|
-
function collectNestedFieldPathsFromEntityColumns(entity) {
|
|
7682
|
-
if (!entity?.columns?.length) {
|
|
7683
|
-
return [];
|
|
7684
|
-
}
|
|
7685
|
-
const paths = new Set();
|
|
7686
|
-
for (const col of entity.columns) {
|
|
7687
|
-
const name = col.name.trim();
|
|
7688
|
-
if (name.includes('.')) {
|
|
7689
|
-
paths.add(name);
|
|
7690
|
-
}
|
|
7691
|
-
const rawDp = col.options?.['dataPath'];
|
|
7692
|
-
if (typeof rawDp === 'string') {
|
|
7693
|
-
const dp = rawDp.trim();
|
|
7694
|
-
if (dp.includes('.')) {
|
|
7695
|
-
paths.add(dp);
|
|
7696
|
-
}
|
|
7697
|
-
}
|
|
7698
|
-
}
|
|
7699
|
-
return [...paths];
|
|
7700
|
-
}
|
|
7701
|
-
//#endregion
|
|
7702
|
-
//#region ---- Related merge-detail paths ----
|
|
7703
|
-
function parseRelatedEntityFullName(fullName) {
|
|
7704
|
-
const t = fullName.trim();
|
|
7705
|
-
const idx = t.indexOf('.');
|
|
7706
|
-
if (idx <= 0 || idx >= t.length - 1) {
|
|
7707
|
-
return null;
|
|
7708
|
-
}
|
|
7709
|
-
return {
|
|
7710
|
-
moduleName: t.slice(0, idx),
|
|
7711
|
-
entityName: t.slice(idx + 1),
|
|
7712
|
-
};
|
|
7713
|
-
}
|
|
7714
|
-
//#endregion
|
|
7715
|
-
//#region ---- Public API ----
|
|
7716
|
-
/**
|
|
7717
|
-
* Collects lodash-get field paths used for mock/API quick search (`contains` / OR filters):
|
|
7718
|
-
* host properties and lookup expose targets, dotted column paths, and merge-detail related entities
|
|
7719
|
-
* prefixed with the related entity merge `persistence.dataPath` (e.g. `person.firstName`).
|
|
7720
|
-
*/
|
|
7721
|
-
async function collectEntityQuickSearchFieldPaths(entity, resolveRelatedDefinition) {
|
|
7722
|
-
if (!entity) {
|
|
7723
|
-
return [];
|
|
7724
|
-
}
|
|
7725
|
-
const paths = new Set();
|
|
7726
|
-
for (const p of collectQuickSearchPathsFromSingleEntityDefinition(entity)) {
|
|
7727
|
-
paths.add(p);
|
|
7728
|
-
}
|
|
7729
|
-
for (const p of collectNestedFieldPathsFromEntityColumns(entity)) {
|
|
7730
|
-
paths.add(p);
|
|
7731
|
-
}
|
|
7732
|
-
const related = entity.relatedEntities ?? [];
|
|
7733
|
-
for (const rel of related) {
|
|
7734
|
-
const dataPath = rel.persistence?.dataPath?.trim();
|
|
7735
|
-
if (!dataPath || rel.layout?.type !== 'merge-detail') {
|
|
7736
|
-
continue;
|
|
7737
|
-
}
|
|
7738
|
-
const parsed = rel.entity ? parseRelatedEntityFullName(rel.entity) : null;
|
|
7739
|
-
if (!parsed) {
|
|
7740
|
-
continue;
|
|
7741
|
-
}
|
|
7742
|
-
const relatedDef = await resolveRelatedDefinition(parsed.moduleName, parsed.entityName);
|
|
7743
|
-
if (!relatedDef) {
|
|
7744
|
-
continue;
|
|
7745
|
-
}
|
|
7746
|
-
for (const p of collectQuickSearchPathsFromSingleEntityDefinition(relatedDef)) {
|
|
7747
|
-
paths.add(`${dataPath}.${p}`);
|
|
7748
|
-
}
|
|
7749
|
-
for (const p of collectNestedFieldPathsFromEntityColumns(relatedDef)) {
|
|
7750
|
-
paths.add(`${dataPath}.${p}`);
|
|
7751
|
-
}
|
|
7752
|
-
}
|
|
7753
|
-
return [...paths];
|
|
7754
|
-
}
|
|
7755
|
-
//#endregion
|
|
7756
|
-
|
|
7757
7472
|
//#region ---- Path / numeric helpers ----
|
|
7758
7473
|
function getPath(obj, path) {
|
|
7759
7474
|
if (obj == null || path.length === 0) {
|
|
@@ -12392,6 +12107,7 @@ class AXPEntityListTableService {
|
|
|
12392
12107
|
const evaluatedOptions = await this.evaluateExpressions(action?.options, data);
|
|
12393
12108
|
const options = this.mergeRelatedListFormOptions(command, evaluatedOptions, relatedListExcludeProperties);
|
|
12394
12109
|
if (this.commandService.exists(command)) {
|
|
12110
|
+
const excludeProperties = options['excludeProperties'];
|
|
12395
12111
|
await this.commandService.execute(command, {
|
|
12396
12112
|
__context__: {
|
|
12397
12113
|
entity: getEntityInfo(entity).source,
|
|
@@ -12408,6 +12124,7 @@ class AXPEntityListTableService {
|
|
|
12408
12124
|
},
|
|
12409
12125
|
options,
|
|
12410
12126
|
metadata: action?.metadata,
|
|
12127
|
+
...(excludeProperties?.length ? { excludeProperties } : {}),
|
|
12411
12128
|
});
|
|
12412
12129
|
}
|
|
12413
12130
|
else {
|
|
@@ -12433,7 +12150,7 @@ class AXPEntityListTableService {
|
|
|
12433
12150
|
mergeRelatedListFormOptions(command, evaluatedOptions, relatedListExcludeProperties) {
|
|
12434
12151
|
const exclusions = relatedListExcludeProperties?.filter(Boolean);
|
|
12435
12152
|
if (!exclusions?.length ||
|
|
12436
|
-
(command !== 'Entity:Create' && command !== 'Entity:Update')) {
|
|
12153
|
+
(command !== 'Entity:Create' && command !== 'Entity:Update' && command !== 'Entity:View')) {
|
|
12437
12154
|
return evaluatedOptions;
|
|
12438
12155
|
}
|
|
12439
12156
|
return {
|
|
@@ -12484,6 +12201,7 @@ class AXPEntityListToolbarService {
|
|
|
12484
12201
|
constructor() {
|
|
12485
12202
|
//#region ---- Services & Dependencies ----
|
|
12486
12203
|
this.widgetResolver = inject(AXPWidgetRegistryService);
|
|
12204
|
+
this.entityRegistry = inject(AXPEntityDefinitionRegistryService);
|
|
12487
12205
|
}
|
|
12488
12206
|
//#endregion
|
|
12489
12207
|
//#region ---- Public Methods ----
|
|
@@ -12491,7 +12209,7 @@ class AXPEntityListToolbarService {
|
|
|
12491
12209
|
* Convert Entity to Toolbar Options
|
|
12492
12210
|
*/
|
|
12493
12211
|
async convertEntityToolbarOptions(entity, options) {
|
|
12494
|
-
const baseFilters = this.createFilterDefinitions(entity);
|
|
12212
|
+
const baseFilters = await this.createFilterDefinitions(entity);
|
|
12495
12213
|
const toolbarOptions = {
|
|
12496
12214
|
filterDefinitions: this.mergeFilterDefinitions(baseFilters, options?.customFilterDefinitions),
|
|
12497
12215
|
columnDefinitions: this.createColumnDefinitions(entity, options),
|
|
@@ -12571,30 +12289,9 @@ class AXPEntityListToolbarService {
|
|
|
12571
12289
|
/**
|
|
12572
12290
|
* Create Filter Definitions for Toolbar
|
|
12573
12291
|
*/
|
|
12574
|
-
createFilterDefinitions(entity) {
|
|
12575
|
-
|
|
12576
|
-
|
|
12577
|
-
const widgetConfig = this.widgetResolver.resolve(e.schema.interface?.type);
|
|
12578
|
-
const type = (e.options?.filter?.advance?.widgetType ||
|
|
12579
|
-
widgetConfig?.defaultFilterWidgetName ||
|
|
12580
|
-
e.schema.interface?.type);
|
|
12581
|
-
const iface = e.schema.interface ?? {};
|
|
12582
|
-
return {
|
|
12583
|
-
title: e.title,
|
|
12584
|
-
field: e.name,
|
|
12585
|
-
operator: {
|
|
12586
|
-
type: 'contains',
|
|
12587
|
-
},
|
|
12588
|
-
widget: { ...omit(iface, 'triggers'), path: e.name, type },
|
|
12589
|
-
filters: [],
|
|
12590
|
-
isParametric: false,
|
|
12591
|
-
icon: widgetConfig?.icon,
|
|
12592
|
-
filterType: {
|
|
12593
|
-
advance: e.options?.filter?.advance?.enabled ?? false,
|
|
12594
|
-
inline: e.options?.filter?.inline?.enabled ?? false,
|
|
12595
|
-
},
|
|
12596
|
-
triggers: e.schema.interface?.triggers,
|
|
12597
|
-
};
|
|
12292
|
+
async createFilterDefinitions(entity) {
|
|
12293
|
+
return collectEntityListFilterDefinitions(entity, (moduleName, entityName) => this.entityRegistry.resolve(moduleName, entityName).catch(() => null), {
|
|
12294
|
+
resolveWidget: (type) => this.widgetResolver.resolve(type),
|
|
12598
12295
|
});
|
|
12599
12296
|
}
|
|
12600
12297
|
/**
|
|
@@ -13977,6 +13674,8 @@ class AXPLookupWidgetViewComponent extends AXPValueWidgetComponent {
|
|
|
13977
13674
|
super(...arguments);
|
|
13978
13675
|
this.formatService = inject(AXFormatService);
|
|
13979
13676
|
this.translation = inject(AXTranslationService);
|
|
13677
|
+
this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
|
|
13678
|
+
this.contextEvalFactory = inject(AXPContextEvalFactory);
|
|
13980
13679
|
this.entityResolver = inject(AXPEntityDefinitionRegistryService);
|
|
13981
13680
|
this.entity = computed(() => this.options()['entity'], ...(ngDevMode ? [{ debugName: "entity" }] : /* istanbul ignore next */ []));
|
|
13982
13681
|
this.multiple = computed(() => this.options()['multiple'], ...(ngDevMode ? [{ debugName: "multiple" }] : /* istanbul ignore next */ []));
|
|
@@ -14010,7 +13709,7 @@ class AXPLookupWidgetViewComponent extends AXPValueWidgetComponent {
|
|
|
14010
13709
|
if (typeof item == 'object') {
|
|
14011
13710
|
return {
|
|
14012
13711
|
id: item[this.valueField()],
|
|
14013
|
-
text: this.getDisplayRaw(item),
|
|
13712
|
+
text: await this.getDisplayRaw(item),
|
|
14014
13713
|
};
|
|
14015
13714
|
}
|
|
14016
13715
|
const def = this.entityDef();
|
|
@@ -14021,7 +13720,7 @@ class AXPLookupWidgetViewComponent extends AXPValueWidgetComponent {
|
|
|
14021
13720
|
this.loading.set(false);
|
|
14022
13721
|
return {
|
|
14023
13722
|
id: fetchedItem[this.valueField()],
|
|
14024
|
-
text: this.getDisplayRaw(fetchedItem),
|
|
13723
|
+
text: await this.getDisplayRaw(fetchedItem),
|
|
14025
13724
|
};
|
|
14026
13725
|
}
|
|
14027
13726
|
return {
|
|
@@ -14029,12 +13728,17 @@ class AXPLookupWidgetViewComponent extends AXPValueWidgetComponent {
|
|
|
14029
13728
|
text: item,
|
|
14030
13729
|
};
|
|
14031
13730
|
}
|
|
14032
|
-
getDisplayRaw(item) {
|
|
14033
|
-
const
|
|
13731
|
+
async getDisplayRaw(item) {
|
|
13732
|
+
const locale = this.translation.getActiveLang() ?? 'en-US';
|
|
13733
|
+
return formatLookupItemDisplayAsync(item, this.entityDef(), {
|
|
14034
13734
|
displayFormat: this.options()['displayFormat'],
|
|
14035
13735
|
textField: this.textField(),
|
|
14036
|
-
}, this.formatService,
|
|
14037
|
-
|
|
13736
|
+
}, this.formatService, {
|
|
13737
|
+
expressionEvaluator: this.expressionEvaluator,
|
|
13738
|
+
contextEvalFactory: this.contextEvalFactory,
|
|
13739
|
+
translationService: this.translation,
|
|
13740
|
+
locale,
|
|
13741
|
+
}, (value) => this.translation.resolve(value));
|
|
14038
13742
|
}
|
|
14039
13743
|
get __class() {
|
|
14040
13744
|
const cls = {};
|
|
@@ -15184,6 +14888,8 @@ class AXPLookupWidgetTagboxComponent extends LookupWidgetLookBase {
|
|
|
15184
14888
|
this.formatService = inject(AXFormatService);
|
|
15185
14889
|
this.translateService = inject(AXTranslationService);
|
|
15186
14890
|
this.entityDataSelectorService = inject(AXPEntityDataSelectorService);
|
|
14891
|
+
this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
|
|
14892
|
+
this.contextEvalFactory = inject(AXPContextEvalFactory);
|
|
15187
14893
|
//#endregion
|
|
15188
14894
|
//#region ---- Inputs ----
|
|
15189
14895
|
this.selectedItems = input.required(...(ngDevMode ? [{ debugName: "selectedItems" }] : /* istanbul ignore next */ []));
|
|
@@ -15213,6 +14919,8 @@ class AXPLookupWidgetTagboxComponent extends LookupWidgetLookBase {
|
|
|
15213
14919
|
//#region ---- Internal State ----
|
|
15214
14920
|
this.searchTerm = signal('', ...(ngDevMode ? [{ debugName: "searchTerm" }] : /* istanbul ignore next */ []));
|
|
15215
14921
|
this.isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
|
|
14922
|
+
this.itemLabels = signal({}, ...(ngDevMode ? [{ debugName: "itemLabels" }] : /* istanbul ignore next */ []));
|
|
14923
|
+
this.itemLabelsVersion = 0;
|
|
15216
14924
|
//#endregion
|
|
15217
14925
|
//#region ---- View Children ----
|
|
15218
14926
|
this.tagBox = viewChild('tagBoxComponent', ...(ngDevMode ? [{ debugName: "tagBox" }] : /* istanbul ignore next */ []));
|
|
@@ -15235,6 +14943,31 @@ class AXPLookupWidgetTagboxComponent extends LookupWidgetLookBase {
|
|
|
15235
14943
|
}
|
|
15236
14944
|
}
|
|
15237
14945
|
}, ...(ngDevMode ? [{ debugName: "#focusEffect" }] : /* istanbul ignore next */ []));
|
|
14946
|
+
this.#itemLabelsEffect = effect(() => {
|
|
14947
|
+
void this.translateService.getActiveLang();
|
|
14948
|
+
const items = this.selectedItemsValue();
|
|
14949
|
+
const entityDef = this.entityDef()();
|
|
14950
|
+
const valueField = this.valueFieldValue();
|
|
14951
|
+
const version = ++this.itemLabelsVersion;
|
|
14952
|
+
void Promise.all(items.map(async (item) => {
|
|
14953
|
+
const id = String(get(item, valueField) ?? '');
|
|
14954
|
+
const label = await formatLookupItemDisplayAsync(item, entityDef, {
|
|
14955
|
+
displayFormat: this.displayFormatValue(),
|
|
14956
|
+
textField: this.displayFieldValue(),
|
|
14957
|
+
}, this.formatService, {
|
|
14958
|
+
expressionEvaluator: this.expressionEvaluator,
|
|
14959
|
+
contextEvalFactory: this.contextEvalFactory,
|
|
14960
|
+
translationService: this.translateService,
|
|
14961
|
+
locale: this.translateService.getActiveLang() ?? 'en-US',
|
|
14962
|
+
}, (value) => this.translateService.resolve(value));
|
|
14963
|
+
return [id, label];
|
|
14964
|
+
})).then((entries) => {
|
|
14965
|
+
if (version !== this.itemLabelsVersion) {
|
|
14966
|
+
return;
|
|
14967
|
+
}
|
|
14968
|
+
this.itemLabels.set(Object.fromEntries(entries));
|
|
14969
|
+
});
|
|
14970
|
+
}, ...(ngDevMode ? [{ debugName: "#itemLabelsEffect" }] : /* istanbul ignore next */ []));
|
|
15238
14971
|
//#endregion
|
|
15239
14972
|
//#region ---- Computed Properties ----
|
|
15240
14973
|
this.tagBoxComponent = computed(() => this.tagBox(), ...(ngDevMode ? [{ debugName: "tagBoxComponent" }] : /* istanbul ignore next */ []));
|
|
@@ -15250,6 +14983,7 @@ class AXPLookupWidgetTagboxComponent extends LookupWidgetLookBase {
|
|
|
15250
14983
|
this.placeholderValue = computed(() => this.placeholder()?.() ?? '', ...(ngDevMode ? [{ debugName: "placeholderValue" }] : /* istanbul ignore next */ []));
|
|
15251
14984
|
}
|
|
15252
14985
|
#focusEffect;
|
|
14986
|
+
#itemLabelsEffect;
|
|
15253
14987
|
focus() {
|
|
15254
14988
|
this.shouldFocus.set(true);
|
|
15255
14989
|
}
|
|
@@ -15315,11 +15049,9 @@ class AXPLookupWidgetTagboxComponent extends LookupWidgetLookBase {
|
|
|
15315
15049
|
}
|
|
15316
15050
|
//#endregion
|
|
15317
15051
|
//#region ---- Utility Methods ----
|
|
15318
|
-
|
|
15319
|
-
|
|
15320
|
-
|
|
15321
|
-
textField: this.displayFieldValue(),
|
|
15322
|
-
}, this.formatService, (value) => this.translateService.resolve(value));
|
|
15052
|
+
getItemLabel(item) {
|
|
15053
|
+
const id = String(get(item, this.valueFieldValue()) ?? '');
|
|
15054
|
+
return this.itemLabels()[id] ?? '';
|
|
15323
15055
|
}
|
|
15324
15056
|
/**
|
|
15325
15057
|
* Get current input value from tag box
|
|
@@ -15466,7 +15198,7 @@ class AXPLookupWidgetTagboxComponent extends LookupWidgetLookBase {
|
|
|
15466
15198
|
</ax-tag-box>
|
|
15467
15199
|
<ng-template #tagTemplate let-item let-index="index">
|
|
15468
15200
|
<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">
|
|
15469
|
-
<span>{{
|
|
15201
|
+
<span>{{ getItemLabel(item) }}</span>
|
|
15470
15202
|
<button type="button" (click)="tagBoxComponent.removeItem(index)">
|
|
15471
15203
|
<ax-icon class="ax-icon ax-icon-close"></ax-icon>
|
|
15472
15204
|
</button>
|
|
@@ -15526,7 +15258,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
15526
15258
|
</ax-tag-box>
|
|
15527
15259
|
<ng-template #tagTemplate let-item let-index="index">
|
|
15528
15260
|
<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">
|
|
15529
|
-
<span>{{
|
|
15261
|
+
<span>{{ getItemLabel(item) }}</span>
|
|
15530
15262
|
<button type="button" (click)="tagBoxComponent.removeItem(index)">
|
|
15531
15263
|
<ax-icon class="ax-icon ax-icon-close"></ax-icon>
|
|
15532
15264
|
</button>
|
|
@@ -16004,6 +15736,8 @@ class AXPLookupWidgetColumnComponent extends AXPColumnWidgetComponent {
|
|
|
16004
15736
|
this.entityService = inject(AXPEntityService);
|
|
16005
15737
|
this.entityResolver = inject(AXPEntityDefinitionRegistryService);
|
|
16006
15738
|
this.queryExecutor = inject(AXPQueryExecutor);
|
|
15739
|
+
this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
|
|
15740
|
+
this.contextEvalFactory = inject(AXPContextEvalFactory);
|
|
16007
15741
|
//#endregion
|
|
16008
15742
|
//#region ---- View Children ----
|
|
16009
15743
|
this.moreButton = viewChild('moreButton', ...(ngDevMode ? [{ debugName: "moreButton" }] : /* istanbul ignore next */ []));
|
|
@@ -16041,11 +15775,16 @@ class AXPLookupWidgetColumnComponent extends AXPColumnWidgetComponent {
|
|
|
16041
15775
|
this.resolveError = signal(null, ...(ngDevMode ? [{ debugName: "resolveError" }] : /* istanbul ignore next */ []));
|
|
16042
15776
|
this.summaryLabel = signal('', ...(ngDevMode ? [{ debugName: "summaryLabel" }] : /* istanbul ignore next */ []));
|
|
16043
15777
|
this.popoverHeader = signal('', ...(ngDevMode ? [{ debugName: "popoverHeader" }] : /* istanbul ignore next */ []));
|
|
15778
|
+
this.mainItemLabels = signal([], ...(ngDevMode ? [{ debugName: "mainItemLabels" }] : /* istanbul ignore next */ []));
|
|
15779
|
+
this.lazyPopoverItemLabels = signal([], ...(ngDevMode ? [{ debugName: "lazyPopoverItemLabels" }] : /* istanbul ignore next */ []));
|
|
16044
15780
|
this.entityDef = signal(null, ...(ngDevMode ? [{ debugName: "entityDef" }] : /* istanbul ignore next */ []));
|
|
16045
15781
|
this.hydratedDisplayItems = signal(null, ...(ngDevMode ? [{ debugName: "hydratedDisplayItems" }] : /* istanbul ignore next */ []));
|
|
16046
15782
|
this.hydrateRequestId = 0;
|
|
15783
|
+
this.mainLabelsVersion = 0;
|
|
15784
|
+
this.lazyPopoverLabelsVersion = 0;
|
|
16047
15785
|
//#endregion
|
|
16048
15786
|
//#region ---- Computed ----
|
|
15787
|
+
this.popoverItemLabels = computed(() => this.isHydratedStrategy() ? this.mainItemLabels() : this.lazyPopoverItemLabels(), ...(ngDevMode ? [{ debugName: "popoverItemLabels" }] : /* istanbul ignore next */ []));
|
|
16049
15788
|
this.displayItems = computed(() => isNil(this.rawValue)
|
|
16050
15789
|
? []
|
|
16051
15790
|
: castArray(this.rawValue)
|
|
@@ -16165,6 +15904,36 @@ class AXPLookupWidgetColumnComponent extends AXPColumnWidgetComponent {
|
|
|
16165
15904
|
}
|
|
16166
15905
|
void this.hydrateScalarIds(entityKey, values);
|
|
16167
15906
|
});
|
|
15907
|
+
effect(() => {
|
|
15908
|
+
void this.translation.getActiveLang();
|
|
15909
|
+
this.entityDef();
|
|
15910
|
+
const items = this.allItems();
|
|
15911
|
+
const version = ++this.mainLabelsVersion;
|
|
15912
|
+
void this.resolveLabelsForItems(items).then((labels) => {
|
|
15913
|
+
if (version === this.mainLabelsVersion) {
|
|
15914
|
+
this.mainItemLabels.set(labels);
|
|
15915
|
+
}
|
|
15916
|
+
});
|
|
15917
|
+
});
|
|
15918
|
+
effect(() => {
|
|
15919
|
+
if (this.isHydratedStrategy()) {
|
|
15920
|
+
return;
|
|
15921
|
+
}
|
|
15922
|
+
void this.translation.getActiveLang();
|
|
15923
|
+
this.entityDef();
|
|
15924
|
+
const status = this.resolveStatus();
|
|
15925
|
+
const items = this.resolvedPopoverItems();
|
|
15926
|
+
if (status !== 'ready') {
|
|
15927
|
+
this.lazyPopoverItemLabels.set([]);
|
|
15928
|
+
return;
|
|
15929
|
+
}
|
|
15930
|
+
const version = ++this.lazyPopoverLabelsVersion;
|
|
15931
|
+
void this.resolveLabelsForItems(items).then((labels) => {
|
|
15932
|
+
if (version === this.lazyPopoverLabelsVersion) {
|
|
15933
|
+
this.lazyPopoverItemLabels.set(labels);
|
|
15934
|
+
}
|
|
15935
|
+
});
|
|
15936
|
+
});
|
|
16168
15937
|
}
|
|
16169
15938
|
//#endregion
|
|
16170
15939
|
//#region ---- Public methods ----
|
|
@@ -16220,7 +15989,9 @@ class AXPLookupWidgetColumnComponent extends AXPColumnWidgetComponent {
|
|
|
16220
15989
|
let resolvedTitle = '';
|
|
16221
15990
|
if (headerItem != null && this.hasDisplayTextOnLookupValue(headerItem)) {
|
|
16222
15991
|
resolvedTitle =
|
|
16223
|
-
typeof headerItem === 'object'
|
|
15992
|
+
typeof headerItem === 'object'
|
|
15993
|
+
? await this.resolveItemLabel(headerItem)
|
|
15994
|
+
: this.formatDisplayValue(headerItem);
|
|
16224
15995
|
}
|
|
16225
15996
|
else if (!this.isMultiValueLookup()) {
|
|
16226
15997
|
const rowText = this.getRowDisplayTextFromTextField();
|
|
@@ -16229,8 +16000,7 @@ class AXPLookupWidgetColumnComponent extends AXPColumnWidgetComponent {
|
|
|
16229
16000
|
}
|
|
16230
16001
|
}
|
|
16231
16002
|
if (!resolvedTitle) {
|
|
16232
|
-
|
|
16233
|
-
resolvedTitle = typeof displayTitle === 'string' ? displayTitle : this.translation.resolve(displayTitle);
|
|
16003
|
+
resolvedTitle = await this.resolveItemLabel(headerItem);
|
|
16234
16004
|
if (isUnresolvedEntityDisplayTemplate(resolvedTitle)) {
|
|
16235
16005
|
resolvedTitle = '';
|
|
16236
16006
|
}
|
|
@@ -16296,8 +16066,22 @@ class AXPLookupWidgetColumnComponent extends AXPColumnWidgetComponent {
|
|
|
16296
16066
|
const values = castArray(raw).filter((value) => value != null && value !== '');
|
|
16297
16067
|
return values.length > 0 && values.every((value) => this.hasDisplayTextOnLookupValue(value));
|
|
16298
16068
|
}
|
|
16299
|
-
|
|
16300
|
-
|
|
16069
|
+
getItemLabel(index) {
|
|
16070
|
+
return this.mainItemLabels()[index] ?? '';
|
|
16071
|
+
}
|
|
16072
|
+
getPopoverItemLabel(index) {
|
|
16073
|
+
return this.popoverItemLabels()[index] ?? '';
|
|
16074
|
+
}
|
|
16075
|
+
//#endregion
|
|
16076
|
+
//#region ---- Private methods ----
|
|
16077
|
+
async resolveLabelsForItems(items) {
|
|
16078
|
+
return Promise.all(items.map((item) => this.resolveItemLabel(item)));
|
|
16079
|
+
}
|
|
16080
|
+
async resolveItemLabel(item) {
|
|
16081
|
+
if (item == null) {
|
|
16082
|
+
return '';
|
|
16083
|
+
}
|
|
16084
|
+
if (typeof item === 'object' && this.translation.isValidMultiLanguageObject(item)) {
|
|
16301
16085
|
return this.translation.resolve(item);
|
|
16302
16086
|
}
|
|
16303
16087
|
if (!this.isMultiValueLookup()) {
|
|
@@ -16306,16 +16090,19 @@ class AXPLookupWidgetColumnComponent extends AXPColumnWidgetComponent {
|
|
|
16306
16090
|
return this.formatDisplayValue(rowText);
|
|
16307
16091
|
}
|
|
16308
16092
|
}
|
|
16309
|
-
if (
|
|
16310
|
-
if (typeof item
|
|
16311
|
-
return this.
|
|
16093
|
+
if (this.hasDisplayTextOnLookupValue(item)) {
|
|
16094
|
+
if (typeof item !== 'object') {
|
|
16095
|
+
return this.formatDisplayValue(item);
|
|
16312
16096
|
}
|
|
16313
|
-
return this.formatDisplayValue(item);
|
|
16314
16097
|
}
|
|
16315
|
-
|
|
16098
|
+
const locale = this.translation.getActiveLang() ?? 'en-US';
|
|
16099
|
+
return formatLookupItemDisplayAsync(item, this.entityDef(), this.lookupDisplayOptions(), this.formatService, {
|
|
16100
|
+
expressionEvaluator: this.expressionEvaluator,
|
|
16101
|
+
contextEvalFactory: this.contextEvalFactory,
|
|
16102
|
+
translationService: this.translation,
|
|
16103
|
+
locale,
|
|
16104
|
+
}, (value) => this.translation.resolve(value));
|
|
16316
16105
|
}
|
|
16317
|
-
//#endregion
|
|
16318
|
-
//#region ---- Private methods ----
|
|
16319
16106
|
async refreshSummaryLabel(count) {
|
|
16320
16107
|
const text = await this.translation.translateAsync('@general:widgets.lookup.column.items-count', {
|
|
16321
16108
|
params: { count: String(count) },
|
|
@@ -16639,10 +16426,6 @@ class AXPLookupWidgetColumnComponent extends AXPColumnWidgetComponent {
|
|
|
16639
16426
|
return !isNil(candidate) && candidate !== '' && !this.isLikelyEntityId(candidate);
|
|
16640
16427
|
});
|
|
16641
16428
|
}
|
|
16642
|
-
renderLookupLabel(value) {
|
|
16643
|
-
const label = formatLookupItemDisplay(value, this.entityDef(), this.lookupDisplayOptions(), this.formatService, (item) => this.translation.resolve(item));
|
|
16644
|
-
return typeof label === 'string' ? label : this.translation.resolve(label);
|
|
16645
|
-
}
|
|
16646
16429
|
formatDisplayValue(value) {
|
|
16647
16430
|
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
|
|
16648
16431
|
return String(value);
|
|
@@ -16663,11 +16446,11 @@ class AXPLookupWidgetColumnComponent extends AXPColumnWidgetComponent {
|
|
|
16663
16446
|
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value) || /^\d+$/.test(value);
|
|
16664
16447
|
}
|
|
16665
16448
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLookupWidgetColumnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
16666
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPLookupWidgetColumnComponent, isStandalone: true, selector: "ng-component", inputs: { rawValue: "rawValue", rowData: "rowData" }, viewQueries: [{ propertyName: "moreButton", first: true, predicate: ["moreButton"], descendants: true, isSignal: true }, { propertyName: "lazyTrigger", first: true, predicate: ["lazyTrigger"], descendants: true, isSignal: true }, { propertyName: "morePopover", first: true, predicate: ["morePopover"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@if (isHydratedStrategy()) {\n<div class=\"ax-relative ax-flex ax-min-w-0 ax-items-center ax-gap-1\">\n
|
|
16449
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPLookupWidgetColumnComponent, isStandalone: true, selector: "ng-component", inputs: { rawValue: "rawValue", rowData: "rowData" }, viewQueries: [{ propertyName: "moreButton", first: true, predicate: ["moreButton"], descendants: true, isSignal: true }, { propertyName: "lazyTrigger", first: true, predicate: ["lazyTrigger"], descendants: true, isSignal: true }, { propertyName: "morePopover", first: true, predicate: ["morePopover"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@if (isHydratedStrategy()) {\n <div class=\"ax-relative ax-flex ax-min-w-0 ax-items-center ax-gap-1\">\n @for (item of visibleItems(); track $index) {\n <span\n [class.ax-cursor-pointer]=\"detailPopoverEnabled()\"\n [class.hover:ax-text-primary]=\"detailPopoverEnabled()\"\n [class.hover:ax-underline]=\"detailPopoverEnabled()\"\n (click)=\"handleItemClick($index, $event)\"\n >\n {{ getItemLabel($index) }}\n </span>\n @if ($index < visibleItems().length - 1) {\n <span class=\"ax-text-muted\">\u2022</span>\n }\n } @empty {\n <span class=\"ax-text-muted\">---</span>\n }\n @if (hasMoreItems()) {\n <span\n class=\"ax-absolute ax-end-0 ax-flex ax-h-full ax-cursor-pointer ax-items-center ax-px-1 hover:ax-primary-lighter\"\n (click)=\"showMoreItems(); $event.stopPropagation()\"\n #moreButton\n >\n <i class=\"fa-light fa-ellipsis-vertical\"></i>\n </span>\n }\n </div>\n} @else {\n <div class=\"ax-flex ax-min-w-0 ax-items-center ax-gap-1\">\n @if (displayCount() > 0) {\n <span\n class=\"ax-cursor-pointer ax-text-primary hover:ax-underline\"\n (click)=\"openLazyPopover(); $event.stopPropagation()\"\n #lazyTrigger\n >\n {{ summaryLabel() }}\n </span>\n } @else {\n <span class=\"ax-text-muted\">---</span>\n }\n </div>\n}\n\n<ax-popover [openOn]=\"'manual'\" #morePopover (openChange)=\"onPopoverOpenChange($event)\">\n <div class=\"ax-lightest-surface dark:ax-dark-surface ax-min-w-[280px] ax-rounded-lg ax-p-4 ax-shadow-lg\">\n <div class=\"ax-mb-4 ax-border-b ax-pb-2\">\n <h3 class=\"ax-text-base ax-font-semibold\">{{ popoverHeader() }}</h3>\n </div>\n\n @if (!isHydratedStrategy() && resolveStatus() === 'loading') {\n <div class=\"ax-flex ax-min-h-[120px] ax-items-center ax-justify-center\">\n <ax-loading></ax-loading>\n </div>\n } @else if (!isHydratedStrategy() && resolveStatus() === 'error') {\n <div class=\"ax-text-danger ax-text-sm\">{{ resolveError() }}</div>\n } @else {\n <div class=\"ax-flex ax-max-h-64 ax-flex-col ax-gap-3\">\n @for (item of popoverListItems(); track $index) {\n <span\n [class.ax-cursor-pointer]=\"detailPopoverEnabled()\"\n [class.hover:ax-text-primary]=\"detailPopoverEnabled()\"\n [class.hover:ax-underline]=\"detailPopoverEnabled()\"\n (click)=\"handlePopoverItemClick($index, $event)\"\n >\n {{ getPopoverItemLabel($index) }}\n </span>\n } @empty {\n <span class=\"ax-text-muted\">---</span>\n }\n </div>\n }\n </div>\n</ax-popover>\n", dependencies: [{ kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i1$2.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i2$3.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disablePanelClass", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "closeOnScroll", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
16667
16450
|
}
|
|
16668
16451
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLookupWidgetColumnComponent, decorators: [{
|
|
16669
16452
|
type: Component,
|
|
16670
|
-
args: [{ changeDetection: ChangeDetectionStrategy.OnPush, imports: [AXLoadingModule, AXPopoverModule], inputs: ['rawValue', 'rowData'], template: "@if (isHydratedStrategy()) {\n<div class=\"ax-relative ax-flex ax-min-w-0 ax-items-center ax-gap-1\">\n
|
|
16453
|
+
args: [{ changeDetection: ChangeDetectionStrategy.OnPush, imports: [AXLoadingModule, AXPopoverModule], inputs: ['rawValue', 'rowData'], template: "@if (isHydratedStrategy()) {\n <div class=\"ax-relative ax-flex ax-min-w-0 ax-items-center ax-gap-1\">\n @for (item of visibleItems(); track $index) {\n <span\n [class.ax-cursor-pointer]=\"detailPopoverEnabled()\"\n [class.hover:ax-text-primary]=\"detailPopoverEnabled()\"\n [class.hover:ax-underline]=\"detailPopoverEnabled()\"\n (click)=\"handleItemClick($index, $event)\"\n >\n {{ getItemLabel($index) }}\n </span>\n @if ($index < visibleItems().length - 1) {\n <span class=\"ax-text-muted\">\u2022</span>\n }\n } @empty {\n <span class=\"ax-text-muted\">---</span>\n }\n @if (hasMoreItems()) {\n <span\n class=\"ax-absolute ax-end-0 ax-flex ax-h-full ax-cursor-pointer ax-items-center ax-px-1 hover:ax-primary-lighter\"\n (click)=\"showMoreItems(); $event.stopPropagation()\"\n #moreButton\n >\n <i class=\"fa-light fa-ellipsis-vertical\"></i>\n </span>\n }\n </div>\n} @else {\n <div class=\"ax-flex ax-min-w-0 ax-items-center ax-gap-1\">\n @if (displayCount() > 0) {\n <span\n class=\"ax-cursor-pointer ax-text-primary hover:ax-underline\"\n (click)=\"openLazyPopover(); $event.stopPropagation()\"\n #lazyTrigger\n >\n {{ summaryLabel() }}\n </span>\n } @else {\n <span class=\"ax-text-muted\">---</span>\n }\n </div>\n}\n\n<ax-popover [openOn]=\"'manual'\" #morePopover (openChange)=\"onPopoverOpenChange($event)\">\n <div class=\"ax-lightest-surface dark:ax-dark-surface ax-min-w-[280px] ax-rounded-lg ax-p-4 ax-shadow-lg\">\n <div class=\"ax-mb-4 ax-border-b ax-pb-2\">\n <h3 class=\"ax-text-base ax-font-semibold\">{{ popoverHeader() }}</h3>\n </div>\n\n @if (!isHydratedStrategy() && resolveStatus() === 'loading') {\n <div class=\"ax-flex ax-min-h-[120px] ax-items-center ax-justify-center\">\n <ax-loading></ax-loading>\n </div>\n } @else if (!isHydratedStrategy() && resolveStatus() === 'error') {\n <div class=\"ax-text-danger ax-text-sm\">{{ resolveError() }}</div>\n } @else {\n <div class=\"ax-flex ax-max-h-64 ax-flex-col ax-gap-3\">\n @for (item of popoverListItems(); track $index) {\n <span\n [class.ax-cursor-pointer]=\"detailPopoverEnabled()\"\n [class.hover:ax-text-primary]=\"detailPopoverEnabled()\"\n [class.hover:ax-underline]=\"detailPopoverEnabled()\"\n (click)=\"handlePopoverItemClick($index, $event)\"\n >\n {{ getPopoverItemLabel($index) }}\n </span>\n } @empty {\n <span class=\"ax-text-muted\">---</span>\n }\n </div>\n }\n </div>\n</ax-popover>\n" }]
|
|
16671
16454
|
}], ctorParameters: () => [], propDecorators: { moreButton: [{ type: i0.ViewChild, args: ['moreButton', { isSignal: true }] }], lazyTrigger: [{ type: i0.ViewChild, args: ['lazyTrigger', { isSignal: true }] }], morePopover: [{ type: i0.ViewChild, args: ['morePopover', { isSignal: true }] }] } });
|
|
16672
16455
|
|
|
16673
16456
|
var lookupWidgetColumn_component = /*#__PURE__*/Object.freeze({
|
|
@@ -21930,13 +21713,20 @@ class AXPPageDetailsConverter extends AXPBaseRelatedEntityConverter {
|
|
|
21930
21713
|
const p = relatedEntity?.persistence || {};
|
|
21931
21714
|
const strategy = p.strategy || 'embedded';
|
|
21932
21715
|
const mappedTargets = Object.keys(p.map || {}).map((k) => (k || '').split('.')[0]);
|
|
21716
|
+
const excludeProperties = relatedEntity.excludeProperties && relatedEntity.excludeProperties.length > 0
|
|
21717
|
+
? new Set(relatedEntity.excludeProperties)
|
|
21718
|
+
: undefined;
|
|
21933
21719
|
const helpers = {
|
|
21934
21720
|
...baseHelpers,
|
|
21935
21721
|
getPropertyByGroupId: (groupId) => {
|
|
21936
|
-
|
|
21937
|
-
if (strategy
|
|
21938
|
-
|
|
21939
|
-
|
|
21722
|
+
let props = baseHelpers.getPropertyByGroupId(groupId) ?? [];
|
|
21723
|
+
if (strategy === 'referenced' && mappedTargets.length > 0) {
|
|
21724
|
+
props = props.filter((prop) => !mappedTargets.includes(prop?.name ?? ''));
|
|
21725
|
+
}
|
|
21726
|
+
if (excludeProperties) {
|
|
21727
|
+
props = props.filter((prop) => !excludeProperties.has(prop.name ?? ''));
|
|
21728
|
+
}
|
|
21729
|
+
return props;
|
|
21940
21730
|
},
|
|
21941
21731
|
};
|
|
21942
21732
|
const evaluateExpressions = async (actionData) => {
|
|
@@ -22054,18 +21844,70 @@ class AXPPageDetailsConverter extends AXPBaseRelatedEntityConverter {
|
|
|
22054
21844
|
}
|
|
22055
21845
|
createLoadFunction(entityDef, relatedEntity, evaluateExpressions) {
|
|
22056
21846
|
return async (context) => {
|
|
22057
|
-
const
|
|
21847
|
+
const conditions = relatedEntity.conditions ?? [];
|
|
21848
|
+
if (conditions.length > 0) {
|
|
21849
|
+
const evaluatedFilters = await Promise.all(conditions.map(async (c) => ({
|
|
21850
|
+
field: c.name,
|
|
21851
|
+
operator: c.operator,
|
|
21852
|
+
value: await evaluateExpressions(c.value),
|
|
21853
|
+
})));
|
|
21854
|
+
if (conditions.length === 1 && conditions[0].name === 'id') {
|
|
21855
|
+
const byKeyFn = entityDef?.queries?.byKey?.execute;
|
|
21856
|
+
const id = evaluatedFilters[0]?.value;
|
|
21857
|
+
const result = id ? await byKeyFn(id) : null;
|
|
21858
|
+
return { success: true, data: result ?? {} };
|
|
21859
|
+
}
|
|
21860
|
+
const listFn = entityDef?.queries?.list?.execute;
|
|
21861
|
+
const filter = evaluatedFilters.length === 1
|
|
21862
|
+
? evaluatedFilters[0]
|
|
21863
|
+
: { logic: 'and', filters: evaluatedFilters };
|
|
21864
|
+
const page = await listFn({ skip: 0, take: 1, filter });
|
|
21865
|
+
const item = page?.items?.[0];
|
|
21866
|
+
const data = item ? { ...item } : {};
|
|
21867
|
+
if (!item) {
|
|
21868
|
+
for (const evaluated of evaluatedFilters) {
|
|
21869
|
+
if (evaluated.field) {
|
|
21870
|
+
set(data, evaluated.field, evaluated.value);
|
|
21871
|
+
}
|
|
21872
|
+
}
|
|
21873
|
+
}
|
|
21874
|
+
return { success: true, data };
|
|
21875
|
+
}
|
|
21876
|
+
const fn = entityDef?.queries?.byKey?.execute;
|
|
22058
21877
|
const conditionValues = relatedEntity.conditions?.map((c) => c.value) ?? [];
|
|
22059
21878
|
const evaluatedConditionValues = await Promise.all(conditionValues.map((c) => evaluateExpressions(c)));
|
|
22060
21879
|
const id = evaluatedConditionValues[0];
|
|
22061
|
-
const result = await fn(id);
|
|
22062
|
-
return { success: true, data: result };
|
|
21880
|
+
const result = id ? await fn(id) : null;
|
|
21881
|
+
return { success: true, data: result ?? {} };
|
|
22063
21882
|
};
|
|
22064
21883
|
}
|
|
22065
21884
|
createExecuteFunction(entityDef, actions, evaluateExpressions, converterContext) {
|
|
22066
21885
|
return async (e, context) => {
|
|
22067
21886
|
try {
|
|
22068
21887
|
if (e.name === 'update-entity') {
|
|
21888
|
+
const recordId = context?.['id'];
|
|
21889
|
+
if (!recordId) {
|
|
21890
|
+
const createFn = entityDef?.commands?.create?.execute;
|
|
21891
|
+
const created = await createFn(context);
|
|
21892
|
+
if (created && typeof created === 'object' && 'success' in created) {
|
|
21893
|
+
const cmd = created;
|
|
21894
|
+
if (!cmd.success) {
|
|
21895
|
+
const errorText = commandMessageTextForError(cmd.message?.text) || 'Failed to create entity';
|
|
21896
|
+
return {
|
|
21897
|
+
success: false,
|
|
21898
|
+
message: cmd.message ?? { text: errorText },
|
|
21899
|
+
};
|
|
21900
|
+
}
|
|
21901
|
+
return {
|
|
21902
|
+
success: true,
|
|
21903
|
+
data: cmd.data ?? created,
|
|
21904
|
+
};
|
|
21905
|
+
}
|
|
21906
|
+
return {
|
|
21907
|
+
success: true,
|
|
21908
|
+
data: created,
|
|
21909
|
+
};
|
|
21910
|
+
}
|
|
22069
21911
|
const fn = entityDef?.commands?.update?.execute;
|
|
22070
21912
|
const result = await fn(context);
|
|
22071
21913
|
if (result && typeof result === 'object' && 'success' in result) {
|
|
@@ -22327,11 +22169,16 @@ class AXPPageListConverter extends AXPBaseRelatedEntityConverter {
|
|
|
22327
22169
|
const excludeForUpdate = commandName === 'Entity:Update' &&
|
|
22328
22170
|
relatedEntity.excludeProperties &&
|
|
22329
22171
|
relatedEntity.excludeProperties.length > 0;
|
|
22172
|
+
const excludeForView = commandName === 'Entity:View' &&
|
|
22173
|
+
relatedEntity.excludeProperties &&
|
|
22174
|
+
relatedEntity.excludeProperties.length > 0;
|
|
22330
22175
|
const mergedOptions = excludeForCreate
|
|
22331
22176
|
? { ...evaluatedOptions, excludeProperties: createExcludes }
|
|
22332
22177
|
: excludeForUpdate
|
|
22333
22178
|
? { ...evaluatedOptions, excludeProperties: relatedEntity.excludeProperties }
|
|
22334
|
-
:
|
|
22179
|
+
: excludeForView
|
|
22180
|
+
? { ...evaluatedOptions, excludeProperties: relatedEntity.excludeProperties }
|
|
22181
|
+
: evaluatedOptions;
|
|
22335
22182
|
if (context.commandService.exists(commandName)) {
|
|
22336
22183
|
// check options for evaluation
|
|
22337
22184
|
await context.commandService.execute(commandName, {
|
|
@@ -22350,6 +22197,7 @@ class AXPPageListConverter extends AXPBaseRelatedEntityConverter {
|
|
|
22350
22197
|
},
|
|
22351
22198
|
options: mergedOptions,
|
|
22352
22199
|
metadata: action.metadata,
|
|
22200
|
+
...(excludeForView ? { excludeProperties: relatedEntity.excludeProperties } : {}),
|
|
22353
22201
|
});
|
|
22354
22202
|
}
|
|
22355
22203
|
else {
|
|
@@ -23260,6 +23108,7 @@ class AXPLayoutAdapterFactory {
|
|
|
23260
23108
|
this.layoutAdapterBuilder = layoutAdapterBuilder;
|
|
23261
23109
|
this.filterOperatorMiddleware = filterOperatorMiddleware;
|
|
23262
23110
|
this.pageComponentConverter = inject(AXPPageComponentConverter);
|
|
23111
|
+
this.contextEvalFactory = inject(AXPContextEvalFactory);
|
|
23263
23112
|
}
|
|
23264
23113
|
async createDetailsViewAdapter(entityResolver, moduleName, entityName, id, dependencies) {
|
|
23265
23114
|
const entity = await entityResolver.resolve(moduleName, entityName);
|
|
@@ -23313,9 +23162,7 @@ class AXPLayoutAdapterFactory {
|
|
|
23313
23162
|
if (hidden && typeof hidden === 'string') {
|
|
23314
23163
|
try {
|
|
23315
23164
|
const scope = {
|
|
23316
|
-
context:
|
|
23317
|
-
eval: (path) => get(rootContext, path),
|
|
23318
|
-
},
|
|
23165
|
+
context: this.contextEvalFactory.createScope(rootContext),
|
|
23319
23166
|
};
|
|
23320
23167
|
const result = await dependencies.expressionEvaluator.evaluate({ hidden }, scope);
|
|
23321
23168
|
hidden = result.hidden;
|
|
@@ -23477,9 +23324,7 @@ class AXPLayoutAdapterFactory {
|
|
|
23477
23324
|
}
|
|
23478
23325
|
const scope = {
|
|
23479
23326
|
...rootContext,
|
|
23480
|
-
context:
|
|
23481
|
-
eval: (path) => get(rootContext, path),
|
|
23482
|
-
},
|
|
23327
|
+
context: this.contextEvalFactory.createScope(rootContext),
|
|
23483
23328
|
};
|
|
23484
23329
|
const title = await dependencies.expressionEvaluator.evaluate(titleTemplate, scope);
|
|
23485
23330
|
return title;
|
|
@@ -24288,7 +24133,7 @@ const AXPCrudModifier = {
|
|
|
24288
24133
|
queries.list = {
|
|
24289
24134
|
execute: async (e) => {
|
|
24290
24135
|
const res = await dataService.query(e);
|
|
24291
|
-
//
|
|
24136
|
+
//console.log('query', res, ctx.module.get() + '.' + ctx.name.get(), e);
|
|
24292
24137
|
return res;
|
|
24293
24138
|
},
|
|
24294
24139
|
type: AXPEntityQueryType.List,
|
|
@@ -24321,6 +24166,68 @@ class AXPEntityCommandSearchDefinitionProvider {
|
|
|
24321
24166
|
function moduleNameToI18nScope(moduleName) {
|
|
24322
24167
|
return moduleName.replace(/([A-Z])/g, '-$1').toLowerCase().replace(/^-/, '');
|
|
24323
24168
|
}
|
|
24169
|
+
//#region ---- Entity search definition builder ----
|
|
24170
|
+
function buildEntitySearchDefinition(entity, manifestRegistry) {
|
|
24171
|
+
const manifest = manifestRegistry.get(entity.module);
|
|
24172
|
+
const i18nScope = manifest?.i18n ?? moduleNameToI18nScope(entity.module);
|
|
24173
|
+
const searchTitleTemplate = entity.formats.searchResult?.title;
|
|
24174
|
+
const titleContext = buildEntitySearchTitleContext(entity, searchTitleTemplate);
|
|
24175
|
+
return {
|
|
24176
|
+
name: `Module.${entity.module}.${entity.name}`,
|
|
24177
|
+
title: `@${i18nScope}:module.title`,
|
|
24178
|
+
group: `Module.${entity.module}`,
|
|
24179
|
+
icon: entity.icon ?? 'fa-solid fa-objects-column',
|
|
24180
|
+
order: 4,
|
|
24181
|
+
format: {
|
|
24182
|
+
title: searchTitleTemplate,
|
|
24183
|
+
description: entity.formats.searchResult?.description ?? `${entity.module} / ${entity.title}`,
|
|
24184
|
+
id: '{{data.id}}',
|
|
24185
|
+
titleFallbackTemplates: titleContext.fallbackTemplates,
|
|
24186
|
+
titleFallbackFields: titleContext.fallbackFields,
|
|
24187
|
+
},
|
|
24188
|
+
actions: [
|
|
24189
|
+
{
|
|
24190
|
+
name: 'open-entity',
|
|
24191
|
+
type: AXPSystemActionType.View,
|
|
24192
|
+
priority: 'primary',
|
|
24193
|
+
},
|
|
24194
|
+
],
|
|
24195
|
+
};
|
|
24196
|
+
}
|
|
24197
|
+
//#endregion
|
|
24198
|
+
//#region ---- Lazy resolver ----
|
|
24199
|
+
class AXPEntitySearchDefinitionLazyResolver {
|
|
24200
|
+
constructor() {
|
|
24201
|
+
this.entityResolver = inject(AXPEntityResolver);
|
|
24202
|
+
this.manifestRegistry = inject(AXPModuleManifestRegistry);
|
|
24203
|
+
this.resolved = new Map();
|
|
24204
|
+
}
|
|
24205
|
+
async resolve(definitionName) {
|
|
24206
|
+
const cached = this.resolved.get(definitionName);
|
|
24207
|
+
if (cached) {
|
|
24208
|
+
return cached;
|
|
24209
|
+
}
|
|
24210
|
+
const match = definitionName.match(/^Module\.([^.]+)\.(.+)$/);
|
|
24211
|
+
if (!match) {
|
|
24212
|
+
return null;
|
|
24213
|
+
}
|
|
24214
|
+
const [, moduleName, entityName] = match;
|
|
24215
|
+
await this.manifestRegistry.initialize();
|
|
24216
|
+
const entity = await this.entityResolver.get(moduleName, entityName);
|
|
24217
|
+
if (!entity) {
|
|
24218
|
+
return null;
|
|
24219
|
+
}
|
|
24220
|
+
const definition = buildEntitySearchDefinition(entity, this.manifestRegistry);
|
|
24221
|
+
this.resolved.set(definitionName, definition);
|
|
24222
|
+
return definition;
|
|
24223
|
+
}
|
|
24224
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntitySearchDefinitionLazyResolver, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
24225
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntitySearchDefinitionLazyResolver }); }
|
|
24226
|
+
}
|
|
24227
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntitySearchDefinitionLazyResolver, decorators: [{
|
|
24228
|
+
type: Injectable
|
|
24229
|
+
}] });
|
|
24230
|
+
|
|
24324
24231
|
class AXPEntitySearchDefinitionProvider {
|
|
24325
24232
|
constructor() {
|
|
24326
24233
|
this.entityRegister = inject(AXPEntityDefinitionRegistryService);
|
|
@@ -24328,28 +24235,13 @@ class AXPEntitySearchDefinitionProvider {
|
|
|
24328
24235
|
}
|
|
24329
24236
|
async provide(context) {
|
|
24330
24237
|
await this.manifestRegistry.initialize();
|
|
24331
|
-
this.entityRegister.getAll()
|
|
24332
|
-
const
|
|
24333
|
-
|
|
24334
|
-
|
|
24335
|
-
|
|
24336
|
-
context.addDefinition(`Module.${entity.module}.${entity.name}`, `@${i18nScope}:module.title`, `Module.${entity.module}`, entity.icon ?? 'fa-solid fa-objects-column', 4, {
|
|
24337
|
-
actions: [
|
|
24338
|
-
{
|
|
24339
|
-
name: 'open-entity',
|
|
24340
|
-
type: 'view',
|
|
24341
|
-
priority: 'primary',
|
|
24342
|
-
},
|
|
24343
|
-
],
|
|
24344
|
-
format: {
|
|
24345
|
-
title: searchTitleTemplate,
|
|
24346
|
-
description: (entity.formats.searchResult?.description) ?? `${entity.module} / ${entity.title}`,
|
|
24347
|
-
id: '{{data.id}}',
|
|
24348
|
-
titleFallbackTemplates: titleContext.fallbackTemplates,
|
|
24349
|
-
titleFallbackFields: titleContext.fallbackFields,
|
|
24350
|
-
},
|
|
24238
|
+
for (const entity of this.entityRegister.getAll()) {
|
|
24239
|
+
const definition = buildEntitySearchDefinition(entity, this.manifestRegistry);
|
|
24240
|
+
context.addDefinition(definition.name, definition.title, definition.group, definition.icon, definition.order, {
|
|
24241
|
+
actions: definition.actions,
|
|
24242
|
+
format: definition.format,
|
|
24351
24243
|
});
|
|
24352
|
-
}
|
|
24244
|
+
}
|
|
24353
24245
|
}
|
|
24354
24246
|
}
|
|
24355
24247
|
|
|
@@ -24455,9 +24347,9 @@ class AXPMiddlewareEntityStorageService extends AXPEntityStorageService {
|
|
|
24455
24347
|
...init,
|
|
24456
24348
|
};
|
|
24457
24349
|
}
|
|
24458
|
-
async initial(entityName, collection
|
|
24350
|
+
async initial(entityName, collection) {
|
|
24459
24351
|
const ctx = this.createCtx('initial', entityName, { data: collection });
|
|
24460
|
-
return this.run(ctx, () => this.backend.initial(ctx.entityName, ctx.data
|
|
24352
|
+
return this.run(ctx, () => this.backend.initial(ctx.entityName, ctx.data));
|
|
24461
24353
|
}
|
|
24462
24354
|
async getOne(entityName, id) {
|
|
24463
24355
|
const key = getDedupKey('getOne', entityName, { id });
|
|
@@ -24741,6 +24633,9 @@ class AXPQuickEntityModifyPopupAction extends AXPWorkflowAction {
|
|
|
24741
24633
|
this.popupService = inject(AXPopupService);
|
|
24742
24634
|
this.platform = inject(AXPlatform);
|
|
24743
24635
|
this.translateService = inject(AXTranslationService);
|
|
24636
|
+
this.formatService = inject(AXFormatService);
|
|
24637
|
+
this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
|
|
24638
|
+
this.contextEvalFactory = inject(AXPContextEvalFactory);
|
|
24744
24639
|
this.entityRegistery = inject(AXPEntityDefinitionRegistryService);
|
|
24745
24640
|
this.config = inject(AXP_ENTITY_CONFIG_TOKEN);
|
|
24746
24641
|
this.factory = inject(AXPEntityMasterUpdateViewModelFactory);
|
|
@@ -24750,10 +24645,8 @@ class AXPQuickEntityModifyPopupAction extends AXPWorkflowAction {
|
|
|
24750
24645
|
const data = context.getVariable('data');
|
|
24751
24646
|
const entityRef = await this.entityRegistery.resolve(moduleName, entityName);
|
|
24752
24647
|
const { parentKey } = entityRef;
|
|
24753
|
-
console.log(data);
|
|
24754
24648
|
const { id } = data;
|
|
24755
|
-
const
|
|
24756
|
-
const properties = interfaces?.master?.update?.properties?.map((p) => p.name) || [];
|
|
24649
|
+
const properties = entityRef.interfaces?.master?.update?.properties?.map((p) => p.name) || [];
|
|
24757
24650
|
const vm = await this.factory.create(moduleName, entityName, id, properties);
|
|
24758
24651
|
const options = context.getVariable('options');
|
|
24759
24652
|
const decoration = options?.['decoration'];
|
|
@@ -24763,12 +24656,11 @@ class AXPQuickEntityModifyPopupAction extends AXPWorkflowAction {
|
|
|
24763
24656
|
if (parentKey) {
|
|
24764
24657
|
context.setVariable('parentKey', parentKey);
|
|
24765
24658
|
}
|
|
24766
|
-
console.log(`${this.translateService.translateSync('entity.modify')}`);
|
|
24767
24659
|
const com = await this.config.viewers.master.modify();
|
|
24768
24660
|
const popup = await this.popupService.open(com, {
|
|
24769
24661
|
title: headerTitle
|
|
24770
24662
|
? headerTitle
|
|
24771
|
-
:
|
|
24663
|
+
: await resolveEntityModifyPopupTitle(entityRef, vm.context(), this.translateService, this.formatService, this.expressionEvaluator, this.contextEvalFactory),
|
|
24772
24664
|
size: this.platform.is('Mobile') || this.platform.is('SM') ? 'full' : size ? size : 'md',
|
|
24773
24665
|
data: {
|
|
24774
24666
|
vm,
|
|
@@ -25031,6 +24923,7 @@ function routesFacory() {
|
|
|
25031
24923
|
return config.viewers.root();
|
|
25032
24924
|
},
|
|
25033
24925
|
canActivate: [...AXP_PROTECTED_ROUTE_GUARDS],
|
|
24926
|
+
data: { rootLayout: true },
|
|
25034
24927
|
children: [
|
|
25035
24928
|
{
|
|
25036
24929
|
path: ':module',
|
|
@@ -25075,7 +24968,7 @@ function routesFacory() {
|
|
|
25075
24968
|
const refreshChanged = from.queryParams['_ts'] !== to.queryParams['_ts'];
|
|
25076
24969
|
return entityChanged || idChanged || refreshChanged;
|
|
25077
24970
|
},
|
|
25078
|
-
data: { reuse:
|
|
24971
|
+
data: { reuse: 'queryParamsChange' },
|
|
25079
24972
|
},
|
|
25080
24973
|
{
|
|
25081
24974
|
path: 'e/:entity/:id',
|
|
@@ -25108,6 +25001,15 @@ class AXPEntityModule {
|
|
|
25108
25001
|
AXPAttachmentsPluginModule, i1$3.AXPWorkflowModule, AXPWidgetCoreModule,
|
|
25109
25002
|
LayoutBuilderModule] }); }
|
|
25110
25003
|
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityModule, providers: [
|
|
25004
|
+
{
|
|
25005
|
+
provide: AXP_REPEATER_ENTITY_BY_KEY_LOOKUP,
|
|
25006
|
+
useFactory: () => {
|
|
25007
|
+
const entityService = inject(AXPEntityService);
|
|
25008
|
+
return {
|
|
25009
|
+
byKey: (entityKey, id) => entityService.withEntity(entityKey).data().byKey(id),
|
|
25010
|
+
};
|
|
25011
|
+
},
|
|
25012
|
+
},
|
|
25111
25013
|
{ provide: AXP_WIDGET_DEFINITION_PROVIDER, useClass: AXPEntityWidgetsProvider, multi: true },
|
|
25112
25014
|
{
|
|
25113
25015
|
provide: ROUTES,
|
|
@@ -25124,6 +25026,10 @@ class AXPEntityModule {
|
|
|
25124
25026
|
useClass: AXPEntityCommandSearchDefinitionProvider,
|
|
25125
25027
|
multi: true,
|
|
25126
25028
|
},
|
|
25029
|
+
{
|
|
25030
|
+
provide: AXP_SEARCH_DEFINITION_LAZY_RESOLVER,
|
|
25031
|
+
useClass: AXPEntitySearchDefinitionLazyResolver,
|
|
25032
|
+
},
|
|
25127
25033
|
// Bind the middleware wrapper as the public storage service
|
|
25128
25034
|
{ provide: AXPEntityStorageService, useClass: AXPMiddlewareEntityStorageService },
|
|
25129
25035
|
{
|
|
@@ -25295,6 +25201,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
25295
25201
|
exports: [],
|
|
25296
25202
|
declarations: [],
|
|
25297
25203
|
providers: [
|
|
25204
|
+
{
|
|
25205
|
+
provide: AXP_REPEATER_ENTITY_BY_KEY_LOOKUP,
|
|
25206
|
+
useFactory: () => {
|
|
25207
|
+
const entityService = inject(AXPEntityService);
|
|
25208
|
+
return {
|
|
25209
|
+
byKey: (entityKey, id) => entityService.withEntity(entityKey).data().byKey(id),
|
|
25210
|
+
};
|
|
25211
|
+
},
|
|
25212
|
+
},
|
|
25298
25213
|
{ provide: AXP_WIDGET_DEFINITION_PROVIDER, useClass: AXPEntityWidgetsProvider, multi: true },
|
|
25299
25214
|
{
|
|
25300
25215
|
provide: ROUTES,
|
|
@@ -25311,6 +25226,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
25311
25226
|
useClass: AXPEntityCommandSearchDefinitionProvider,
|
|
25312
25227
|
multi: true,
|
|
25313
25228
|
},
|
|
25229
|
+
{
|
|
25230
|
+
provide: AXP_SEARCH_DEFINITION_LAZY_RESOLVER,
|
|
25231
|
+
useClass: AXPEntitySearchDefinitionLazyResolver,
|
|
25232
|
+
},
|
|
25314
25233
|
// Bind the middleware wrapper as the public storage service
|
|
25315
25234
|
{ provide: AXPEntityStorageService, useClass: AXPMiddlewareEntityStorageService },
|
|
25316
25235
|
{
|
|
@@ -25618,5 +25537,5 @@ var getEntityDetails_query = /*#__PURE__*/Object.freeze({
|
|
|
25618
25537
|
* Generated bundle index. Do not edit.
|
|
25619
25538
|
*/
|
|
25620
25539
|
|
|
25621
|
-
export { ATTACHMENTS_PAGE_COMPONENT_KEY, AXMEntityCrudService, AXMEntityCrudServiceImpl, AXPCategoryTreeService, AXPCreateEntityCommand, AXPCreateEntityWorkflow, AXPDataSeederService, AXPDeleteEntityWorkflow, AXPEditFileUploaderCommand, AXPEntitiesListDataSourceDefinition, AXPEntityApplyUpdatesAction, AXPEntityCategoryTreeSelectorComponent, AXPEntityCategoryWidget, AXPEntityCategoryWidgetColumnComponent, AXPEntityCategoryWidgetEditComponent, AXPEntityCategoryWidgetViewComponent, AXPEntityCommandTriggerViewModel, AXPEntityCreateEvent, AXPEntityCreatePopupAction, AXPEntityCreateSubmittedAction, AXPEntityCreateViewElementViewModel, AXPEntityCreateViewModelFactory, AXPEntityCreateViewSectionViewModel, AXPEntityDataProvider, AXPEntityDataProviderImpl, AXPEntityDataSelectorRowActionsService, AXPEntityDataSelectorService,
|
|
25540
|
+
export { ATTACHMENTS_PAGE_COMPONENT_KEY, AXMEntityCrudService, AXMEntityCrudServiceImpl, AXPCategoryTreeService, AXPCreateEntityCommand, AXPCreateEntityWorkflow, AXPDataSeederService, AXPDeleteEntityWorkflow, AXPEditFileUploaderCommand, AXPEntitiesListDataSourceDefinition, AXPEntityApplyUpdatesAction, AXPEntityCategoryTreeSelectorComponent, AXPEntityCategoryWidget, AXPEntityCategoryWidgetColumnComponent, AXPEntityCategoryWidgetEditComponent, AXPEntityCategoryWidgetViewComponent, AXPEntityCommandTriggerViewModel, AXPEntityCreateEvent, AXPEntityCreatePopupAction, AXPEntityCreateSubmittedAction, AXPEntityCreateViewElementViewModel, AXPEntityCreateViewModelFactory, AXPEntityCreateViewSectionViewModel, AXPEntityDataProvider, AXPEntityDataProviderImpl, AXPEntityDataSelectorRowActionsService, AXPEntityDataSelectorService, AXPEntityDefinitionProviderWidget, AXPEntityDefinitionProviderWidgetEditComponent, AXPEntityDefinitionRegistryService, AXPEntityDeletedEvent, AXPEntityDetailListViewModel, AXPEntityDetailPopoverComponent, AXPEntityDetailPopoverService, AXPEntityDetailViewModelFactory, AXPEntityDetailViewModelResolver, AXPEntityEventDispatcherService, AXPEntityFormBuilderService, AXPEntityListPersistenceModeDefault, AXPEntityListTableService, AXPEntityListToolbarService, AXPEntityListViewCardFieldViewModel, AXPEntityListViewColumnViewModel, AXPEntityListViewModelFactory, AXPEntityListViewModelResolver, AXPEntityListWidget, AXPEntityListWidgetViewComponent, AXPEntityMasterCreateViewModel, AXPEntityMasterListCardSelectActionName, AXPEntityMasterListViewModel, AXPEntityMasterListViewQueryViewModel, AXPEntityMasterSingleElementViewModel, AXPEntityMasterSingleViewGroupViewModel, AXPEntityMasterSingleViewModel, AXPEntityMasterUpdateElementViewModel, AXPEntityMasterUpdateViewModel, AXPEntityMasterUpdateViewModelFactory, AXPEntityMiddleware, AXPEntityModifyConfirmedAction, AXPEntityModifyEvent, AXPEntityModifySectionPopupAction, AXPEntityModule, AXPEntityPerformDeleteAction, AXPEntityPreloadFiltersContainerComponent, AXPEntityPreloadFiltersViewModel, AXPEntityPreloadFiltersViewModelResolver, AXPEntityResolver, AXPEntityService, AXPEntityStorageService, AXPEntityUpdateViewSectionViewModel, AXPFileListComponent, AXPFileUploaderLoadFilesQuery, AXPFileUploaderSaveFilesCommand, AXPFileUploaderWidget, AXPFileUploaderWidgetColumnComponent, AXPFileUploaderWidgetEditComponent, AXPFileUploaderWidgetService, AXPFileUploaderWidgetViewComponent, AXPGetEntityDetailsQuery, AXPLayoutOrderingConfigService, AXPLookupWidget, AXPLookupWidgetColumnComponent, AXPLookupWidgetEditComponent, AXPLookupWidgetViewComponent, AXPMiddlewareAbortError, AXPMiddlewareEntityStorageService, AXPModifyEntitySectionWorkflow, AXPMultiSourceDefinitionProviderContext, AXPMultiSourceDefinitionProviderService, AXPMultiSourceFederatedSearchService, AXPMultiSourceSelectorComponent, AXPMultiSourceSelectorService, AXPMultiSourceSelectorWidget, AXPMultiSourceSelectorWidgetColumnComponent, AXPMultiSourceSelectorWidgetEditComponent, AXPMultiSourceSelectorWidgetViewComponent, AXPMultiSourceType, AXPOpenEntityDetailsCommand, AXPQuickEntityModifyPopupAction, AXPQuickModifyEntityWorkflow, AXPRelatedColumnEnrichmentService, AXPRelatedColumnMetadataResolver, AXPSelectorStructureWidget, AXPSelectorStructureWidgetColumnComponent, AXPSelectorStructureWidgetEditComponent, AXPSelectorStructureWidgetViewComponent, AXPShowDetailViewAction, AXPShowDetailsViewWorkflow, AXPShowListViewAction, AXPShowListViewWorkflow, AXPTruncatedBreadcrumbComponent, AXPUpdateEntityCommand, AXPViewEntityDetailsCommand, AXP_CATEGORY_TREE_ROOT_TITLE_I18N_KEY, 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, AXP_MULTI_SOURCE_DEFINITION_PROVIDER, DEFAULT_COLUMN_ORDER, DEFAULT_PAIR_SPAN_RULES, DEFAULT_PROPERTY_ORDER, DEFAULT_SECTION_ORDER, ENTITY_LIST_ROUTE_CONTEXT_SESSION_KEY, EntityBuilder, EntityDataAccessor, actionExists, applyDataSourcePagingWithoutLoad, attachmentFieldCount, attachmentsPlugin, attachmentsSemanticallyEqual, axpCreateEntityAiToolInputDefaults, axpCreateEntityCommandDefinition, canPersistEntityListState, cloneLayoutArrays, columnOrderingMiddleware, columnOrderingMiddlewareProvider, columnWidthMiddleware, columnWidthMiddlewareProvider, commandMessageTextForError, committedAttachments, computeEntityAggregates, createColumnOrderingMiddlewareProvider, createLayoutOrderingMiddlewareProvider, createModifierContext, defaultCardLayoutMiddleware, defaultCardLayoutMiddlewareProvider, defaultMultiLanguageMiddleware, defaultMultiLanguageMiddlewareProvider, detectEntityChanges, ensureLayoutPropertyView, ensureLayoutSection, ensureListActions, eventDispatchMiddleware, filterSortEntityRows, findEntityListRowDataInTree, fingerprintAttachmentItem, fingerprintAttachments, formatLookupItemDisplay, formatLookupItemDisplayAsync, getDataSourcePageIndex, getEntityListRowId, getMasterInterfacePropertySortKey, hasFileUploaderTitleOrDescriptionFields, isAXPMiddlewareAbortError, isAttachmentListEntry, isCategoryEntity, isCategoryFilter, isFileListItem, isFileUploaderEditDialogAuto, isLegacyEntityDataSelectorOptions, layoutOrderingMiddlewareFactory, layoutOrderingMiddlewareProvider, mapEntityStorageErrorToCommandResult, mapLegacyEntityDataSelectorOptions, normalizeEntityDataSelectorOptions, normalizeEntityFieldToFileList, normalizeEntityListPersistenceMode, normalizeListPaging, persistedAttachments, provideEntity, resolveEntityPluginDetailPageOrder, resolveFileUploaderEditDialog, resolveFileUploaderEntityScope, resolveLookupDisplayField, resolveLookupDisplayTemplate, restoreEntityListExpandedRows, runEntityQuery, searchResultDescriptionMiddleware, searchResultDescriptionMiddlewareProvider, shouldLoadEntityListStateFromStorage, shouldResetEntityListStateOnRouteEntry };
|
|
25622
25541
|
//# sourceMappingURL=acorex-platform-layout-entity.mjs.map
|