@acorex/platform 20.7.20 → 20.7.22

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 (22) hide show
  1. package/common/index.d.ts +4 -1
  2. package/fesm2022/{acorex-platform-common-common-settings.provider-gyb6ohAE.mjs → acorex-platform-common-common-settings.provider-73370m-b.mjs} +43 -1
  3. package/fesm2022/acorex-platform-common-common-settings.provider-73370m-b.mjs.map +1 -0
  4. package/fesm2022/acorex-platform-common.mjs +5 -2
  5. package/fesm2022/acorex-platform-common.mjs.map +1 -1
  6. package/fesm2022/acorex-platform-layout-builder.mjs +16 -8
  7. package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
  8. package/fesm2022/acorex-platform-layout-entity.mjs +369 -151
  9. package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
  10. package/fesm2022/acorex-platform-layout-views.mjs +19 -66
  11. package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
  12. package/fesm2022/acorex-platform-layout-widgets.mjs +31 -6
  13. package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
  14. package/fesm2022/{acorex-platform-themes-default-entity-master-list-view.component-DDd7YryZ.mjs → acorex-platform-themes-default-entity-master-list-view.component-3djSN0h5.mjs} +1 -2
  15. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-3djSN0h5.mjs.map +1 -0
  16. package/fesm2022/acorex-platform-themes-default.mjs +2 -2
  17. package/layout/entity/index.d.ts +31 -1
  18. package/layout/views/index.d.ts +6 -1
  19. package/layout/widgets/index.d.ts +14 -1
  20. package/package.json +9 -9
  21. package/fesm2022/acorex-platform-common-common-settings.provider-gyb6ohAE.mjs.map +0 -1
  22. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-DDd7YryZ.mjs.map +0 -1
@@ -1,14 +1,14 @@
1
1
  import { AXToastService } from '@acorex/components/toast';
2
2
  import * as i6 from '@acorex/core/translation';
3
3
  import { AXTranslationService, AXTranslationModule } from '@acorex/core/translation';
4
+ import * as i4$1 from '@acorex/platform/common';
5
+ import { AXPSettingsService, AXPCommonSettings, AXPFilterOperatorMiddlewareService, AXPEntityCommandScope, getEntityInfo, AXPRefreshEvent, AXPReloadEvent, AXPEntityQueryType, AXPCleanNestedFilters, AXPWorkflowNavigateAction, AXPToastAction, AXP_SEARCH_DEFINITION_PROVIDER } from '@acorex/platform/common';
4
6
  import * as i0 from '@angular/core';
5
7
  import { InjectionToken, inject, Injector, runInInjectionContext, Injectable, input, viewChild, signal, ElementRef, ChangeDetectionStrategy, Component, ApplicationRef, EnvironmentInjector, createComponent, computed, ChangeDetectorRef, effect, Input, afterNextRender, untracked, ViewEncapsulation, viewChildren, linkedSignal, HostBinding, output, NgModule } from '@angular/core';
6
8
  import { Subject, takeUntil } from 'rxjs';
7
9
  import { AXPLayoutBuilderService } from '@acorex/platform/layout/builder';
8
10
  import { AXPDeviceService, AXPBroadcastEventService, applyFilterArray, applySortArray, resolveActionLook, AXPExpressionEvaluatorService, AXPDistributedEventListenerService, AXPPlatformScope, AXPColumnWidthService, AXHighlightService, extractValue, setSmart, getChangedPaths, defaultColumnWidthProvider, AXP_COLUMN_WIDTH_PROVIDER, AXP_DATASOURCE_DEFINITION_PROVIDER, AXPSystemActionType } from '@acorex/platform/core';
9
11
  import { merge, castArray, get, cloneDeep, set, orderBy, isNil, isEmpty, isEqual } from 'lodash-es';
10
- import * as i4$1 from '@acorex/platform/common';
11
- import { AXPSettingsService, AXPFilterOperatorMiddlewareService, AXPEntityCommandScope, getEntityInfo, AXPRefreshEvent, AXPReloadEvent, AXPCommonSettings, AXPEntityQueryType, AXPCleanNestedFilters, AXPWorkflowNavigateAction, AXPToastAction, AXP_SEARCH_DEFINITION_PROVIDER } from '@acorex/platform/common';
12
12
  import { AXPSessionService, AXPAuthGuard } from '@acorex/platform/auth';
13
13
  import { Router, RouterModule, ROUTES } from '@angular/router';
14
14
  import * as i3 from '@acorex/components/button';
@@ -53,7 +53,7 @@ import { AXFormModule } from '@acorex/components/form';
53
53
  import * as i6$1 from '@acorex/components/tag-box';
54
54
  import { AXTagBoxModule } from '@acorex/components/tag-box';
55
55
  import { AXValidationModule } from '@acorex/core/validation';
56
- import { AXP_DISABLED_PROPERTY, AXP_ALLOW_CLEAR_PROPERTY, AXP_DATA_PATH_PROPERTY, AXP_DATA_PROPERTY_GROUP, AXP_ALLOW_MULTIPLE_PROPERTY, AXP_NAME_PROPERTY, AXPFileUploaderWidgetService } from '@acorex/platform/layout/widgets';
56
+ import { AXP_DISABLED_PROPERTY, AXP_ALLOW_CLEAR_PROPERTY, AXP_DATA_PATH_PROPERTY, AXP_DATA_PROPERTY_GROUP, AXP_ALLOW_MULTIPLE_PROPERTY, AXP_ROW_EXPR_PREFIX, AXP_NAME_PROPERTY, AXPFileUploaderWidgetService } from '@acorex/platform/layout/widgets';
57
57
  import * as i4$3 from '@acorex/components/dropdown';
58
58
  import { AXDropdownModule } from '@acorex/components/dropdown';
59
59
  import * as i4$4 from '@acorex/components/select-box';
@@ -380,7 +380,6 @@ class AXPEntityMiddleware {
380
380
  }
381
381
  // Apply all matching modifiers in order
382
382
  for (const modifier of modifiers) {
383
- //TODO Check side EFFECTS
384
383
  runInInjectionContext(this.injector, () => modifier(context));
385
384
  }
386
385
  return context.toEntity();
@@ -1365,12 +1364,80 @@ function sortMergedSections(mainSections, extraSections, mainSectionIds) {
1365
1364
  return [...beforeSections, ...sortedMiddleBlock, ...afterSections];
1366
1365
  }
1367
1366
 
