@acorex/platform 20.7.6 → 20.7.7

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 (23) hide show
  1. package/fesm2022/acorex-platform-core.mjs +5 -3
  2. package/fesm2022/acorex-platform-core.mjs.map +1 -1
  3. package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-ZnTG7wlJ.mjs +121 -0
  4. package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-ZnTG7wlJ.mjs.map +1 -0
  5. package/fesm2022/acorex-platform-layout-components.mjs +232 -107
  6. package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
  7. package/fesm2022/acorex-platform-layout-entity.mjs +543 -306
  8. package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
  9. package/fesm2022/acorex-platform-layout-widget-core.mjs +10 -2
  10. package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -1
  11. package/fesm2022/{acorex-platform-layout-widgets-repeater-widget-column.component-D4UOMW6k.mjs → acorex-platform-layout-widgets-repeater-widget-column.component-fcCirNxz.mjs} +2 -2
  12. package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-fcCirNxz.mjs.map +1 -0
  13. package/fesm2022/acorex-platform-layout-widgets.mjs +582 -76
  14. package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
  15. package/fesm2022/{acorex-platform-themes-default-entity-master-list-view.component-C31xDGGb.mjs → acorex-platform-themes-default-entity-master-list-view.component-DzWjSMSK.mjs} +5 -4
  16. package/fesm2022/{acorex-platform-themes-default-entity-master-list-view.component-C31xDGGb.mjs.map → acorex-platform-themes-default-entity-master-list-view.component-DzWjSMSK.mjs.map} +1 -1
  17. package/fesm2022/acorex-platform-themes-default.mjs +2 -2
  18. package/layout/components/index.d.ts +49 -28
  19. package/layout/entity/index.d.ts +40 -40
  20. package/layout/widget-core/index.d.ts +11 -2
  21. package/layout/widgets/index.d.ts +130 -8
  22. package/package.json +1 -1
  23. package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-D4UOMW6k.mjs.map +0 -1
@@ -1,9 +1,10 @@
1
1
  import { AXToastService } from '@acorex/components/toast';
2
+ import { AXPlatform } from '@acorex/core/platform';
2
3
  import * as i6 from '@acorex/core/translation';
3
4
  import { AXTranslationService, AXTranslationModule } from '@acorex/core/translation';
4
5
  import * as i4$1 from '@acorex/platform/common';
5
6
  import { AXPSettingsService, AXPFilterOperatorMiddlewareService, AXPEntityCommandScope, getEntityInfo, AXPRefreshEvent, AXPReloadEvent, AXPCommonSettings, AXPEntityQueryType, AXPCleanNestedFilters, AXPWorkflowNavigateAction, AXPToastAction, AXP_SEARCH_DEFINITION_PROVIDER } from '@acorex/platform/common';
6
- import { AXPDeviceService, AXPBroadcastEventService, resolveActionLook, AXPExpressionEvaluatorService, AXPDistributedEventListenerService, AXPPlatformScope, AXPColumnWidthService, AXHighlightService, extractValue, setSmart, getChangedPaths, defaultColumnWidthProvider, AXP_COLUMN_WIDTH_PROVIDER, AXPSystemActionType } from '@acorex/platform/core';
7
+ 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';
7
8
  import * as i0 from '@angular/core';
8
9
  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';
9
10
  import { Subject, takeUntil } from 'rxjs';
@@ -18,7 +19,7 @@ import { AXLoadingModule } from '@acorex/components/loading';
18
19
  import * as i2 from '@acorex/components/popover';
19
20
  import { AXPopoverModule } from '@acorex/components/popover';
20
21
  import * as i3$1 from '@acorex/platform/layout/widget-core';
21
- import { AXPWidgetsCatalog, AXPWidgetCoreModule, AXPPageStatus, AXPWidgetRegistryService, AXPColumnWidgetComponent, AXPValueWidgetComponent, AXPWidgetGroupEnum, AXPWidgetRendererDirective } from '@acorex/platform/layout/widget-core';
22
+ import { AXPWidgetsCatalog, AXPWidgetCoreModule, AXPPageStatus, AXPWidgetRegistryService, AXPColumnWidgetComponent, AXPValueWidgetComponent, AXPWidgetGroupEnum, AXPWidgetRendererDirective, AXP_WIDGETS_EDITOR_CATEGORY } from '@acorex/platform/layout/widget-core';
22
23
  import { AXPCommandService, AXPQueryService, AXPQueryExecutor, provideCommandSetups, provideQuerySetups } from '@acorex/platform/runtime';
23
24
  import * as i5 from '@angular/common';
24
25
  import { CommonModule } from '@angular/common';
@@ -31,7 +32,6 @@ import { moveItemInArray } from '@angular/cdk/drag-drop';
31
32
  import { AXDialogService } from '@acorex/components/dialog';
32
33
  import { AXLoadingDialogService } from '@acorex/components/loading-dialog';
33
34
  import { AXPopupService } from '@acorex/components/popup';
34
- import { AXPlatform } from '@acorex/core/platform';
35
35
  import * as i2$1 from '@acorex/components/badge';
36
36
  import { AXBadgeModule } from '@acorex/components/badge';
37
37
  import { AXCheckBoxModule } from '@acorex/components/check-box';
@@ -58,7 +58,6 @@ 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';
60
60
  import { AXSelectBoxModule } from '@acorex/components/select-box';
61
- import { AXTextBoxModule } from '@acorex/components/text-box';
62
61
  import * as i2$2 from '@acorex/components/tabs';
63
62
  import { AXTabsModule } from '@acorex/components/tabs';
64
63
  import { transform, isEqual as isEqual$1 } from 'lodash';
