@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.
Files changed (52) hide show
  1. package/fesm2022/acorex-platform-auth.mjs +8 -2
  2. package/fesm2022/acorex-platform-auth.mjs.map +1 -1
  3. package/fesm2022/{acorex-platform-common-common-settings.provider-VfmZct9H.mjs → acorex-platform-common-common-settings.provider-DilV4dql.mjs} +15 -42
  4. package/fesm2022/acorex-platform-common-common-settings.provider-DilV4dql.mjs.map +1 -0
  5. package/fesm2022/acorex-platform-common.mjs +3299 -3200
  6. package/fesm2022/acorex-platform-common.mjs.map +1 -1
  7. package/fesm2022/acorex-platform-core.mjs +621 -26
  8. package/fesm2022/acorex-platform-core.mjs.map +1 -1
  9. package/fesm2022/acorex-platform-layout-builder.mjs +98 -189
  10. package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
  11. 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
  12. package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-RttFwaw9.mjs.map +1 -0
  13. package/fesm2022/acorex-platform-layout-components.mjs +125 -26
  14. package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
  15. package/fesm2022/acorex-platform-layout-designer.mjs +4 -4
  16. package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
  17. package/fesm2022/acorex-platform-layout-entity-contracts.mjs +106 -12
  18. package/fesm2022/acorex-platform-layout-entity-contracts.mjs.map +1 -1
  19. package/fesm2022/acorex-platform-layout-entity.mjs +419 -147
  20. package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
  21. package/fesm2022/acorex-platform-layout-views.mjs +851 -162
  22. package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
  23. package/fesm2022/acorex-platform-layout-widget-core.mjs +378 -103
  24. package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -1
  25. 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
  26. 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
  27. 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
  28. 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
  29. package/fesm2022/acorex-platform-layout-widgets.mjs +575 -239
  30. package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
  31. package/fesm2022/acorex-platform-themes-default.mjs +221 -24
  32. package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
  33. package/fesm2022/{acorex-platform-themes-shared-settings.provider-BUwPqwUS.mjs → acorex-platform-themes-shared-settings.provider-UyKdkeyk.mjs} +48 -1
  34. package/fesm2022/acorex-platform-themes-shared-settings.provider-UyKdkeyk.mjs.map +1 -0
  35. package/fesm2022/acorex-platform-themes-shared.mjs +103 -24
  36. package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
  37. package/package.json +1 -1
  38. package/types/acorex-platform-auth.d.ts +1 -0
  39. package/types/acorex-platform-common.d.ts +202 -151
  40. package/types/acorex-platform-core.d.ts +161 -6
  41. package/types/acorex-platform-layout-builder.d.ts +10 -20
  42. package/types/acorex-platform-layout-components.d.ts +14 -1
  43. package/types/acorex-platform-layout-entity-contracts.d.ts +27 -2
  44. package/types/acorex-platform-layout-entity.d.ts +61 -12
  45. package/types/acorex-platform-layout-views.d.ts +101 -19
  46. package/types/acorex-platform-layout-widget-core.d.ts +65 -9
  47. package/types/acorex-platform-layout-widgets.d.ts +48 -26
  48. package/types/acorex-platform-themes-default.d.ts +56 -5
  49. package/types/acorex-platform-themes-shared.d.ts +4 -0
  50. package/fesm2022/acorex-platform-common-common-settings.provider-VfmZct9H.mjs.map +0 -1
  51. package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-CXEdvDTf.mjs.map +0 -1
  52. 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, 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';
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, 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';
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 = redirectOption !== undefined
2421
- ? redirectOption
2422
- : await this.settingsService.get(AXPCommonSettings.RedirectToDetailsAfterCreate);
2423
- if (commandResult.success && shouldRedirect && commandResult.data) {
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
- if (createdId != null) {
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
- if (!this.crudService) {
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
- if (!this.crudService) {
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
- if (!this.crudService) {
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
- if (!this.crudService) {
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
- if (!this.crudService) {
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
- if (!this.crudService) {
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
- history: 4,
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
- const props = this.entityDef.properties.filter((c) => c.options?.sort?.enabled);
5571
- return props.map((e) => {
5572
- return {
5573
- name: e.name,
5574
- title: e.title,
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.entityDef.properties.filter((c) => c.options?.sort?.enabled).length ?? 0;
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('[Entity] Deleted');
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 entity.properties with sort enabled, plus enriched columns (dotted paths).
12370
+ * Includes host properties and merge-detail related fields with sort enabled.
12343
12371
  */
12344
- createSortDefinitions(entity) {
12345
- const fromProperties = entity.properties
12346
- .filter((c) => c.options?.sort?.enabled)
12347
- .map((e) => ({ name: e.name, title: e.title }));
12348
- const columns = entity.columns ?? [];
12349
- const fromColumns = columns
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 = { mode: legacy.allowCreate };
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 allowCreate = options.create?.mode ?? this.getAllowCreate(options.entity);
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' ? (mode) => this.executeCreate(options.entity, mode) : undefined,
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.allowCreate = input('none', ...(ngDevMode ? [{ debugName: "allowCreate" }] : /* istanbul ignore next */ []));
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
- allowCreate: this.allowCreate(),
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 }, allowCreate: { classPropertyName: "allowCreate", publicName: "allowCreate", 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: [
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 }] }], allowCreate: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowCreate", 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 }] }] } });
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.allowCreate = computed(() => this.options()['allowCreate'] ?? 'none', ...(ngDevMode ? [{ debugName: "allowCreate" }] : /* istanbul ignore next */ []));
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
- this.expoesItems();
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
- const newValue = this.singleOrMultiple(keys);
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.allowCreate();
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 createdItem = await this.entityDataSelectorService.executeEntityCreate(entity, mode);
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
- expoesItems() {
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
- [allowCreate]="allowCreate()"
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 (allowCreate() === 'quick' || allowCreate() === 'full') {
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", "allowCreate", "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 }); }
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
- [allowCreate]="allowCreate()"
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 (allowCreate() === 'quick' || allowCreate() === 'full') {
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(...arguments);
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: null, target: i0.ɵɵFactoryTarget.Component }); }
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: await dependencies.reloadRootContext(),
23013
+ data: cachedRootContext,
22770
23014
  };
22771
23015
  }
22772
23016
  return {
22773
23017
  success: true,
22774
- data: rootContext,
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
- const AXPLayoutDetailsViewRouteResolver = async (route, state, entityResolver = inject(AXPEntityDefinitionRegistryService), expressionEvaluator = inject(AXPExpressionEvaluatorService), session = inject(AXPSessionService), formatService = inject(AXFormatService), workflowService = inject(AXPWorkflowService), commandService = inject(AXPCommandService), layoutAdapterFactory = inject(AXPLayoutAdapterFactory), router = inject(Router)) => {
23343
- const moduleName = route.parent?.paramMap.get('module');
23344
- const entityName = route.paramMap.get('entity');
23345
- const id = route.paramMap.get('id');
23346
- const dependencies = {
23347
- entityResolver,
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
- catch (error) {
23358
- if (error instanceof AXPNotFoundError) {
23359
- return axpRedirectToNotFound(router);
23360
- }
23361
- throw error;
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
- workflowEventService.dispatch(AXPRefreshEvent({
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
- return await dataService.updateOne(id, patch);
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
- if (entityRef.parentKey && result.data.item[entityRef.parentKey]) {
24568
- context.setVariable('meta', { ...prevMeta, refreshTargetId: result.data.item[entityRef.parentKey] });
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("options")?.process?.redirect != false' }],
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: () => {