1367
+ //#endregion
1368
+ //#region ---- Entity Open Details Command ----
1369
+ /**
1370
+ * Generic command to open entity details view
1371
+ * Can be used by any entity to navigate to its detail page
1372
+ */
1373
+ class AXPOpenEntityDetailsCommand {
1374
+ constructor() {
1375
+ //#endregion
1376
+ //#region ---- Services & Dependencies ----
1377
+ this.router = inject(Router);
1378
+ this.sessionService = inject(AXPSessionService);
1379
+ }
1380
+ //#endregion
1381
+ //#region ---- Command Execution ----
1382
+ /**
1383
+ * Execute the command to navigate to entity details
1384
+ * @param input - Command input containing entity and data information
1385
+ */
1386
+ async execute(input) {
1387
+ const { entity, data } = input;
1388
+ if (!entity) {
1389
+ return {
1390
+ success: false,
1391
+ message: {
1392
+ text: 'Entity name is required for opening details view',
1393
+ },
1394
+ };
1395
+ }
1396
+ if (!data?.id) {
1397
+ return {
1398
+ success: false,
1399
+ message: {
1400
+ text: 'Entity ID is required for opening details view',
1401
+ },
1402
+ };
1403
+ }
1404
+ const [module, entityName] = entity.split('.');
1405
+ if (!module || !entityName) {
1406
+ return {
1407
+ success: false,
1408
+ message: {
1409
+ text: 'Entity must be in format "ModuleName.EntityName"',
1410
+ },
1411
+ };
1412
+ }
1413
+ const url = `/${this.sessionService.application?.name}/m/${module}/e/${entityName}/${data.id}/view`;
1414
+ // Navigate to the entity details page
1415
+ this.router.navigate([url]);
1416
+ return {
1417
+ success: true,
1418
+ };
1419
+ }
1420
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPOpenEntityDetailsCommand, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1421
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPOpenEntityDetailsCommand, providedIn: 'root' }); }
1422
+ }
1423
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPOpenEntityDetailsCommand, decorators: [{
1424
+ type: Injectable,
1425
+ args: [{ providedIn: 'root' }]
1426
+ }] });
1427
+
1428
+ var openEntityDetails_command = /*#__PURE__*/Object.freeze({
1429
+ __proto__: null,
1430
+ AXPOpenEntityDetailsCommand: AXPOpenEntityDetailsCommand
1431
+ });
1432
+
1368
1433
  class AXPCreateEntityCommand {
1369
1434
  constructor() {
1370
1435
  this.entityForm = inject(AXPEntityFormBuilderService);
1371
1436
  this.entityService = inject(AXPEntityDefinitionRegistryService);
1372
1437
  this.toastService = inject(AXToastService);
1373
1438
  this.translationService = inject(AXTranslationService);
1439
+ this.settingsService = inject(AXPSettingsService);
1440
+ this.openEntityDetailsCommand = inject(AXPOpenEntityDetailsCommand);
1374
1441
  this.context = {};
1375
1442
  }
1376
1443
  async execute(input) {
@@ -1469,7 +1536,22 @@ class AXPCreateEntityCommand {
1469
1536
  }
1470
1537
  })
1471
1538
  .show();
1472
- return result;
1539
+ const commandResult = result;
1540
+ const redirectOption = options?.process?.redirect;
1541
+ const shouldRedirect = redirectOption !== undefined
1542
+ ? redirectOption
1543
+ : await this.settingsService.get(AXPCommonSettings.RedirectToDetailsAfterCreate);
1544
+ if (commandResult.success && shouldRedirect && commandResult.data) {
1545
+ const createdItem = commandResult.data?.item ?? commandResult.data;
1546
+ const createdId = createdItem?.id;
1547
+ if (createdId != null) {
1548
+ await this.openEntityDetailsCommand.execute({
1549
+ entity: `${moduleName}.${entityName}`,
1550
+ data: { id: String(createdId) },
1551
+ });
1552
+ }
1553
+ }
1554
+ return commandResult;
1473
1555
  }
1474
1556
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPCreateEntityCommand, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1475
1557
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPCreateEntityCommand, providedIn: 'root' }); }
@@ -1710,72 +1792,6 @@ var viewEntityDetails_command = /*#__PURE__*/Object.freeze({
1710
1792
  AXPViewEntityDetailsCommand: AXPViewEntityDetailsCommand
1711
1793
  });
1712
1794
 