@@ -411,42 +410,43 @@ class AXPEntityResolver {
411
410
  constructor() {
412
411
  this.providers = inject(AXP_ENTITY_DEFINITION_LOADER);
413
412
  }
414
- async get(moduleName, entityName) {
415
- // Load from DI tokens
416
- if (Array.isArray(this.providers)) {
417
- for (const loader of this.providers) {
418
- let resolvedLoader;
419
- if (loader instanceof Promise) {
420
- // If loader is a promise, resolve it
421
- resolvedLoader = await loader;
422
- }
423
- else {
424
- // If loader is a direct instance, use it directly
425
- resolvedLoader = loader;
426
- }
427
- const entity = await resolvedLoader.get(moduleName, entityName);
428
- if (entity) {
429
- return entity;
430
- }
413
+ /** Aggregates list() from all entity loaders (including lazy). Populates fullName. */
414
+ async listAll() {
415
+ const loaders = await this.resolveLoaders();
416
+ const results = [];
417
+ for (const loader of loaders) {
418
+ const items = await loader.list();
419
+ for (const it of items) {
420
+ results.push({
421
+ name: it.name,
422
+ module: it.module,
423
+ fullName: `${it.module}.${it.name}`,
424
+ });
431
425
  }
432
426
  }
433
- else {
434
- let resolvedLoader;
435
- if (this.providers instanceof Promise) {
436
- // If loader is a promise, resolve it
437
- resolvedLoader = await this.providers;
438
- }
439
- else {
440
- // If loader is a direct instance, use it directly
441
- resolvedLoader = this.providers;
442
- }
443
- const entity = await resolvedLoader.get(moduleName, entityName);
444
- if (entity) {
427
+ return results;
428
+ }
429
+ async get(moduleName, entityName) {
430
+ const loaders = await this.resolveLoaders();
431
+ for (const loader of loaders) {
432
+ const entity = await loader.get(moduleName, entityName);
433
+ if (entity)
445
434
  return entity;
446
- }
447
435
  }
448
436
  return null;
449
437
  }
438
+ async resolveLoaders() {
439
+ const raw = this.providers;
440
+ if (!raw)
441
+ return [];
442
+ const arr = Array.isArray(raw) ? raw : [raw];
443
+ const loaders = [];
444
+ for (const p of arr) {
445
+ const loader = p instanceof Promise ? await p : p;
446
+ loaders.push(loader);
447
+ }
448
+ return loaders;
449
+ }
450
450
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPEntityResolver, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
451
451
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPEntityResolver, providedIn: 'root' }); }
452
452
  }
@@ -784,28 +784,173 @@ class PropertyFilter {
784
784
  const { moduleName, entityName } = parseEntityFullName(this.fullName);
785
785
  const entity = await this.entityRegistry.resolve(moduleName, entityName);
786
786
  // Select the appropriate interface based on kind
787
- let iface;
788
- if (this.kind === 'create') {
789
- iface = entity?.interfaces?.master?.create;
790
- }
791
- else if (this.kind === 'update') {
792
- iface = entity?.interfaces?.master?.update;
793
- }
794
- else {
795
- iface = entity?.interfaces?.master?.single;
796
- }
787
+ const iface = getEntityInterface(entity, this.kind);
797
788
  if (!iface) {
798
789
  throw new Error(`Entity interface not found: ${entity.module}.${entity.name}.interfaces.master.${this.kind}`);
799
790
  }
800
791
  // Title and size
801
792
  const title = this.overrideTitle || entity.formats?.individual || entity.title || `${entity.module}.${entity.name}`;
802
793
  // Build content using LayoutBuilder
803
- const sections = (iface.sections ?? []).slice();
804
- const entityProps = (entity.properties ?? []).slice();
805
- const nameToViewLayout = buildViewLayoutMap(iface.properties ?? []);
806
- const allowedNames = this.computeAllowedNames(entityProps.map((p) => p.name));
807
- // Calculate recommended dialog size based on form complexity
808
- const calculatedSize = this.calculateRecommendedDialogSize(sections, entityProps, nameToViewLayout, allowedNames);
794
+ const mainSections = (iface.sections ?? []).slice();
795
+ const mainProps = (entity.properties ?? []).slice();
796
+ const mainViewLayoutMap = buildViewLayoutMap(iface.properties ?? []);
797
+ const allowedNames = this.computeAllowedNames(mainProps.map((p) => p.name));
798
+ // Collect all groups for title lookup (main + merged)
799
+ const allGroups = [...(entity.groups ?? [])];
800
+ // Process merge-detail related entities
801
+ const mergeDetailEntities = (entity.relatedEntities ?? []).filter((re) => !re.hidden && re.layout?.type === 'merge-detail');
802
+ // Build merged properties map by section
803
+ const mergedPropsBySection = new Map();
804
+ // Initialize with main entity properties
805
+ for (const prop of mainProps) {
806
+ if (!allowedNames.has(prop.name) || !mainViewLayoutMap.has(prop.name))
807
+ continue;
808
+ const groupId = prop.groupId ?? 'default';
809
+ if (!mergedPropsBySection.has(groupId)) {
810
+ mergedPropsBySection.set(groupId, []);
811
+ }
812
+ const viewLayout = mainViewLayoutMap.get(prop.name);
813
+ mergedPropsBySection.get(groupId).push({
814
+ ...prop,
815
+ __layout: viewLayout?.layout,
816
+ __order: viewLayout?.layout?.order,
817
+ });
818
+ }
819
+ // Track extra sections from related entities
820
+ const extraSections = [];
821
+ const mainSectionIds = new Set(mainSections.map((s) => s.id));
822
+ // Group related entities by position for ordered processing
823
+ const beforeEntities = mergeDetailEntities
824
+ .filter((re) => re.layout?.position === 'before')
825
+ .sort((a, b) => (a.layout?.order ?? Infinity) - (b.layout?.order ?? Infinity));
826
+ const middleEntities = mergeDetailEntities.filter((re) => !re.layout?.position || re.layout?.position === 'middle');
827
+ const afterEntities = mergeDetailEntities
828
+ .filter((re) => re.layout?.position === 'after')
829
+ .sort((a, b) => (a.layout?.order ?? Infinity) - (b.layout?.order ?? Infinity));
830
+ // Process related entities in order: before, middle, after
831
+ const processRelatedEntity = async (relatedEntity) => {
832
+ try {
833
+ const [relModuleName, relEntityName] = relatedEntity.entity.split('.');
834
+ const relEntityDef = await this.entityRegistry.resolve(relModuleName, relEntityName);
835
+ if (!relEntityDef)
836
+ return;
837
+ // Get the matching interface for the related entity
838
+ const relIface = getEntityInterface(relEntityDef, this.kind);
839
+ if (!relIface)
840
+ return;
841
+ // Merge related groups into allGroups (avoid duplicates)
842
+ for (const rg of relEntityDef.groups ?? []) {
843
+ if (!allGroups.some((g) => g.id === rg.id)) {
844
+ allGroups.push(rg);
845
+ }
846
+ }
847
+ // Compute dataPath for field prefixing
848
+ const dataPath = relatedEntity.persistence?.dataPath || relEntityName;
849
+ const position = relatedEntity.layout?.position ?? 'middle';
850
+ const entityOrder = relatedEntity.layout?.order ?? Infinity;
851
+ // Build view layout map for related entity
852
+ const relViewLayoutMap = buildViewLayoutMap(relIface.properties ?? []);
853
+ // Process each section in related interface
854
+ for (const relSection of relIface.sections ?? []) {
855
+ const sectionId = relSection.id;
856
+ const sectionHasMainEquivalent = mainSectionIds.has(sectionId);
857
+ // Get properties for this section
858
+ const sectionProps = [];
859
+ for (const prop of relEntityDef.properties ?? []) {
860
+ if (prop.groupId !== sectionId)
861
+ continue;
862
+ if (!relViewLayoutMap.has(prop.name))
863
+ continue;
864
+ const viewLayout = relViewLayoutMap.get(prop.name);
865
+ // Clone property and add merge-detail metadata
866
+ const mergedProp = {
867
+ ...prop,
868
+ __dataPath: dataPath,
869
+ __layout: viewLayout?.layout,
870
+ __order: viewLayout?.layout?.order,
871
+ };
872
+ // Prefix expressions in schema options
873
+ if (mergedProp.schema?.interface?.options) {
874
+ mergedProp.schema = {
875
+ ...mergedProp.schema,
876
+ interface: {
877
+ ...mergedProp.schema.interface,
878
+ options: prefixExpressions(mergedProp.schema.interface.options, dataPath),
879
+ },
880
+ };
881
+ }
882
+ // Prefix expressions in visible/readonly if they are strings
883
+ if (typeof mergedProp.schema?.visible === 'string') {
884
+ mergedProp.schema = {
885
+ ...mergedProp.schema,
886
+ visible: prefixExpressions(mergedProp.schema.visible, dataPath),
887
+ };
888
+ }
889
+ if (typeof mergedProp.schema?.readonly === 'string') {
890
+ mergedProp.schema = {
891
+ ...mergedProp.schema,
892
+ readonly: prefixExpressions(mergedProp.schema.readonly, dataPath),
893
+ };
894
+ }
895
+ sectionProps.push(mergedProp);
896
+ }
897
+ if (sectionProps.length === 0)
898
+ continue;
899
+ if (sectionHasMainEquivalent) {
900
+ // Merge into existing section
901
+ const existing = mergedPropsBySection.get(sectionId) ?? [];
902
+ if (position === 'before') {
903
+ mergedPropsBySection.set(sectionId, [...sectionProps, ...existing]);
904
+ }
905
+ else {
906
+ mergedPropsBySection.set(sectionId, [...existing, ...sectionProps]);
907
+ }
908
+ }
909
+ else {
910
+ // Create new section entry
911
+ if (!mergedPropsBySection.has(sectionId)) {
912
+ mergedPropsBySection.set(sectionId, []);
913
+ }
914
+ const existing = mergedPropsBySection.get(sectionId) ?? [];
915
+ if (position === 'before') {
916
+ mergedPropsBySection.set(sectionId, [...sectionProps, ...existing]);
917
+ }
918
+ else {
919
+ mergedPropsBySection.set(sectionId, [...existing, ...sectionProps]);
920
+ }
921
+ // Track as extra section if not already tracked
922
+ if (!extraSections.some((s) => s.id === sectionId)) {
923
+ extraSections.push({
924
+ ...relSection,
925
+ __entityOrder: entityOrder,
926
+ __position: position,
927
+ });
928
+ }
929
+ }
930
+ }
931
+ }
932
+ catch {
933
+ // Silently ignore failures to resolve or merge
934
+ }
935
+ };
936
+ // Process in order
937
+ for (const re of beforeEntities)
938
+ await processRelatedEntity(re);
939
+ for (const re of middleEntities)
940
+ await processRelatedEntity(re);
941
+ for (const re of afterEntities)
942
+ await processRelatedEntity(re);
943
+ // Build final sorted sections list
944
+ const finalSections = sortMergedSections(mainSections, extraSections, mainSectionIds);
945
+ // Calculate recommended dialog size based on form complexity (using merged data)
946
+ const allMergedProps = Array.from(mergedPropsBySection.values()).flat();
947
+ const mergedViewLayoutMap = new Map();
948
+ for (const prop of allMergedProps) {
949
+ if (prop.__layout) {
950
+ mergedViewLayoutMap.set(prop.name, { name: prop.name, layout: prop.__layout });
951
+ }
952
+ }
953
+ const calculatedSize = this.calculateRecommendedDialogSize(finalSections, allMergedProps, mergedViewLayoutMap, new Set(allMergedProps.map((p) => p.name)));
809
954
  const dialog = this.layoutBuilder.create().dialog((d) => {
810
955
  d.setTitle(title);
811
956
  d.setSize(this.externalSize ?? calculatedSize);
@@ -819,24 +964,27 @@ class PropertyFilter {
819
964
  // Configure grid with 12 columns (like Bootstrap)
820
965
  grid.setColumns(12);
821
966
  grid.setGap('1rem');
822
- for (const section of sections) {
967
+ for (const section of finalSections) {
823
968
  const groupId = section.id;
824
- // Only render properties that are explicitly present in the selected interface's `properties` list.
825
- // This prevents cross-plugin leaks when multiple properties share the same group/section.
826
- const groupProps = entityProps.filter((p) => p.groupId === groupId && allowedNames.has(p.name) && nameToViewLayout.has(p.name));
969
+ const sectionProps = mergedPropsBySection.get(groupId) ?? [];
827
970
  const extraFields = this.extraFieldsByGroup.get(groupId) ?? [];
828
- if (groupProps.length === 0 && extraFields.length === 0) {
971
+ if (sectionProps.length === 0 && extraFields.length === 0) {
829
972
  continue;
830
973
  }
831
974
  grid.fieldset((fs) => {
832
975
  fs.setLook('fieldset');
833
- fs.setTitle((getGroupTitle(entity, groupId) || groupId));
976
+ fs.setTitle((getGroupTitleFromList(allGroups, groupId) || groupId));
834
977
  fs.setCols(12); // Set fieldset to use 12-column grid layout
835
- // Preserve properties order as defined in interface.properties (if present), otherwise entity.properties order
836
- const orderedProps = orderProperties(groupProps, iface.properties ?? []);
978
+ // Sort properties by order within section
979
+ const orderedProps = [...sectionProps].sort((a, b) => {
980
+ const aOrder = a.__order ?? Infinity;
981
+ const bOrder = b.__order ?? Infinity;
982
+ return aOrder - bOrder;
983
+ });
837
984
  for (const prop of orderedProps) {
838
- const viewLayout = nameToViewLayout.get(prop.name);
839
- const fieldPath = buildFieldPath(prop, iface.properties ?? []);
985
+ const mergedProp = prop;
986
+ const dataPath = mergedProp.__dataPath;
987
+ const fieldPath = dataPath ? `${dataPath}.${prop.name}` : prop.name;
840
988
  fs.formField(prop.title, (field) => {
841
989
  // Path & field-level visibility/readonly
842
990
  field.path(fieldPath);
@@ -849,8 +997,8 @@ class PropertyFilter {
849
997
  if (prop.schema?.defaultValue !== undefined) {
850
998
  field.defaultValue(prop.schema.defaultValue);
851
999
  }
852
- // Layout mapping (per-field). Only colSpan is supported by dynamic-form per breakpoint.
853
- const fieldLayout = toFieldLayout(viewLayout?.layout);
1000
+ // Layout mapping (per-field)
1001
+ const fieldLayout = toFieldLayout(mergedProp.__layout);
854
1002
  if (fieldLayout) {
855
1003
  field.layout(fieldLayout);
856
1004
  }
@@ -861,8 +1009,12 @@ class PropertyFilter {
861
1009
  const widgetType = prop.schema?.interface?.type || '';
862
1010
  const widgetOptions = buildWidgetOptions(prop);
863
1011
  const extendedProperties = buildWidgetExtendedProperties(prop);
1012
+ // Prefix extended properties expressions if from related entity
1013
+ const finalExtendedProps = dataPath
1014
+ ? prefixExpressions(extendedProperties, dataPath)
1015
+ : extendedProperties;
864
1016
  // Merge extended properties into options (they will be extracted in addSingleWidget)
865
- field.customWidget(widgetType, { ...widgetOptions, ...extendedProperties });
1017
+ field.customWidget(widgetType, { ...widgetOptions, ...finalExtendedProps });
866
1018
  });
867
1019
  }
868
1020
  // Append any extra fields requested by the caller for this group
@@ -1088,6 +1240,24 @@ function getGroupTitle(entity, groupId) {
1088
1240
  const g = (entity.groups || []).find((x) => x.id === groupId);
1089
1241
  return g?.title;
1090
1242
  }
1243
+ function getGroupTitleFromList(groups, groupId) {
1244
+ const g = groups.find((x) => x.id === groupId);
1245
+ return g?.title;
1246
+ }
1247
+ /**
1248
+ * Gets the appropriate interface from an entity based on the kind
1249
+ */
1250
+ function getEntityInterface(entity, kind) {
1251
+ if (kind === 'create') {
1252
+ return entity?.interfaces?.master?.create;
1253
+ }
1254
+ else if (kind === 'update') {
1255
+ return entity?.interfaces?.master?.update;
1256
+ }
1257
+ else {
1258
+ return entity?.interfaces?.master?.single;
1259
+ }
1260
+ }
1091
1261
  function toCompatFormFieldBuilder(field) {
1092
1262
  return {
1093
1263
  ...field,
@@ -1099,6 +1269,109 @@ function toCompatFormFieldBuilder(field) {
1099
1269
  mode: (mode) => field.mode(mode),
1100
1270
  };
1101
1271
  }
1272
+ /**
1273
+ * Prefixes context.eval() expressions and expose targets with a dataPath.
1274
+ * - Transforms `context.eval("field")` to `context.eval("dataPath.field")`
1275
+ * - Transforms expose `target: "field"` to `target: "dataPath.field"`
1276
+ * Recursively processes objects and arrays.
1277
+ */
1278
+ function prefixExpressions(value, dataPath, parentKey) {
1279
+ if (!dataPath)
1280
+ return value;
1281
+ if (typeof value === 'string') {
1282
+ // Special handling for 'target' key in expose arrays - prefix the path directly
1283
+ if (parentKey === 'target') {
1284
+ // Don't prefix if already prefixed or if it starts with $ (absolute path)
1285
+ if (value.startsWith(dataPath + '.') || value.startsWith('$')) {
1286
+ return value;
1287
+ }
1288
+ return `${dataPath}.${value}`;
1289
+ }
1290
+ // Match context.eval("...") or context.eval('...')
1291
+ return value.replace(/context\.eval\(["']([^"']+)["']\)/g, (match, path) => {
1292
+ // Don't prefix if already prefixed or if it's an absolute path
1293
+ if (path.startsWith(dataPath + '.') || path.startsWith('$')) {
1294
+ return match;
1295
+ }
1296
+ return `context.eval("${dataPath}.${path}")`;
1297
+ });
1298
+ }
1299
+ if (Array.isArray(value)) {
1300
+ return value.map((item) => prefixExpressions(item, dataPath, parentKey));
1301
+ }
1302
+ if (value !== null && typeof value === 'object') {
1303
+ const result = {};
1304
+ for (const key of Object.keys(value)) {
1305
+ result[key] = prefixExpressions(value[key], dataPath, key);
1306
+ }
1307
+ return result;
1308
+ }
1309
+ return value;
1310
+ }
1311
+ /**
1312
+ * Groups properties by their groupId (section)
1313
+ */
1314
+ function groupPropertiesBySection(properties) {
1315
+ const map = new Map();
1316
+ for (const prop of properties) {
1317
+ const groupId = prop.groupId ?? 'default';
1318
+ if (!map.has(groupId)) {
1319
+ map.set(groupId, []);
1320
+ }
1321
+ map.get(groupId).push(prop);
1322
+ }
1323
+ return map;
1324
+ }
1325
+ /**
1326
+ * Sorts sections by position and order:
1327
+ * 1. Before sections (sorted by entityOrder, then section order)
1328
+ * 2. Middle sections (main + middle-only, sorted by effective order while preserving original index for stable sort)
1329
+ * 3. After sections (sorted by entityOrder, then section order)
1330
+ */
1331
+ function sortMergedSections(mainSections, extraSections, mainSectionIds) {
1332
+ const beforeSections = extraSections
1333
+ .filter((s) => s.__position === 'before' && !mainSectionIds.has(s.id))
1334
+ .sort((a, b) => {
1335
+ const entityOrderDiff = (a.__entityOrder ?? Infinity) - (b.__entityOrder ?? Infinity);
1336
+ if (entityOrderDiff !== 0)
1337
+ return entityOrderDiff;
1338
+ return (a.order ?? 0) - (b.order ?? 0);
1339
+ });
1340
+ const middleSections = extraSections.filter((s) => s.__position === 'middle' && !mainSectionIds.has(s.id));
1341
+ const afterSections = extraSections
1342
+ .filter((s) => s.__position === 'after' && !mainSectionIds.has(s.id))
1343
+ .sort((a, b) => {
1344
+ const entityOrderDiff = (a.__entityOrder ?? Infinity) - (b.__entityOrder ?? Infinity);
1345
+ if (entityOrderDiff !== 0)
1346
+ return entityOrderDiff;
1347
+ return (a.order ?? 0) - (b.order ?? 0);
1348
+ });
1349
+ // Build index map for main sections to preserve original order when no explicit order is specified
1350
+ const mainSectionIndexMap = new Map();
1351
+ mainSections.forEach((s, idx) => mainSectionIndexMap.set(s.id, idx));
1352
+ // Middle block: main sections + middle-only sections
1353
+ // Sort by explicit order if present, otherwise use original array index for main sections
1354
+ // Extra middle sections without order go after main sections
1355
+ const middleBlock = [...mainSections, ...middleSections].sort((a, b) => {
1356
+ const aHasOrder = a.order !== undefined;
1357
+ const bHasOrder = b.order !== undefined;
1358
+ // If both have explicit order, sort by order
1359
+ if (aHasOrder && bHasOrder) {
1360
+ return a.order - b.order;
1361
+ }
1362
+ // If neither has order, preserve original array position for main sections
1363
+ if (!aHasOrder && !bHasOrder) {
1364
+ const aIdx = mainSectionIndexMap.get(a.id) ?? Infinity;
1365
+ const bIdx = mainSectionIndexMap.get(b.id) ?? Infinity;
1366
+ return aIdx - bIdx;
1367
+ }
1368
+ // If only one has order, the one with order comes first (explicit ordering takes precedence)
1369
+ if (aHasOrder)
1370
+ return -1;
1371
+ return 1;
1372
+ });
1373
+ return [...beforeSections, ...middleBlock, ...afterSections];
1374
+ }
1102
1375
 
1103
1376
  class AXPCreateEntityCommand {
1104
1377
  constructor() {
@@ -1108,6 +1381,7 @@ class AXPCreateEntityCommand {
1108
1381
  this.toastService = inject(AXToastService);
1109
1382
  this.translationService = inject(AXTranslationService);
1110
1383
  this.eventService = inject(AXPBroadcastEventService);
1384
+ this.platform = inject(AXPlatform);
1111
1385
  this.context = {};
1112
1386
  }
1113
1387
  async execute(input) {
@@ -1115,6 +1389,11 @@ class AXPCreateEntityCommand {
1115
1389
  const { entity, entityInfo, data, options } = input.__context__;
1116
1390
  const excludeProperties = options?.excludeProperties;
1117
1391
  const includeProperties = options?.includeProperties;
1392
+ // Extract decoration and layout from options (similar to workflow)
1393
+ const decoration = options?.['decoration'];
1394
+ const layout = options?.['layout'];
1395
+ const headerTitle = decoration?.header?.title;
1396
+ const layoutSize = layout?.size;
1118
1397
  const [moduleName, entityName] = (entity || '').split('.');
1119
1398
  if (!moduleName || !entityName) {
1120
1399
  return {
@@ -1138,13 +1417,25 @@ class AXPCreateEntityCommand {
1138
1417
  if (includeProperties && includeProperties.length > 0) {
1139
1418
  chain = chain.include(...includeProperties);
1140
1419
  }
1141
- if (entityInfo?.title) {
1420
+ // Set dialog title: use decoration.header.title if available, otherwise use entityInfo.title
1421
+ if (headerTitle) {
1422
+ chain = chain.title(headerTitle);
1423
+ }
1424
+ else if (entityInfo?.title) {
1142
1425
  const createText = await this.translationService.translateAsync('@general:actions.create.title');
1143
1426
  const translatedTitle = await this.translationService.translateAsync(entityInfo.title);
1144
1427
  chain = chain.title(`${createText} ${translatedTitle}`);
1145
1428
  }
1146
- if (dialogSize) {
1147
- chain.size(dialogSize);
1429
+ // Set dialog size: prioritize layout.size, then dialogSize from input, with platform-aware defaults
1430
+ const finalSize = layoutSize || dialogSize;
1431
+ if (this.platform.is('Mobile') || this.platform.is('SM')) {
1432
+ chain.size('full');
1433
+ }
1434
+ else if (finalSize) {
1435
+ chain.size(finalSize);
1436
+ }
1437
+ else {
1438
+ chain.size('md');
1148
1439
  }
1149
1440
  dialogRef = await chain.show();
1150
1441
  if (dialogRef.action() == 'cancel') {
@@ -1780,7 +2071,7 @@ class AXPEntityDetailPopoverComponent {
1780
2071
  return importantProperties;
1781
2072
  }
1782
2073
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPEntityDetailPopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1783
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: AXPEntityDetailPopoverComponent, isStandalone: true, selector: "axp-entity-detail-popover", inputs: { entity: { classPropertyName: "entity", publicName: "entity", isSignal: true, isRequired: true, transformFunction: null }, entityId: { classPropertyName: "entityId", publicName: "entityId", isSignal: true, isRequired: true, transformFunction: null }, textField: { classPropertyName: "textField", publicName: "textField", isSignal: true, isRequired: false, transformFunction: null }, valueField: { classPropertyName: "valueField", publicName: "valueField", isSignal: true, isRequired: false, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: false, transformFunction: null }, breadcrumb: { classPropertyName: "breadcrumb", publicName: "breadcrumb", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "detailPopover", first: true, predicate: ["detailPopover"], descendants: true, isSignal: true }], ngImport: i0, template: "<ax-popover [openOn]=\"'manual'\" #detailPopover (openChange)=\"onDetailPopoverOpenChange($event)\">\n <div class=\"ax-lightest-surface ax-border ax-rounded-lg ax-shadow-lg ax-p-4 ax-min-w-[400px]\">\n <div class=\"ax-mb-4 ax-border-b ax-pb-2\">\n <h3 class=\"ax-text-base ax-font-semibold ax-text-on-lightest-surface\">\n @if (entityDetails()?.entityData?.[textField()]) {\n {{ entityDetails()?.entityData[textField()] }}\n } @else {\n {{ item()?.[textField()] }}\n }\n </h3>\n @if (breadcrumb()) {\n <div class=\"ax-text-xs ax-text-neutral-500 ax-mt-1\">{{ breadcrumb() }}</div>\n }\n </div>\n @if (isLoadingDetails()) {\n <div class=\"ax-flex ax-items-center ax-justify-center ax-py-8\">\n <ax-loading>Loading details...</ax-loading>\n </div>\n } @else if (entityDetails()) {\n <div class=\"ax-space-y-3 ax-mb-4\">\n <!-- Important Entity Data -->\n @if (entityDetails()?.entityData) {\n <axp-widgets-container [context]=\"entityDetails()?.entityData\">\n <div class=\"ax-space-y-2\">\n @for (item of getEntityPropertiesWithWidgets(); track item.name) {\n <div class=\"ax-flex ax-justify-between ax-items-center\">\n <span class=\"ax-text-sm ax-font-medium\">{{ item.title | translate | async }}:</span>\n <div class=\"ax-flex-1 ax-ml-2 ax-max-w-48\">\n <ng-container axp-widget-renderer [node]=\"item.node\" [mode]=\"'view'\"></ng-container>\n </div>\n </div>\n }\n </div>\n </axp-widgets-container>\n }\n </div>\n <div class=\"ax-flex ax-gap-2 ax-justify-end ax-sm\">\n <ax-button [color]=\"'primary'\" [look]=\"'solid'\" text=\"Open Details\" (click)=\"navigateToDetails()\"> </ax-button>\n </div>\n }\n </div>\n</ax-popover>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i2.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: i3$1.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i3$1.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged", "onLoad"], exportAs: ["widgetRenderer"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i4.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2074
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: AXPEntityDetailPopoverComponent, isStandalone: true, selector: "axp-entity-detail-popover", inputs: { entity: { classPropertyName: "entity", publicName: "entity", isSignal: true, isRequired: true, transformFunction: null }, entityId: { classPropertyName: "entityId", publicName: "entityId", isSignal: true, isRequired: true, transformFunction: null }, textField: { classPropertyName: "textField", publicName: "textField", isSignal: true, isRequired: false, transformFunction: null }, valueField: { classPropertyName: "valueField", publicName: "valueField", isSignal: true, isRequired: false, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: false, transformFunction: null }, breadcrumb: { classPropertyName: "breadcrumb", publicName: "breadcrumb", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "detailPopover", first: true, predicate: ["detailPopover"], descendants: true, isSignal: true }], ngImport: i0, template: "<ax-popover [openOn]=\"'manual'\" #detailPopover (openChange)=\"onDetailPopoverOpenChange($event)\">\n <div class=\"ax-lightest-surface ax-border ax-rounded-lg ax-shadow-lg ax-p-4 ax-min-w-[400px]\">\n <div class=\"ax-mb-4 ax-border-b ax-pb-2\">\n <h3 class=\"ax-text-base ax-font-semibold ax-text-on-lightest-surface\">\n @if (entityDetails()?.entityData?.[textField()]) {\n {{ entityDetails()?.entityData[textField()] }}\n } @else {\n {{ item()?.[textField()] }}\n }\n </h3>\n @if (breadcrumb()) {\n <div class=\"ax-text-xs ax-text-neutral-500 ax-mt-1\">{{ breadcrumb() }}</div>\n }\n </div>\n @if (isLoadingDetails()) {\n <div class=\"ax-flex ax-items-center ax-justify-center ax-py-8\">\n <ax-loading>Loading details...</ax-loading>\n </div>\n } @else if (entityDetails()) {\n <div class=\"ax-space-y-3 ax-mb-4\">\n <!-- Important Entity Data -->\n @if (entityDetails()?.entityData) {\n <axp-widgets-container [context]=\"entityDetails()?.entityData\">\n <div class=\"ax-space-y-2\">\n @for (item of getEntityPropertiesWithWidgets(); track item.name) {\n <div class=\"ax-flex ax-justify-between ax-items-center\">\n <span class=\"ax-text-sm ax-font-medium\">{{ item.title | translate | async }}:</span>\n <div class=\"ax-flex-1 ax-ml-2 ax-max-w-48\">\n <ng-container axp-widget-renderer [node]=\"item.node\" [mode]=\"'view'\"></ng-container>\n </div>\n </div>\n }\n </div>\n </axp-widgets-container>\n }\n </div>\n <div class=\"ax-flex ax-gap-2 ax-justify-end ax-sm\">\n <ax-button [color]=\"'primary'\" [look]=\"'solid'\" text=\"Open Details\" (click)=\"navigateToDetails()\"> </ax-button>\n </div>\n }\n </div>\n</ax-popover>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i2.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "repositionOnScroll", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: i3$1.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i3$1.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged", "onLoad"], exportAs: ["widgetRenderer"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i4.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1784
2075
  }
1785
2076
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPEntityDetailPopoverComponent, decorators: [{
1786
2077
  type: Component,
@@ -1884,6 +2175,95 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
1884
2175
  args: [{ providedIn: 'root' }]
1885
2176
  }] });
1886
2177
 
2178
+ /**
2179
+ * Data source definition provider that returns all entity names
2180
+ * from entity loaders' list() (const.ts in each module).
2181
+ */
2182
+ class AXPEntitiesListDataSourceDefinition {
2183
+ constructor() {
2184
+ //#region ---- Services & Dependencies ----
2185
+ this.entityResolver = inject(AXPEntityResolver);
2186
+ //#endregion
2187
+ }
2188
+ //#endregion
2189
+ //#region ---- Public Methods ----
2190
+ items() {
2191
+ return Promise.resolve([
2192
+ {
2193
+ name: 'entities',
2194
+ title: 'Entities',
2195
+ columns: [
2196
+ {
2197
+ name: 'entity',
2198
+ title: 'Entity',
2199
+ datatype: 'string',
2200
+ type: AXPWidgetsCatalog.text,
2201
+ },
2202
+ {
2203
+ name: 'module',
2204
+ title: 'Module',
2205
+ datatype: 'string',
2206
+ type: AXPWidgetsCatalog.text,
2207
+ },
2208
+ {
2209
+ name: 'title',
2210
+ title: 'Title',
2211
+ datatype: 'string',
2212
+ type: AXPWidgetsCatalog.text,
2213
+ },
2214
+ ],
2215
+ filters: [
2216
+ {
2217
+ field: 'entity',
2218
+ title: 'Entity',
2219
+ operator: { type: 'equal' },
2220
+ widget: { type: AXPWidgetsCatalog.text },
2221
+ filterType: { advance: true, inline: true },
2222
+ },
2223
+ {
2224
+ field: 'module',
2225
+ title: 'Module',
2226
+ operator: { type: 'equal' },
2227
+ widget: { type: AXPWidgetsCatalog.text },
2228
+ filterType: { advance: true, inline: true },
2229
+ },
2230
+ ],
2231
+ textField: { name: 'title', title: 'Title' },
2232
+ valueField: { name: 'title', title: 'Title' },
2233
+ source: () => {
2234
+ return new AXDataSource({
2235
+ key: 'title',
2236
+ load: async (query) => {
2237
+ const entries = await this.entityResolver.listAll();
2238
+ let items = entries.map((e) => ({
2239
+ title: e.fullName,
2240
+ entity: e.name,
2241
+ module: e.module,
2242
+ }));
2243
+ if (query.filter) {
2244
+ items = applyFilterArray(items, [query.filter]);
2245
+ }
2246
+ const rawSort = Array.isArray(query.sort) ? query.sort : query.sort ? [query.sort] : [];
2247
+ const sortOpt = rawSort.length > 0 ? rawSort : [{ field: 'title', dir: 'asc' }];
2248
+ items = applySortArray(items, sortOpt);
2249
+ return { items, total: items.length };
2250
+ },
2251
+ byKey: async (key) => {
2252
+ const k = String(key);
2253
+ const entries = await this.entityResolver.listAll();
2254
+ const e = entries.find((x) => x.fullName === k);
2255
+ if (!e)
2256
+ throw new Error(`Entity not found: ${k}`);
2257
+ return { title: e.fullName, entity: e.name, module: e.module };
2258
+ },
2259
+ pageSize: 1000,
2260
+ });
2261
+ },
2262
+ },
2263
+ ]);
2264
+ }
2265
+ }
2266
+
1887
2267
  class AXPEntityCommandTriggerViewModel {
1888
2268
  constructor(entity, action) {
1889
2269
  this.name = `${typeof action.command === 'string' ? action.command : action.command.name}&${action.name}`;
@@ -2909,6 +3289,8 @@ class AXPEntityMasterListViewModel {
2909
3289
  if (sortKey === this.lastAppliedSortKey && filterKey === this.lastAppliedFilterKey) {
2910
3290
  return; // No effective change; avoid redundant refresh
2911
3291
  }
3292
+ // Determine if filters changed (for pagination reset)
3293
+ const filtersChanged = filterKey !== this.lastAppliedFilterKey;
2912
3294
  this.lastAppliedSortKey = sortKey;
2913
3295
  this.lastAppliedFilterKey = filterKey;
2914
3296
  this.dataSource.clearFilter();
@@ -2919,7 +3301,7 @@ class AXPEntityMasterListViewModel {
2919
3301
  operator: null,
2920
3302
  filters: filters,
2921
3303
  }));
2922
- this.events$.next({ action: 'refresh' });
3304
+ this.events$.next({ action: 'refresh', meta: { resetPagination: filtersChanged } });
2923
3305
  }
2924
3306
  resetColumns() {
2925
3307
  this.applyViewColumns();
@@ -4854,6 +5236,7 @@ class AXPTabListConverter extends AXPBaseRelatedEntityConverter {
4854
5236
  showToolbar: false,
4855
5237
  actions: actions,
4856
5238
  maxHeight: '300px',
5239
+ includeColumns: relatedEntity.columns,
4857
5240
  },
4858
5241
  },
4859
5242
  ],
@@ -5989,6 +6372,7 @@ const AXPCrudModifier = {
5989
6372
  if (!queries?.list) {
5990
6373
  queries.list = {
5991
6374
  execute: async (e) => {
6375
+ console.log({ e });
5992
6376
  return await dataService.query(e);
5993
6377
  },
5994
6378
  type: AXPEntityQueryType.List,
@@ -10957,189 +11341,6 @@ const AXPEntityListWidget = {
10957
11341
  },
10958
11342
  };
10959
11343
 
10960
- class AXPLookupFilterWidgetEditComponent extends AXPValueWidgetComponent {
10961
- constructor() {
10962
- super(...arguments);
10963
- //#region ---- Computed Properties ----
10964
- this.editorPath = `__${this.path}EditorValue`;
10965
- this.lookupWidgetRenderer = viewChild('widgetRenderer', ...(ngDevMode ? [{ debugName: "lookupWidgetRenderer" }] : []));
10966
- this.entity = computed(() => this.options()['entity'], ...(ngDevMode ? [{ debugName: "entity" }] : []));
10967
- this.textField = computed(() => this.options()['textField'] ?? 'title', ...(ngDevMode ? [{ debugName: "textField" }] : []));
10968
- this.valueField = computed(() => this.options()['valueField'] ?? 'id', ...(ngDevMode ? [{ debugName: "valueField" }] : []));
10969
- // protected expose = computed<string | undefined | any[]>(() => this.options()['expose'] as string);
10970
- this.customFilter = computed(() => this.options()['filter'], ...(ngDevMode ? [{ debugName: "customFilter" }] : []));
10971
- this.multiple = computed(() => (this.options()['multiple'] ?? false), ...(ngDevMode ? [{ debugName: "multiple" }] : []));
10972
- //#endregion
10973
- //#region ---- Lookup Node ----
10974
- this.lookupNode = signal({
10975
- type: 'lookup-editor',
10976
- path: this.path,
10977
- options: {},
10978
- }, ...(ngDevMode ? [{ debugName: "lookupNode" }] : []));
10979
- //#endregion
10980
- //#region ---- Effects ----
10981
- this.#efUpdateLookupNode = effect(() => {
10982
- // console.log('path:', this.path, this.expose());
10983
- const node = {
10984
- type: 'lookup-editor',
10985
- defaultValue: this.getValue()?.value,
10986
- path: this.editorPath,
10987
- options: {
10988
- entity: this.entity(),
10989
- expose: [
10990
- {
10991
- source: this.textField(),
10992
- target: this.multiple() ? `${this.path}EditorObj.{title}` : `${this.path}EditorObj.title`,
10993
- },
10994
- {
10995
- source: this.valueField(),
10996
- target: this.multiple() ? `${this.path}EditorObj.{id}` : `${this.path}EditorObj.id`,
10997
- },
10998
- ],
10999
- look: 'select',
11000
- multiple: this.multiple(),
11001
- textField: this.textField(),
11002
- filter: this.customFilter(),
11003
- allowClear: false,
11004
- },
11005
- };
11006
- this.lookupNode.set(node);
11007
- }, ...(ngDevMode ? [{ debugName: "#efUpdateLookupNode" }] : []));
11008
- this.#efUpdateValue = effect(() => {
11009
- const newValueObj = this.contextService.getValue(`${this.path}EditorObj`);
11010
- const newValueId = untracked(() => this.contextService.getValue(this.editorPath));
11011
- const prevValue = untracked(() => this.getValue()?.value);
11012
- const newValue = this.multiple()
11013
- ? newValueObj?.map((v) => v[this.valueField()])
11014
- : newValueObj?.[this.valueField()];
11015
- const valueIsChanged = !isEqual(prevValue, newValue);
11016
- if (!valueIsChanged) {
11017
- return;
11018
- }
11019
- if (!newValueId || newValueId?.length == 0) {
11020
- this.setValue({
11021
- value: undefined,
11022
- operation: {
11023
- type: this.multiple() ? 'in' : 'equal',
11024
- },
11025
- });
11026
- }
11027
- const value = this.multiple()
11028
- ? newValueObj.map((v) => v[this.valueField()])
11029
- : newValueObj?.[this.valueField()];
11030
- const displayText = this.multiple()
11031
- ? newValueObj.map((v) => v[this.textField()]).join(',')
11032
- : newValueObj?.[this.textField()];
11033
- this.setValue({
11034
- value: value,
11035
- operation: {
11036
- type: this.multiple() ? 'in' : 'equal',
11037
- },
11038
- displayText: displayText,
11039
- });
11040
- }, ...(ngDevMode ? [{ debugName: "#efUpdateValue" }] : []));
11041
- //#endregion
11042
- //#region ---- Focus Management ----
11043
- this.shouldFocus = signal(false, ...(ngDevMode ? [{ debugName: "shouldFocus" }] : []));
11044
- /**
11045
- * Reactive effect to auto-focus the lookup editor when component is ready
11046
- */
11047
- this.#focusEffect = effect(() => {
11048
- const renderer = this.lookupWidgetRenderer();
11049
- const shouldFocus = this.shouldFocus();
11050
- // Early return if no renderer or shouldn't focus
11051
- if (!renderer || !shouldFocus) {
11052
- return;
11053
- }
11054
- // Listen to componentRefSignal reactively
11055
- const componentRef = renderer.componentRefSignal();
11056
- // When componentRef is set (not null), focus the widget
11057
- if (componentRef) {
11058
- const componentInstance = componentRef.instance;
11059
- // Try to use the component's native focus method
11060
- if (componentInstance && typeof componentInstance.focus === 'function') {
11061
- try {
11062
- componentInstance.focus();
11063
- // Reset focus flag after successful focus
11064
- this.shouldFocus.set(false);
11065
- }
11066
- catch (error) {
11067
- // console.error('Error focusing lookup widget component:', error);
11068
- }
11069
- }
11070
- }
11071
- }, ...(ngDevMode ? [{ debugName: "#focusEffect" }] : []));
11072
- }
11073
- //#endregion
11074
- //#region ---- Effects ----
11075
- #efUpdateLookupNode;
11076
- #efUpdateValue;
11077
- /**
11078
- * Reactive effect to auto-focus the lookup editor when component is ready
11079
- */
11080
- #focusEffect;
11081
- /**
11082
- * Public focus method to trigger focusing
11083
- */
11084
- focus() {
11085
- this.shouldFocus.set(true);
11086
- }
11087
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPLookupFilterWidgetEditComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
11088
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.3.16", type: AXPLookupFilterWidgetEditComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "lookupWidgetRenderer", first: true, predicate: ["widgetRenderer"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
11089
- <ng-container
11090
- axp-widget-renderer
11091
- #widgetRenderer="widgetRenderer"
11092
- [node]="lookupNode()"
11093
- [mode]="'edit'"
11094
- ></ng-container>
11095
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: AXSelectBoxModule }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "ngmodule", type: AXValidationModule }, { kind: "ngmodule", type: AXFormModule }, { kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "directive", type: i3$1.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged", "onLoad"], exportAs: ["widgetRenderer"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
11096
- }
11097
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPLookupFilterWidgetEditComponent, decorators: [{
11098
- type: Component,
11099
- args: [{
11100
- template: `
11101
- <ng-container
11102
- axp-widget-renderer
11103
- #widgetRenderer="widgetRenderer"
11104
- [node]="lookupNode()"
11105
- [mode]="'edit'"
11106
- ></ng-container>
11107
- `,
11108
- changeDetection: ChangeDetectionStrategy.OnPush,
11109
- imports: [
11110
- FormsModule,
11111
- AXSelectBoxModule,
11112
- AXTextBoxModule,
11113
- AXButtonModule,
11114
- AXDecoratorModule,
11115
- AXLoadingModule,
11116
- AXValidationModule,
11117
- AXFormModule,
11118
- AXPWidgetCoreModule,
11119
- ],
11120
- }]
11121
- }], propDecorators: { lookupWidgetRenderer: [{ type: i0.ViewChild, args: ['widgetRenderer', { isSignal: true }] }] } });
11122
-
11123
- var lookupFilterWidgetEdit_component = /*#__PURE__*/Object.freeze({
11124
- __proto__: null,
11125
- AXPLookupFilterWidgetEditComponent: AXPLookupFilterWidgetEditComponent
11126
- });
11127
-
11128
- const AXPLookupFilterWidget = {
11129
- name: 'lookup-filter',
11130
- title: 'Lookup Filter',
11131
- // categories: AXP_WIDGETS_FILTER_CATEGORY,
11132
- type: 'filter',
11133
- groups: [AXPWidgetGroupEnum.EntityWidget],
11134
- icon: 'fa-light fa-square',
11135
- properties: [AXP_NAME_PROPERTY, AXP_DATA_PATH_PROPERTY, AXP_DISABLED_PROPERTY],
11136
- components: {
11137
- edit: {
11138
- component: () => Promise.resolve().then(function () { return lookupFilterWidgetEdit_component; }).then((c) => c.AXPLookupFilterWidgetEditComponent),
11139
- },
11140
- },
11141
- };
11142
-
11143
11344
  class AXPLookupWidgetViewComponent extends AXPValueWidgetComponent {
11144
11345
  constructor() {
11145
11346
  super(...arguments);
@@ -11853,7 +12054,7 @@ class AXPLookupWidgetTagboxComponent extends LookupWidgetLookBase {
11853
12054
  this.multiple = input.required(...(ngDevMode ? [{ debugName: "multiple" }] : []));
11854
12055
  this.isLoading = input.required(...(ngDevMode ? [{ debugName: "isLoading" }] : []));
11855
12056
  this.validationRules = input.required(...(ngDevMode ? [{ debugName: "validationRules" }] : []));
11856
- this.allowClear = input.required(...(ngDevMode ? [{ debugName: "allowClear" }] : []));
12057
+ this.hasClearButton = input(false, ...(ngDevMode ? [{ debugName: "hasClearButton" }] : []));
11857
12058
  // Entity and configuration data (for showSelector and searchByValue)
11858
12059
  this.entityDef = input.required(...(ngDevMode ? [{ debugName: "entityDef" }] : []));
11859
12060
  this.customFilter = input.required(...(ngDevMode ? [{ debugName: "customFilter" }] : []));
@@ -11902,7 +12103,6 @@ class AXPLookupWidgetTagboxComponent extends LookupWidgetLookBase {
11902
12103
  this.multipleValue = computed(() => this.multiple()(), ...(ngDevMode ? [{ debugName: "multipleValue" }] : []));
11903
12104
  this.isLoadingValue = computed(() => this.isLoading()(), ...(ngDevMode ? [{ debugName: "isLoadingValue" }] : []));
11904
12105
  this.validationRulesValue = computed(() => this.validationRules()(), ...(ngDevMode ? [{ debugName: "validationRulesValue" }] : []));
11905
- this.allowClearValue = computed(() => this.allowClear()(), ...(ngDevMode ? [{ debugName: "allowClearValue" }] : []));
11906
12106
  }
11907
12107
  #focusEffect;
11908
12108
  focus() {
@@ -12055,7 +12255,7 @@ class AXPLookupWidgetTagboxComponent extends LookupWidgetLookBase {
12055
12255
  refresh() {
12056
12256
  }
12057
12257
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPLookupWidgetTagboxComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
12058
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", 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 }, allowClear: { classPropertyName: "allowClear", publicName: "allowClear", isSignal: true, isRequired: true, 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 }, onSetLoading: { classPropertyName: "onSetLoading", publicName: "onSetLoading", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { valueChanged: "valueChanged" }, providers: [
12258
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", 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 }, hasClearButton: { classPropertyName: "hasClearButton", publicName: "hasClearButton", 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 }, onSetLoading: { classPropertyName: "onSetLoading", publicName: "onSetLoading", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { valueChanged: "valueChanged" }, providers: [
12059
12259
  {
12060
12260
  provide: LookupWidgetLookBase,
12061
12261
  useExisting: AXPLookupWidgetTagboxComponent,
@@ -12082,7 +12282,7 @@ class AXPLookupWidgetTagboxComponent extends LookupWidgetLookBase {
12082
12282
  [options]="validation.options"
12083
12283
  ></ax-validation-rule>
12084
12284
  }
12085
- @if (selectedItemsValue().length > 1 || allowClearValue()) {
12285
+ @if (selectedItemsValue().length > 1 || hasClearButton()) {
12086
12286
  <ax-clear-button ></ax-clear-button>
12087
12287
  }
12088
12288
 
@@ -12137,7 +12337,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
12137
12337
  [options]="validation.options"
12138
12338
  ></ax-validation-rule>
12139
12339
  }
12140
- @if (selectedItemsValue().length > 1 || allowClearValue()) {
12340
+ @if (selectedItemsValue().length > 1 || hasClearButton()) {
12141
12341
  <ax-clear-button ></ax-clear-button>
12142
12342
  }
12143
12343
 
@@ -12184,7 +12384,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
12184
12384
  }
12185
12385
  ],
12186
12386
  }]
12187
- }], 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 }] }], allowClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowClear", required: true }] }], 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 }] }], 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 }] }] } });
12387
+ }], 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 }] }], hasClearButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasClearButton", 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 }] }], 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 }] }] } });
12188
12388
 
12189
12389
  class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
12190
12390
  constructor() {
@@ -12206,16 +12406,11 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
12206
12406
  this.textField = computed(() => this.options()['textField'] ?? '', ...(ngDevMode ? [{ debugName: "textField" }] : []));
12207
12407
  this.hasClearButton = computed(() => this.options()['hasClearButton'] ?? false, ...(ngDevMode ? [{ debugName: "hasClearButton" }] : []));
12208
12408
  this.customFilter = computed(() => this.options()['filter'], ...(ngDevMode ? [{ debugName: "customFilter" }] : []));
12409
+ this.filterMode = computed(() => this.options()['filterMode'], ...(ngDevMode ? [{ debugName: "filterMode" }] : []));
12209
12410
  this.multiple = computed(() => (this.options()['multiple'] ?? false), ...(ngDevMode ? [{ debugName: "multiple" }] : []));
12210
12411
  this.look = computed(() => this.options()['look'] ?? 'lookup', ...(ngDevMode ? [{ debugName: "look" }] : []));
12211
- this.allowClear = computed(() => (this.options()['allowClear'] ?? false), ...(ngDevMode ? [{ debugName: "allowClear" }] : []));
12212
12412
  this.defaultTextField = computed(() => {
12213
- const list = [
12214
- 'title',
12215
- 'name',
12216
- 'code',
12217
- 'description',
12218
- ];
12413
+ const list = ['title', 'name', 'code', 'description'];
12219
12414
  const textField = list.find((c) => this.entityDef()?.properties.find((p) => p.name == c)) ?? 'title';
12220
12415
  return textField;
12221
12416
  }, ...(ngDevMode ? [{ debugName: "defaultTextField" }] : []));
@@ -12240,9 +12435,6 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
12240
12435
  const [module, entity] = this.entity().split('.');
12241
12436
  this.entityDef.set(await this.entityResolver.resolve(module, entity));
12242
12437
  }, ...(ngDevMode ? [{ debugName: "#efEntity" }] : []));
12243
- this.#efFilter = effect(async () => {
12244
- console.log('filter:', this.customFilter());
12245
- }, ...(ngDevMode ? [{ debugName: "#efFilter" }] : []));
12246
12438
  this.hasValue = (value) => (Array.isArray(value) && !isEmpty(value)) || !isNil(value);
