@acorex/platform 21.0.0-next.88 → 21.0.0-next.89
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 +8 -2
- package/fesm2022/acorex-platform-auth.mjs.map +1 -1
- package/fesm2022/{acorex-platform-common-common-settings.provider-VfmZct9H.mjs → acorex-platform-common-common-settings.provider-DilV4dql.mjs} +15 -42
- package/fesm2022/acorex-platform-common-common-settings.provider-DilV4dql.mjs.map +1 -0
- package/fesm2022/acorex-platform-common.mjs +3299 -3200
- package/fesm2022/acorex-platform-common.mjs.map +1 -1
- package/fesm2022/acorex-platform-core.mjs +621 -26
- package/fesm2022/acorex-platform-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-builder.mjs +98 -189
- package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
- package/fesm2022/{acorex-platform-layout-components-binding-expression-editor-popup.component-CXEdvDTf.mjs → acorex-platform-layout-components-binding-expression-editor-popup.component-RttFwaw9.mjs} +17 -4
- package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-RttFwaw9.mjs.map +1 -0
- package/fesm2022/acorex-platform-layout-components.mjs +125 -26
- package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-designer.mjs +4 -4
- package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity-contracts.mjs +106 -12
- package/fesm2022/acorex-platform-layout-entity-contracts.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity.mjs +419 -147
- package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-views.mjs +851 -162
- package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widget-core.mjs +378 -103
- package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -1
- package/fesm2022/{acorex-platform-layout-widgets-tabular-data-edit-popup.component-D4MOHEpI.mjs → acorex-platform-layout-widgets-tabular-data-edit-popup.component-CZc2zFlg.mjs} +2 -2
- package/fesm2022/{acorex-platform-layout-widgets-tabular-data-edit-popup.component-D4MOHEpI.mjs.map → acorex-platform-layout-widgets-tabular-data-edit-popup.component-CZc2zFlg.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-layout-widgets-tabular-data-view-popup.component-gX-3Kx9I.mjs → acorex-platform-layout-widgets-tabular-data-view-popup.component-XWRUVoL4.mjs} +2 -2
- package/fesm2022/{acorex-platform-layout-widgets-tabular-data-view-popup.component-gX-3Kx9I.mjs.map → acorex-platform-layout-widgets-tabular-data-view-popup.component-XWRUVoL4.mjs.map} +1 -1
- package/fesm2022/acorex-platform-layout-widgets.mjs +575 -239
- package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
- package/fesm2022/acorex-platform-themes-default.mjs +221 -24
- package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
- package/fesm2022/{acorex-platform-themes-shared-settings.provider-BUwPqwUS.mjs → acorex-platform-themes-shared-settings.provider-UyKdkeyk.mjs} +48 -1
- package/fesm2022/acorex-platform-themes-shared-settings.provider-UyKdkeyk.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-shared.mjs +103 -24
- package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
- package/package.json +1 -1
- package/types/acorex-platform-auth.d.ts +1 -0
- package/types/acorex-platform-common.d.ts +202 -151
- package/types/acorex-platform-core.d.ts +161 -6
- package/types/acorex-platform-layout-builder.d.ts +10 -20
- package/types/acorex-platform-layout-components.d.ts +14 -1
- package/types/acorex-platform-layout-entity-contracts.d.ts +27 -2
- package/types/acorex-platform-layout-entity.d.ts +61 -12
- package/types/acorex-platform-layout-views.d.ts +101 -19
- package/types/acorex-platform-layout-widget-core.d.ts +65 -9
- package/types/acorex-platform-layout-widgets.d.ts +48 -26
- package/types/acorex-platform-themes-default.d.ts +56 -5
- package/types/acorex-platform-themes-shared.d.ts +4 -0
- package/fesm2022/acorex-platform-common-common-settings.provider-VfmZct9H.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-CXEdvDTf.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-shared-settings.provider-BUwPqwUS.mjs.map +0 -1
|
@@ -1,18 +1,20 @@
|
|
|
1
|
+
import { mergeForeignKeyFieldIntoCreateActions, collectNestedCreateHiddenProperties, normalizeEntityDisplayTemplate, sanitizeResolvedEntityDisplayTitle, isUnresolvedEntityDisplayTemplate, AXPEntityDataSourceKeys, AXPEntityEventsKeys, collectEntityListSortableFields, collectEntityListFilterDefinitions, parseDottedFieldPath, ENTITY_ROW_POPUP_TITLE_OPTION, buildEntitySearchTitleContext } from '@acorex/platform/layout/entity-contracts';
|
|
2
|
+
export * from '@acorex/platform/layout/entity-contracts';
|
|
3
|
+
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';
|
|
1
4
|
import { AXToastService } from '@acorex/components/toast';
|
|
2
5
|
import * as i3$1 from '@acorex/core/translation';
|
|
3
6
|
import { AXTranslationService, resolveMultiLanguageString, AXTranslationModule, translateSync } from '@acorex/core/translation';
|
|
4
7
|
import * as i4$2 from '@acorex/platform/common';
|
|
5
|
-
import { AXPNotFoundError, AXPEntityCommandScope, axpNavigateAppPath, AXPSettingsService, AXPCommonSettings, resolveEntityModifyPopupTitle, resolveSearchableText, evaluateEntityDisplayTemplate, AXPFilterOperatorMiddlewareService, isCardFieldBadgeDisplay, resolveCardFieldBadgeColor, getEntityInfo, resolveEnabledMasterListLayouts, resolveDefaultMasterListLayout,
|
|
8
|
+
import { AXPNotFoundError, AXPEntityCommandScope, axpNavigateAppPath, AXPSettingsService, AXPCommonSettings, resolveEntityCreateListBehavior, AXPRefreshEvent, resolveEntityModifyPopupTitle, resolveSearchableText, evaluateEntityDisplayTemplate, AXPFilterOperatorMiddlewareService, isCardFieldBadgeDisplay, resolveCardFieldBadgeColor, getEntityInfo, resolveEnabledMasterListLayouts, resolveDefaultMasterListLayout, AXPReloadEvent, axpRedirectToNotFound, AXP_ENTITY_DELETED_WORKFLOW_EVENT_TYPE, 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';
|
|
9
|
+
import * as i1$3 from '@acorex/platform/workflow';
|
|
10
|
+
import { AXPWorkflowEventService, AXPWorkflowService, ofType, createWorkFlowEvent, AXPWorkflowAction, AXPWorkflowModule } from '@acorex/platform/workflow';
|
|
6
11
|
import * as i0 from '@angular/core';
|
|
7
12
|
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';
|
|
13
|
+
import { cloneDeep, merge, get, castArray, set, orderBy, isNil, isEmpty, isEqual as isEqual$1, isObjectLike, isArray, has, isString } from 'lodash-es';
|
|
9
14
|
import { Subject, filter, takeUntil } from 'rxjs';
|
|
10
15
|
import { AXPLayoutBuilderService, LayoutBuilderModule } from '@acorex/platform/layout/builder';
|
|
11
16
|
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,
|
|
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';
|
|
17
|
+
import { AXPDeviceService, AXPExpressionEvaluatorService, AXPContextEvalFactory, AXPBroadcastEventService, applyFilterArray, applySortArray, resolveActionLook, AXPDistributedEventListenerService, AXHighlightService, extractValue, setSmart, getChangedPaths, AXPContextStore, isSelectionValueEqual, AXPDebugService, FORM_DIRTY_TRACE_NS, objectKeyValueTransforms, setupPopupFooterKeyboardShortcuts, AXPHookService, AXPComponentSlotModule, AXPColumnWidthService, AXPModuleManifestRegistry, defaultColumnWidthProvider, AXP_COLUMN_WIDTH_PROVIDER, AXP_DATASOURCE_DEFINITION_PROVIDER, AXPModuleManifestsDataSourceDefinition } from '@acorex/platform/core';
|
|
16
18
|
import { transform, isEqual } from 'lodash';
|
|
17
19
|
import { AXPSessionService, AXPPermissionDefinitionsDataSourceDefinition } from '@acorex/platform/auth';
|
|
18
20
|
import { Router, NavigationStart, ActivatedRoute, RouterModule, ROUTES } from '@angular/router';
|
|
@@ -30,12 +32,10 @@ import { AXOverlayService } from '@acorex/cdk/overlay';
|
|
|
30
32
|
import { AXLocaleService } from '@acorex/core/locale';
|
|
31
33
|
import { AXPlatform } from '@acorex/core/platform';
|
|
32
34
|
import { AXPThemeLayoutBlockComponent, AXPPreloadFiltersComponent, AXP_PAGE_COMPONENT_PROVIDER, AXPStateMessageComponent, AXPColumnItemListComponent, AXPDataSelectorService, AXPPageComponentRegistryService } from '@acorex/platform/layout/components';
|
|
33
|
-
import { AXPPageLayoutBaseComponent, AXPPageLayoutComponent, AXPPageComponentRendererDirective, AXPPageComponentInstanceRegistryService, axpDetailsViewCanDeactivateGuard } from '@acorex/platform/layout/views';
|
|
35
|
+
import { AXPPageLayoutBaseComponent, AXPPageLayoutComponent, AXPPageComponentRendererDirective, AXPPageComponentInstanceRegistryService, AXP_LAYOUT_DETAILS_VIEW_ADAPTER_LOADER, axpDetailsViewCanDeactivateGuard } from '@acorex/platform/layout/views';
|
|
34
36
|
import { AXDataSource } from '@acorex/cdk/common';
|
|
35
37
|
import { AXP_ENTITY_CRUD_SETUP } from '@acorex/platform/domain';
|
|
36
38
|
export { AXP_ENTITY_DEFINITION_CRUD_SERVICE } from '@acorex/platform/domain';
|
|
37
|
-
import * as i1$3 from '@acorex/platform/workflow';
|
|
38
|
-
import { AXPWorkflowService, ofType, createWorkFlowEvent, AXPWorkflowAction, AXPWorkflowEventService, AXPWorkflowModule } from '@acorex/platform/workflow';
|
|
39
39
|
import { AXPLayoutThemeService } from '@acorex/platform/themes/shared';
|
|
40
40
|
import { moveItemInArray } from '@angular/cdk/drag-drop';
|
|
41
41
|
import { AXDialogService } from '@acorex/components/dialog';
|
|
@@ -2302,6 +2302,7 @@ class AXPCreateEntityCommand {
|
|
|
2302
2302
|
this.translationService = inject(AXTranslationService);
|
|
2303
2303
|
this.settingsService = inject(AXPSettingsService);
|
|
2304
2304
|
this.openEntityDetailsCommand = inject(AXPOpenEntityDetailsCommand);
|
|
2305
|
+
this.workflowEventService = inject(AXPWorkflowEventService);
|
|
2305
2306
|
this.context = {};
|
|
2306
2307
|
}
|
|
2307
2308
|
async execute(input) {
|
|
@@ -2359,7 +2360,6 @@ class AXPCreateEntityCommand {
|
|
|
2359
2360
|
const createFn = entityRef.commands?.create?.execute;
|
|
2360
2361
|
const updateFn = entityRef.commands?.update?.execute;
|
|
2361
2362
|
const context = merge({}, data, dialogRef.context());
|
|
2362
|
-
console.log('context', context);
|
|
2363
2363
|
const hasPersistedId = hasPersistedRootId(context);
|
|
2364
2364
|
const persistFn = hasPersistedId ? updateFn : createFn;
|
|
2365
2365
|
const missingPersistHandlerMsg = hasPersistedId
|
|
@@ -2417,13 +2417,24 @@ class AXPCreateEntityCommand {
|
|
|
2417
2417
|
.show();
|
|
2418
2418
|
const commandResult = result;
|
|
2419
2419
|
const redirectOption = options?.process?.redirect;
|
|
2420
|
-
const shouldRedirect =
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
if (commandResult.success &&
|
|
2420
|
+
const { shouldRedirect, shouldHighlight } = await resolveEntityCreateListBehavior(this.settingsService, {
|
|
2421
|
+
redirect: redirectOption,
|
|
2422
|
+
});
|
|
2423
|
+
if (commandResult.success && commandResult.data) {
|
|
2424
2424
|
const createdItem = commandResult.data?.item ?? commandResult.data;
|
|
2425
|
-
const createdId = createdItem?.id;
|
|
2426
|
-
|
|
2425
|
+
const createdId = createdItem?.id ?? createdItem?._id;
|
|
2426
|
+
const refreshMeta = { resetPagination: true };
|
|
2427
|
+
if (createdId != null && shouldHighlight) {
|
|
2428
|
+
refreshMeta['highlightRowId'] = createdId;
|
|
2429
|
+
}
|
|
2430
|
+
if (entityRef.parentKey && createdItem?.[entityRef.parentKey]) {
|
|
2431
|
+
refreshMeta['refreshTargetId'] = createdItem[entityRef.parentKey];
|
|
2432
|
+
}
|
|
2433
|
+
this.workflowEventService.dispatch(AXPRefreshEvent({
|
|
2434
|
+
entity: `${moduleName}.${entityName}`,
|
|
2435
|
+
meta: refreshMeta,
|
|
2436
|
+
}));
|
|
2437
|
+
if (shouldRedirect && createdId != null) {
|
|
2427
2438
|
await this.openEntityDetailsCommand.execute({
|
|
2428
2439
|
entity: `${moduleName}.${entityName}`,
|
|
2429
2440
|
data: { id: String(createdId) },
|
|
@@ -3700,16 +3711,27 @@ function commandMessageTextForError(value) {
|
|
|
3700
3711
|
* 2. Falls back to CRUD service if not defined
|
|
3701
3712
|
*/
|
|
3702
3713
|
class EntityDataAccessor {
|
|
3703
|
-
constructor(module, entity, entityRegistry, queryExecutor, commandService) {
|
|
3714
|
+
constructor(module, entity, entityRegistry, queryExecutor, commandService, injector) {
|
|
3704
3715
|
this.module = module;
|
|
3705
3716
|
this.entity = entity;
|
|
3706
3717
|
this.entityRegistry = entityRegistry;
|
|
3707
3718
|
this.queryExecutor = queryExecutor;
|
|
3708
3719
|
this.commandService = commandService;
|
|
3720
|
+
this.injector = injector;
|
|
3709
3721
|
this.crudService = null;
|
|
3710
3722
|
this.entityDef = null;
|
|
3711
3723
|
this.entityDefPromise = null;
|
|
3712
3724
|
}
|
|
3725
|
+
/**
|
|
3726
|
+
* Lazily creates the CRUD fallback inside an injection context so {@link AXMEntityCrudServiceImpl}
|
|
3727
|
+
* can resolve {@link AXPEntityStorageService} via `inject()`.
|
|
3728
|
+
*/
|
|
3729
|
+
ensureCrudService() {
|
|
3730
|
+
if (!this.crudService) {
|
|
3731
|
+
this.crudService = runInInjectionContext(this.injector, () => new AXMEntityCrudServiceImpl(`${this.module}.${this.entity}`));
|
|
3732
|
+
}
|
|
3733
|
+
return this.crudService;
|
|
3734
|
+
}
|
|
3713
3735
|
/**
|
|
3714
3736
|
* Resolves the entity definition lazily and caches it.
|
|
3715
3737
|
* @returns The resolved entity definition
|
|
@@ -3742,10 +3764,7 @@ class EntityDataAccessor {
|
|
|
3742
3764
|
return await this.queryExecutor.fetch(execute, key);
|
|
3743
3765
|
}
|
|
3744
3766
|
// Fallback to CRUD service
|
|
3745
|
-
|
|
3746
|
-
this.crudService = new AXMEntityCrudServiceImpl(`${this.module}.${this.entity}`);
|
|
3747
|
-
}
|
|
3748
|
-
return await this.crudService.getOne(key);
|
|
3767
|
+
return await this.ensureCrudService().getOne(key);
|
|
3749
3768
|
}
|
|
3750
3769
|
/**
|
|
3751
3770
|
* Queries a list of entities.
|
|
@@ -3768,20 +3787,14 @@ class EntityDataAccessor {
|
|
|
3768
3787
|
return result;
|
|
3769
3788
|
}
|
|
3770
3789
|
// Fallback to CRUD service
|
|
3771
|
-
|
|
3772
|
-
this.crudService = new AXMEntityCrudServiceImpl(`${this.module}.${this.entity}`);
|
|
3773
|
-
}
|
|
3774
|
-
return await this.crudService.query(queryRequest);
|
|
3790
|
+
return await this.ensureCrudService().query(queryRequest);
|
|
3775
3791
|
}
|
|
3776
3792
|
/**
|
|
3777
3793
|
* Queries category entities linked to this entity (`{module}.{entity}Category`).
|
|
3778
3794
|
* Falls back to CRUD category storage (same as {@link AXMEntityCrudServiceImpl.getCategoriesList}).
|
|
3779
3795
|
*/
|
|
3780
3796
|
async getCategoriesList(request = { skip: 0, take: 1000 }) {
|
|
3781
|
-
|
|
3782
|
-
this.crudService = new AXMEntityCrudServiceImpl(`${this.module}.${this.entity}`);
|
|
3783
|
-
}
|
|
3784
|
-
return await this.crudService.getCategoriesList(request);
|
|
3797
|
+
return await this.ensureCrudService().getCategoriesList(request);
|
|
3785
3798
|
}
|
|
3786
3799
|
/**
|
|
3787
3800
|
* Creates a new entity.
|
|
@@ -3803,10 +3816,7 @@ class EntityDataAccessor {
|
|
|
3803
3816
|
return result.data?.id || result.data;
|
|
3804
3817
|
}
|
|
3805
3818
|
// Fallback to CRUD service
|
|
3806
|
-
|
|
3807
|
-
this.crudService = new AXMEntityCrudServiceImpl(`${this.module}.${this.entity}`);
|
|
3808
|
-
}
|
|
3809
|
-
return await this.crudService.insertOne(data);
|
|
3819
|
+
return await this.ensureCrudService().insertOne(data);
|
|
3810
3820
|
}
|
|
3811
3821
|
/**
|
|
3812
3822
|
* Updates an existing entity.
|
|
@@ -3829,10 +3839,7 @@ class EntityDataAccessor {
|
|
|
3829
3839
|
return result.data;
|
|
3830
3840
|
}
|
|
3831
3841
|
// Fallback to CRUD service
|
|
3832
|
-
|
|
3833
|
-
this.crudService = new AXMEntityCrudServiceImpl(`${this.module}.${this.entity}`);
|
|
3834
|
-
}
|
|
3835
|
-
return await this.crudService.updateOne(id, data);
|
|
3842
|
+
return await this.ensureCrudService().updateOne(id, data);
|
|
3836
3843
|
}
|
|
3837
3844
|
/**
|
|
3838
3845
|
* Deletes an entity.
|
|
@@ -3853,10 +3860,7 @@ class EntityDataAccessor {
|
|
|
3853
3860
|
return;
|
|
3854
3861
|
}
|
|
3855
3862
|
// Fallback to CRUD service
|
|
3856
|
-
|
|
3857
|
-
this.crudService = new AXMEntityCrudServiceImpl(`${this.module}.${this.entity}`);
|
|
3858
|
-
}
|
|
3859
|
-
return await this.crudService.deleteOne(id);
|
|
3863
|
+
return await this.ensureCrudService().deleteOne(id);
|
|
3860
3864
|
}
|
|
3861
3865
|
}
|
|
3862
3866
|
//#endregion
|
|
@@ -3866,11 +3870,12 @@ class EntityDataAccessor {
|
|
|
3866
3870
|
* Provides methods to create paths and access entity data.
|
|
3867
3871
|
*/
|
|
3868
3872
|
class EntityBuilder {
|
|
3869
|
-
constructor(module, entity, sessionService, entityRegistry, queryExecutor, commandService) {
|
|
3873
|
+
constructor(module, entity, sessionService, entityRegistry, queryExecutor, commandService, injector) {
|
|
3870
3874
|
this.sessionService = sessionService;
|
|
3871
3875
|
this.entityRegistry = entityRegistry;
|
|
3872
3876
|
this.queryExecutor = queryExecutor;
|
|
3873
3877
|
this.commandService = commandService;
|
|
3878
|
+
this.injector = injector;
|
|
3874
3879
|
this.module = module;
|
|
3875
3880
|
this.entity = entity;
|
|
3876
3881
|
}
|
|
@@ -3888,7 +3893,7 @@ class EntityBuilder {
|
|
|
3888
3893
|
* @returns An EntityDataAccessor instance
|
|
3889
3894
|
*/
|
|
3890
3895
|
data() {
|
|
3891
|
-
return new EntityDataAccessor(this.module, this.entity, this.entityRegistry, this.queryExecutor, this.commandService);
|
|
3896
|
+
return new EntityDataAccessor(this.module, this.entity, this.entityRegistry, this.queryExecutor, this.commandService, this.injector);
|
|
3892
3897
|
}
|
|
3893
3898
|
}
|
|
3894
3899
|
//#endregion
|
|
@@ -3898,6 +3903,7 @@ class AXPEntityService {
|
|
|
3898
3903
|
this.entityRegistry = inject(AXPEntityDefinitionRegistryService);
|
|
3899
3904
|
this.queryExecutor = inject(AXPQueryExecutor);
|
|
3900
3905
|
this.commandService = inject(AXPCommandService);
|
|
3906
|
+
this.injector = inject(Injector);
|
|
3901
3907
|
}
|
|
3902
3908
|
/**
|
|
3903
3909
|
* @deprecated Use `withEntity(module, entity).createPath(path)` instead.
|
|
@@ -3923,7 +3929,7 @@ class AXPEntityService {
|
|
|
3923
3929
|
module = moduleOrEntityKey.substring(0, dotIndex);
|
|
3924
3930
|
entityName = moduleOrEntityKey.substring(dotIndex + 1);
|
|
3925
3931
|
}
|
|
3926
|
-
return new EntityBuilder(module, entityName, this.sessionService, this.entityRegistry, this.queryExecutor, this.commandService);
|
|
3932
|
+
return new EntityBuilder(module, entityName, this.sessionService, this.entityRegistry, this.queryExecutor, this.commandService, this.injector);
|
|
3927
3933
|
}
|
|
3928
3934
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
3929
3935
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityService, providedIn: 'root' }); }
|
|
@@ -4227,7 +4233,8 @@ const PLUGIN_SLOT_INDEX = {
|
|
|
4227
4233
|
attachments: 1,
|
|
4228
4234
|
documents: 2,
|
|
4229
4235
|
comments: 3,
|
|
4230
|
-
|
|
4236
|
+
dashboard: 4,
|
|
4237
|
+
history: 5,
|
|
4231
4238
|
};
|
|
4232
4239
|
//#endregion
|
|
4233
4240
|
//#region ---- Helpers ----
|
|
@@ -5523,7 +5530,6 @@ class AXPEntityMasterListViewModel {
|
|
|
5523
5530
|
this.primaryRowActions = computed(() => this.allActions().filter((a) => a.scope == AXPEntityCommandScope.Individual && a.priority === 'primary'), ...(ngDevMode ? [{ debugName: "primaryRowActions" }] : /* istanbul ignore next */ []));
|
|
5524
5531
|
//****************** Filter ******************//
|
|
5525
5532
|
this.filterQueries = signal([], ...(ngDevMode ? [{ debugName: "filterQueries" }] : /* istanbul ignore next */ []));
|
|
5526
|
-
//****************** Columns ******************//
|
|
5527
5533
|
this.allAvailableColumns = () => {
|
|
5528
5534
|
const { columns = [], properties } = this.entityDef;
|
|
5529
5535
|
// const visibleProperties = properties.filter(({ schema }) => schema?.visible !== false);
|
|
@@ -5531,13 +5537,15 @@ class AXPEntityMasterListViewModel {
|
|
|
5531
5537
|
return columns
|
|
5532
5538
|
.filter(({ name, showAs, options }) => (propNames.has(name) || showAs) && options?.visible !== false)
|
|
5533
5539
|
.map((column) => {
|
|
5540
|
+
const relatedProperty = this.resolveMergeDetailProperty(column.name);
|
|
5534
5541
|
if (column.showAs) {
|
|
5535
5542
|
const widgetConfig = this.widgetResolver.resolve(column.showAs.type);
|
|
5536
5543
|
const { title: _wcTitle, description: _wcDescription, ...widgetRest } = widgetConfig;
|
|
5537
5544
|
const property = {
|
|
5538
5545
|
...widgetRest,
|
|
5539
5546
|
name: column.name,
|
|
5540
|
-
title: column.title ?? '',
|
|
5547
|
+
title: column.title ?? relatedProperty?.title ?? '',
|
|
5548
|
+
options: relatedProperty?.options,
|
|
5541
5549
|
schema: {
|
|
5542
5550
|
dataType: 'string',
|
|
5543
5551
|
interface: {
|
|
@@ -5566,18 +5574,16 @@ class AXPEntityMasterListViewModel {
|
|
|
5566
5574
|
};
|
|
5567
5575
|
this.cardFields = signal([], ...(ngDevMode ? [{ debugName: "cardFields" }] : /* istanbul ignore next */ []));
|
|
5568
5576
|
//****************** Sort ******************//
|
|
5577
|
+
this.sortableFieldDefinitions = signal([], ...(ngDevMode ? [{ debugName: "sortableFieldDefinitions" }] : /* istanbul ignore next */ []));
|
|
5569
5578
|
this.sortableFields = () => {
|
|
5570
|
-
|
|
5571
|
-
|
|
5572
|
-
|
|
5573
|
-
|
|
5574
|
-
|
|
5575
|
-
dir: undefined,
|
|
5576
|
-
};
|
|
5577
|
-
});
|
|
5579
|
+
return this.sortableFieldDefinitions().map((field) => ({
|
|
5580
|
+
name: field.name,
|
|
5581
|
+
title: field.title,
|
|
5582
|
+
dir: undefined,
|
|
5583
|
+
}));
|
|
5578
5584
|
};
|
|
5579
5585
|
this.sortableFieldsCount = () => {
|
|
5580
|
-
return this.
|
|
5586
|
+
return this.sortableFieldDefinitions().length;
|
|
5581
5587
|
};
|
|
5582
5588
|
this.canSort = () => {
|
|
5583
5589
|
return this.sortableFieldsCount() > 0;
|
|
@@ -6176,6 +6182,13 @@ class AXPEntityMasterListViewModel {
|
|
|
6176
6182
|
}
|
|
6177
6183
|
return false;
|
|
6178
6184
|
}
|
|
6185
|
+
/**
|
|
6186
|
+
* Loads host and merge-detail related sortable field definitions (async registry resolution).
|
|
6187
|
+
*/
|
|
6188
|
+
async loadSortableFields() {
|
|
6189
|
+
const fields = await collectEntityListSortableFields(this.entityDef, (moduleName, entityName) => this.entityDefinitionRegistry.resolve(moduleName, entityName).catch(() => null));
|
|
6190
|
+
this.sortableFieldDefinitions.set(fields);
|
|
6191
|
+
}
|
|
6179
6192
|
/**
|
|
6180
6193
|
* Loads host and merge-detail related filter definitions (async registry resolution).
|
|
6181
6194
|
*/
|
|
@@ -6240,6 +6253,20 @@ class AXPEntityMasterListViewModel {
|
|
|
6240
6253
|
this.dataSource.filter(transformedFilter);
|
|
6241
6254
|
this.events$.next({ action: 'refresh', meta: { resetPagination: filtersChanged } });
|
|
6242
6255
|
}
|
|
6256
|
+
//****************** Columns ******************//
|
|
6257
|
+
resolveMergeDetailProperty(columnName) {
|
|
6258
|
+
const parsed = parseDottedFieldPath(columnName);
|
|
6259
|
+
if (!parsed) {
|
|
6260
|
+
return null;
|
|
6261
|
+
}
|
|
6262
|
+
const { dataPath, propertyName } = parsed;
|
|
6263
|
+
const related = this.entityDef.relatedEntities?.find((entry) => entry.layout?.type === 'merge-detail' && entry.persistence?.dataPath?.trim() === dataPath);
|
|
6264
|
+
if (!related?.entity) {
|
|
6265
|
+
return null;
|
|
6266
|
+
}
|
|
6267
|
+
const relatedDef = this.getRegisteredEntity(related.entity);
|
|
6268
|
+
return relatedDef?.properties?.find((property) => property.name === propertyName) ?? null;
|
|
6269
|
+
}
|
|
6243
6270
|
resetColumns() {
|
|
6244
6271
|
this.applyViewColumns();
|
|
6245
6272
|
}
|
|
@@ -6635,6 +6662,7 @@ class AXPEntityListViewModelFactory {
|
|
|
6635
6662
|
this.layout.setNavigationLoading(false);
|
|
6636
6663
|
const vm = new AXPEntityMasterListViewModel(this.injector, config);
|
|
6637
6664
|
await vm.loadFilterDefinitions();
|
|
6665
|
+
await vm.loadSortableFields();
|
|
6638
6666
|
await vm.initializeListPersistence();
|
|
6639
6667
|
return vm;
|
|
6640
6668
|
}
|
|
@@ -6669,7 +6697,7 @@ const AXPEntityListViewModelResolver = async (route, state, service = inject(AXP
|
|
|
6669
6697
|
}
|
|
6670
6698
|
};
|
|
6671
6699
|
|
|
6672
|
-
const AXPEntityDeletedEvent = createWorkFlowEvent(
|
|
6700
|
+
const AXPEntityDeletedEvent = createWorkFlowEvent(AXP_ENTITY_DELETED_WORKFLOW_EVENT_TYPE);
|
|
6673
6701
|
class AXPEntityPerformDeleteAction extends AXPWorkflowAction {
|
|
6674
6702
|
constructor() {
|
|
6675
6703
|
super(...arguments);
|
|
@@ -9864,7 +9892,7 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
|
|
|
9864
9892
|
></ax-button>
|
|
9865
9893
|
</ax-suffix>
|
|
9866
9894
|
</ax-footer>
|
|
9867
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i2$1.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXCheckBoxModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3$2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3$2.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i4.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i3.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "component", type: AXTreeViewComponent, selector: "ax-tree-view", inputs: ["datasource", "selectMode", "selectionBehavior", "dragArea", "dragBehavior", "showIcons", "showChildrenBadge", "expandedIcon", "collapsedIcon", "indentSize", "look", "nodeTemplate", "idField", "titleField", "tooltipField", "iconField", "expandedField", "selectedField", "indeterminateField", "disabledField", "hiddenField", "childrenField", "childrenCountField", "dataField", "inheritDisabled", "expandOnDoubleClick", "doubleClickDuration", "tooltipDelay", "controlledSelection", "selectedIds"], outputs: ["datasourceChange", "selectedIdsChange", "onBeforeDrop", "onNodeToggle", "onNodeSelect", "onNodeDoubleClick", "onNodeClick", "onSelectionChange", "onOrderChange", "onMoveChange", "onItemsChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "look"] }, { kind: "ngmodule", type: FormsModule }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
9895
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i2$1.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXCheckBoxModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3$2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3$2.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i4.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i3.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "component", type: AXTreeViewComponent, selector: "ax-tree-view", inputs: ["datasource", "selectMode", "selectionBehavior", "dragArea", "dragBehavior", "showIcons", "showChildrenBadge", "expandedIcon", "collapsedIcon", "indentSize", "look", "nodeTemplate", "idField", "titleField", "tooltipField", "iconField", "expandedField", "selectedField", "indeterminateField", "disabledField", "hiddenField", "childrenField", "childrenCountField", "dataField", "inheritDisabled", "expandOnDoubleClick", "doubleClickDuration", "tooltipDelay", "controlledSelection", "selectedIds"], outputs: ["datasourceChange", "selectedIdsChange", "onBeforeDrop", "onNodeToggle", "onNodeSelect", "onNodeDoubleClick", "onNodeClick", "onSelectionChange", "onOrderChange", "onMoveChange", "onItemsChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "titleParams", "descriptionParams", "look"] }, { kind: "ngmodule", type: FormsModule }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
9868
9896
|
}
|
|
9869
9897
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityCategoryTreeSelectorComponent, decorators: [{
|
|
9870
9898
|
type: Component,
|
|
@@ -12213,7 +12241,7 @@ class AXPEntityListToolbarService {
|
|
|
12213
12241
|
const toolbarOptions = {
|
|
12214
12242
|
filterDefinitions: this.mergeFilterDefinitions(baseFilters, options?.customFilterDefinitions),
|
|
12215
12243
|
columnDefinitions: this.createColumnDefinitions(entity, options),
|
|
12216
|
-
sortDefinitions: this.createSortDefinitions(entity),
|
|
12244
|
+
sortDefinitions: await this.createSortDefinitions(entity),
|
|
12217
12245
|
canFilter: true,
|
|
12218
12246
|
canColumns: true,
|
|
12219
12247
|
canSort: true,
|
|
@@ -12339,23 +12367,14 @@ class AXPEntityListToolbarService {
|
|
|
12339
12367
|
}
|
|
12340
12368
|
/**
|
|
12341
12369
|
* Create Sort Definitions for Toolbar.
|
|
12342
|
-
* Includes
|
|
12370
|
+
* Includes host properties and merge-detail related fields with sort enabled.
|
|
12343
12371
|
*/
|
|
12344
|
-
createSortDefinitions(entity) {
|
|
12345
|
-
const
|
|
12346
|
-
|
|
12347
|
-
|
|
12348
|
-
|
|
12349
|
-
|
|
12350
|
-
.filter((col) => col.name.includes('.') && col.title)
|
|
12351
|
-
.map((col) => ({ name: col.name, title: col.title ?? col.name }));
|
|
12352
|
-
const seen = new Set();
|
|
12353
|
-
return [...fromProperties, ...fromColumns].filter((s) => {
|
|
12354
|
-
if (seen.has(s.name))
|
|
12355
|
-
return false;
|
|
12356
|
-
seen.add(s.name);
|
|
12357
|
-
return true;
|
|
12358
|
-
});
|
|
12372
|
+
async createSortDefinitions(entity) {
|
|
12373
|
+
const fields = await collectEntityListSortableFields(entity, (moduleName, entityName) => this.entityRegistry.resolve(moduleName, entityName).catch(() => null));
|
|
12374
|
+
return fields.map((field) => ({
|
|
12375
|
+
name: field.name,
|
|
12376
|
+
title: field.title,
|
|
12377
|
+
}));
|
|
12359
12378
|
}
|
|
12360
12379
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityListToolbarService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
12361
12380
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityListToolbarService }); }
|
|
@@ -13390,7 +13409,7 @@ class AXPPageComponentWidgetViewComponent extends AXPBaseWidgetComponent {
|
|
|
13390
13409
|
return;
|
|
13391
13410
|
}
|
|
13392
13411
|
for (const [path, value] of Object.entries(partial)) {
|
|
13393
|
-
this.contextService.update(path, value);
|
|
13412
|
+
this.contextService.update(path, value, { origin: 'user' });
|
|
13394
13413
|
}
|
|
13395
13414
|
}
|
|
13396
13415
|
//#endregion
|
|
@@ -13801,6 +13820,108 @@ var lookupWidgetView_component = /*#__PURE__*/Object.freeze({
|
|
|
13801
13820
|
AXPLookupWidgetViewComponent: AXPLookupWidgetViewComponent
|
|
13802
13821
|
});
|
|
13803
13822
|
|
|
13823
|
+
//#region ---- Expression Scope ----
|
|
13824
|
+
/**
|
|
13825
|
+
* Builds the expression scope used to evaluate lookup `create.context` templates.
|
|
13826
|
+
* Matches widget-renderer `context.eval` / `context.set` semantics.
|
|
13827
|
+
*/
|
|
13828
|
+
function buildLookupExpressionScope(contextService, parentPath) {
|
|
13829
|
+
return {
|
|
13830
|
+
context: {
|
|
13831
|
+
eval: (path) => {
|
|
13832
|
+
const fullPath = path.startsWith('>') && parentPath ? `${parentPath}.${path.substring(1)}` : path;
|
|
13833
|
+
return contextService.getValue(fullPath);
|
|
13834
|
+
},
|
|
13835
|
+
set: (path, value) => {
|
|
13836
|
+
contextService.update(path, value, { origin: 'user' });
|
|
13837
|
+
},
|
|
13838
|
+
data: () => contextService.data(),
|
|
13839
|
+
isDirty: () => {
|
|
13840
|
+
if (!contextService.isSavedCommitted()) {
|
|
13841
|
+
return false;
|
|
13842
|
+
}
|
|
13843
|
+
return contextService.isDirty();
|
|
13844
|
+
},
|
|
13845
|
+
options: (path) => {
|
|
13846
|
+
if (path == null || path === '') {
|
|
13847
|
+
return contextService.getValue('options');
|
|
13848
|
+
}
|
|
13849
|
+
return contextService.getValue(`options.${path}`);
|
|
13850
|
+
},
|
|
13851
|
+
},
|
|
13852
|
+
events: {},
|
|
13853
|
+
widget: {},
|
|
13854
|
+
methods: {},
|
|
13855
|
+
vars: {},
|
|
13856
|
+
};
|
|
13857
|
+
}
|
|
13858
|
+
//#endregion
|
|
13859
|
+
//#region ---- Create Context Evaluation ----
|
|
13860
|
+
/**
|
|
13861
|
+
* Deep-evaluates expression strings inside lookup `create.context` (e.g. parentId from context).
|
|
13862
|
+
*/
|
|
13863
|
+
async function evaluateLookupCreateContext(template, expressionEvaluator, scope) {
|
|
13864
|
+
if (!template || !isObjectLike(template)) {
|
|
13865
|
+
return {};
|
|
13866
|
+
}
|
|
13867
|
+
return (await evaluateLookupCreateContextValue(template, expressionEvaluator, scope));
|
|
13868
|
+
}
|
|
13869
|
+
async function evaluateLookupCreateContextValue(value, expressionEvaluator, scope) {
|
|
13870
|
+
if (typeof value === 'string' && expressionEvaluator.isExpression(value)) {
|
|
13871
|
+
return expressionEvaluator.evaluate(value, scope);
|
|
13872
|
+
}
|
|
13873
|
+
if (isArray(value)) {
|
|
13874
|
+
const results = await Promise.all(value.map((entry) => evaluateLookupCreateContextValue(entry, expressionEvaluator, scope)));
|
|
13875
|
+
return results;
|
|
13876
|
+
}
|
|
13877
|
+
if (isObjectLike(value)) {
|
|
13878
|
+
const result = {};
|
|
13879
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
13880
|
+
result[key] = await evaluateLookupCreateContextValue(entry, expressionEvaluator, scope);
|
|
13881
|
+
}
|
|
13882
|
+
return result;
|
|
13883
|
+
}
|
|
13884
|
+
return value;
|
|
13885
|
+
}
|
|
13886
|
+
/**
|
|
13887
|
+
* Removes null/undefined entries from resolved create context before Entity:Create.
|
|
13888
|
+
*/
|
|
13889
|
+
function compactLookupCreateContext(data) {
|
|
13890
|
+
const result = {};
|
|
13891
|
+
for (const [key, value] of Object.entries(cloneDeep(data))) {
|
|
13892
|
+
if (!isNil(value) && value !== '') {
|
|
13893
|
+
result[key] = value;
|
|
13894
|
+
}
|
|
13895
|
+
}
|
|
13896
|
+
return result;
|
|
13897
|
+
}
|
|
13898
|
+
//#endregion
|
|
13899
|
+
|
|
13900
|
+
//#endregion
|
|
13901
|
+
//#region ---- Resolution ----
|
|
13902
|
+
/**
|
|
13903
|
+
* Resolves lookup create options from `create` and legacy `allowCreate` (mode).
|
|
13904
|
+
*/
|
|
13905
|
+
function resolveLookupWidgetCreateOptions(options) {
|
|
13906
|
+
const create = options.create;
|
|
13907
|
+
const legacyMode = options.allowCreate;
|
|
13908
|
+
const context = create?.context;
|
|
13909
|
+
if (create?.enable !== undefined) {
|
|
13910
|
+
if (!create.enable) {
|
|
13911
|
+
return { enabled: false, mode: 'none', context };
|
|
13912
|
+
}
|
|
13913
|
+
const mode = legacyMode && legacyMode !== 'none' ? legacyMode : 'quick';
|
|
13914
|
+
return { enabled: true, mode, context };
|
|
13915
|
+
}
|
|
13916
|
+
const mode = legacyMode ?? 'none';
|
|
13917
|
+
return {
|
|
13918
|
+
enabled: mode !== 'none',
|
|
13919
|
+
mode,
|
|
13920
|
+
context,
|
|
13921
|
+
};
|
|
13922
|
+
}
|
|
13923
|
+
//#endregion
|
|
13924
|
+
|
|
13804
13925
|
//#endregion
|
|
13805
13926
|
class AXPEntityDataSelectorRowActionsService {
|
|
13806
13927
|
constructor() {
|
|
@@ -14077,11 +14198,20 @@ function mapLegacyEntityDataSelectorOptions(legacy) {
|
|
|
14077
14198
|
normalized.category = { enabled: legacy.showCategoryFilter };
|
|
14078
14199
|
}
|
|
14079
14200
|
if (legacy.allowCreate !== undefined) {
|
|
14080
|
-
normalized.create = {
|
|
14201
|
+
normalized.create = {
|
|
14202
|
+
...(legacy.allowCreate !== undefined && {
|
|
14203
|
+
enable: legacy.allowCreate !== 'none',
|
|
14204
|
+
mode: legacy.allowCreate,
|
|
14205
|
+
}),
|
|
14206
|
+
...normalized.create,
|
|
14207
|
+
};
|
|
14081
14208
|
}
|
|
14082
14209
|
if (legacy.rowActions !== undefined) {
|
|
14083
14210
|
normalized.rowActions = legacy.rowActions;
|
|
14084
14211
|
}
|
|
14212
|
+
if (legacy.contextStore !== undefined) {
|
|
14213
|
+
normalized.contextStore = legacy.contextStore;
|
|
14214
|
+
}
|
|
14085
14215
|
return normalized;
|
|
14086
14216
|
}
|
|
14087
14217
|
/**
|
|
@@ -14117,6 +14247,9 @@ function normalizeEntityDataSelectorOptions(options) {
|
|
|
14117
14247
|
if (nested.create) {
|
|
14118
14248
|
normalized.create = { ...normalized.create, ...nested.create };
|
|
14119
14249
|
}
|
|
14250
|
+
if (nested.contextStore !== undefined) {
|
|
14251
|
+
normalized.contextStore = nested.contextStore;
|
|
14252
|
+
}
|
|
14120
14253
|
if (nested.rowActions !== undefined) {
|
|
14121
14254
|
normalized.rowActions = nested.rowActions;
|
|
14122
14255
|
}
|
|
@@ -14134,9 +14267,21 @@ class AXPEntityDataSelectorService {
|
|
|
14134
14267
|
this.categoryTreeService = inject(AXPCategoryTreeService);
|
|
14135
14268
|
this.translationService = inject(AXTranslationService);
|
|
14136
14269
|
this.rowActionsService = inject(AXPEntityDataSelectorRowActionsService);
|
|
14270
|
+
this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
|
|
14137
14271
|
}
|
|
14138
14272
|
//#endregion
|
|
14139
14273
|
//#region ---- Public Methods ----
|
|
14274
|
+
/**
|
|
14275
|
+
* Resolves lookup `create.context` templates using the provided form context store.
|
|
14276
|
+
*/
|
|
14277
|
+
async resolveCreateContext(template, contextStore) {
|
|
14278
|
+
if (!template || !contextStore) {
|
|
14279
|
+
return {};
|
|
14280
|
+
}
|
|
14281
|
+
const scope = buildLookupExpressionScope(contextStore);
|
|
14282
|
+
const resolved = await evaluateLookupCreateContext(template, this.expressionEvaluator, scope);
|
|
14283
|
+
return compactLookupCreateContext(resolved);
|
|
14284
|
+
}
|
|
14140
14285
|
/**
|
|
14141
14286
|
* Open entity data selector popup.
|
|
14142
14287
|
* Accepts nested {@link AXPEntityDataSelectorOpenOptions} or deprecated flat {@link AXPEntityDataSelectorOptions}.
|
|
@@ -14152,8 +14297,8 @@ class AXPEntityDataSelectorService {
|
|
|
14152
14297
|
* Execute Entity:Create and return created item.
|
|
14153
14298
|
* Used by lookup widget and data selector for inline create.
|
|
14154
14299
|
*/
|
|
14155
|
-
async executeEntityCreate(entity, mode) {
|
|
14156
|
-
return this.executeCreate(entity, mode);
|
|
14300
|
+
async executeEntityCreate(entity, mode, initialData = {}) {
|
|
14301
|
+
return this.executeCreate(entity, mode, initialData);
|
|
14157
14302
|
}
|
|
14158
14303
|
/**
|
|
14159
14304
|
* Normalize item's phones/emails for expose/display.
|
|
@@ -14216,7 +14361,16 @@ class AXPEntityDataSelectorService {
|
|
|
14216
14361
|
const dataSource = this.createDataSource(options);
|
|
14217
14362
|
const columns = this.createColumns(options);
|
|
14218
14363
|
const searchFields = this.getSearchFields(options);
|
|
14219
|
-
const
|
|
14364
|
+
const hasCreateConfig = options.create !== undefined;
|
|
14365
|
+
const resolvedCreate = resolveLookupWidgetCreateOptions({
|
|
14366
|
+
create: options.create,
|
|
14367
|
+
allowCreate: options.create?.mode,
|
|
14368
|
+
});
|
|
14369
|
+
const allowCreate = hasCreateConfig
|
|
14370
|
+
? resolvedCreate.enabled
|
|
14371
|
+
? resolvedCreate.mode
|
|
14372
|
+
: 'none'
|
|
14373
|
+
: this.getAllowCreate(options.entity);
|
|
14220
14374
|
const rowActions = options.rowActions
|
|
14221
14375
|
? this.rowActionsService.createHandler(options.entity, options.rowActions)
|
|
14222
14376
|
: undefined;
|
|
@@ -14241,7 +14395,12 @@ class AXPEntityDataSelectorService {
|
|
|
14241
14395
|
filter: options.filter?.value ? { value: options.filter.value } : undefined,
|
|
14242
14396
|
create: {
|
|
14243
14397
|
mode: allowCreate,
|
|
14244
|
-
onCreate: allowCreate !== 'none'
|
|
14398
|
+
onCreate: allowCreate !== 'none'
|
|
14399
|
+
? async (mode) => {
|
|
14400
|
+
const data = await this.resolveCreateContext(resolvedCreate.context, options.contextStore);
|
|
14401
|
+
return this.executeCreate(options.entity, mode, data);
|
|
14402
|
+
}
|
|
14403
|
+
: undefined,
|
|
14245
14404
|
},
|
|
14246
14405
|
rowActions,
|
|
14247
14406
|
};
|
|
@@ -14389,7 +14548,7 @@ class AXPEntityDataSelectorService {
|
|
|
14389
14548
|
/**
|
|
14390
14549
|
* Execute Entity:Create and return created item
|
|
14391
14550
|
*/
|
|
14392
|
-
async executeCreate(entity, mode) {
|
|
14551
|
+
async executeCreate(entity, mode, initialData = {}) {
|
|
14393
14552
|
const quickCreate = entity.interfaces?.master?.create?.quickCreate;
|
|
14394
14553
|
const options = {};
|
|
14395
14554
|
if (mode === 'quick' && quickCreate) {
|
|
@@ -14413,7 +14572,7 @@ class AXPEntityDataSelectorService {
|
|
|
14413
14572
|
title: entity.title,
|
|
14414
14573
|
parentKey: entity.parentKey,
|
|
14415
14574
|
},
|
|
14416
|
-
data:
|
|
14575
|
+
data: initialData,
|
|
14417
14576
|
options,
|
|
14418
14577
|
},
|
|
14419
14578
|
});
|
|
@@ -14890,6 +15049,7 @@ class AXPLookupWidgetTagboxComponent extends LookupWidgetLookBase {
|
|
|
14890
15049
|
this.entityDataSelectorService = inject(AXPEntityDataSelectorService);
|
|
14891
15050
|
this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
|
|
14892
15051
|
this.contextEvalFactory = inject(AXPContextEvalFactory);
|
|
15052
|
+
this.contextStore = inject(AXPContextStore, { optional: true });
|
|
14893
15053
|
//#endregion
|
|
14894
15054
|
//#region ---- Inputs ----
|
|
14895
15055
|
this.selectedItems = input.required(...(ngDevMode ? [{ debugName: "selectedItems" }] : /* istanbul ignore next */ []));
|
|
@@ -14902,7 +15062,7 @@ class AXPLookupWidgetTagboxComponent extends LookupWidgetLookBase {
|
|
|
14902
15062
|
this.validationRules = input.required(...(ngDevMode ? [{ debugName: "validationRules" }] : /* istanbul ignore next */ []));
|
|
14903
15063
|
this.placeholder = input(...(ngDevMode ? [undefined, { debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
14904
15064
|
this.hasClearButton = input(false, ...(ngDevMode ? [{ debugName: "hasClearButton" }] : /* istanbul ignore next */ []));
|
|
14905
|
-
this.
|
|
15065
|
+
this.resolvedCreate = input({ enabled: false, mode: 'none' }, ...(ngDevMode ? [{ debugName: "resolvedCreate" }] : /* istanbul ignore next */ []));
|
|
14906
15066
|
this.allowUnselect = input(true, ...(ngDevMode ? [{ debugName: "allowUnselect" }] : /* istanbul ignore next */ []));
|
|
14907
15067
|
// Entity and configuration data (for showSelector and searchByValue)
|
|
14908
15068
|
this.entityDef = input.required(...(ngDevMode ? [{ debugName: "entityDef" }] : /* istanbul ignore next */ []));
|
|
@@ -15111,6 +15271,7 @@ class AXPLookupWidgetTagboxComponent extends LookupWidgetLookBase {
|
|
|
15111
15271
|
.map((item) => get(item, this.valueField()()))
|
|
15112
15272
|
.filter((id) => id != null);
|
|
15113
15273
|
try {
|
|
15274
|
+
const createOptions = this.resolvedCreate();
|
|
15114
15275
|
const result = await this.entityDataSelectorService.open({
|
|
15115
15276
|
entity,
|
|
15116
15277
|
title: `${this.translateService.translateSync(entity.formats.plural ?? '')}`,
|
|
@@ -15119,7 +15280,12 @@ class AXPLookupWidgetTagboxComponent extends LookupWidgetLookBase {
|
|
|
15119
15280
|
filters: this.customFilter()(),
|
|
15120
15281
|
parentFilters: this.parentFilters(),
|
|
15121
15282
|
columns: this.columns()(),
|
|
15122
|
-
|
|
15283
|
+
create: {
|
|
15284
|
+
enable: createOptions.enabled,
|
|
15285
|
+
mode: createOptions.mode,
|
|
15286
|
+
context: createOptions.context,
|
|
15287
|
+
},
|
|
15288
|
+
contextStore: this.contextStore ?? undefined,
|
|
15123
15289
|
initialSearchTerm: searchTerm,
|
|
15124
15290
|
selectedItemIds: selectedItemIds.length > 0 ? selectedItemIds : undefined,
|
|
15125
15291
|
rowActions: this.rowActions(),
|
|
@@ -15145,7 +15311,7 @@ class AXPLookupWidgetTagboxComponent extends LookupWidgetLookBase {
|
|
|
15145
15311
|
this.clear();
|
|
15146
15312
|
}
|
|
15147
15313
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLookupWidgetTagboxComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
15148
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPLookupWidgetTagboxComponent, isStandalone: true, selector: "axp-lookup-widget-tagbox", inputs: { selectedItems: { classPropertyName: "selectedItems", publicName: "selectedItems", isSignal: true, isRequired: true, transformFunction: null }, displayField: { classPropertyName: "displayField", publicName: "displayField", isSignal: true, isRequired: true, transformFunction: null }, valueField: { classPropertyName: "valueField", publicName: "valueField", isSignal: true, isRequired: true, transformFunction: null }, displayFormat: { classPropertyName: "displayFormat", publicName: "displayFormat", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: true, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: true, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: true, transformFunction: null }, validationRules: { classPropertyName: "validationRules", publicName: "validationRules", isSignal: true, isRequired: true, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, hasClearButton: { classPropertyName: "hasClearButton", publicName: "hasClearButton", isSignal: true, isRequired: false, transformFunction: null },
|
|
15314
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPLookupWidgetTagboxComponent, isStandalone: true, selector: "axp-lookup-widget-tagbox", inputs: { selectedItems: { classPropertyName: "selectedItems", publicName: "selectedItems", isSignal: true, isRequired: true, transformFunction: null }, displayField: { classPropertyName: "displayField", publicName: "displayField", isSignal: true, isRequired: true, transformFunction: null }, valueField: { classPropertyName: "valueField", publicName: "valueField", isSignal: true, isRequired: true, transformFunction: null }, displayFormat: { classPropertyName: "displayFormat", publicName: "displayFormat", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: true, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: true, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: true, transformFunction: null }, validationRules: { classPropertyName: "validationRules", publicName: "validationRules", isSignal: true, isRequired: true, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, hasClearButton: { classPropertyName: "hasClearButton", publicName: "hasClearButton", isSignal: true, isRequired: false, transformFunction: null }, resolvedCreate: { classPropertyName: "resolvedCreate", publicName: "resolvedCreate", isSignal: true, isRequired: false, transformFunction: null }, allowUnselect: { classPropertyName: "allowUnselect", publicName: "allowUnselect", isSignal: true, isRequired: false, transformFunction: null }, entityDef: { classPropertyName: "entityDef", publicName: "entityDef", isSignal: true, isRequired: true, transformFunction: null }, customFilter: { classPropertyName: "customFilter", publicName: "customFilter", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, parentFilters: { classPropertyName: "parentFilters", publicName: "parentFilters", isSignal: true, isRequired: false, transformFunction: null }, rowActions: { classPropertyName: "rowActions", publicName: "rowActions", isSignal: true, isRequired: false, transformFunction: null }, onSetLoading: { classPropertyName: "onSetLoading", publicName: "onSetLoading", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { valueChanged: "valueChanged" }, providers: [
|
|
15149
15315
|
{
|
|
15150
15316
|
provide: LookupWidgetLookBase,
|
|
15151
15317
|
useExisting: AXPLookupWidgetTagboxComponent,
|
|
@@ -15284,7 +15450,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
15284
15450
|
},
|
|
15285
15451
|
],
|
|
15286
15452
|
}]
|
|
15287
|
-
}], propDecorators: { selectedItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedItems", required: true }] }], displayField: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayField", required: true }] }], valueField: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueField", required: true }] }], displayFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayFormat", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: true }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: true }] }], isLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLoading", required: true }] }], validationRules: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationRules", required: true }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], hasClearButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasClearButton", required: false }] }],
|
|
15453
|
+
}], propDecorators: { selectedItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedItems", required: true }] }], displayField: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayField", required: true }] }], valueField: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueField", required: true }] }], displayFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayFormat", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: true }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: true }] }], isLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLoading", required: true }] }], validationRules: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationRules", required: true }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], hasClearButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasClearButton", required: false }] }], resolvedCreate: [{ type: i0.Input, args: [{ isSignal: true, alias: "resolvedCreate", required: false }] }], allowUnselect: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowUnselect", required: false }] }], entityDef: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityDef", required: true }] }], customFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "customFilter", required: true }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], parentFilters: [{ type: i0.Input, args: [{ isSignal: true, alias: "parentFilters", required: false }] }], rowActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowActions", required: false }] }], onSetLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "onSetLoading", required: true }] }], valueChanged: [{ type: i0.Output, args: ["valueChanged"] }], tagBox: [{ type: i0.ViewChild, args: ['tagBoxComponent', { isSignal: true }] }] } });
|
|
15288
15454
|
|
|
15289
15455
|
class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
15290
15456
|
constructor() {
|
|
@@ -15327,7 +15493,10 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15327
15493
|
this.allowUnselect = computed(() => this.options()['allowUnselect'] ?? true, ...(ngDevMode ? [{ debugName: "allowUnselect" }] : /* istanbul ignore next */ []));
|
|
15328
15494
|
this.look = computed(() => this.options()['look'] ?? 'lookup', ...(ngDevMode ? [{ debugName: "look" }] : /* istanbul ignore next */ []));
|
|
15329
15495
|
this.displayField = computed(() => resolveLookupDisplayField(this.entityDef(), { textField: this.textField() }), ...(ngDevMode ? [{ debugName: "displayField" }] : /* istanbul ignore next */ []));
|
|
15330
|
-
this.
|
|
15496
|
+
this.resolvedCreate = computed(() => resolveLookupWidgetCreateOptions({
|
|
15497
|
+
create: this.options()['create'],
|
|
15498
|
+
allowCreate: this.options()['allowCreate'],
|
|
15499
|
+
}), ...(ngDevMode ? [{ debugName: "resolvedCreate" }] : /* istanbul ignore next */ []));
|
|
15331
15500
|
this.selectorRowActions = computed(() => this.options()['selectorRowActions'], ...(ngDevMode ? [{ debugName: "selectorRowActions" }] : /* istanbul ignore next */ []));
|
|
15332
15501
|
this.valueField = computed(() => this.entityDef()?.properties.find((c) => c.name == 'id')?.name ?? 'id', ...(ngDevMode ? [{ debugName: "valueField" }] : /* istanbul ignore next */ []));
|
|
15333
15502
|
this.displayFormat = computed(() => resolveLookupDisplayTemplate(this.entityDef(), {
|
|
@@ -15373,6 +15542,12 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15373
15542
|
//#region ---- Business Logic Methods (Passed to Dumb Components) ----
|
|
15374
15543
|
this.setLoading = (loading) => {
|
|
15375
15544
|
this.isLoading.set(loading);
|
|
15545
|
+
if (loading) {
|
|
15546
|
+
this.beginHydration();
|
|
15547
|
+
}
|
|
15548
|
+
else {
|
|
15549
|
+
this.endHydration();
|
|
15550
|
+
}
|
|
15376
15551
|
};
|
|
15377
15552
|
/** @param syncContext When false, only updates UI (hydration/revert); skips context writes. */
|
|
15378
15553
|
this.setItems = (items, syncContext = true) => {
|
|
@@ -15382,6 +15557,8 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15382
15557
|
items = items.filter((item) => item != null);
|
|
15383
15558
|
// Normalize phones/emails from repeater nested structure to { value: string }
|
|
15384
15559
|
items = items.map((item) => this.entityDataSelectorService.normalizeItemContactArrays(item));
|
|
15560
|
+
/** Preserve raw entity fields (e.g. MLS maps) before display-field resolution for expose writes. */
|
|
15561
|
+
const itemsForExpose = cloneDeep(items);
|
|
15385
15562
|
const displayField = this.displayField();
|
|
15386
15563
|
items = items.map((item) => {
|
|
15387
15564
|
const raw = get(item, displayField);
|
|
@@ -15396,10 +15573,32 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15396
15573
|
}
|
|
15397
15574
|
const keys = items.map((item) => get(item, this.valueField()));
|
|
15398
15575
|
const text = items.map((item) => this.mlsResolver.resolve(get(item, displayField)));
|
|
15576
|
+
const newValue = this.singleOrMultiple(keys);
|
|
15577
|
+
const widgetPath = this.fullPath();
|
|
15578
|
+
const savedWidgetValue = widgetPath ? this.contextService.getSavedValue(widgetPath) : undefined;
|
|
15579
|
+
const selectionMatchesSaved = this.contextService.isSavedCommitted() &&
|
|
15580
|
+
widgetPath != null &&
|
|
15581
|
+
isSelectionValueEqual(newValue, savedWidgetValue);
|
|
15399
15582
|
if (this.expose()) {
|
|
15400
|
-
|
|
15583
|
+
AXPDebugService.instance?.trace(FORM_DIRTY_TRACE_NS, 'lookup-widget', 'setItems expose', () => ({
|
|
15584
|
+
path: this.fullPath(),
|
|
15585
|
+
items: items.map((item) => get(item, this.valueField())),
|
|
15586
|
+
expose: this.expose(),
|
|
15587
|
+
selectionMatchesSaved,
|
|
15588
|
+
}));
|
|
15589
|
+
if (selectionMatchesSaved) {
|
|
15590
|
+
this.syncExposePathsToSavedBaseline();
|
|
15591
|
+
}
|
|
15592
|
+
else {
|
|
15593
|
+
this.expoesItems(itemsForExpose);
|
|
15594
|
+
}
|
|
15401
15595
|
}
|
|
15402
|
-
|
|
15596
|
+
AXPDebugService.instance?.trace(FORM_DIRTY_TRACE_NS, 'lookup-widget', 'setItems setValue', () => ({
|
|
15597
|
+
path: this.fullPath(),
|
|
15598
|
+
newValue,
|
|
15599
|
+
keys,
|
|
15600
|
+
syncContext,
|
|
15601
|
+
}));
|
|
15403
15602
|
if (this.filterMode()) {
|
|
15404
15603
|
this.setValue({
|
|
15405
15604
|
value: newValue,
|
|
@@ -15412,12 +15611,16 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15412
15611
|
else {
|
|
15413
15612
|
this.setValue(newValue);
|
|
15414
15613
|
}
|
|
15614
|
+
if (this.expose() && selectionMatchesSaved) {
|
|
15615
|
+
this.syncExposePathsToSavedBaseline();
|
|
15616
|
+
}
|
|
15415
15617
|
};
|
|
15416
15618
|
}
|
|
15417
15619
|
#efEntity;
|
|
15418
15620
|
#efValue;
|
|
15419
15621
|
async findByValue() {
|
|
15420
15622
|
this.isLoading.set(true);
|
|
15623
|
+
this.beginHydration();
|
|
15421
15624
|
const rawValue = this.getValue();
|
|
15422
15625
|
// When multiple is true, ensure we always work with arrays
|
|
15423
15626
|
const values = this.multiple()
|
|
@@ -15426,6 +15629,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15426
15629
|
if (!values.length) {
|
|
15427
15630
|
this.setItems([], false);
|
|
15428
15631
|
this.isLoading.set(false);
|
|
15632
|
+
this.endHydration();
|
|
15429
15633
|
return;
|
|
15430
15634
|
}
|
|
15431
15635
|
try {
|
|
@@ -15458,6 +15662,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15458
15662
|
}
|
|
15459
15663
|
finally {
|
|
15460
15664
|
this.isLoading.set(false);
|
|
15665
|
+
this.endHydration();
|
|
15461
15666
|
}
|
|
15462
15667
|
}
|
|
15463
15668
|
//#region ---- Event Handlers from Dumb Components ----
|
|
@@ -15468,7 +15673,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15468
15673
|
const entity = this.entityDef();
|
|
15469
15674
|
if (!entity || !entity.commands?.create?.execute)
|
|
15470
15675
|
return;
|
|
15471
|
-
const mode = this.
|
|
15676
|
+
const { mode } = this.resolvedCreate();
|
|
15472
15677
|
if (mode !== 'full' && mode !== 'quick')
|
|
15473
15678
|
return;
|
|
15474
15679
|
await this.executeCreate(mode);
|
|
@@ -15478,8 +15683,11 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15478
15683
|
if (!entity || !entity.commands?.create?.execute)
|
|
15479
15684
|
return;
|
|
15480
15685
|
this.isLoading.set(true);
|
|
15686
|
+
this.beginHydration();
|
|
15481
15687
|
try {
|
|
15482
|
-
const
|
|
15688
|
+
const { context } = this.resolvedCreate();
|
|
15689
|
+
const createData = await this.entityDataSelectorService.resolveCreateContext(context, this.contextService);
|
|
15690
|
+
const createdItem = await this.entityDataSelectorService.executeEntityCreate(entity, mode, createData);
|
|
15483
15691
|
if (createdItem) {
|
|
15484
15692
|
const currentItems = this.selectedItems();
|
|
15485
15693
|
const valueField = this.valueField();
|
|
@@ -15499,6 +15707,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15499
15707
|
}
|
|
15500
15708
|
finally {
|
|
15501
15709
|
this.isLoading.set(false);
|
|
15710
|
+
this.endHydration();
|
|
15502
15711
|
}
|
|
15503
15712
|
}
|
|
15504
15713
|
/**
|
|
@@ -15507,9 +15716,31 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15507
15716
|
* so e.g. `{ person: { educationLevel: { id, title } } }` would replace the entire `person`
|
|
15508
15717
|
* object and drop sibling fields like `person.educationLevelId`, causing a value/effect loop.
|
|
15509
15718
|
*/
|
|
15510
|
-
|
|
15719
|
+
syncExposePathsToSavedBaseline() {
|
|
15720
|
+
const exposeValue = castArray(this.expose());
|
|
15721
|
+
const parentPaths = new Set();
|
|
15722
|
+
exposeValue.forEach((item) => {
|
|
15723
|
+
const target = typeof item === 'string' ? item : item.target;
|
|
15724
|
+
if (target.includes('.')) {
|
|
15725
|
+
parentPaths.add(target.split('.').slice(0, -1).join('.'));
|
|
15726
|
+
}
|
|
15727
|
+
this.contextService.syncPathToSavedBaseline(target, { origin: 'system' });
|
|
15728
|
+
});
|
|
15729
|
+
const saved = this.contextService.saved();
|
|
15730
|
+
parentPaths.forEach((parentPath) => {
|
|
15731
|
+
if (!has(saved, parentPath)) {
|
|
15732
|
+
this.contextService.syncPathToSavedBaseline(parentPath, { origin: 'system' });
|
|
15733
|
+
}
|
|
15734
|
+
});
|
|
15735
|
+
AXPDebugService.instance?.trace(FORM_DIRTY_TRACE_NS, 'lookup-widget', 'syncExposePathsToSavedBaseline', () => ({
|
|
15736
|
+
path: this.fullPath(),
|
|
15737
|
+
expose: this.expose(),
|
|
15738
|
+
parentPaths: [...parentPaths],
|
|
15739
|
+
}));
|
|
15740
|
+
}
|
|
15741
|
+
expoesItems(sourceItems) {
|
|
15511
15742
|
const exposeValue = castArray(this.expose());
|
|
15512
|
-
const items = this.selectedItems();
|
|
15743
|
+
const items = sourceItems ?? this.selectedItems();
|
|
15513
15744
|
const isEmpty = !items || items.length === 0;
|
|
15514
15745
|
if (isEmpty) {
|
|
15515
15746
|
const parentPaths = new Set();
|
|
@@ -15520,7 +15751,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15520
15751
|
parentPaths.add(pathParts.slice(0, -1).join('.'));
|
|
15521
15752
|
}
|
|
15522
15753
|
else {
|
|
15523
|
-
this.contextService.update(i, null);
|
|
15754
|
+
this.contextService.update(i, null, { origin: 'user' });
|
|
15524
15755
|
}
|
|
15525
15756
|
}
|
|
15526
15757
|
else {
|
|
@@ -15529,25 +15760,25 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15529
15760
|
parentPaths.add(pathParts.slice(0, -1).join('.'));
|
|
15530
15761
|
}
|
|
15531
15762
|
else {
|
|
15532
|
-
this.contextService.update(i.target, null);
|
|
15763
|
+
this.contextService.update(i.target, null, { origin: 'user' });
|
|
15533
15764
|
}
|
|
15534
15765
|
}
|
|
15535
15766
|
});
|
|
15536
15767
|
parentPaths.forEach((parentPath) => {
|
|
15537
|
-
this.contextService.update(parentPath, null);
|
|
15768
|
+
this.contextService.update(parentPath, null, { origin: 'user' });
|
|
15538
15769
|
});
|
|
15539
15770
|
return;
|
|
15540
15771
|
}
|
|
15541
15772
|
exposeValue.forEach((i) => {
|
|
15542
15773
|
if (typeof i === 'string') {
|
|
15543
15774
|
const values = items.map((item) => set({}, i, get(item, i)));
|
|
15544
|
-
this.contextService.update(i, this.singleOrMultiple(values));
|
|
15775
|
+
this.contextService.update(i, this.singleOrMultiple(values), { origin: 'user' });
|
|
15545
15776
|
}
|
|
15546
15777
|
else {
|
|
15547
15778
|
const values = this.multiple()
|
|
15548
15779
|
? items.map((item) => set({}, i.source, get(item, i.source)))
|
|
15549
15780
|
: items.map((item) => get(item, i.source));
|
|
15550
|
-
this.contextService.update(i.target, this.singleOrMultiple(values));
|
|
15781
|
+
this.contextService.update(i.target, this.singleOrMultiple(values), { origin: 'user' });
|
|
15551
15782
|
}
|
|
15552
15783
|
});
|
|
15553
15784
|
}
|
|
@@ -15590,7 +15821,6 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15590
15821
|
[placeholder]="placeholder"
|
|
15591
15822
|
[validationRules]="validationRules"
|
|
15592
15823
|
[hasClearButton]="hasClearButton()"
|
|
15593
|
-
[allowCreate]="allowCreate()"
|
|
15594
15824
|
[showItemTooltip]="showItemTooltip()"
|
|
15595
15825
|
[isItemTruncated]="isItemTruncated()"
|
|
15596
15826
|
(valueChanged)="handleComponentValueChanged($event)"
|
|
@@ -15609,7 +15839,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15609
15839
|
[isLoading]="isLoading"
|
|
15610
15840
|
[validationRules]="validationRules"
|
|
15611
15841
|
[hasClearButton]="hasClearButton()"
|
|
15612
|
-
[
|
|
15842
|
+
[resolvedCreate]="resolvedCreate()"
|
|
15613
15843
|
[allowUnselect]="allowUnselect()"
|
|
15614
15844
|
[entityDef]="entityDef"
|
|
15615
15845
|
[customFilter]="customFilter"
|
|
@@ -15621,7 +15851,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15621
15851
|
/>
|
|
15622
15852
|
}
|
|
15623
15853
|
}
|
|
15624
|
-
@if (
|
|
15854
|
+
@if (resolvedCreate().enabled) {
|
|
15625
15855
|
<div class="ax-sm">
|
|
15626
15856
|
<ax-button
|
|
15627
15857
|
color="primary"
|
|
@@ -15636,7 +15866,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15636
15866
|
}
|
|
15637
15867
|
</div>
|
|
15638
15868
|
}
|
|
15639
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3$2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPLookupWidgetSelectComponent, selector: "axp-lookup-widget-select", inputs: ["entityDef", "customFilter", "selectedItems", "displayField", "valueField", "disabled", "multiple", "validationRules", "placeholder", "hasClearButton", "allowCreate", "showItemTooltip", "isItemTruncated"], outputs: ["valueChanged"] }, { kind: "component", type: AXPLookupWidgetTagboxComponent, selector: "axp-lookup-widget-tagbox", inputs: ["selectedItems", "displayField", "valueField", "displayFormat", "disabled", "multiple", "isLoading", "validationRules", "placeholder", "hasClearButton", "
|
|
15869
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3$2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPLookupWidgetSelectComponent, selector: "axp-lookup-widget-select", inputs: ["entityDef", "customFilter", "selectedItems", "displayField", "valueField", "disabled", "multiple", "validationRules", "placeholder", "hasClearButton", "allowCreate", "showItemTooltip", "isItemTruncated"], outputs: ["valueChanged"] }, { kind: "component", type: AXPLookupWidgetTagboxComponent, selector: "axp-lookup-widget-tagbox", inputs: ["selectedItems", "displayField", "valueField", "displayFormat", "disabled", "multiple", "isLoading", "validationRules", "placeholder", "hasClearButton", "resolvedCreate", "allowUnselect", "entityDef", "customFilter", "columns", "parentFilters", "rowActions", "onSetLoading"], outputs: ["valueChanged"] }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
15640
15870
|
}
|
|
15641
15871
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLookupWidgetEditComponent, decorators: [{
|
|
15642
15872
|
type: Component,
|
|
@@ -15659,7 +15889,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
15659
15889
|
[placeholder]="placeholder"
|
|
15660
15890
|
[validationRules]="validationRules"
|
|
15661
15891
|
[hasClearButton]="hasClearButton()"
|
|
15662
|
-
[allowCreate]="allowCreate()"
|
|
15663
15892
|
[showItemTooltip]="showItemTooltip()"
|
|
15664
15893
|
[isItemTruncated]="isItemTruncated()"
|
|
15665
15894
|
(valueChanged)="handleComponentValueChanged($event)"
|
|
@@ -15678,7 +15907,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
15678
15907
|
[isLoading]="isLoading"
|
|
15679
15908
|
[validationRules]="validationRules"
|
|
15680
15909
|
[hasClearButton]="hasClearButton()"
|
|
15681
|
-
[
|
|
15910
|
+
[resolvedCreate]="resolvedCreate()"
|
|
15682
15911
|
[allowUnselect]="allowUnselect()"
|
|
15683
15912
|
[entityDef]="entityDef"
|
|
15684
15913
|
[customFilter]="customFilter"
|
|
@@ -15690,7 +15919,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
15690
15919
|
/>
|
|
15691
15920
|
}
|
|
15692
15921
|
}
|
|
15693
|
-
@if (
|
|
15922
|
+
@if (resolvedCreate().enabled) {
|
|
15694
15923
|
<div class="ax-sm">
|
|
15695
15924
|
<ax-button
|
|
15696
15925
|
color="primary"
|
|
@@ -17003,8 +17232,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
17003
17232
|
* Multi-source selector popup component
|
|
17004
17233
|
*/
|
|
17005
17234
|
class AXPMultiSourceSelectorComponent extends AXBasePageComponent {
|
|
17235
|
+
//#endregion
|
|
17006
17236
|
constructor() {
|
|
17007
|
-
super(
|
|
17237
|
+
super();
|
|
17008
17238
|
//#region ---- Services & Dependencies ----
|
|
17009
17239
|
this.entityDataSelectorService = inject(AXPEntityDataSelectorService);
|
|
17010
17240
|
this.entityResolver = inject(AXPEntityDefinitionRegistryService);
|
|
@@ -17027,8 +17257,20 @@ class AXPMultiSourceSelectorComponent extends AXBasePageComponent {
|
|
|
17027
17257
|
}, ...(ngDevMode ? [{ debugName: "activeSource" }] : /* istanbul ignore next */ []));
|
|
17028
17258
|
this.selectedItems = signal([], ...(ngDevMode ? [{ debugName: "selectedItems" }] : /* istanbul ignore next */ []));
|
|
17029
17259
|
this.AXPMultiSourceType = AXPMultiSourceType;
|
|
17260
|
+
setupPopupFooterKeyboardShortcuts(() => [
|
|
17261
|
+
{
|
|
17262
|
+
title: '@general:actions.cancel.title',
|
|
17263
|
+
command: 'cancel',
|
|
17264
|
+
handler: () => this.handleCancel(),
|
|
17265
|
+
},
|
|
17266
|
+
{
|
|
17267
|
+
title: '@general:actions.select.title',
|
|
17268
|
+
command: 'select',
|
|
17269
|
+
disabled: () => this.selectedItems().length === 0,
|
|
17270
|
+
handler: () => this.handleConfirm(),
|
|
17271
|
+
},
|
|
17272
|
+
], { id: 'multi-source-selector-popup' });
|
|
17030
17273
|
}
|
|
17031
|
-
//#endregion
|
|
17032
17274
|
//#region ---- Lifecycle ----
|
|
17033
17275
|
ngOnInit() {
|
|
17034
17276
|
super.ngOnInit();
|
|
@@ -17105,7 +17347,7 @@ class AXPMultiSourceSelectorComponent extends AXBasePageComponent {
|
|
|
17105
17347
|
items: this.selectedItems(),
|
|
17106
17348
|
});
|
|
17107
17349
|
}
|
|
17108
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPMultiSourceSelectorComponent, deps:
|
|
17350
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPMultiSourceSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
17109
17351
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPMultiSourceSelectorComponent, isStandalone: true, selector: "axp-multi-source-selector", usesInheritance: true, ngImport: i0, template: `
|
|
17110
17352
|
<div class="ax-flex ax-flex-col ax-h-full ax-overflow-hidden">
|
|
17111
17353
|
@if (definition().searchStrategy === 'tabs') {
|
|
@@ -17254,7 +17496,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
17254
17496
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
17255
17497
|
imports: [CommonModule, AXButtonModule, AXTabsModule, AXDecoratorModule, AXTranslationModule],
|
|
17256
17498
|
}]
|
|
17257
|
-
}] });
|
|
17499
|
+
}], ctorParameters: () => [] });
|
|
17258
17500
|
|
|
17259
17501
|
var multiSourceSelector_component = /*#__PURE__*/Object.freeze({
|
|
17260
17502
|
__proto__: null,
|
|
@@ -18689,7 +18931,7 @@ class AXPFileListComponent {
|
|
|
18689
18931
|
// ACoreX
|
|
18690
18932
|
AXFormModule }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXLabelModule }, { kind: "ngmodule", type: AXCheckBoxModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3$2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type:
|
|
18691
18933
|
// Platform
|
|
18692
|
-
AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "look"] }, { kind: "pipe", type:
|
|
18934
|
+
AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "titleParams", "descriptionParams", "look"] }, { kind: "pipe", type:
|
|
18693
18935
|
// Angular
|
|
18694
18936
|
AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }] }); }
|
|
18695
18937
|
}
|
|
@@ -22728,6 +22970,7 @@ class AXPMainEntityContentBuilder {
|
|
|
22728
22970
|
const tabListTabs = await this.buildTabLists(tabListEntities ?? [], rootContext, dependencies);
|
|
22729
22971
|
// Build actions from single interface
|
|
22730
22972
|
const actions = this.buildActions(entity, singleInterface);
|
|
22973
|
+
let cachedRootContext = rootContext;
|
|
22731
22974
|
//console.log({ rootContext, dependencies });
|
|
22732
22975
|
return {
|
|
22733
22976
|
id: entity?.name ?? '',
|
|
@@ -22764,14 +23007,15 @@ class AXPMainEntityContentBuilder {
|
|
|
22764
23007
|
},
|
|
22765
23008
|
load: async (params) => {
|
|
22766
23009
|
if (params?.forceRefresh) {
|
|
23010
|
+
cachedRootContext = await dependencies.reloadRootContext();
|
|
22767
23011
|
return {
|
|
22768
23012
|
success: true,
|
|
22769
|
-
data:
|
|
23013
|
+
data: cachedRootContext,
|
|
22770
23014
|
};
|
|
22771
23015
|
}
|
|
22772
23016
|
return {
|
|
22773
23017
|
success: true,
|
|
22774
|
-
data:
|
|
23018
|
+
data: cachedRootContext,
|
|
22775
23019
|
};
|
|
22776
23020
|
},
|
|
22777
23021
|
execute: async (e, context) => {
|
|
@@ -23339,27 +23583,44 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
23339
23583
|
}]
|
|
23340
23584
|
}], ctorParameters: () => [{ type: AXPRelatedEntityConverterFactory }, { type: AXPMainEntityContentBuilder }, { type: AXPLayoutAdapterBuilder }, { type: i4$2.AXPFilterOperatorMiddlewareService }] });
|
|
23341
23585
|
|
|
23342
|
-
|
|
23343
|
-
|
|
23344
|
-
|
|
23345
|
-
|
|
23346
|
-
|
|
23347
|
-
|
|
23348
|
-
expressionEvaluator
|
|
23349
|
-
session
|
|
23350
|
-
formatService
|
|
23351
|
-
workflowService
|
|
23352
|
-
commandService
|
|
23353
|
-
};
|
|
23354
|
-
try {
|
|
23355
|
-
return await layoutAdapterFactory.createDetailsViewAdapter(entityResolver, moduleName, entityName, id, dependencies);
|
|
23586
|
+
//#region ---- Entity Details View Adapter Loader ----
|
|
23587
|
+
class AXPEntityDetailsViewAdapterLoader {
|
|
23588
|
+
constructor() {
|
|
23589
|
+
//#region ---- Services & Dependencies ----
|
|
23590
|
+
this.entityResolver = inject(AXPEntityDefinitionRegistryService);
|
|
23591
|
+
this.layoutAdapterFactory = inject(AXPLayoutAdapterFactory);
|
|
23592
|
+
this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
|
|
23593
|
+
this.session = inject(AXPSessionService);
|
|
23594
|
+
this.formatService = inject(AXFormatService);
|
|
23595
|
+
this.workflowService = inject(AXPWorkflowService);
|
|
23596
|
+
this.commandService = inject(AXPCommandService);
|
|
23356
23597
|
}
|
|
23357
|
-
|
|
23358
|
-
|
|
23359
|
-
|
|
23360
|
-
|
|
23361
|
-
|
|
23598
|
+
//#endregion
|
|
23599
|
+
/**
|
|
23600
|
+
* Builds the details-view adapter for an entity record (definition, layout pages, root context).
|
|
23601
|
+
*/
|
|
23602
|
+
async load(params) {
|
|
23603
|
+
const { moduleName, entityName, id } = params;
|
|
23604
|
+
const dependencies = {
|
|
23605
|
+
entityResolver: this.entityResolver,
|
|
23606
|
+
expressionEvaluator: this.expressionEvaluator,
|
|
23607
|
+
session: this.session,
|
|
23608
|
+
formatService: this.formatService,
|
|
23609
|
+
workflowService: this.workflowService,
|
|
23610
|
+
commandService: this.commandService,
|
|
23611
|
+
};
|
|
23612
|
+
return this.layoutAdapterFactory.createDetailsViewAdapter(this.entityResolver, moduleName, entityName, id, dependencies);
|
|
23362
23613
|
}
|
|
23614
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityDetailsViewAdapterLoader, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
23615
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityDetailsViewAdapterLoader, providedIn: 'root' }); }
|
|
23616
|
+
}
|
|
23617
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityDetailsViewAdapterLoader, decorators: [{
|
|
23618
|
+
type: Injectable,
|
|
23619
|
+
args: [{ providedIn: 'root' }]
|
|
23620
|
+
}] });
|
|
23621
|
+
const AXP_ENTITY_DETAILS_VIEW_ADAPTER_LOADER_PROVIDER = {
|
|
23622
|
+
provide: AXP_LAYOUT_DETAILS_VIEW_ADAPTER_LOADER,
|
|
23623
|
+
useExisting: AXPEntityDetailsViewAdapterLoader,
|
|
23363
23624
|
};
|
|
23364
23625
|
|
|
23365
23626
|
class AXPEntityPreloadFilterGuard {
|
|
@@ -23422,9 +23683,7 @@ const eventDispatchMiddleware = {
|
|
|
23422
23683
|
if (ctx.op === 'create') {
|
|
23423
23684
|
const createdData = ctx.result ? { ...ctx.data, id: ctx.result } : ctx.data;
|
|
23424
23685
|
await dispatcher.dispatchInserted(ctx.entityName, { refType: ctx.entityName, data: createdData });
|
|
23425
|
-
|
|
23426
|
-
entity: ctx.entityName,
|
|
23427
|
-
}));
|
|
23686
|
+
// List refresh is dispatched after create UI closes (Entity:Create command / create-entity workflow).
|
|
23428
23687
|
}
|
|
23429
23688
|
else if (ctx.op === 'update') {
|
|
23430
23689
|
await dispatcher.dispatchUpdated(ctx.entityName, {
|
|
@@ -24089,8 +24348,8 @@ const AXPCrudModifier = {
|
|
|
24089
24348
|
if (!command?.create) {
|
|
24090
24349
|
command.create = {
|
|
24091
24350
|
execute: async (data) => {
|
|
24092
|
-
console.log('create', ctx.module.get() + '.' + ctx.name.get(), data);
|
|
24093
24351
|
const res = await dataService.insertOne(data);
|
|
24352
|
+
//await delay(2000);
|
|
24094
24353
|
return { id: res };
|
|
24095
24354
|
},
|
|
24096
24355
|
};
|
|
@@ -24110,7 +24369,9 @@ const AXPCrudModifier = {
|
|
|
24110
24369
|
if (id == null || id === '') {
|
|
24111
24370
|
throw new Error(`Update requires entity id (${entityKey})`);
|
|
24112
24371
|
}
|
|
24113
|
-
|
|
24372
|
+
const updated = await dataService.updateOne(id, patch);
|
|
24373
|
+
//await delay(2000);
|
|
24374
|
+
return updated;
|
|
24114
24375
|
},
|
|
24115
24376
|
};
|
|
24116
24377
|
}
|
|
@@ -24124,6 +24385,7 @@ const AXPCrudModifier = {
|
|
|
24124
24385
|
queries.byKey = {
|
|
24125
24386
|
execute: async (id) => {
|
|
24126
24387
|
const data = await dataService.getOne(id);
|
|
24388
|
+
//await delay(1000);
|
|
24127
24389
|
return data;
|
|
24128
24390
|
},
|
|
24129
24391
|
type: AXPEntityQueryType.Single,
|
|
@@ -24533,6 +24795,7 @@ class AXPEntityCreatePopupAction extends AXPWorkflowAction {
|
|
|
24533
24795
|
this.factory = inject(AXPEntityCreateViewModelFactory);
|
|
24534
24796
|
this.config = inject(AXP_ENTITY_CONFIG_TOKEN);
|
|
24535
24797
|
this.translateService = inject(AXTranslationService);
|
|
24798
|
+
this.settingsService = inject(AXPSettingsService);
|
|
24536
24799
|
}
|
|
24537
24800
|
async execute(context) {
|
|
24538
24801
|
const [module, entity] = context.getVariable('entity').split('.');
|
|
@@ -24564,8 +24827,22 @@ class AXPEntityCreatePopupAction extends AXPWorkflowAction {
|
|
|
24564
24827
|
const prevData = context.getVariable('data');
|
|
24565
24828
|
const prevMeta = context.getVariable('meta');
|
|
24566
24829
|
context.setVariable('data', { ...prevData, ...result.data.item });
|
|
24567
|
-
|
|
24568
|
-
|
|
24830
|
+
const createdItem = result.data.item;
|
|
24831
|
+
const highlightRowId = createdItem?.id ?? createdItem?._id;
|
|
24832
|
+
const { shouldRedirect, shouldHighlight } = await resolveEntityCreateListBehavior(this.settingsService, {
|
|
24833
|
+
redirect: process?.redirect,
|
|
24834
|
+
});
|
|
24835
|
+
context.setVariable('shouldRedirect', shouldRedirect);
|
|
24836
|
+
const meta = {
|
|
24837
|
+
...prevMeta,
|
|
24838
|
+
resetPagination: true,
|
|
24839
|
+
...(shouldHighlight && highlightRowId != null ? { highlightRowId } : {}),
|
|
24840
|
+
...(entityRef.parentKey && createdItem[entityRef.parentKey]
|
|
24841
|
+
? { refreshTargetId: createdItem[entityRef.parentKey] }
|
|
24842
|
+
: {}),
|
|
24843
|
+
};
|
|
24844
|
+
if (Object.keys(meta).length > 0) {
|
|
24845
|
+
context.setVariable('meta', meta);
|
|
24569
24846
|
}
|
|
24570
24847
|
}
|
|
24571
24848
|
}
|
|
@@ -24616,7 +24893,7 @@ const AXPCreateEntityWorkflow = {
|
|
|
24616
24893
|
action: 'AXPEntityCreateSubmittedAction',
|
|
24617
24894
|
nextSteps: [
|
|
24618
24895
|
{
|
|
24619
|
-
conditions: [{ type: 'SINGLE', expression: 'context.getVariable("
|
|
24896
|
+
conditions: [{ type: 'SINGLE', expression: 'context.getVariable("shouldRedirect") == true' }],
|
|
24620
24897
|
nextStepId: 'show-entity',
|
|
24621
24898
|
},
|
|
24622
24899
|
],
|
|
@@ -24957,17 +25234,10 @@ function routesFacory() {
|
|
|
24957
25234
|
// },
|
|
24958
25235
|
{
|
|
24959
25236
|
path: 'e/:entity/:id/view',
|
|
24960
|
-
resolve: { adapter: AXPLayoutDetailsViewRouteResolver },
|
|
24961
25237
|
loadComponent: () => {
|
|
24962
25238
|
return config.viewers.master.details();
|
|
24963
25239
|
},
|
|
24964
25240
|
canDeactivate: [axpDetailsViewCanDeactivateGuard],
|
|
24965
|
-
runGuardsAndResolvers: (from, to) => {
|
|
24966
|
-
const entityChanged = from.params['module'] !== to.params['module'] || from.params['entity'] !== to.params['entity'];
|
|
24967
|
-
const idChanged = from.params['id'] !== to.params['id'];
|
|
24968
|
-
const refreshChanged = from.queryParams['_ts'] !== to.queryParams['_ts'];
|
|
24969
|
-
return entityChanged || idChanged || refreshChanged;
|
|
24970
|
-
},
|
|
24971
25241
|
data: { reuse: 'queryParamsChange' },
|
|
24972
25242
|
},
|
|
24973
25243
|
{
|
|
@@ -25001,6 +25271,7 @@ class AXPEntityModule {
|
|
|
25001
25271
|
AXPAttachmentsPluginModule, i1$3.AXPWorkflowModule, AXPWidgetCoreModule,
|
|
25002
25272
|
LayoutBuilderModule] }); }
|
|
25003
25273
|
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityModule, providers: [
|
|
25274
|
+
AXP_ENTITY_DETAILS_VIEW_ADAPTER_LOADER_PROVIDER,
|
|
25004
25275
|
{
|
|
25005
25276
|
provide: AXP_REPEATER_ENTITY_BY_KEY_LOOKUP,
|
|
25006
25277
|
useFactory: () => {
|
|
@@ -25201,6 +25472,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
25201
25472
|
exports: [],
|
|
25202
25473
|
declarations: [],
|
|
25203
25474
|
providers: [
|
|
25475
|
+
AXP_ENTITY_DETAILS_VIEW_ADAPTER_LOADER_PROVIDER,
|
|
25204
25476
|
{
|
|
25205
25477
|
provide: AXP_REPEATER_ENTITY_BY_KEY_LOOKUP,
|
|
25206
25478
|
useFactory: () => {
|