1713
- //#endregion
1714
- //#region ---- Entity Open Details Command ----
1715
- /**
1716
- * Generic command to open entity details view
1717
- * Can be used by any entity to navigate to its detail page
1718
- */
1719
- class AXPOpenEntityDetailsCommand {
1720
- constructor() {
1721
- //#endregion
1722
- //#region ---- Services & Dependencies ----
1723
- this.router = inject(Router);
1724
- this.sessionService = inject(AXPSessionService);
1725
- }
1726
- //#endregion
1727
- //#region ---- Command Execution ----
1728
- /**
1729
- * Execute the command to navigate to entity details
1730
- * @param input - Command input containing entity and data information
1731
- */
1732
- async execute(input) {
1733
- const { entity, data } = input;
1734
- if (!entity) {
1735
- return {
1736
- success: false,
1737
- message: {
1738
- text: 'Entity name is required for opening details view',
1739
- },
1740
- };
1741
- }
1742
- if (!data?.id) {
1743
- return {
1744
- success: false,
1745
- message: {
1746
- text: 'Entity ID is required for opening details view',
1747
- },
1748
- };
1749
- }
1750
- const [module, entityName] = entity.split('.');
1751
- if (!module || !entityName) {
1752
- return {
1753
- success: false,
1754
- message: {
1755
- text: 'Entity must be in format "ModuleName.EntityName"',
1756
- },
1757
- };
1758
- }
1759
- const url = `/${this.sessionService.application?.name}/m/${module}/e/${entityName}/${data.id}/view`;
1760
- // Navigate to the entity details page
1761
- this.router.navigate([url]);
1762
- return {
1763
- success: true,
1764
- };
1765
- }
1766
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPOpenEntityDetailsCommand, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1767
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPOpenEntityDetailsCommand, providedIn: 'root' }); }
1768
- }
1769
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPOpenEntityDetailsCommand, decorators: [{
1770
- type: Injectable,
1771
- args: [{ providedIn: 'root' }]
1772
- }] });
1773
-
1774
- var openEntityDetails_command = /*#__PURE__*/Object.freeze({
1775
- __proto__: null,
1776
- AXPOpenEntityDetailsCommand: AXPOpenEntityDetailsCommand
1777
- });
1778
-
1779
1795
  class AXPEntityDetailPopoverComponent {
1780
1796
  constructor() {
1781
1797
  //#region ---- Dependencies ----
@@ -4532,8 +4548,82 @@ const AXPEntityDetailViewModelResolver = (route, state, service = inject(AXPEnti
4532
4548
  return service.create(moduleName, entityName, id);
4533
4549
  };
4534
4550
 
4551
+ class AXPDetailsViewBadgeStatusService {
4552
+ constructor() {
4553
+ this.entityRegistry = inject(AXPEntityDefinitionRegistryService);
4554
+ this.translateService = inject(AXTranslationService);
4555
+ }
4556
+ async getPageBadge(entityName, _context, isDirty) {
4557
+ if (!isDirty) {
4558
+ return null;
4559
+ }
4560
+ return {
4561
+ title: await this.translateService.translateAsync('@general:terms.interface.save-status.not-saved.title'),
4562
+ color: 'warning',
4563
+ description: await this.translateService.translateAsync('@general:terms.interface.save-status.not-saved.description'),
4564
+ };
4565
+ }
4566
+ async getPageStatus(entityName, context, currentPage) {
4567
+ if (!entityName) {
4568
+ return null;
4569
+ }
4570
+ const [moduleName, entityNamePart] = entityName.split('.');
4571
+ if (!moduleName || !entityNamePart) {
4572
+ return null;
4573
+ }
4574
+ try {
4575
+ const entityDefinition = await this.entityRegistry.resolve(moduleName, entityNamePart);
4576
+ if (!entityDefinition) {
4577
+ return null;
4578
+ }
4579
+ const statusPlugin = entityDefinition.plugins?.find((p) => p.name === 'status');
4580
+ if (!statusPlugin?.options) {
4581
+ return null;
4582
+ }
4583
+ const statusOptions = statusPlugin.options;
4584
+ const statusField = statusOptions.field ?? 'statusId';
4585
+ const statusDefinitionKey = statusOptions.definition;
4586
+ let definitionKey = typeof statusDefinitionKey === 'string' ? statusDefinitionKey : undefined;
4587
+ if (!definitionKey) {
4588
+ const statusProperty = entityDefinition.properties?.find((p) => p.name === statusField);
4589
+ const widgetOptions = statusProperty?.schema?.interface?.options;
4590
+ if (widgetOptions?.definitionKey) {
4591
+ definitionKey = widgetOptions.definitionKey;
4592
+ }
4593
+ }
4594
+ if (!definitionKey) {
4595
+ return null;
4596
+ }
4597
+ const statusValue = context?.[statusField];
4598
+ if (statusValue == null) {
4599
+ return null;
4600
+ }
4601
+ const value = typeof statusValue === 'string' ? statusValue : statusValue?.name ?? statusValue;
4602
+ return {
4603
+ definitionKey,
4604
+ value: String(value),
4605
+ dataPath: statusField,
4606
+ readonly: currentPage?.isReadonly ?? false,
4607
+ };
4608
+ }
4609
+ catch (error) {
4610
+ console.warn('Failed to get page status:', error);
4611
+ return null;
4612
+ }
4613
+ }
4614
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPDetailsViewBadgeStatusService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4615
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPDetailsViewBadgeStatusService, providedIn: 'root' }); }
4616
+ }
4617
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPDetailsViewBadgeStatusService, decorators: [{
4618
+ type: Injectable,
4619
+ args: [{
4620
+ providedIn: 'root',
4621
+ }]
4622
+ }] });
4623
+
4535
4624
  class AXPLayoutAdapterBuilder {
4536
4625
  constructor() {
4626
+ this.badgeStatusService = inject(AXPDetailsViewBadgeStatusService);
4537
4627
  this.adapter = {};
4538
4628
  }
4539
4629
  setEntity(entity, rootContext) {
@@ -4562,8 +4652,9 @@ class AXPLayoutAdapterBuilder {
4562
4652
  return this;
4563
4653
  }
4564
4654
  build() {
4655
+ const name = `${this.entity?.module}.${this.entity?.name}`;
4565
4656
  return {
4566
- name: `${this.entity?.module}.${this.entity?.name}`,
4657
+ name,
4567
4658
  title: `${this.entity?.interfaces?.master?.single?.title}`,
4568
4659
  label: this.entity?.formats.plural,
4569
4660
  actions: [],
@@ -4572,6 +4663,8 @@ class AXPLayoutAdapterBuilder {
4572
4663
  load: this.createLoadFunction(),
4573
4664
  pages: this.adapter.pages || [],
4574
4665
  exitUrl: this.adapter.exitUrl,
4666
+ getPageBadge: (context, isDirty) => this.badgeStatusService.getPageBadge(name, context, isDirty),
4667
+ getPageStatus: (context, currentPage) => this.badgeStatusService.getPageStatus(name, context, currentPage),
4575
4668
  };
4576
4669
  }
4577
4670
  createBreadcrumbs() {
@@ -5069,7 +5162,8 @@ class AXPPageListConverter extends AXPBaseRelatedEntityConverter {
5069
5162
  return {
5070
5163
  ...a,
5071
5164
  zone: 'header',
5072
- visible: !a.hidden,
5165
+ // visible: !a.hidden,
5166
+ hidden: a.hidden,
5073
5167
  priority: 'primary',
5074
5168
  name: a.name,
5075
5169
  title: a.title,
@@ -5217,7 +5311,7 @@ class AXPPageListConverter extends AXPBaseRelatedEntityConverter {
5217
5311
  return !usedOverrideActions.has(actionKey);
5218
5312
  })
5219
5313
  .map((action) => new AXPEntityCommandTriggerViewModel(entityDef, action));
5220
- return [...additionalActions, ...mergedActions].filter((a) => !a.hidden);
5314
+ return [...additionalActions, ...mergedActions];
5221
5315
  }
5222
5316
  }
5223
5317
 
@@ -5989,11 +6083,14 @@ class AXPLayoutAdapterFactory {
5989
6083
  throw new Error(`Entity ${moduleName}.${entityName} not found`);
5990
6084
  }
5991
6085
  const rootContext = await this.loadRootContext(entity, id);
5992
- // Build main and related pages
5993
- const mainPage = await this.buildMainPage(entity, rootContext, id, dependencies);
5994
- const relatedPages = await this.buildRelatedPages(entity, rootContext, dependencies);
6086
+ // Evaluate hidden expressions for related entities once, reuse across building and composing
6087
+ const evaluatedRelatedEntities = await this.evaluateRelatedEntitiesHidden(entity?.relatedEntities ?? [], rootContext, dependencies);
6088
+ // Build main and related pages using evaluated related entities
6089
+ const entityWithEvaluatedRelated = { ...entity, relatedEntities: evaluatedRelatedEntities };
6090
+ const mainPage = await this.buildMainPage(entityWithEvaluatedRelated, rootContext, id, dependencies);
6091
+ const relatedPages = await this.buildRelatedPages(entityWithEvaluatedRelated, rootContext, dependencies);
5995
6092
  // Compose ordered pages around the primary page
5996
- const orderedPages = this.composePagesWithPositions(mainPage, relatedPages, entity);
6093
+ const orderedPages = this.composePagesWithPositions(mainPage, relatedPages, entityWithEvaluatedRelated);
5997
6094
  const applicationName = dependencies.session.application?.name ?? 'default';
5998
6095
  return this.layoutAdapterBuilder
5999
6096
  .setEntity(entity, rootContext)
@@ -6009,11 +6106,40 @@ class AXPLayoutAdapterFactory {
6009
6106
  async buildMainPage(entity, rootContext, id, dependencies) {
6010
6107
  return this.mainEntityContentBuilder.build(entity, rootContext, { ...dependencies, reloadRootContext: () => this.loadRootContext(entity, id) }, await this.getRootTitle(entity, rootContext, dependencies));
6011
6108
  }
6109
+ /**
6110
+ * Evaluates the 'hidden' expression for each related entity using the expression evaluator.
6111
+ * Returns a new array of related entities with the evaluated hidden values.
6112
+ */
6113
+ async evaluateRelatedEntitiesHidden(relatedEntities, rootContext, dependencies) {
6114
+ if (!relatedEntities?.length || !dependencies?.expressionEvaluator) {
6115
+ return relatedEntities ?? [];
6116
+ }
6117
+ return Promise.all(relatedEntities.map(async (re) => {
6118
+ let hidden = re.hidden;
6119
+ if (hidden && typeof hidden === 'string') {
6120
+ try {
6121
+ const scope = {
6122
+ context: {
6123
+ eval: (path) => get(rootContext, path),
6124
+ },
6125
+ };
6126
+ const result = await dependencies.expressionEvaluator.evaluate({ hidden }, scope);
6127
+ hidden = result.hidden;
6128
+ }
6129
+ catch {
6130
+ // Keep original hidden value if evaluation fails
6131
+ }
6132
+ }
6133
+ return { ...re, hidden };
6134
+ }));
6135
+ }
6012
6136
  async buildRelatedPages(entity, rootContext, dependencies) {
6013
6137
  const pages = [];
6014
6138
  const rootTitle = await this.getRootTitle(entity, rootContext, dependencies);
6139
+ // Evaluate hidden expressions before filtering related entities
6140
+ const evaluatedRelatedEntities = await this.evaluateRelatedEntitiesHidden(entity?.relatedEntities ?? [], rootContext, dependencies);
6015
6141
  // Page Details
6016
- const pageDetailEntities = entity?.relatedEntities?.filter((re) => !re.hidden && re.layout?.type === 'page-detail');
6142
+ const pageDetailEntities = evaluatedRelatedEntities.filter((re) => !re.hidden && re.layout?.type === 'page-detail');
6017
6143
  for (const relatedEntity of pageDetailEntities || []) {
6018
6144
  const converter = this.relatedEntityConverterFactory.createPageDetailsConverter();
6019
6145
  pages.push(await converter.convert(relatedEntity, {
@@ -6023,7 +6149,7 @@ class AXPLayoutAdapterFactory {
6023
6149
  }));
6024
6150
  }
6025
6151
  // Page Lists
6026
- const pageListEntities = entity?.relatedEntities?.filter((re) => !re.hidden && re.layout?.type === 'page-list');
6152
+ const pageListEntities = evaluatedRelatedEntities.filter((re) => !re.hidden && re.layout?.type === 'page-list');
6027
6153
  for (const relatedEntity of pageListEntities || []) {
6028
6154
  const converter = this.relatedEntityConverterFactory.createPageListConverter();
6029
6155
  pages.push(await converter.convert(relatedEntity, {
@@ -6034,7 +6160,7 @@ class AXPLayoutAdapterFactory {
6034
6160
  }));
6035
6161
  }
6036
6162
  // Include nested page-related entities from merge-detail related entities
6037
- const mergeDetailEntities = entity?.relatedEntities?.filter((re) => !re.hidden && re.layout?.type === 'merge-detail');
6163
+ const mergeDetailEntities = evaluatedRelatedEntities.filter((re) => !re.hidden && re.layout?.type === 'merge-detail');
6038
6164
  for (const mergeRelated of mergeDetailEntities || []) {
6039
6165
  try {
6040
6166
  const [moduleName, childEntityName] = (mergeRelated.entity || '').split('.');
@@ -6044,7 +6170,9 @@ class AXPLayoutAdapterFactory {
6044
6170
  }
6045
6171
  const nestedDataPath = mergeRelated?.persistence?.dataPath || childEntityName;
6046
6172
  const nestedContext = get(rootContext, nestedDataPath) ?? rootContext;
6047
- const nestedPageDetailEntities = childEntity?.relatedEntities?.filter((re) => !re.hidden && re.layout?.type === 'page-detail');
6173
+ // Evaluate hidden expressions for nested related entities
6174
+ const evaluatedNestedEntities = await this.evaluateRelatedEntitiesHidden(childEntity?.relatedEntities ?? [], nestedContext, dependencies);
6175
+ const nestedPageDetailEntities = evaluatedNestedEntities.filter((re) => !re.hidden && re.layout?.type === 'page-detail');
6048
6176
  for (const nestedRelated of nestedPageDetailEntities || []) {
6049
6177
  const converter = this.relatedEntityConverterFactory.createPageDetailsConverter();
6050
6178
  pages.push(await converter.convert(nestedRelated, {
@@ -6053,7 +6181,7 @@ class AXPLayoutAdapterFactory {
6053
6181
  rootTitle: rootTitle,
6054
6182
  }));
6055
6183
  }
6056
- const nestedPageListEntities = childEntity?.relatedEntities?.filter((re) => !re.hidden && re.layout?.type === 'page-list');
6184
+ const nestedPageListEntities = evaluatedNestedEntities.filter((re) => !re.hidden && re.layout?.type === 'page-list');
6057
6185
  for (const nestedRelated of nestedPageListEntities || []) {
6058
6186
  const converter = this.relatedEntityConverterFactory.createPageListConverter();
6059
6187
  pages.push(await converter.convert(nestedRelated, {
@@ -6219,6 +6347,47 @@ const columnWidthMiddlewareProvider = {
6219
6347
  };
6220
6348
  //#endregion
6221
6349
 
6350
+ const DEFAULT_APPLY_ORDERING = true;
6351
+ /**
6352
+ * Provides synchronous access to the ApplyLayoutOrdering setting.
6353
+ * Used by layout ordering middleware to avoid async in the modifier and prevent startup deadlocks.
6354
+ * Value is updated on onLoaded/onChanged; first read can trigger a one-time background get (no await).
6355
+ */
6356
+ class AXPLayoutOrderingConfigService {
6357
+ constructor() {
6358
+ this.settingsService = inject(AXPSettingsService);
6359
+ this._applyOrdering = signal(DEFAULT_APPLY_ORDERING, ...(ngDevMode ? [{ debugName: "_applyOrdering" }] : []));
6360
+ this.syncScheduled = false;
6361
+ this.settingsService.onLoaded.subscribe(() => this.syncFromSettings());
6362
+ this.settingsService.onChanged.subscribe(() => this.syncFromSettings());
6363
+ }
6364
+ getApplyOrdering() {
6365
+ if (!this.syncScheduled) {
6366
+ this.syncScheduled = true;
6367
+ this.settingsService
6368
+ .get(AXPCommonSettings.ApplyLayoutOrdering)
6369
+ .then((value) => this._applyOrdering.set(value ?? DEFAULT_APPLY_ORDERING))
6370
+ .catch(() => this._applyOrdering.set(DEFAULT_APPLY_ORDERING));
6371
+ }
6372
+ return this._applyOrdering();
6373
+ }
6374
+ async syncFromSettings() {
6375
+ try {
6376
+ const value = await this.settingsService.get(AXPCommonSettings.ApplyLayoutOrdering);
6377
+ this._applyOrdering.set(value ?? DEFAULT_APPLY_ORDERING);
6378
+ }
6379
+ catch {
6380
+ this._applyOrdering.set(DEFAULT_APPLY_ORDERING);
6381
+ }
6382
+ }
6383
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPLayoutOrderingConfigService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
6384
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPLayoutOrderingConfigService, providedIn: 'root' }); }
6385
+ }
6386
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPLayoutOrderingConfigService, decorators: [{
6387
+ type: Injectable,
6388
+ args: [{ providedIn: 'root' }]
6389
+ }], ctorParameters: () => [] });
6390
+
6222
6391
  /**
6223
6392
  * Default order for common sections
6224
6393
  */
@@ -6289,6 +6458,10 @@ const getPropertyOrder = (sectionId, propertyName, orderConfig) => {
6289
6458
  */
6290
6459
  const layoutOrderingMiddlewareFactory = (config) => {
6291
6460
  return (context) => {
6461
+ const configService = inject(AXPLayoutOrderingConfigService);
6462
+ if (!configService.getApplyOrdering()) {
6463
+ return;
6464
+ }
6292
6465
  const { sections: sectionOrder, properties: propertyOrder } = config;
6293
6466
  //#region ---- Order Sections ----
6294
6467
  const orderSections = (layout) => {
@@ -6438,7 +6611,9 @@ const AXPCrudModifier = {
6438
6611
  if (!queries?.byKey) {
6439
6612
  queries.byKey = {
6440
6613
  execute: async (id) => {
6441
- return await dataService.getOne(id);
6614
+ const data = await dataService.getOne(id);
6615
+ // debugger;
6616
+ return data;
6442
6617
  },
6443
6618
  type: AXPEntityQueryType.Single,
6444
6619
  };
@@ -7683,7 +7858,7 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
7683
7858
  await this.selectAllLeafDescendants(nodeId);
7684
7859
  }
7685
7860
  else {
7686
- // childrenCount is undefined - need to check if it has children
7861
+ // childrenCount is undefined - fetch once and reuse to avoid double datasource call
7687
7862
  const childNodes = await this.datasource(nodeId);
7688
7863
  if (!childNodes || childNodes.length === 0) {
7689
7864
  // No children - this is a leaf node, add it
@@ -7692,8 +7867,8 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
7692
7867
  this.selectedNodeIds.set(Array.from(currentSelected));
7693
7868
  }
7694
7869
  else {
7695
- // Has children - only add leaf descendants
7696
- await this.selectAllLeafDescendants(nodeId);
7870
+ // Has children - pass prefetched childNodes to avoid datasource(nodeId) again
7871
+ await this.selectAllLeafDescendants(nodeId, childNodes);
7697
7872
  }
7698
7873
  }
7699
7874
  }
@@ -7759,16 +7934,17 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
7759
7934
  /**
7760
7935
  * Expands parent nodes, collects all LEAF descendants, and selects them visually.
7761
7936
  * If the parent itself is a leaf (no children), it will be added.
7937
+ * When prefetchedChildren is provided, avoids an extra datasource(parentId) call.
7762
7938
  */
7763
- async selectAllLeafDescendants(parentId) {
7939
+ async selectAllLeafDescendants(parentId, prefetchedChildren) {
7764
7940
  if (!this.treeData || !this.treeConfig) {
7765
7941
  return;
7766
7942
  }
7767
7943
  const treeComponent = this.tree();
7768
7944
  try {
7769
7945
  const leafIds = new Set();
7770
- // Expand and collect leaf nodes simultaneously
7771
- await this.collectLeafNodes(parentId, leafIds, treeComponent);
7946
+ // Expand and collect leaf nodes; pass prefetchedChildren to avoid duplicate API call
7947
+ await this.collectLeafNodes(parentId, leafIds, treeComponent, prefetchedChildren);
7772
7948
  // Also check if the parent itself is a leaf (has no children)
7773
7949
  if (parentId !== 'all') {
7774
7950
  const isLeaf = await this.isLeafNodeCheck(parentId);
@@ -7843,14 +8019,19 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
7843
8019
  /**
7844
8020
  * Recursively expands parent nodes and collects LEAF node IDs.
7845
8021
  * When treeComponent is provided, expands each parent node before loading children.
8022
+ * When prefetchedChildren is provided, uses it instead of calling datasource(parentId) (one less API call).
8023
+ * Fetches each node's children at most once by passing grandchildren when recursing.
7846
8024
  */
7847
- async collectLeafNodes(parentId, collection, treeComponent) {
8025
+ async collectLeafNodes(parentId, collection, treeComponent, prefetchedChildren) {
7848
8026
  if (!this.treeData || !this.treeConfig) {
7849
8027
  return;
7850
8028
  }
7851
8029
  try {
7852
8030
  let childNodes;
7853
- if (parentId === 'all') {
8031
+ if (prefetchedChildren !== undefined) {
8032
+ childNodes = prefetchedChildren;
8033
+ }
8034
+ else if (parentId === 'all') {
7854
8035
  // Expand 'all' node if tree component provided
7855
8036
  if (treeComponent) {
7856
8037
  try {
@@ -7860,7 +8041,7 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
7860
8041
  // Ignore expand errors
7861
8042
  }
7862
8043
  }
7863
- // Get root node's children
8044
+ // Get root node's children (single datasource call)
7864
8045
  const rootNodes = await this.datasource();
7865
8046
  if (!rootNodes || rootNodes.length === 0) {
7866
8047
  return;
@@ -7878,13 +8059,13 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
7878
8059
  // Ignore expand errors
7879
8060
  }
7880
8061
  }
7881
- // Load children via datasource
8062
+ // Load children via datasource (single call per parent)
7882
8063
  childNodes = await this.datasource(parentId);
7883
8064
  }
7884
8065
  if (!childNodes || childNodes.length === 0) {
7885
8066
  return;
7886
8067
  }
7887
- // Process each child
8068
+ // Process each child: fetch grandchildren once, then recurse with them to avoid double datasource call
7888
8069
  for (const childNode of childNodes) {
7889
8070
  const childId = String(childNode['id'] ?? '');
7890
8071
  if (!childId || childId === 'all' || collection.has(childId)) {
@@ -7892,15 +8073,13 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
7892
8073
  }
7893
8074
  // Cache node data
7894
8075
  this.cacheNodeFromTreeNode(childNode);
7895
- // Check if this child has children
7896
- const hasChildren = await this.nodeHasChildren(childId, childNode);
7897
- if (!hasChildren) {
7898
- // This is a LEAF node - add it
8076
+ // Fetch children once; use result to decide leaf vs recurse (avoids nodeHasChildren -> extra datasource)
8077
+ const grandchildNodes = await this.datasource(childId);
8078
+ if (!grandchildNodes || grandchildNodes.length === 0) {
7899
8079
  collection.add(childId);
7900
8080
  }
7901
8081
  else {
7902
- // Has children - expand and recurse (pass tree component to expand children too)
7903
- await this.collectLeafNodes(childId, collection, treeComponent);
8082
+ await this.collectLeafNodes(childId, collection, treeComponent, grandchildNodes);
7904
8083
  }
7905
8084
  }
7906
8085
  }
@@ -7961,6 +8140,7 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
7961
8140
  /**
7962
8141
  * Builds complete ancestor chains for all selected node IDs.
7963
8142
  * Returns a Map where key is the selected node ID and value is array of ancestor IDs from root to parent.
8143
+ * Batch-fetches missing node and ancestor data in parallel to minimize API calls.
7964
8144
  */
7965
8145
  async buildAncestorChains(selectedIds) {
7966
8146
  const ancestorChains = new Map();
@@ -7968,18 +8148,44 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
7968
8148
  return ancestorChains;
7969
8149
  if (!this.treeData.categoryEntityDef?.parentKey)
7970
8150
  return ancestorChains;
8151
+ // Collect and batch-fetch all missing IDs (selected nodes without parent + ancestors) in rounds
8152
+ let toFetch = new Set();
8153
+ for (const nodeId of selectedIds) {
8154
+ const cached = this.nodeDataCache.get(nodeId);
8155
+ if (!cached || this.getParentIdFromNodeData(cached) === null) {
8156
+ toFetch.add(nodeId);
8157
+ }
8158
+ }
8159
+ while (toFetch.size > 0) {
8160
+ const results = await Promise.all(Array.from(toFetch).map((id) => this.fetchItemById(id)));
8161
+ const idsArr = Array.from(toFetch);
8162
+ results.forEach((item, i) => {
8163
+ if (item)
8164
+ this.nodeDataCache.set(idsArr[i], item);
8165
+ });
8166
+ toFetch = new Set();
8167
+ for (const nodeId of selectedIds) {
8168
+ let currentData = this.nodeDataCache.get(nodeId) ?? null;
8169
+ const visited = new Set();
8170
+ while (currentData) {
8171
+ const parentId = this.getParentIdFromNodeData(currentData);
8172
+ if (!parentId || visited.has(parentId))
8173
+ break;
8174
+ visited.add(parentId);
8175
+ if (!this.nodeDataCache.has(parentId)) {
8176
+ toFetch.add(parentId);
8177
+ break;
8178
+ }
8179
+ currentData = this.nodeDataCache.get(parentId) ?? null;
8180
+ }
8181
+ }
8182
+ }
8183
+ // Build chains from cache (no further API calls)
7971
8184
  for (const nodeId of selectedIds) {
7972
8185
  const chain = [];
7973
8186
  let currentData = this.nodeDataCache.get(nodeId) ?? null;
7974
8187
  if (!currentData)
7975
8188
  continue;
7976
- if (!this.getParentIdFromNodeData(currentData)) {
7977
- const refetched = await this.fetchItemById(nodeId);
7978
- if (refetched) {
7979
- currentData = refetched;
7980
- this.nodeDataCache.set(nodeId, refetched);
7981
- }
7982
- }
7983
8189
  const visited = new Set();
7984
8190
  while (currentData) {
7985
8191
  const parentId = this.getParentIdFromNodeData(currentData);
@@ -7987,19 +8193,7 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
7987
8193
  break;
7988
8194
  visited.add(parentId);
7989
8195
  chain.unshift(parentId);
7990
- if (!this.nodeDataCache.has(parentId)) {
7991
- const parentData = await this.fetchItemById(parentId);
7992
- if (parentData) {
7993
- this.nodeDataCache.set(parentId, parentData);
7994
- currentData = parentData;
7995
- }
7996
- else {
7997
- break;
7998
- }
7999
- }
8000
- else {
8001
- currentData = this.nodeDataCache.get(parentId) ?? null;
8002
- }
8196
+ currentData = this.nodeDataCache.get(parentId) ?? null;
8003
8197
  }
8004
8198
  ancestorChains.set(nodeId, chain);
8005
8199
  }
@@ -8163,27 +8357,34 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
8163
8357
  // Sort parents by depth (deepest first so we update bottom-up)
8164
8358
  const sortedParents = await this.sortParentsByDepth(Array.from(parentsToUpdate));
8165
8359
  const reversedParents = [...sortedParents].reverse(); // Deepest first
8360
+ // Batch-load children for parents that don't have them in tree (parallel instead of sequential)
8361
+ const parentIdsNeedingLoad = reversedParents.filter((parentId) => {
8362
+ const parentNode = treeComponent.findNode(parentId);
8363
+ const treeChildren = parentNode?.['children'];
8364
+ return !treeChildren || treeChildren.length === 0;
8365
+ });
8366
+ const childrenByParentId = new Map();
8367
+ if (parentIdsNeedingLoad.length > 0) {
8368
+ const results = await Promise.all(parentIdsNeedingLoad.map((id) => this.datasource(id)));
8369
+ results.forEach((dsChildren, index) => {
8370
+ if (dsChildren && dsChildren.length > 0) {
8371
+ childrenByParentId.set(parentIdsNeedingLoad[index], dsChildren.map((c) => ({ id: String(c['id'] ?? '') })));
8372
+ }
8373
+ });
8374
+ }
8166
8375
  for (const parentId of reversedParents) {
8167
8376
  try {
8168
8377
  const parentNode = treeComponent.findNode(parentId);
8169
- // Get all direct children of this parent
8170
- // First try from tree node, then fall back to datasource
8378
+ // Get all direct children: from tree node, or from batch-loaded map
8171
8379
  let childrenList = [];
8172
8380
  const treeChildren = parentNode?.['children'];
8173
8381
  if (treeChildren && treeChildren.length > 0) {
8174
8382
  childrenList = treeChildren.map((c) => ({ id: String(c['id'] ?? '') }));
8175
8383
  }
8176
8384
  else {
8177
- // Children not in tree node - load via datasource
8178
- try {
8179
- const dsChildren = await this.datasource(parentId);
8180
- if (dsChildren && dsChildren.length > 0) {
8181
- childrenList = dsChildren.map((c) => ({ id: String(c['id'] ?? '') }));
8182
- }
8183
- }
8184
- catch {
8185
- // Datasource failed, skip this parent
8186
- continue;
8385
+ const loaded = childrenByParentId.get(parentId);
8386
+ if (loaded && loaded.length > 0) {
8387
+ childrenList = loaded;
8187
8388
  }
8188
8389
  }
8189
8390
  if (childrenList.length === 0) {
@@ -8244,6 +8445,7 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
8244
8445
  /**
8245
8446
  * Loads node data for IDs that are selected but not yet in the cache.
8246
8447
  * This is critical for pre-selected values in collapsed branches.
8448
+ * Fetches all missing IDs in parallel to minimize API calls and latency.
8247
8449
  */
8248
8450
  async loadMissingNodeData(selectedIds) {
8249
8451
  if (!this.treeData || !this.treeConfig || selectedIds.length === 0) {
@@ -8253,13 +8455,14 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
8253
8455
  if (missingIds.length === 0)
8254
8456
  return;
8255
8457
  try {
8256
- // Prefer fetching each id via service (uses byKey when available = full item with parent)
8257
8458
  const valueField = this.treeConfig.valueField || 'id';
8258
- for (const id of missingIds) {
8259
- const item = await this.fetchItemById(id);
8260
- if (item)
8459
+ const results = await Promise.all(missingIds.map((id) => this.fetchItemById(id)));
8460
+ results.forEach((item, index) => {
8461
+ if (item) {
8462
+ const id = missingIds[index];
8261
8463
  this.nodeDataCache.set(String(item[valueField] ?? id), item);
8262
- }
8464
+ }
8465
+ });
8263
8466
  }
8264
8467
  catch (error) {
8265
8468
  console.error('Error loading missing node data:', error);
@@ -8268,18 +8471,22 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
8268
8471
  /**
8269
8472
  * For each selected id, if cached item has no parent (e.g. batch query returned minimal fields),
8270
8473
  * re-fetch by id so we have parent/parentId for building ancestor chains.
8474
+ * Fetches all needing refresh in parallel.
8271
8475
  */
8272
8476
  async ensureParentDataInCache(selectedIds) {
8273
8477
  if (!this.treeConfig)
8274
8478
  return;
8275
- for (const id of selectedIds) {
8479
+ const idsNeedingFetch = selectedIds.filter((id) => {
8276
8480
  const cached = this.nodeDataCache.get(id);
8277
- if (cached && this.getParentIdFromNodeData(cached) === null) {
8278
- const full = await this.fetchItemById(id);
8279
- if (full)
8280
- this.nodeDataCache.set(id, full);
8281
- }
8282
- }
8481
+ return cached && this.getParentIdFromNodeData(cached) === null;
8482
+ });
8483
+ if (idsNeedingFetch.length === 0)
8484
+ return;
8485
+ const results = await Promise.all(idsNeedingFetch.map((id) => this.fetchItemById(id)));
8486
+ results.forEach((full, index) => {
8487
+ if (full)
8488
+ this.nodeDataCache.set(idsNeedingFetch[index], full);
8489
+ });
8283
8490
  }
8284
8491
  /**
8285
8492
  * Resolves parent ID from node data: supports nested `parent` object or flat parentId/parentKey.
@@ -10612,6 +10819,7 @@ class AXPEntityListTableService {
10612
10819
  // 🎪 Events
10613
10820
  ...this.createDefaultEvents(entity, allActions),
10614
10821
  };
10822
+ console.log('listOptions', listOptions);
10615
10823
  return listOptions;
10616
10824
  }
10617
10825
  //#endregion
@@ -10660,18 +10868,28 @@ class AXPEntityListTableService {
10660
10868
  createRowCommands(actions, priority) {
10661
10869
  return actions
10662
10870
  .filter((action) => action.scope === AXPEntityCommandScope.Individual && // Only individual actions
10663
- action.priority === priority && // Matching priority
10664
- !action.hidden)
10871
+ action.priority === priority)
10665
10872
  .map((action) => ({
10666
10873
  name: action.name,
10667
10874
  text: action.title,
10668
10875
  icon: action.icon,
10669
10876
  color: action.color,
10670
10877
  look: 'outline',
10671
- visible: !action.hidden,
10672
- disabled: action.disabled,
10878
+ hidden: priority === 'secondary' ? this.wrapRowExpr(action.hidden) : action.hidden,
10879
+ disabled: priority === 'secondary' ? this.wrapRowExpr(action.disabled) : action.disabled,
10673
10880
  }));
10674
10881
  }
10882
+ /**
10883
+ * Wraps string values with AXP_ROW_EXPR_PREFIX so widget-renderer does not
10884
+ * evaluate them (it only treats {{ ... }} as expressions). Data-list will
10885
+ * unwrap and evaluate per row with row data. Only used for secondary commands.
10886
+ */
10887
+ wrapRowExpr(value) {
10888
+ if (value === undefined || value === null || typeof value !== 'string') {
10889
+ return value;
10890
+ }
10891
+ return `${AXP_ROW_EXPR_PREFIX}${value}`;
10892
+ }
10675
10893
  /**
10676
10894
  * Check if entity has Selected Scope Actions
10677
10895
  */
@@ -10918,7 +11136,7 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
10918
11136
  return !usedOverrideActions.has(actionKey);
10919
11137
  })
10920
11138
  .map((action) => new AXPEntityCommandTriggerViewModel(this.entity(), action));
10921
- return [...additionalActions, ...mergedActions].filter((a) => !a.hidden);
11139
+ return [...additionalActions, ...mergedActions];
10922
11140
  }, ...(ngDevMode ? [{ debugName: "allActions" }] : []));
10923
11141
  this.primaryActions = computed(() => {
10924
11142
  const actions = this.allActions()
@@ -15332,5 +15550,5 @@ function detectEntityChanges(oldObj, newObj) {
15332
15550
  * Generated bundle index. Do not edit.
15333
15551
  */
15334
15552
 
15335
- export { AXMEntityCrudService, AXMEntityCrudServiceImpl, AXPCategoryTreeService, AXPCreateEntityCommand, AXPCreateEntityWorkflow, AXPDataSeederService, AXPDeleteEntityWorkflow, AXPEntitiesListDataSourceDefinition, AXPEntityApplyUpdatesAction, AXPEntityCategoryTreeSelectorComponent, AXPEntityCategoryWidget, AXPEntityCategoryWidgetColumnComponent, AXPEntityCategoryWidgetEditComponent, AXPEntityCategoryWidgetViewComponent, AXPEntityCommandTriggerViewModel, AXPEntityCreateEvent, AXPEntityCreatePopupAction, AXPEntityCreateSubmittedAction, AXPEntityCreateViewElementViewModel, AXPEntityCreateViewModelFactory, AXPEntityCreateViewSectionViewModel, AXPEntityDataProvider, AXPEntityDataProviderImpl, AXPEntityDataSelectorService, AXPEntityDefinitionRegistryService, AXPEntityDeletedEvent, AXPEntityDetailListViewModel, AXPEntityDetailPopoverComponent, AXPEntityDetailPopoverService, AXPEntityDetailViewModelFactory, AXPEntityDetailViewModelResolver, AXPEntityEventDispatcherService, AXPEntityEventsKeys, AXPEntityFormBuilderService, AXPEntityListTableService, AXPEntityListViewColumnViewModel, AXPEntityListViewModelFactory, AXPEntityListViewModelResolver, AXPEntityListWidget, AXPEntityListWidgetViewComponent, AXPEntityMasterCreateViewModel, AXPEntityMasterListViewModel, AXPEntityMasterListViewQueryViewModel, AXPEntityMasterSingleElementViewModel, AXPEntityMasterSingleViewGroupViewModel, AXPEntityMasterSingleViewModel, AXPEntityMasterUpdateElementViewModel, AXPEntityMasterUpdateViewModel, AXPEntityMasterUpdateViewModelFactory, AXPEntityMiddleware, AXPEntityModifyConfirmedAction, AXPEntityModifyEvent, AXPEntityModifySectionPopupAction, AXPEntityModule, AXPEntityPerformDeleteAction, AXPEntityResolver, AXPEntityService, AXPEntityStorageService, AXPEntityUpdateViewSectionViewModel, AXPGetEntityDetailsQuery, AXPLookupWidget, AXPLookupWidgetColumnComponent, AXPLookupWidgetEditComponent, AXPLookupWidgetViewComponent, AXPMiddlewareAbortError, AXPMiddlewareEntityStorageService, AXPModifyEntitySectionWorkflow, AXPMultiSourceDefinitionProviderContext, AXPMultiSourceDefinitionProviderService, AXPMultiSourceFederatedSearchService, AXPMultiSourceSelectorComponent, AXPMultiSourceSelectorService, AXPMultiSourceSelectorWidget, AXPMultiSourceSelectorWidgetColumnComponent, AXPMultiSourceSelectorWidgetEditComponent, AXPMultiSourceSelectorWidgetViewComponent, AXPMultiSourceType, AXPOpenEntityDetailsCommand, AXPQuickEntityModifyPopupAction, AXPQuickModifyEntityWorkflow, AXPShowDetailViewAction, AXPShowDetailsViewWorkflow, AXPShowListViewAction, AXPShowListViewWorkflow, AXPTruncatedBreadcrumbComponent, AXPUpdateEntityCommand, AXPViewEntityDetailsCommand, AXP_DATA_SEEDER_TOKEN, AXP_ENTITY_ACTION_PLUGIN, AXP_ENTITY_CONFIG_TOKEN, AXP_ENTITY_DEFINITION_LOADER, AXP_ENTITY_MODIFIER, AXP_ENTITY_STORAGE_BACKEND, AXP_ENTITY_STORAGE_MIDDLEWARE, AXP_MULTI_SOURCE_DEFINITION_PROVIDER, DEFAULT_PROPERTY_ORDER, DEFAULT_SECTION_ORDER, EntityBuilder, EntityDataAccessor, actionExists, cloneLayoutArrays, columnWidthMiddleware, columnWidthMiddlewareProvider, createLayoutOrderingMiddlewareProvider, createModifierContext, detectEntityChanges, ensureLayoutPropertyView, ensureLayoutSection, ensureListActions, entityDetailsCreateActions, entityDetailsCrudActions, entityDetailsEditAction, entityDetailsNewEditAction, entityDetailsReferenceCondition, entityDetailsReferenceCreateActions, entityDetailsSimpleCondition, entityMasterBulkDeleteAction, entityMasterCreateAction, entityMasterCrudActions, entityMasterDeleteAction, entityMasterEditAction, entityMasterRecordActions, entityMasterViewAction, entityOverrideDetailsViewAction, eventDispatchMiddleware, isAXPMiddlewareAbortError, layoutOrderingMiddlewareFactory, layoutOrderingMiddlewareProvider };
15553
+ export { AXMEntityCrudService, AXMEntityCrudServiceImpl, AXPCategoryTreeService, AXPCreateEntityCommand, AXPCreateEntityWorkflow, AXPDataSeederService, AXPDeleteEntityWorkflow, AXPEntitiesListDataSourceDefinition, AXPEntityApplyUpdatesAction, AXPEntityCategoryTreeSelectorComponent, AXPEntityCategoryWidget, AXPEntityCategoryWidgetColumnComponent, AXPEntityCategoryWidgetEditComponent, AXPEntityCategoryWidgetViewComponent, AXPEntityCommandTriggerViewModel, AXPEntityCreateEvent, AXPEntityCreatePopupAction, AXPEntityCreateSubmittedAction, AXPEntityCreateViewElementViewModel, AXPEntityCreateViewModelFactory, AXPEntityCreateViewSectionViewModel, AXPEntityDataProvider, AXPEntityDataProviderImpl, AXPEntityDataSelectorService, AXPEntityDefinitionRegistryService, AXPEntityDeletedEvent, AXPEntityDetailListViewModel, AXPEntityDetailPopoverComponent, AXPEntityDetailPopoverService, AXPEntityDetailViewModelFactory, AXPEntityDetailViewModelResolver, AXPEntityEventDispatcherService, AXPEntityEventsKeys, AXPEntityFormBuilderService, AXPEntityListTableService, AXPEntityListViewColumnViewModel, AXPEntityListViewModelFactory, AXPEntityListViewModelResolver, AXPEntityListWidget, AXPEntityListWidgetViewComponent, AXPEntityMasterCreateViewModel, AXPEntityMasterListViewModel, AXPEntityMasterListViewQueryViewModel, AXPEntityMasterSingleElementViewModel, AXPEntityMasterSingleViewGroupViewModel, AXPEntityMasterSingleViewModel, AXPEntityMasterUpdateElementViewModel, AXPEntityMasterUpdateViewModel, AXPEntityMasterUpdateViewModelFactory, AXPEntityMiddleware, AXPEntityModifyConfirmedAction, AXPEntityModifyEvent, AXPEntityModifySectionPopupAction, AXPEntityModule, AXPEntityPerformDeleteAction, AXPEntityResolver, AXPEntityService, AXPEntityStorageService, AXPEntityUpdateViewSectionViewModel, AXPGetEntityDetailsQuery, AXPLayoutOrderingConfigService, AXPLookupWidget, AXPLookupWidgetColumnComponent, AXPLookupWidgetEditComponent, AXPLookupWidgetViewComponent, AXPMiddlewareAbortError, AXPMiddlewareEntityStorageService, AXPModifyEntitySectionWorkflow, AXPMultiSourceDefinitionProviderContext, AXPMultiSourceDefinitionProviderService, AXPMultiSourceFederatedSearchService, AXPMultiSourceSelectorComponent, AXPMultiSourceSelectorService, AXPMultiSourceSelectorWidget, AXPMultiSourceSelectorWidgetColumnComponent, AXPMultiSourceSelectorWidgetEditComponent, AXPMultiSourceSelectorWidgetViewComponent, AXPMultiSourceType, AXPOpenEntityDetailsCommand, AXPQuickEntityModifyPopupAction, AXPQuickModifyEntityWorkflow, AXPShowDetailViewAction, AXPShowDetailsViewWorkflow, AXPShowListViewAction, AXPShowListViewWorkflow, AXPTruncatedBreadcrumbComponent, AXPUpdateEntityCommand, AXPViewEntityDetailsCommand, AXP_DATA_SEEDER_TOKEN, AXP_ENTITY_ACTION_PLUGIN, AXP_ENTITY_CONFIG_TOKEN, AXP_ENTITY_DEFINITION_LOADER, AXP_ENTITY_MODIFIER, AXP_ENTITY_STORAGE_BACKEND, AXP_ENTITY_STORAGE_MIDDLEWARE, AXP_MULTI_SOURCE_DEFINITION_PROVIDER, DEFAULT_PROPERTY_ORDER, DEFAULT_SECTION_ORDER, EntityBuilder, EntityDataAccessor, actionExists, cloneLayoutArrays, columnWidthMiddleware, columnWidthMiddlewareProvider, createLayoutOrderingMiddlewareProvider, createModifierContext, detectEntityChanges, ensureLayoutPropertyView, ensureLayoutSection, ensureListActions, entityDetailsCreateActions, entityDetailsCrudActions, entityDetailsEditAction, entityDetailsNewEditAction, entityDetailsReferenceCondition, entityDetailsReferenceCreateActions, entityDetailsSimpleCondition, entityMasterBulkDeleteAction, entityMasterCreateAction, entityMasterCrudActions, entityMasterDeleteAction, entityMasterEditAction, entityMasterRecordActions, entityMasterViewAction, entityOverrideDetailsViewAction, eventDispatchMiddleware, isAXPMiddlewareAbortError, layoutOrderingMiddlewareFactory, layoutOrderingMiddlewareProvider };
15336
15554
  //# sourceMappingURL=acorex-platform-layout-entity.mjs.map