12247
12439
  this.#efValue = effect(() => {
12248
12440
  const currentValue = this.getValue();
@@ -12277,7 +12469,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
12277
12469
  // Ensure items is always an array
12278
12470
  items = castArray(items);
12279
12471
  // Filter out null/undefined items
12280
- items = items.filter(item => item != null);
12472
+ items = items.filter((item) => item != null);
12281
12473
  this.selectedItems.set(items);
12282
12474
  //
12283
12475
  const keys = items.map((item) => get(item, this.valueField()));
@@ -12288,17 +12480,29 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
12288
12480
  this.expoesItems();
12289
12481
  }
12290
12482
  const newValue = this.singleOrMultiple(keys);
12291
- this.setValue(newValue);
12483
+ if (this.filterMode()) {
12484
+ this.setValue({
12485
+ value: newValue,
12486
+ displayText: text,
12487
+ operation: {
12488
+ type: this.multiple() ? 'in' : 'contains',
12489
+ },
12490
+ });
12491
+ }
12492
+ else {
12493
+ this.setValue(newValue);
12494
+ }
12292
12495
  };
12293
12496
  }
12294
12497
  #efEntity;
12295
- #efFilter;
12296
12498
  #efValue;
12297
12499
  async findByValue() {
12298
12500
  this.isLoading.set(true);
12299
12501
  const rawValue = this.getValue();
12300
12502
  // When multiple is true, ensure we always work with arrays
12301
- const values = this.multiple() ? castArray(rawValue) : [rawValue].filter(v => v != null);
12503
+ const values = this.multiple()
12504
+ ? castArray(this.filterMode() ? rawValue.value : rawValue)
12505
+ : [rawValue].filter((v) => v != null);
12302
12506
  if (!values.length) {
12303
12507
  this.setItems([]);
12304
12508
  this.isLoading.set(false);
@@ -12311,14 +12515,14 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
12311
12515
  if (this.multiple()) {
12312
12516
  const items = await Promise.all(values
12313
12517
  .map((value) => extractValue(value, this.valueField()))
12314
- .filter(id => id != null)
12518
+ .filter((id) => id != null)
12315
12519
  .map((id) => entityDataAccessor.byKey(id)));
12316
12520
  // Filter out null/undefined results
12317
- const validItems = items.filter(item => item != null);
12521
+ const validItems = items.filter((item) => item != null);
12318
12522
  this.setItems(validItems);
12319
12523
  }
12320
12524
  else {
12321
- const id = extractValue(values[0], this.valueField());
12525
+ const id = extractValue(this.filterMode() ? values[0].value : values[0], this.valueField());
12322
12526
  if (id != null) {
12323
12527
  const item = await entityDataAccessor.byKey(id);
12324
12528
  this.setItems(item != null ? [item] : []);
@@ -12445,7 +12649,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
12445
12649
  [multiple]="multiple"
12446
12650
  [isLoading]="isLoading"
12447
12651
  [validationRules]="validationRules"
12448
- [allowClear]="allowClear"
12652
+ [hasClearButton]="hasClearButton()"
12449
12653
  [entityDef]="entityDef"
12450
12654
  [customFilter]="customFilter"
12451
12655
  [columns]="columns"
@@ -12456,7 +12660,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
12456
12660
  }
12457
12661
  }
12458
12662
  }
12459
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AXPLookupWidgetSelectComponent, selector: "axp-lookup-widget-select", inputs: ["entityDef", "customFilter", "selectedItems", "displayField", "valueField", "disabled", "multiple", "validationRules", "hasClearButton"], outputs: ["valueChanged"] }, { kind: "component", type: AXPLookupWidgetTagboxComponent, selector: "axp-lookup-widget-tagbox", inputs: ["selectedItems", "displayField", "valueField", "displayFormat", "disabled", "multiple", "isLoading", "validationRules", "allowClear", "entityDef", "customFilter", "columns", "parentFilters", "onSetLoading"], outputs: ["valueChanged"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
12663
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AXPLookupWidgetSelectComponent, selector: "axp-lookup-widget-select", inputs: ["entityDef", "customFilter", "selectedItems", "displayField", "valueField", "disabled", "multiple", "validationRules", "hasClearButton"], outputs: ["valueChanged"] }, { kind: "component", type: AXPLookupWidgetTagboxComponent, selector: "axp-lookup-widget-tagbox", inputs: ["selectedItems", "displayField", "valueField", "displayFormat", "disabled", "multiple", "isLoading", "validationRules", "hasClearButton", "entityDef", "customFilter", "columns", "parentFilters", "onSetLoading"], outputs: ["valueChanged"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
12460
12664
  }
12461
12665
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPLookupWidgetEditComponent, decorators: [{
12462
12666
  type: Component,
@@ -12489,7 +12693,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
12489
12693
  [multiple]="multiple"
12490
12694
  [isLoading]="isLoading"
12491
12695
  [validationRules]="validationRules"
12492
- [allowClear]="allowClear"
12696
+ [hasClearButton]="hasClearButton()"
12493
12697
  [entityDef]="entityDef"
12494
12698
  [customFilter]="customFilter"
12495
12699
  [columns]="columns"
@@ -12502,11 +12706,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
12502
12706
  }
12503
12707
  `,
12504
12708
  changeDetection: ChangeDetectionStrategy.OnPush,
12505
- imports: [
12506
- CommonModule,
12507
- AXPLookupWidgetSelectComponent,
12508
- AXPLookupWidgetTagboxComponent,
12509
- ],
12709
+ imports: [CommonModule, AXPLookupWidgetSelectComponent, AXPLookupWidgetTagboxComponent],
12510
12710
  }]
12511
12711
  }], propDecorators: { componentLook: [{ type: i0.ViewChild, args: [i0.forwardRef(() => LookupWidgetLookBase), { isSignal: true }] }] } });
12512
12712
 
@@ -12632,7 +12832,7 @@ class AXPLookupWidgetColumnComponent extends AXPColumnWidgetComponent {
12632
12832
  return get(item, this.displayField()) ?? '';
12633
12833
  }
12634
12834
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPLookupWidgetColumnComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
12635
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: AXPLookupWidgetColumnComponent, isStandalone: true, selector: "ng-component", inputs: { rawValue: "rawValue", rowData: "rowData" }, viewQueries: [{ propertyName: "moreButton", first: true, predicate: ["moreButton"], descendants: true, isSignal: true }, { propertyName: "morePopover", first: true, predicate: ["morePopover"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"ax-flex ax-gap-1 ax-items-center\">\n @if (visibleItems().length > 0) {\n @for (item of visibleItems(); track $index) {\n <span class=\"ax-cursor-pointer hover:ax-text-primary hover:ax-underline\" (click)=\"handleItemClick($index)\">\n {{ getDisplayText(item) }}\n </span>\n @if ($index < visibleItems().length - 1) { <span class=\"ax-text-muted\">\u2022</span>\n }\n }\n } @else {\n <span class=\"ax-text-muted\">---</span>\n }\n\n @if (hasMoreItems()) {\n <span\n class=\"ax-absolute ax-flex ax-items-center ax-end-0 ax-px-1 ax-cursor-pointer ax-h-full hover:ax-primary-lighter\"\n (click)=\"showMoreItems()\" #moreButton>\n <i class=\"fa-light fa-ellipsis-vertical\"></i>\n </span>\n }\n</div>\n\n<!-- More Items Popover -->\n<ax-popover [openOn]=\"'manual'\" #morePopover (openChange)=\"onMorePopoverOpenChange($event)\">\n <div class=\"ax-lightest-surface ax-border ax-rounded-lg ax-shadow-lg ax-p-4 ax-min-w-[280px]\">\n <div class=\"ax-mb-4 ax-border-b ax-pb-2\">\n <h3 class=\"ax-text-base ax-font-semibold\">All {{ allItems().length }} Items</h3>\n </div>\n <div class=\"ax-max-h-64 ax-flex ax-flex-col ax-gap-3\">\n @for (item of allItems(); track $index) {\n <span class=\"ax-cursor-pointer hover:ax-text-primary hover:ax-underline\" (click)=\"showItemDetail(item, $index)\">\n {{ getDisplayText(item) }}\n </span>\n }\n </div>\n </div>\n</ax-popover>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i2.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
12835
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: AXPLookupWidgetColumnComponent, isStandalone: true, selector: "ng-component", inputs: { rawValue: "rawValue", rowData: "rowData" }, viewQueries: [{ propertyName: "moreButton", first: true, predicate: ["moreButton"], descendants: true, isSignal: true }, { propertyName: "morePopover", first: true, predicate: ["morePopover"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"ax-flex ax-gap-1 ax-items-center\">\n @if (visibleItems().length > 0) {\n @for (item of visibleItems(); track $index) {\n <span class=\"ax-cursor-pointer hover:ax-text-primary hover:ax-underline\" (click)=\"handleItemClick($index)\">\n {{ getDisplayText(item) }}\n </span>\n @if ($index < visibleItems().length - 1) { <span class=\"ax-text-muted\">\u2022</span>\n }\n }\n } @else {\n <span class=\"ax-text-muted\">---</span>\n }\n\n @if (hasMoreItems()) {\n <span\n class=\"ax-absolute ax-flex ax-items-center ax-end-0 ax-px-1 ax-cursor-pointer ax-h-full hover:ax-primary-lighter\"\n (click)=\"showMoreItems()\" #moreButton>\n <i class=\"fa-light fa-ellipsis-vertical\"></i>\n </span>\n }\n</div>\n\n<!-- More Items Popover -->\n<ax-popover [openOn]=\"'manual'\" #morePopover (openChange)=\"onMorePopoverOpenChange($event)\">\n <div class=\"ax-lightest-surface ax-border ax-rounded-lg ax-shadow-lg ax-p-4 ax-min-w-[280px]\">\n <div class=\"ax-mb-4 ax-border-b ax-pb-2\">\n <h3 class=\"ax-text-base ax-font-semibold\">All {{ allItems().length }} Items</h3>\n </div>\n <div class=\"ax-max-h-64 ax-flex ax-flex-col ax-gap-3\">\n @for (item of allItems(); track $index) {\n <span class=\"ax-cursor-pointer hover:ax-text-primary hover:ax-underline\" (click)=\"showItemDetail(item, $index)\">\n {{ getDisplayText(item) }}\n </span>\n }\n </div>\n </div>\n</ax-popover>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i2.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "repositionOnScroll", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
12636
12836
  }
12637
12837
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPLookupWidgetColumnComponent, decorators: [{
12638
12838
  type: Component,
@@ -14461,6 +14661,12 @@ class AXPEntityModule {
14461
14661
  useValue: defaultColumnWidthProvider,
14462
14662
  multi: true,
14463
14663
  },
14664
+ // Entities list data source (all entity names from registry)
14665
+ {
14666
+ provide: AXP_DATASOURCE_DEFINITION_PROVIDER,
14667
+ useClass: AXPEntitiesListDataSourceDefinition,
14668
+ multi: true,
14669
+ },
14464
14670
  // {
14465
14671
  // provide: AXP_ENTITY_MODIFIER,
14466
14672
  // useValue: layoutOrderingMiddlewareProvider,
@@ -14519,12 +14725,23 @@ class AXPEntityModule {
14519
14725
  functions: {},
14520
14726
  }),
14521
14727
  AXPWidgetCoreModule.forChild({
14522
- widgets: [
14523
- AXPLookupWidget,
14524
- AXPLookupFilterWidget,
14525
- AXPEntityListWidget,
14526
- AXPEntityCategoryWidget,
14527
- AXPMultiSourceSelectorWidget,
14728
+ widgets: [AXPLookupWidget, AXPEntityListWidget, AXPEntityCategoryWidget, AXPMultiSourceSelectorWidget],
14729
+ extendedWidgets: [
14730
+ {
14731
+ parentName: AXPLookupWidget.name,
14732
+ widget: {
14733
+ name: 'lookup-filter',
14734
+ title: 'Lookup Filter',
14735
+ categories: AXP_WIDGETS_EDITOR_CATEGORY,
14736
+ groups: [AXPWidgetGroupEnum.EntityWidget],
14737
+ type: 'filter',
14738
+ components: {},
14739
+ options: {
14740
+ look: 'select',
14741
+ filterMode: true,
14742
+ },
14743
+ },
14744
+ },
14528
14745
  ],
14529
14746
  })] }); }
14530
14747
  }
@@ -14561,12 +14778,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
14561
14778
  functions: {},
14562
14779
  }),
14563
14780
  AXPWidgetCoreModule.forChild({
14564
- widgets: [
14565
- AXPLookupWidget,
14566
- AXPLookupFilterWidget,
14567
- AXPEntityListWidget,
14568
- AXPEntityCategoryWidget,
14569
- AXPMultiSourceSelectorWidget,
14781
+ widgets: [AXPLookupWidget, AXPEntityListWidget, AXPEntityCategoryWidget, AXPMultiSourceSelectorWidget],
14782
+ extendedWidgets: [
14783
+ {
14784
+ parentName: AXPLookupWidget.name,
14785
+ widget: {
14786
+ name: 'lookup-filter',
14787
+ title: 'Lookup Filter',
14788
+ categories: AXP_WIDGETS_EDITOR_CATEGORY,
14789
+ groups: [AXPWidgetGroupEnum.EntityWidget],
14790
+ type: 'filter',
14791
+ components: {},
14792
+ options: {
14793
+ look: 'select',
14794
+ filterMode: true,
14795
+ },
14796
+ },
14797
+ },
14570
14798
  ],
14571
14799
  }),
14572
14800
  ],
@@ -14606,6 +14834,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
14606
14834
  useValue: defaultColumnWidthProvider,
14607
14835
  multi: true,
14608
14836
  },
14837
+ // Entities list data source (all entity names from registry)
14838
+ {
14839
+ provide: AXP_DATASOURCE_DEFINITION_PROVIDER,
14840
+ useClass: AXPEntitiesListDataSourceDefinition,
14841
+ multi: true,
14842
+ },
14609
14843
  // {
14610
14844
  // provide: AXP_ENTITY_MODIFIER,
14611
14845
  // useValue: layoutOrderingMiddlewareProvider,
@@ -14723,18 +14957,22 @@ function entityMasterCreateAction() {
14723
14957
  title: '@general:actions.create.title',
14724
14958
  command: {
14725
14959
  name: 'Entity:Create',
14726
- // options: {
14727
- // process: {
14728
- // redirect: true,
14729
- // canCreateNewOne: true,
14730
- // },
14731
- // },
14732
14960
  },
14733
14961
  priority: 'primary',
14734
14962
  type: AXPSystemActionType.Create,
14735
14963
  scope: AXPEntityCommandScope.TypeLevel,
14736
14964
  };
14737
14965
  }
14966
+ function entityMasterEditAction() {
14967
+ return {
14968
+ title: '@general:actions.edit.title',
14969
+ command: 'Entity:Update',
14970
+ priority: 'secondary',
14971
+ type: AXPSystemActionType.Update,
14972
+ scope: AXPEntityCommandScope.Individual,
14973
+ default: true,
14974
+ };
14975
+ }
14738
14976
  function entityMasterBulkDeleteAction() {
14739
14977
  return {
14740
14978
  title: '@general:actions.delete-items.title',
@@ -14784,10 +15022,9 @@ function entityMasterCrudActions(options) {
14784
15022
  if (opts.view) {
14785
15023
  actions.push(entityMasterViewAction());
14786
15024
  }
14787
- // TODO: Add edit action
14788
- // if (opts.edit) {
14789
- // actions.push(entityMasterViewAction());
14790
- // }
15025
+ if (opts.edit) {
15026
+ actions.push(entityMasterEditAction());
15027
+ }
14791
15028
  return actions;
14792
15029
  }
14793
15030
  function entityMasterRecordActions() {
@@ -14953,5 +15190,5 @@ function detectEntityChanges(oldObj, newObj) {
14953
15190
  * Generated bundle index. Do not edit.
14954
15191
  */
14955
15192
 
14956
- export { AXMEntityCrudService, AXMEntityCrudServiceImpl, AXPCategoryTreeService, AXPCreateEntityCommand, AXPCreateEntityWorkflow, AXPDataSeederService, AXPDeleteEntityWorkflow, AXPEntityApplyUpdatesAction, AXPEntityCategoryTreeSelectorComponent, AXPEntityCategoryWidget, AXPEntityCategoryWidgetColumnComponent, AXPEntityCategoryWidgetEditComponent, AXPEntityCategoryWidgetViewComponent, AXPEntityCommandTriggerViewModel, AXPEntityCreateEvent, AXPEntityCreatePopupAction, AXPEntityCreateSubmittedAction, AXPEntityCreateViewElementViewModel, AXPEntityCreateViewModelFactory, AXPEntityCreateViewSectionViewModel, AXPEntityDataProvider, AXPEntityDataProviderImpl, AXPEntityDataSelectorService, AXPEntityDefinitionRegistryService, AXPEntityDeletedEvent, AXPEntityDetailListViewModel, AXPEntityDetailPopoverComponent, AXPEntityDetailPopoverService, AXPEntityDetailViewModelFactory, AXPEntityDetailViewModelResolver, 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, AXPLookupFilterWidget, AXPLookupFilterWidgetEditComponent, 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, entityMasterRecordActions, entityMasterViewAction, entityOverrideDetailsViewAction, eventDispatchMiddleware, isAXPMiddlewareAbortError, layoutOrderingMiddlewareFactory, layoutOrderingMiddlewareProvider };
15193
+ 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 };
14957
15194
  //# sourceMappingURL=acorex-platform-layout-entity.mjs.map