@acorex/platform 20.2.4-next.2 → 20.2.4-next.3

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 (28) hide show
  1. package/common/index.d.ts +9 -1
  2. package/fesm2022/acorex-platform-common.mjs.map +1 -1
  3. package/fesm2022/acorex-platform-layout-builder.mjs +1 -0
  4. package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
  5. package/fesm2022/acorex-platform-layout-components.mjs +26 -36
  6. package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
  7. package/fesm2022/acorex-platform-layout-entity.mjs +467 -223
  8. package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
  9. package/fesm2022/acorex-platform-layout-views.mjs +37 -24
  10. package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
  11. package/fesm2022/{acorex-platform-themes-default-entity-master-list-view.component-DXGLsVis.mjs → acorex-platform-themes-default-entity-master-list-view.component-e3Lxk5ZT.mjs} +3 -3
  12. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-e3Lxk5ZT.mjs.map +1 -0
  13. package/fesm2022/acorex-platform-themes-default.mjs +3 -3
  14. package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
  15. package/fesm2022/acorex-platform-themes-shared.mjs +1 -1
  16. package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
  17. package/fesm2022/{acorex-platform-widgets-file-list-popup.component-B601gPsW.mjs → acorex-platform-widgets-file-list-popup.component-BafU5Lfl.mjs} +4 -2
  18. package/fesm2022/acorex-platform-widgets-file-list-popup.component-BafU5Lfl.mjs.map +1 -0
  19. package/fesm2022/acorex-platform-widgets.mjs +49 -15
  20. package/fesm2022/acorex-platform-widgets.mjs.map +1 -1
  21. package/layout/builder/index.d.ts +1 -0
  22. package/layout/components/index.d.ts +1 -5
  23. package/layout/entity/index.d.ts +2 -2
  24. package/layout/views/index.d.ts +6 -0
  25. package/package.json +5 -5
  26. package/widgets/index.d.ts +8 -0
  27. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-DXGLsVis.mjs.map +0 -1
  28. package/fesm2022/acorex-platform-widgets-file-list-popup.component-B601gPsW.mjs.map +0 -1
@@ -10,7 +10,7 @@ import { AXPExpressionEvaluatorService, AXPPlatformScope, AXPDistributedEventLis
10
10
  import * as i2$2 from '@acorex/platform/workflow';
11
11
  import { AXPWorkflowService, ofType, createWorkFlowEvent, AXPWorkflowAction, AXPWorkflowModule } from '@acorex/platform/workflow';
12
12
  import * as i2 from '@acorex/platform/layout/builder';
13
- import { AXPPageStatus, AXPWidgetRegistryService, AXPWidgetsCatalog, AXPValueWidgetComponent, AXPWidgetContainerComponent, AXPWidgetRendererDirective, AXPLayoutBuilderModule, AXPWidgetGroupEnum, AXPLayoutWidgetComponent, AXPColumnWidgetComponent, AXP_WIDGETS_EDITOR_CATEGORY } from '@acorex/platform/layout/builder';
13
+ import { AXPPageStatus, AXPWidgetRegistryService, AXPWidgetsCatalog, AXPValueWidgetComponent, AXPWidgetRendererDirective, AXPLayoutBuilderModule, AXPWidgetGroupEnum, AXPLayoutWidgetComponent, AXPColumnWidgetComponent, AXP_WIDGETS_EDITOR_CATEGORY } from '@acorex/platform/layout/builder';
14
14
  import { AXPLayoutThemeService } from '@acorex/platform/themes/shared';
15
15
  import { Subject, takeUntil } from 'rxjs';
16
16
  import { AXPSessionService, AXPAuthGuard } from '@acorex/platform/auth';
@@ -265,7 +265,6 @@ class AXPEntityDetailListViewModel {
265
265
  }, ...(ngDevMode ? [{ debugName: "columns" }] : []));
266
266
  this.evaluateExpressions = async (actionData) => {
267
267
  const parentData = this.parent.data;
268
- console.log({ actionData, parentData });
269
268
  const scope = {
270
269
  context: {
271
270
  eval: (path) => {
@@ -1157,10 +1156,28 @@ class AXPEntityMasterListViewModel {
1157
1156
  const visibleProperties = properties.filter(({ schema }) => !schema?.hidden);
1158
1157
  const visiblePropNames = new Set(visibleProperties.map(({ name }) => name));
1159
1158
  return columns
1160
- .filter(({ name }) => visiblePropNames.has(name))
1159
+ .filter(({ name, showAs }) => visiblePropNames.has(name) || showAs)
1161
1160
  .map((column) => {
1162
- const property = visibleProperties.find(({ name }) => name === column.name);
1163
- return new AXPEntityListViewColumnViewModel(property, column);
1161
+ if (column.showAs) {
1162
+ const widgetConfig = this.widgetResolver.resolve(column.showAs.type);
1163
+ const property = {
1164
+ ...widgetConfig,
1165
+ name: column.name,
1166
+ title: column.title ?? '',
1167
+ schema: {
1168
+ dataType: 'string',
1169
+ interface: {
1170
+ type: column.showAs.type,
1171
+ options: column.showAs.options,
1172
+ },
1173
+ },
1174
+ };
1175
+ return new AXPEntityListViewColumnViewModel(property, column);
1176
+ }
1177
+ else {
1178
+ const property = visibleProperties.find(({ name }) => name === column.name);
1179
+ return new AXPEntityListViewColumnViewModel(property, column);
1180
+ }
1164
1181
  });
1165
1182
  };
1166
1183
  this.visibleColumnCount = () => {
@@ -1459,8 +1476,7 @@ class AXPEntityMasterListViewModel {
1459
1476
  const cols = this.view().columns;
1460
1477
  const cloned = this.allAvailableColumns().map((c) => {
1461
1478
  const column = this.entityDef.columns?.find((cc) => cc.name == c.name);
1462
- const prop = this.entityDef.properties.find((p) => p.name == c.name);
1463
- const col = new AXPEntityListViewColumnViewModel(prop, column);
1479
+ const col = new AXPEntityListViewColumnViewModel(c.property, column);
1464
1480
  col.visible = !cols.some((c) => c == col.name) && col.visible != false;
1465
1481
  return col;
1466
1482
  });
@@ -2556,9 +2572,14 @@ class AXPLayoutAdapterBuilder {
2556
2572
  this.adapter.pages = [...(this.adapter.pages || []), ...relatedPages];
2557
2573
  return this;
2558
2574
  }
2575
+ setPages(pages) {
2576
+ this.adapter.pages = pages;
2577
+ return this;
2578
+ }
2559
2579
  build() {
2560
2580
  return {
2561
- title: this.entity?.formats.plural || this.entity?.title,
2581
+ title: `${this.entity?.interfaces?.master?.single?.title}`,
2582
+ label: this.entity?.formats.plural,
2562
2583
  actions: [],
2563
2584
  breadcrumbs: this.createBreadcrumbs(),
2564
2585
  execute: this.createExecuteFunction(),
@@ -2655,40 +2676,29 @@ class AXPBaseRelatedEntityConverter {
2655
2676
  groups,
2656
2677
  };
2657
2678
  }
2658
- createGridLayoutStructure(singleInterface, helpers) {
2659
- return {
2660
- type: 'grid-layout',
2661
- options: {
2662
- grid: {
2663
- default: {
2664
- gridTemplateColumns: 'repeat(12, 1fr)',
2665
- gridTemplateRows: 'repeat(1, 1fr)',
2666
- gap: '20px',
2667
- },
2668
- },
2669
- },
2670
- children: singleInterface?.sections.map((s) => ({
2671
- type: 'grid-item-layout',
2672
- name: s.id,
2673
- options: {
2674
- colSpan: s.layout?.positions?.lg?.colSpan ?? 12,
2675
- colStart: s.layout?.positions?.lg?.colStart,
2676
- colEnd: s.layout?.positions?.lg?.colEnd,
2677
- },
2678
- children: [
2679
- {
2680
- type: 'fieldset-layout',
2681
- options: {
2682
- title: helpers.getGroupById(s.id)?.title ?? '',
2683
- collapsible: true,
2684
- },
2685
- children: [this.createPropertyGrid(s.id, helpers)],
2686
- },
2687
- ],
2688
- })),
2689
- };
2679
+ async createGridLayoutStructure(singleInterface, helpers, evaluateExpressions) {
2680
+ return await this.createGridLayoutStructureInternal(singleInterface, helpers, evaluateExpressions);
2690
2681
  }
2691
- createPropertyGrid(sectionId, helpers) {
2682
+ //#region ---- Hidden Evaluation Helpers ----
2683
+ async getVisiblePropertiesByGroupId(sectionId, helpers, evaluateExpressions) {
2684
+ const properties = helpers.getPropertyByGroupId(sectionId) ?? [];
2685
+ const evaluated = await Promise.all(properties.map(async (property) => {
2686
+ let hidden = property?.schema?.hidden;
2687
+ if (typeof hidden === 'string' && evaluateExpressions) {
2688
+ try {
2689
+ const result = await evaluateExpressions({ hidden });
2690
+ hidden = result.hidden;
2691
+ }
2692
+ catch {
2693
+ hidden = false;
2694
+ }
2695
+ }
2696
+ return { property, hidden: !!hidden };
2697
+ }));
2698
+ return evaluated.filter((x) => !x.hidden).map((x) => x.property);
2699
+ }
2700
+ async createPropertyGrid(sectionId, helpers, evaluateExpressions) {
2701
+ const visibleProperties = await this.getVisiblePropertiesByGroupId(sectionId, helpers, evaluateExpressions);
2692
2702
  return {
2693
2703
  type: 'grid-layout',
2694
2704
  mode: 'edit',
@@ -2701,10 +2711,7 @@ class AXPBaseRelatedEntityConverter {
2701
2711
  },
2702
2712
  },
2703
2713
  },
2704
- children: helpers
2705
- .getPropertyByGroupId(sectionId)
2706
- .filter((property) => !property.schema.hidden)
2707
- .map((p) => {
2714
+ children: visibleProperties.map((p) => {
2708
2715
  const layout = helpers.getPropertyLayout(p.name);
2709
2716
  return {
2710
2717
  type: 'grid-item-layout',
@@ -2719,6 +2726,7 @@ class AXPBaseRelatedEntityConverter {
2719
2726
  type: 'form-field',
2720
2727
  options: {
2721
2728
  label: p.title,
2729
+ showLabel: layout?.label?.visible ?? true,
2722
2730
  },
2723
2731
  children: [
2724
2732
  {
@@ -2738,6 +2746,39 @@ class AXPBaseRelatedEntityConverter {
2738
2746
  }),
2739
2747
  };
2740
2748
  }
2749
+ async createGridLayoutStructureInternal(singleInterface, helpers, evaluateExpressions) {
2750
+ return {
2751
+ type: 'grid-layout',
2752
+ options: {
2753
+ grid: {
2754
+ default: {
2755
+ gridTemplateColumns: 'repeat(12, 1fr)',
2756
+ gridTemplateRows: 'repeat(1, 1fr)',
2757
+ gap: '20px',
2758
+ },
2759
+ },
2760
+ },
2761
+ children: await Promise.all(singleInterface?.sections.map(async (s) => ({
2762
+ type: 'grid-item-layout',
2763
+ name: s.id,
2764
+ options: {
2765
+ colSpan: s.layout?.positions?.lg?.colSpan ?? 12,
2766
+ colStart: s.layout?.positions?.lg?.colStart,
2767
+ colEnd: s.layout?.positions?.lg?.colEnd,
2768
+ },
2769
+ children: [
2770
+ {
2771
+ type: 'fieldset-layout',
2772
+ options: {
2773
+ title: helpers.getGroupById(s.id)?.title ?? '',
2774
+ collapsible: true,
2775
+ },
2776
+ children: [await this.createPropertyGrid(s.id, helpers, evaluateExpressions)],
2777
+ },
2778
+ ],
2779
+ }))),
2780
+ };
2781
+ }
2741
2782
  }
2742
2783
 
2743
2784
  class AXPPageDetailsConverter extends AXPBaseRelatedEntityConverter {
@@ -2754,17 +2795,25 @@ class AXPPageDetailsConverter extends AXPBaseRelatedEntityConverter {
2754
2795
  };
2755
2796
  return await context.expressionEvaluator.evaluate(actionData, scope);
2756
2797
  };
2798
+ // Build related tabs for the related entity page (mirrors main-entity tab building)
2799
+ const tabDetailEntities = entityDef?.relatedEntities?.filter((re) => !re.hidden && re.layout?.type === 'tab-detail');
2800
+ const tabListEntities = entityDef?.relatedEntities?.filter((re) => !re.hidden && (!re.layout?.type || re.layout?.type === 'tab-list'));
2801
+ const factory = new AXPRelatedEntityConverterFactory();
2802
+ const tabDetailTabs = await this.buildTabDetails(factory, tabDetailEntities ?? [], context);
2803
+ const tabListTabs = await this.buildTabLists(factory, tabListEntities ?? [], context);
2757
2804
  return {
2758
2805
  id: entityDef?.name ?? '',
2759
- title: relatedEntity.title ?? entityDef?.title ?? '',
2806
+ title: `${context.rootTitle}`,
2760
2807
  label: relatedEntity.title ?? entityDef?.formats.displayName ?? '',
2761
2808
  icon: relatedEntity.icon || entityDef.icon,
2762
2809
  settings: this.createPageSettings(),
2763
2810
  load: this.createLoadFunction(entityDef, relatedEntity, evaluateExpressions),
2764
2811
  execute: this.createExecuteFunction(entityDef),
2765
- content: [this.createGridLayoutStructure(helpers.singleInterface, helpers)],
2812
+ // tabs: [...tabDetailTabs, ...tabListTabs],
2813
+ content: [await this.createGridLayoutStructure(helpers.singleInterface, helpers, evaluateExpressions)],
2766
2814
  };
2767
2815
  }
2816
+ //#region ---- Utility Methods ----
2768
2817
  createPageSettings() {
2769
2818
  return {
2770
2819
  commands: {
@@ -2787,7 +2836,7 @@ class AXPPageDetailsConverter extends AXPBaseRelatedEntityConverter {
2787
2836
  return async (context) => {
2788
2837
  const fn = entityDef?.queries.byKey?.execute;
2789
2838
  const conditionValues = relatedEntity.conditions?.map((c) => c.value) ?? [];
2790
- const evaluatedConditionValues = await evaluateExpressions(conditionValues);
2839
+ const evaluatedConditionValues = await Promise.all(conditionValues.map((c) => evaluateExpressions(c)));
2791
2840
  const id = evaluatedConditionValues[0];
2792
2841
  const result = await fn(id);
2793
2842
  return { success: true, result };
@@ -2808,6 +2857,42 @@ class AXPPageDetailsConverter extends AXPBaseRelatedEntityConverter {
2808
2857
  }
2809
2858
  };
2810
2859
  }
2860
+ //#endregion
2861
+ //#region ---- Tab Builders ----
2862
+ /**
2863
+ * Builds tab-detail items for a related entity page using the shared converters.
2864
+ */
2865
+ async buildTabDetails(factory, tabDetailEntities, ctx) {
2866
+ if (!ctx?.entityResolver || !tabDetailEntities?.length) {
2867
+ return [];
2868
+ }
2869
+ const tabs = [];
2870
+ for (const re of tabDetailEntities) {
2871
+ const converter = factory.createTabDetailsConverter();
2872
+ tabs.push(await converter.convert(re, {
2873
+ entityResolver: ctx.entityResolver,
2874
+ }));
2875
+ }
2876
+ return tabs;
2877
+ }
2878
+ /**
2879
+ * Builds tab-list items for a related entity page using the shared converters with context-aware filters/actions.
2880
+ */
2881
+ async buildTabLists(factory, tabListEntities, ctx) {
2882
+ if (!ctx?.entityResolver || !tabListEntities?.length) {
2883
+ return [];
2884
+ }
2885
+ const tabs = [];
2886
+ for (const re of tabListEntities) {
2887
+ const converter = factory.createTabListConverter();
2888
+ tabs.push(await converter.convert(re, {
2889
+ entityResolver: ctx.entityResolver,
2890
+ expressionEvaluator: ctx.expressionEvaluator,
2891
+ context: ctx.context,
2892
+ }));
2893
+ }
2894
+ return tabs;
2895
+ }
2811
2896
  }
2812
2897
 
2813
2898
  class AXPPageListConverter extends AXPBaseRelatedEntityConverter {
@@ -2823,6 +2908,7 @@ class AXPPageListConverter extends AXPBaseRelatedEntityConverter {
2823
2908
  };
2824
2909
  return await context.expressionEvaluator.evaluate(actionData, scope);
2825
2910
  };
2911
+ const evaluatedActions = await evaluateExpressions(relatedEntity?.actions);
2826
2912
  const filters = relatedEntity.conditions?.map(async (c) => {
2827
2913
  const value = await evaluateExpressions(c.value);
2828
2914
  return {
@@ -2837,17 +2923,13 @@ class AXPPageListConverter extends AXPBaseRelatedEntityConverter {
2837
2923
  title: `${context.rootTitle}`,
2838
2924
  label: relatedEntity.title,
2839
2925
  icon: relatedEntity.icon || entityDef.icon,
2840
- actions: this.mergeActions(entityDef, relatedEntity)
2926
+ actions: this.mergeActions(entityDef, evaluatedActions)
2841
2927
  ?.filter((a) => a.priority === 'primary')
2842
2928
  ?.map((a) => {
2843
2929
  return {
2844
2930
  ...a,
2845
2931
  zone: 'header',
2846
- // visible:
2847
- // a.scope === AXPEntityCommandScope.Selected
2848
- // ? "{{widget.find('table').outputs().selectedItem().length > 0}}"
2849
- // : true,
2850
- visible: '{{context.eval("table")}}',
2932
+ visible: !a.hidden,
2851
2933
  priority: 'primary',
2852
2934
  name: a.name,
2853
2935
  title: a.title,
@@ -2865,7 +2947,7 @@ class AXPPageListConverter extends AXPBaseRelatedEntityConverter {
2865
2947
  execute: async (command, executeContext) => {
2866
2948
  try {
2867
2949
  const commandName = command.name.split('&')[0];
2868
- const mergedActions = this.mergeActions(entityDef, relatedEntity);
2950
+ const mergedActions = this.mergeActions(entityDef, evaluatedActions);
2869
2951
  const action = mergedActions.find((a) => {
2870
2952
  return a.name === commandName || a.name.split('&')[0] === commandName;
2871
2953
  });
@@ -2880,10 +2962,6 @@ class AXPPageListConverter extends AXPBaseRelatedEntityConverter {
2880
2962
  },
2881
2963
  };
2882
2964
  }
2883
- let evaluatedOptions = command.options;
2884
- if (action.options) {
2885
- evaluatedOptions = await evaluateExpressions(action.options);
2886
- }
2887
2965
  await context.workflowService.execute(commandName, {
2888
2966
  entity: getEntityInfo(entityDef).source,
2889
2967
  entityInfo: {
@@ -2895,8 +2973,8 @@ class AXPPageListConverter extends AXPBaseRelatedEntityConverter {
2895
2973
  },
2896
2974
  data: action.scope == AXPEntityCommandScope.Selected
2897
2975
  ? executeContext
2898
- : evaluatedOptions?.['process']?.data || null,
2899
- options: evaluatedOptions,
2976
+ : action.options?.['process']?.data || null,
2977
+ options: action.options,
2900
2978
  metadata: action.metadata,
2901
2979
  });
2902
2980
  return { success: true };
@@ -2925,14 +3003,15 @@ class AXPPageListConverter extends AXPBaseRelatedEntityConverter {
2925
3003
  options: {
2926
3004
  entity: relatedEntity.entity,
2927
3005
  showEntityActions: false,
3006
+ actions: evaluatedActions,
2928
3007
  },
2929
3008
  },
2930
3009
  ],
2931
3010
  };
2932
3011
  }
2933
- mergeActions(entityDef, relatedEntity) {
3012
+ mergeActions(entityDef, relatedEntityActions) {
2934
3013
  const originalList = entityDef?.interfaces?.master?.list?.actions ?? [];
2935
- const relatedEntityActionList = relatedEntity.actions ?? [];
3014
+ const relatedEntityActionList = relatedEntityActions ?? [];
2936
3015
  // Create a map to track which actions from relatedEntityActionList have been used
2937
3016
  const usedOverrideActions = new Set();
2938
3017
  // Start with original actions, applying overrides where they exist
@@ -2969,7 +3048,7 @@ class AXPTabDetailsConverter extends AXPBaseRelatedEntityConverter {
2969
3048
  id: entityDef?.name ?? '',
2970
3049
  title: relatedEntity.title ?? entityDef?.title ?? '',
2971
3050
  icon: relatedEntity.icon || entityDef.icon,
2972
- content: [this.createGridLayoutStructure(helpers.singleInterface, helpers)],
3051
+ content: [await this.createGridLayoutStructure(helpers.singleInterface, helpers)],
2973
3052
  };
2974
3053
  }
2975
3054
  }
@@ -3077,30 +3156,46 @@ class AXPMainEntityContentBuilder {
3077
3156
  return groups.some((group) => group.id === section.id);
3078
3157
  }) ?? []);
3079
3158
  };
3080
- const getPropertyByGroupId = (groupId) => {
3081
- return entity?.properties.filter((p) => p.groupId === groupId) ?? [];
3159
+ // Create expression evaluator for actions
3160
+ const evaluateExpressions = dependencies?.expressionEvaluator
3161
+ ? this.createExpressionEvaluator(rootContext, dependencies.expressionEvaluator)
3162
+ : null;
3163
+ const getVisiblePropertyByGroupId = async (groupId) => {
3164
+ const properties = entity?.properties.filter((p) => p.groupId === groupId) ?? [];
3165
+ const evaluated = await Promise.all(properties.map(async (p) => {
3166
+ // If you later need expression-based hidden logic, evaluate it here
3167
+ let hidden = p?.schema?.hidden;
3168
+ if (typeof hidden === 'string' && evaluateExpressions) {
3169
+ try {
3170
+ const res = await evaluateExpressions({ hidden });
3171
+ hidden = res.hidden;
3172
+ }
3173
+ catch {
3174
+ hidden = false;
3175
+ }
3176
+ }
3177
+ return { prop: p, hidden: !!hidden };
3178
+ }));
3179
+ return evaluated.filter((x) => !x.hidden).map((x) => x.prop);
3082
3180
  };
3083
3181
  const getPropertyLayout = (name) => {
3084
3182
  return singleInterface?.properties?.find((p) => p.name === name)?.layout;
3085
3183
  };
3086
3184
  // Get related entities for tabs
3087
- const tabDetailEntities = entity?.relatedEntities?.filter((re) => !re.hidden && re.layoutType === 'tab-detail');
3088
- const tabListEntities = entity?.relatedEntities?.filter((re) => !re.hidden && (!re.layoutType || re.layoutType === 'tab-list'));
3185
+ const tabDetailEntities = entity?.relatedEntities?.filter((re) => !re.hidden && re.layout?.type === 'tab-detail');
3186
+ const tabListEntities = entity?.relatedEntities?.filter((re) => !re.hidden && (!re.layout?.type || re.layout?.type === 'tab-list'));
3089
3187
  // Build related tabs if dependencies are provided
3090
3188
  const tabDetailTabs = await this.buildTabDetails(tabDetailEntities ?? [], dependencies);
3091
3189
  const tabListTabs = await this.buildTabLists(tabListEntities ?? [], rootContext, dependencies);
3092
3190
  // Build actions from single interface
3093
3191
  const actions = this.buildActions(entity, singleInterface);
3094
- // Create expression evaluator for actions
3095
- const evaluateExpressions = dependencies?.expressionEvaluator
3096
- ? this.createExpressionEvaluator(rootContext, dependencies.expressionEvaluator)
3097
- : null;
3098
3192
  return {
3099
3193
  id: entity?.name ?? '',
3100
3194
  title: singleInterface?.title ?? entity?.formats.individual ?? '',
3101
3195
  label: entity?.formats.displayName ?? singleInterface?.title ?? '',
3102
3196
  icon: entity?.icon,
3103
3197
  actions: await this.buildEvaluatedActions(actions, evaluateExpressions),
3198
+ isPrimary: true,
3104
3199
  settings: {
3105
3200
  commands: {
3106
3201
  reject: {
@@ -3197,7 +3292,7 @@ class AXPMainEntityContentBuilder {
3197
3292
  },
3198
3293
  },
3199
3294
  },
3200
- children: filterValidSections(singleInterface?.sections ?? []).map((s) => ({
3295
+ children: await Promise.all(filterValidSections(singleInterface?.sections ?? []).map(async (s) => ({
3201
3296
  type: 'grid-item-layout',
3202
3297
  name: s.id,
3203
3298
  options: {
@@ -3225,9 +3320,7 @@ class AXPMainEntityContentBuilder {
3225
3320
  },
3226
3321
  },
3227
3322
  },
3228
- children: getPropertyByGroupId(s.id)
3229
- .filter((property) => !property.schema.hidden)
3230
- .map((p) => {
3323
+ children: (await getVisiblePropertyByGroupId(s.id)).map((p) => {
3231
3324
  const layout = getPropertyLayout(p.name);
3232
3325
  return {
3233
3326
  type: 'grid-item-layout',
@@ -3242,6 +3335,7 @@ class AXPMainEntityContentBuilder {
3242
3335
  type: 'form-field',
3243
3336
  options: {
3244
3337
  label: p.title,
3338
+ showLabel: layout?.label?.visible ?? true,
3245
3339
  },
3246
3340
  children: [
3247
3341
  {
@@ -3269,7 +3363,7 @@ class AXPMainEntityContentBuilder {
3269
3363
  ],
3270
3364
  },
3271
3365
  ],
3272
- })),
3366
+ }))),
3273
3367
  },
3274
3368
  ],
3275
3369
  };
@@ -3283,7 +3377,8 @@ class AXPMainEntityContentBuilder {
3283
3377
  const scope = {
3284
3378
  context: {
3285
3379
  eval: (path) => {
3286
- return get(context, path);
3380
+ const value = get(context, path);
3381
+ return value;
3287
3382
  },
3288
3383
  },
3289
3384
  };
@@ -3395,11 +3490,15 @@ class AXPLayoutAdapterFactory {
3395
3490
  throw new Error(`Entity ${moduleName}.${entityName} not found`);
3396
3491
  }
3397
3492
  const rootContext = await this.loadRootContext(entity, id);
3493
+ // Build main and related pages
3494
+ const mainPage = await this.buildMainPage(entity, rootContext, dependencies);
3495
+ const relatedPages = await this.buildRelatedPages(entity, rootContext, dependencies);
3496
+ // Compose ordered pages around the primary page
3497
+ const orderedPages = this.composePagesWithPositions(mainPage, relatedPages, entity);
3398
3498
  return this.layoutAdapterBuilder
3399
3499
  .setEntity(entity, rootContext)
3400
3500
  .setDependencies(dependencies)
3401
- .setMainPage(await this.buildMainPage(entity, rootContext, dependencies))
3402
- .setRelatedPages(await this.buildRelatedPages(entity, rootContext, dependencies))
3501
+ .setPages(orderedPages)
3403
3502
  .build();
3404
3503
  }
3405
3504
  async loadRootContext(entity, id) {
@@ -3412,13 +3511,17 @@ class AXPLayoutAdapterFactory {
3412
3511
  async buildRelatedPages(entity, rootContext, dependencies) {
3413
3512
  const pages = [];
3414
3513
  // Page Details
3415
- const pageDetailEntities = entity?.relatedEntities?.filter((re) => !re.hidden && re.layoutType === 'page-detail');
3514
+ const pageDetailEntities = entity?.relatedEntities?.filter((re) => !re.hidden && re.layout?.type === 'page-detail');
3416
3515
  for (const relatedEntity of pageDetailEntities || []) {
3417
3516
  const converter = this.relatedEntityConverterFactory.createPageDetailsConverter();
3418
- pages.push(await converter.convert(relatedEntity, { entityResolver: dependencies.entityResolver }));
3517
+ pages.push(await converter.convert(relatedEntity, {
3518
+ ...dependencies,
3519
+ context: rootContext,
3520
+ rootTitle: await this.getRootTitle(entity, rootContext, dependencies),
3521
+ }));
3419
3522
  }
3420
3523
  // Page Lists
3421
- const pageListEntities = entity?.relatedEntities?.filter((re) => !re.hidden && re.layoutType === 'page-list');
3524
+ const pageListEntities = entity?.relatedEntities?.filter((re) => !re.hidden && re.layout?.type === 'page-list');
3422
3525
  for (const relatedEntity of pageListEntities || []) {
3423
3526
  const converter = this.relatedEntityConverterFactory.createPageListConverter();
3424
3527
  pages.push(await converter.convert(relatedEntity, {
@@ -3429,9 +3532,46 @@ class AXPLayoutAdapterFactory {
3429
3532
  }
3430
3533
  return pages;
3431
3534
  }
3535
+ composePagesWithPositions(mainPage, relatedPages, entity) {
3536
+ // Only consider related entities with layout types page-detail or page-list
3537
+ const pageEntities = (entity?.relatedEntities || []).filter((re) => !re.hidden && (re.layout?.type === 'page-detail' || re.layout?.type === 'page-list'));
3538
+ // Build a map from entity name to its layout config (order/position)
3539
+ const layoutConfigByEntity = {};
3540
+ for (const re of pageEntities) {
3541
+ const [, entityName] = (re.entity || '').split('.');
3542
+ const key = entityName || re.entity;
3543
+ layoutConfigByEntity[key] = { order: re.layout?.order, position: re.layout?.position };
3544
+ }
3545
+ // Split related pages into before/after buckets based on their relatedEntity layout
3546
+ const before = [];
3547
+ const after = [];
3548
+ for (const page of relatedPages) {
3549
+ const conf = layoutConfigByEntity[page.id];
3550
+ const position = conf?.position ?? 'after';
3551
+ if (position === 'before') {
3552
+ before.push(page);
3553
+ }
3554
+ else {
3555
+ after.push(page);
3556
+ }
3557
+ }
3558
+ // Sort by order within each bucket (undefined orders go last)
3559
+ const sortByOrder = (a, b) => {
3560
+ const ao = layoutConfigByEntity[a.id]?.order ?? Number.POSITIVE_INFINITY;
3561
+ const bo = layoutConfigByEntity[b.id]?.order ?? Number.POSITIVE_INFINITY;
3562
+ return ao - bo;
3563
+ };
3564
+ before.sort(sortByOrder);
3565
+ after.sort(sortByOrder);
3566
+ // Ensure the main page is primary
3567
+ mainPage.isPrimary = true;
3568
+ // Compose final pages: before -> main -> after
3569
+ return [...before, mainPage, ...after];
3570
+ }
3432
3571
  async getRootTitle(entity, rootContext, dependencies) {
3433
3572
  // Logic for getting root title
3434
- return await dependencies.expressionEvaluator.evaluate(entity.interfaces?.master?.single?.title, rootContext);
3573
+ const title = await dependencies.expressionEvaluator.evaluate(entity.interfaces?.master?.single?.title, rootContext);
3574
+ return title;
3435
3575
  }
3436
3576
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPLayoutAdapterFactory, deps: [{ token: AXPRelatedEntityConverterFactory }, { token: AXPMainEntityContentBuilder }, { token: AXPLayoutAdapterBuilder }], target: i0.ɵɵFactoryTarget.Injectable }); }
3437
3577
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPLayoutAdapterFactory, providedIn: 'root' }); }
@@ -3499,6 +3639,81 @@ class AXPEntitySearchDefinitionProvider {
3499
3639
  }
3500
3640
  }
3501
3641
 
3642
+ //#region ---- Column Mapping Helpers ----
3643
+ /**
3644
+ * Maps an entity property to a list widget column configuration.
3645
+ * Preserves readonly behavior and leverages the property's interface options when available.
3646
+ */
3647
+ function mapPropertyToWidgetColumn(property) {
3648
+ return {
3649
+ name: property.name,
3650
+ title: property.title,
3651
+ visible: true,
3652
+ widget: property.schema?.interface
3653
+ ? {
3654
+ type: property.schema.interface.type || 'text-editor',
3655
+ path: property.name,
3656
+ options: {
3657
+ readonly: true,
3658
+ ...property.schema.interface.options,
3659
+ },
3660
+ }
3661
+ : {
3662
+ type: 'text-editor',
3663
+ path: property.name,
3664
+ options: { readonly: true },
3665
+ },
3666
+ };
3667
+ }
3668
+ /**
3669
+ * Maps an entity column metadata (and its related property) to a list widget column configuration.
3670
+ */
3671
+ function mapEntityColumnToWidgetColumn(entity, column) {
3672
+ const property = entity.properties.find((p) => p.name === column.name);
3673
+ return {
3674
+ name: column.name,
3675
+ title: column.title || property?.title || column.name,
3676
+ width: column.options?.width,
3677
+ visible: column.options?.visible !== false,
3678
+ widget: property?.schema?.interface
3679
+ ? {
3680
+ type: property.schema.interface.type || 'text-editor',
3681
+ path: column.options?.dataPath || column.name,
3682
+ options: {
3683
+ readonly: true,
3684
+ ...property.schema.interface.options,
3685
+ },
3686
+ }
3687
+ : {
3688
+ type: 'text-editor',
3689
+ path: column.options?.dataPath || column.name,
3690
+ options: { readonly: true },
3691
+ },
3692
+ };
3693
+ }
3694
+ //#endregion
3695
+ //#region ---- Include/Exclude Utilities ----
3696
+ /**
3697
+ * Applies include and exclude filters to a named collection while preserving order.
3698
+ */
3699
+ function applyIncludeExclude(items, include = [], exclude = []) {
3700
+ let result = items;
3701
+ if (include.length > 0) {
3702
+ result = result.filter((i) => include.includes(i.name));
3703
+ }
3704
+ if (exclude.length > 0) {
3705
+ result = result.filter((i) => !exclude.includes(i.name));
3706
+ }
3707
+ return result;
3708
+ }
3709
+ /**
3710
+ * Returns only visible (non-hidden) properties of an entity.
3711
+ */
3712
+ function getVisibleProperties(entity) {
3713
+ return entity.properties.filter((prop) => !prop.schema?.hidden);
3714
+ }
3715
+ //#endregion
3716
+
3502
3717
  class AXPEntityListTableService {
3503
3718
  constructor() {
3504
3719
  //#region ---- Services & Dependencies ----
@@ -3506,6 +3721,9 @@ class AXPEntityListTableService {
3506
3721
  this.workflow = inject(AXPWorkflowService);
3507
3722
  this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
3508
3723
  this.evaluateExpressions = async (options, data) => {
3724
+ if (!options) {
3725
+ return {};
3726
+ }
3509
3727
  const scope = {
3510
3728
  context: {
3511
3729
  eval: (path) => {
@@ -3521,8 +3739,7 @@ class AXPEntityListTableService {
3521
3739
  /**
3522
3740
  * Convert Entity to List Widget Options
3523
3741
  */
3524
- async convertEntityToListOptions(entity, options) {
3525
- const allActions = entity.interfaces?.master?.list?.actions?.map((tr) => new AXPEntityCommandTriggerViewModel(entity, tr)) ?? [];
3742
+ async convertEntityToListOptions(entity, options, allActions) {
3526
3743
  const listOptions = {
3527
3744
  // 📊 Data Source
3528
3745
  dataSource: this.createDataSource(entity),
@@ -3574,72 +3791,17 @@ class AXPEntityListTableService {
3574
3791
  createColumnsFromProperties(entity, options) {
3575
3792
  const excludeColumns = options?.excludeColumns || [];
3576
3793
  const includeColumns = options?.includeColumns || [];
3577
- let columns = [];
3578
- // If columns are defined, use them
3579
- if (entity.columns && entity.columns.length > 0) {
3580
- columns = entity.columns.map((col) => this.mapEntityColumnToWidgetColumn(entity, col));
3581
- }
3582
- else {
3583
- // Otherwise use properties
3584
- columns = entity.properties
3585
- .filter((prop) => !prop.schema.hidden) // Only visible properties
3586
- .map((prop) => ({
3587
- name: prop.name,
3588
- title: prop.title,
3589
- visible: true,
3590
- widget: prop.schema.interface
3591
- ? {
3592
- type: prop.schema.interface.type || 'text-editor',
3593
- path: prop.name,
3594
- options: {
3595
- readonly: true,
3596
- ...prop.schema.interface.options,
3597
- },
3598
- }
3599
- : {
3600
- type: 'text-editor',
3601
- path: prop.name,
3602
- options: { readonly: true },
3603
- },
3604
- }));
3605
- }
3606
- // Apply include/exclude filters
3607
- if (includeColumns.length > 0) {
3608
- // If includeColumns is specified, only include those columns
3609
- columns = columns.filter((col) => includeColumns.includes(col.name));
3610
- }
3611
- if (excludeColumns.length > 0) {
3612
- // If excludeColumns is specified, exclude those columns
3613
- columns = columns.filter((col) => !excludeColumns.includes(col.name));
3614
- }
3615
- return columns;
3794
+ // If columns are defined, use them; otherwise use visible properties
3795
+ const baseColumns = entity.columns && entity.columns.length > 0
3796
+ ? entity.columns.map((col) => this.mapEntityColumnToWidgetColumn(entity, col))
3797
+ : getVisibleProperties(entity).map((prop) => mapPropertyToWidgetColumn(prop));
3798
+ return applyIncludeExclude(baseColumns, includeColumns, excludeColumns);
3616
3799
  }
3617
3800
  /**
3618
3801
  * Map EntityTableColumn to ListWidgetColumn
3619
3802
  */
3620
3803
  mapEntityColumnToWidgetColumn(entity, column) {
3621
- // Find corresponding property
3622
- const property = entity.properties.find((p) => p.name === column.name);
3623
- return {
3624
- name: column.name,
3625
- title: column.title || property?.title || column.name,
3626
- width: column.options?.width,
3627
- visible: column.options?.visible !== false,
3628
- widget: property?.schema.interface
3629
- ? {
3630
- type: property.schema.interface.type || 'text-editor',
3631
- path: column.options?.dataPath || column.name,
3632
- options: {
3633
- readonly: true,
3634
- ...property.schema.interface.options,
3635
- },
3636
- }
3637
- : {
3638
- type: 'text-editor',
3639
- path: column.options?.dataPath || column.name,
3640
- options: { readonly: true },
3641
- },
3642
- };
3804
+ return mapEntityColumnToWidgetColumn(entity, column);
3643
3805
  }
3644
3806
  /**
3645
3807
  * Convert Entity Actions to Row Commands
@@ -3655,7 +3817,7 @@ class AXPEntityListTableService {
3655
3817
  icon: action.icon,
3656
3818
  color: action.color,
3657
3819
  look: 'outline',
3658
- visible: action.hidden,
3820
+ visible: !action.hidden,
3659
3821
  disabled: action.disabled,
3660
3822
  }));
3661
3823
  }
@@ -3666,6 +3828,36 @@ class AXPEntityListTableService {
3666
3828
  const actions = entity.interfaces?.master?.list?.actions || [];
3667
3829
  return actions.some((action) => action.scope === AXPEntityCommandScope.Selected);
3668
3830
  }
3831
+ /**
3832
+ * Handle execution of a row command (shared by double-click and command handlers)
3833
+ */
3834
+ async handleRowCommand(e, selectedRows, entity, allActions) {
3835
+ const data = e.data;
3836
+ const commandName = e.name;
3837
+ const action = allActions.find((c) => {
3838
+ return (c.name == e.name &&
3839
+ ((selectedRows?.length
3840
+ ? c.scope == AXPEntityCommandScope.Selected
3841
+ : c.scope == AXPEntityCommandScope.Individual) ||
3842
+ c.scope == AXPEntityCommandScope.TypeLevel));
3843
+ });
3844
+ const command = commandName.split('&')[0];
3845
+ const options = await this.evaluateExpressions(action?.options, data);
3846
+ await this.workflow.execute(command, {
3847
+ entity: getEntityInfo(entity).source,
3848
+ entityInfo: {
3849
+ name: entity.name,
3850
+ module: entity.module,
3851
+ title: entity.title,
3852
+ parentKey: entity.parentKey,
3853
+ source: entity.source,
3854
+ },
3855
+ data: action?.scope == AXPEntityCommandScope.Selected ? selectedRows : data,
3856
+ options: options,
3857
+ metadata: action?.metadata,
3858
+ });
3859
+ console.log('Entity List - Row command:', e.name, e.data);
3860
+ }
3669
3861
  /**
3670
3862
  * Create default events
3671
3863
  */
@@ -3674,38 +3866,27 @@ class AXPEntityListTableService {
3674
3866
  onRowClick: (row) => {
3675
3867
  console.log('Entity List - Row clicked:', row);
3676
3868
  },
3677
- onRowDoubleClick: (row) => {
3678
- console.log('Entity List - Row double clicked:', row);
3869
+ onRowDoubleClick: (e) => {
3870
+ console.log('Entity List - Row double clicked:', e);
3871
+ const defaultAction = allActions.find((c) => {
3872
+ const commandName = c.name.split('&')[0];
3873
+ return (c.default || commandName === 'open-entity') && !c.hidden;
3874
+ });
3875
+ if (!defaultAction) {
3876
+ return;
3877
+ }
3878
+ const d = {
3879
+ component: e.component,
3880
+ name: defaultAction.name,
3881
+ data: e.data,
3882
+ };
3883
+ this.handleRowCommand(d, undefined, entity, allActions);
3679
3884
  },
3680
3885
  onSelectionChange: (selectedRows) => {
3681
3886
  console.log('Entity List - Selection changed:', selectedRows);
3682
3887
  },
3683
3888
  onRowCommand: async (e, selectedRows) => {
3684
- const data = e.data;
3685
- const commandName = e.name;
3686
- const action = allActions.find((c) => {
3687
- return (c.name == e.name &&
3688
- ((selectedRows?.length
3689
- ? c.scope == AXPEntityCommandScope.Selected
3690
- : c.scope == AXPEntityCommandScope.Individual) ||
3691
- c.scope == AXPEntityCommandScope.TypeLevel));
3692
- });
3693
- const command = commandName.split('&')[0];
3694
- const options = await this.evaluateExpressions(action?.options, data);
3695
- await this.workflow.execute(command, {
3696
- entity: getEntityInfo(entity).source,
3697
- entityInfo: {
3698
- name: entity.name,
3699
- module: entity.module,
3700
- title: entity.title,
3701
- parentKey: entity.parentKey,
3702
- source: entity.source,
3703
- },
3704
- data: action?.scope == AXPEntityCommandScope.Selected ? selectedRows : data,
3705
- options: options,
3706
- metadata: action?.metadata,
3707
- });
3708
- console.log('Entity List - Row command:', e.name, e.data);
3889
+ await this.handleRowCommand(e, selectedRows, entity, allActions);
3709
3890
  },
3710
3891
  };
3711
3892
  }
@@ -3767,29 +3948,29 @@ class AXPEntityListToolbarService {
3767
3948
  * Create Column Definitions for Toolbar
3768
3949
  */
3769
3950
  createColumnDefinitions(entity, options) {
3770
- const { columns = [], properties } = entity;
3951
+ const { columns = [] } = entity;
3771
3952
  const excludeColumns = options?.excludeColumns || [];
3772
3953
  const includeColumns = options?.includeColumns || [];
3773
- const visibleProperties = properties.filter(({ schema }) => !schema?.hidden);
3954
+ const visibleProperties = getVisibleProperties(entity);
3774
3955
  const visiblePropNames = new Set(visibleProperties.map(({ name }) => name));
3775
- let filteredColumns = columns.filter(({ name }) => visiblePropNames.has(name));
3776
- // Apply include/exclude filters
3777
- if (includeColumns.length > 0) {
3778
- // If includeColumns is specified, only include those columns
3779
- filteredColumns = filteredColumns.filter((col) => includeColumns.includes(col.name));
3780
- }
3781
- if (excludeColumns.length > 0) {
3782
- // If excludeColumns is specified, exclude those columns
3783
- filteredColumns = filteredColumns.filter((col) => !excludeColumns.includes(col.name));
3784
- }
3785
- return filteredColumns.map((column) => {
3786
- const property = visibleProperties.find(({ name }) => name === column.name);
3787
- return {
3788
- name: column.name,
3789
- title: property?.title,
3790
- visible: column?.options?.visible ?? true,
3791
- };
3792
- });
3956
+ // Prefer explicit entity.columns if present; fallback to visible properties
3957
+ const baseColumns = columns.length > 0
3958
+ ? columns
3959
+ .filter(({ name }) => visiblePropNames.has(name))
3960
+ .map((column) => {
3961
+ const property = visibleProperties.find(({ name }) => name === column.name);
3962
+ return {
3963
+ name: column.name,
3964
+ title: property?.title,
3965
+ visible: column?.options?.visible ?? true,
3966
+ };
3967
+ })
3968
+ : visibleProperties.map((property) => ({
3969
+ name: property.name,
3970
+ title: property.title,
3971
+ visible: true,
3972
+ }));
3973
+ return applyIncludeExclude(baseColumns, includeColumns, excludeColumns);
3793
3974
  }
3794
3975
  /**
3795
3976
  * Create Sort Definitions for Toolbar
@@ -3818,7 +3999,6 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
3818
3999
  this.entityListTableService = inject(AXPEntityListTableService);
3819
4000
  this.entityListToolbarService = inject(AXPEntityListToolbarService);
3820
4001
  this.layoutThemeService = inject(AXPLayoutThemeService);
3821
- this.container = viewChild(AXPWidgetContainerComponent, ...(ngDevMode ? [{ debugName: "container" }] : []));
3822
4002
  this.isMounted = signal(false, ...(ngDevMode ? [{ debugName: "isMounted" }] : []));
3823
4003
  this.entity = signal(null, ...(ngDevMode ? [{ debugName: "entity" }] : []));
3824
4004
  this.listNode = signal(null, ...(ngDevMode ? [{ debugName: "listNode" }] : []));
@@ -3826,7 +4006,7 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
3826
4006
  this.allWidgets = viewChildren(AXPWidgetRendererDirective, ...(ngDevMode ? [{ debugName: "allWidgets" }] : []));
3827
4007
  this.listWidget = linkedSignal(() => this.allWidgets().find((widget) => widget.node()?.type === AXPWidgetsCatalog.list));
3828
4008
  this.toolbarWidget = computed(() => this.allWidgets().find((widget) => widget.node()?.type === AXPWidgetsCatalog.listToolbar), ...(ngDevMode ? [{ debugName: "toolbarWidget" }] : []));
3829
- this.selectedItems = computed(() => this.getValue()?.table || [], ...(ngDevMode ? [{ debugName: "selectedItems" }] : []));
4009
+ this.selectedItems = signal([], ...(ngDevMode ? [{ debugName: "selectedItems" }] : []));
3830
4010
  this.toolbarNode = signal(null, ...(ngDevMode ? [{ debugName: "toolbarNode" }] : []));
3831
4011
  this.destroyed = new Subject();
3832
4012
  //options
@@ -3839,7 +4019,7 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
3839
4019
  //actions
3840
4020
  this.allActions = computed(() => {
3841
4021
  const originalList = this.entity()?.interfaces?.master?.list?.actions ?? [];
3842
- const externalActionList = (this.options()['actions'] ?? []);
4022
+ const externalActionList = this.externalActions() ?? [];
3843
4023
  const usedOverrideActions = new Set();
3844
4024
  const mergedActions = originalList.map((originalAction) => {
3845
4025
  const originalCommandName = typeof originalAction.command === 'string' ? originalAction.command : originalAction.command?.name;
@@ -3948,7 +4128,9 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
3948
4128
  parentKey: this.entity()?.parentKey,
3949
4129
  source: this.entity()?.source,
3950
4130
  },
3951
- data: action?.scope == AXPEntityCommandScope.Selected ? this.selectedItems() : data,
4131
+ data: action?.scope == AXPEntityCommandScope.Selected
4132
+ ? this.selectedItems()
4133
+ : action?.options?.['process']?.data || null,
3952
4134
  options: action?.options,
3953
4135
  metadata: action?.metadata,
3954
4136
  });
@@ -4014,10 +4196,30 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
4014
4196
  * TODO: Implement column change logic
4015
4197
  */
4016
4198
  handleColumnChanges(changeTracker) {
4017
- if (changeTracker.isColumnsChanged) {
4018
- // TODO: Implement column change handling
4019
- console.log('Column changes detected - implementation needed');
4199
+ if (!changeTracker.isColumnsChanged) {
4200
+ return;
4020
4201
  }
4202
+ const listInstance = this.listWidget()?.instance;
4203
+ const toolbarState = this.getValue()?.toolbar;
4204
+ if (!listInstance || !toolbarState?.columns) {
4205
+ return;
4206
+ }
4207
+ // Current columns from list options
4208
+ const currentColumns = (listInstance.options()['columns'] || []);
4209
+ const columnByName = new Map(currentColumns.map((c) => [c.name, c]));
4210
+ // Build new ordered columns array based on toolbar order/visibility
4211
+ const updatedColumns = toolbarState.columns
4212
+ .map((q) => {
4213
+ const base = columnByName.get(q.name);
4214
+ if (!base) {
4215
+ return null;
4216
+ }
4217
+ // Preserve all existing column config but update visibility
4218
+ return { ...base, visible: q.visible };
4219
+ })
4220
+ .filter((c) => c != null);
4221
+ // Apply updated columns to the list widget and refresh
4222
+ listInstance.setOptions({ columns: updatedColumns });
4021
4223
  }
4022
4224
  async ngOnInit() {
4023
4225
  super.ngOnInit();
@@ -4035,7 +4237,7 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
4035
4237
  excludeColumns: this.excludeColumns(),
4036
4238
  includeColumns: this.includeColumns(),
4037
4239
  };
4038
- const listOptions = await this.entityListTableService.convertEntityToListOptions(resolvedEntity, options);
4240
+ const listOptions = await this.entityListTableService.convertEntityToListOptions(resolvedEntity, options, this.allActions());
4039
4241
  const toolbarOptions = await this.entityListToolbarService.convertEntityToolbarOptions(resolvedEntity, options);
4040
4242
  this.listNode.set({
4041
4243
  type: AXPWidgetsCatalog.list,
@@ -4057,7 +4259,7 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
4057
4259
  },
4058
4260
  });
4059
4261
  }
4060
- ngAfterViewInit() {
4262
+ async ngAfterViewInit() {
4061
4263
  this.workflow.events$
4062
4264
  .pipe(ofType(AXPRefreshEvent))
4063
4265
  .pipe(takeUntil(this.destroyed))
@@ -4066,6 +4268,15 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
4066
4268
  this.listWidget()?.instance.call('refresh');
4067
4269
  }
4068
4270
  });
4271
+ const listWidget = (await this.layoutService.waitForWidget(`${this.entitySource()}-tab-list_table`, 500));
4272
+ if (listWidget?.api && typeof listWidget.api === 'function') {
4273
+ const onSelectionChange = listWidget.api()['onSelectionChange'];
4274
+ if (onSelectionChange) {
4275
+ onSelectionChange.pipe(takeUntil(this.destroyed)).subscribe((e) => {
4276
+ this.selectedItems.set(e);
4277
+ });
4278
+ }
4279
+ }
4069
4280
  }
4070
4281
  ngOnDestroy() {
4071
4282
  this.listWidget.set(undefined);
@@ -4073,7 +4284,7 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
4073
4284
  this.destroyed.complete();
4074
4285
  }
4075
4286
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityListWidgetViewComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
4076
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: AXPEntityListWidgetViewComponent, isStandalone: true, selector: "ng-component", host: { properties: { "class": "\"ax-h-full\"" } }, providers: [AXPEntityListTableService, AXPEntityListToolbarService], viewQueries: [{ propertyName: "container", first: true, predicate: AXPWidgetContainerComponent, descendants: true, isSignal: true }, { propertyName: "list", first: true, predicate: ["list"], descendants: true, isSignal: true }, { propertyName: "allWidgets", predicate: AXPWidgetRendererDirective, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
4287
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: AXPEntityListWidgetViewComponent, isStandalone: true, selector: "ng-component", host: { properties: { "class": "\"ax-h-full\"" } }, providers: [AXPEntityListTableService, AXPEntityListToolbarService], viewQueries: [{ propertyName: "list", first: true, predicate: ["list"], descendants: true, isSignal: true }, { propertyName: "allWidgets", predicate: AXPWidgetRendererDirective, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
4077
4288
  @if (showEntityActions()) {
4078
4289
  <div class="ax-flex ax-gap-2 ax-justify-end ax-mb-4">
4079
4290
  @for (action of primaryActions(); track $index) {
@@ -4804,6 +5015,7 @@ class AXPLookupWidgetSelectorViewModel {
4804
5015
  this.options = options;
4805
5016
  this.workflow = this.injector.get(AXPWorkflowService);
4806
5017
  this.filterOperatorMiddleware = this.injector.get(AXPFilterOperatorMiddlewareService);
5018
+ this.widgetResolver = this.injector.get(AXPWidgetRegistryService);
4807
5019
  this.dataSource = new AXDataSource({
4808
5020
  byKey: (key) => {
4809
5021
  const func = this.entityDef.queries.byKey.execute;
@@ -4833,15 +5045,33 @@ class AXPLookupWidgetSelectorViewModel {
4833
5045
  return this.inlineFiltersPlaceholders().length > 0;
4834
5046
  }, ...(ngDevMode ? [{ debugName: "hasInlineFilters" }] : []));
4835
5047
  this.columns = () => {
4836
- const listColumns = this.entityDef.columns ?? [];
4837
- const columns = listColumns?.map((c) => c.name) ?? [];
4838
- const props = this.entityDef.properties.filter((p) => p.schema.hidden != true);
4839
- const displayColumns = props.filter((p) => (this.options.columns?.length ?? 0) > 0
4840
- ? this.options.columns.some((c) => c == p.name)
4841
- : columns.some((c) => c == p.name));
4842
- //
4843
- return displayColumns.map((p) => {
4844
- return new AXPEntityListViewColumnViewModel(p, listColumns?.find((c) => c.name == p.name));
5048
+ const { columns = [], properties } = this.entityDef;
5049
+ const visibleProperties = properties.filter(({ schema }) => !schema?.hidden);
5050
+ const visiblePropNames = new Set(visibleProperties.map(({ name }) => name));
5051
+ return columns
5052
+ .filter(({ name, showAs }) => visiblePropNames.has(name) || showAs)
5053
+ .filter(({ name }) => ((this.options.columns?.length ?? 0) == 0) || this.options.columns?.includes(name))
5054
+ .map((column) => {
5055
+ if (column.showAs) {
5056
+ const widgetConfig = this.widgetResolver.resolve(column.showAs.type);
5057
+ const property = {
5058
+ ...widgetConfig,
5059
+ name: column.name,
5060
+ title: column.title ?? '',
5061
+ schema: {
5062
+ dataType: 'string',
5063
+ interface: {
5064
+ type: column.showAs.type,
5065
+ options: column.showAs.options,
5066
+ },
5067
+ },
5068
+ };
5069
+ return new AXPEntityListViewColumnViewModel(property, column);
5070
+ }
5071
+ else {
5072
+ const property = visibleProperties.find(({ name }) => name === column.name);
5073
+ return new AXPEntityListViewColumnViewModel(property, column);
5074
+ }
4845
5075
  });
4846
5076
  };
4847
5077
  this.inlineFilters = {
@@ -4950,13 +5180,24 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
4950
5180
  this.entity = computed(() => this.options()['entity'], ...(ngDevMode ? [{ debugName: "entity" }] : []));
4951
5181
  this.disabled = computed(() => this.options()['disabled'], ...(ngDevMode ? [{ debugName: "disabled" }] : []));
4952
5182
  this.columns = computed(() => this.options()['columns'] ?? [], ...(ngDevMode ? [{ debugName: "columns" }] : []));
5183
+ this.textField = computed(() => this.options()['textField'] ?? '', ...(ngDevMode ? [{ debugName: "textField" }] : []));
4953
5184
  this.customFilter = computed(() => this.options()['filter'], ...(ngDevMode ? [{ debugName: "customFilter" }] : []));
4954
5185
  this.multiple = computed(() => (this.options()['multiple'] ?? false), ...(ngDevMode ? [{ debugName: "multiple" }] : []));
4955
5186
  this.look = computed(() => this.options()['look'] ?? 'lookup', ...(ngDevMode ? [{ debugName: "look" }] : []));
4956
5187
  this.allowClear = computed(() => (this.options()['allowClear'] ?? false), ...(ngDevMode ? [{ debugName: "allowClear" }] : []));
4957
- this.textField = computed(() => {
4958
- return (this.entityDef()?.formats.lookup ?? this.entityDef()?.properties.find((c) => c.name != 'id')?.name ?? 'title');
4959
- }, ...(ngDevMode ? [{ debugName: "textField" }] : []));
5188
+ this.defaultTextField = computed(() => {
5189
+ const textField = this.entityDef()?.formats.lookup ?? this.entityDef()?.properties.find((c) => c.name != 'id')?.name ?? 'title';
5190
+ return textField;
5191
+ }, ...(ngDevMode ? [{ debugName: "defaultTextField" }] : []));
5192
+ this.displayField = computed(() => {
5193
+ if (this.textField()) {
5194
+ return this.textField();
5195
+ }
5196
+ return this.defaultTextField();
5197
+ }, ...(ngDevMode ? [{ debugName: "displayField" }] : []));
5198
+ this.selectedItemsText = computed(() => {
5199
+ return this.selectedItems().map((item) => get(item, this.displayField())).join(', ');
5200
+ }, ...(ngDevMode ? [{ debugName: "selectedItemsText" }] : []));
4960
5201
  this.valueField = computed(() => this.entityDef()?.properties.find((c) => c.name == 'id')?.name ?? 'id', ...(ngDevMode ? [{ debugName: "valueField" }] : []));
4961
5202
  this.entityDef = signal(null, ...(ngDevMode ? [{ debugName: "entityDef" }] : []));
4962
5203
  this.searchTerm = signal(null, ...(ngDevMode ? [{ debugName: "searchTerm" }] : []));
@@ -5096,6 +5337,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
5096
5337
  this.selectedItems.set(items);
5097
5338
  //
5098
5339
  const keys = items.map((item) => get(item, this.valueField()));
5340
+ const text = items.map((item) => get(item, this.displayField()));
5099
5341
  //
5100
5342
  // extract data from valueField and set context by expose path
5101
5343
  if (this.expose()) {
@@ -5151,7 +5393,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
5151
5393
  <ax-select-box
5152
5394
  [dataSource]="vm()?.dataSource!"
5153
5395
  [ngModel]="selectedItems()"
5154
- [textField]="textField()"
5396
+ [textField]="displayField()"
5155
5397
  [valueField]="valueField()"
5156
5398
  [disabled]="disabled()"
5157
5399
  [multiple]="multiple()"
@@ -5165,9 +5407,10 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
5165
5407
  }
5166
5408
  </ax-select-box>
5167
5409
  } @else {
5410
+ {{selectedItemsText()}}
5168
5411
  <ax-tag-box
5169
5412
  [ngModel]="selectedItems()"
5170
- [textField]="textField()"
5413
+ [textField]="displayField()"
5171
5414
  [valueField]="valueField()"
5172
5415
  (onValueChanged)="handleValueChange($event)"
5173
5416
  [placeholder]="placeholder() | translate | async"
@@ -5206,7 +5449,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
5206
5449
  }
5207
5450
  `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type:
5208
5451
  //
5209
- AXButtonModule }, { kind: "component", type: i3$1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorClearButtonComponent, selector: "ax-clear-button", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i1.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXValidationModule }, { kind: "ngmodule", type: AXFormModule }, { kind: "directive", type: i5$1.AXValidationRuleDirective, selector: "ax-validation-rule", inputs: ["rule", "options", "message", "disabled"] }, { kind: "ngmodule", type: AXTagBoxModule }, { kind: "component", type: i6.AXTagBoxComponent, selector: "ax-tag-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "allowNull", "type", "look", "addOnComma", "addOnEnter", "valueField", "textField", "readonlyField", "allowDuplicateValues"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXSelectBoxModule }, { kind: "component", type: i7$1.AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "isItemTruncated", "showItemTooltip", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed", "onItemSelected", "onItemClick"] }, { kind: "component", type: AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "pipe", type: i7.AsyncPipe, name: "async" }, { kind: "pipe", type: i8.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5452
+ AXButtonModule }, { kind: "component", type: i3$1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorClearButtonComponent, selector: "ax-clear-button", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i1.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXValidationModule }, { kind: "ngmodule", type: AXFormModule }, { kind: "directive", type: i5$1.AXValidationRuleDirective, selector: "ax-validation-rule", inputs: ["rule", "options", "message", "disabled"] }, { kind: "ngmodule", type: AXTagBoxModule }, { kind: "component", type: i6.AXTagBoxComponent, selector: "ax-tag-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "allowNull", "type", "look", "addOnComma", "addOnEnter", "valueField", "textField", "readonlyField", "allowDuplicateValues"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXSelectBoxModule }, { kind: "component", type: i7$1.AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "isItemTruncated", "showItemTooltip", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed"] }, { kind: "component", type: AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "pipe", type: i7.AsyncPipe, name: "async" }, { kind: "pipe", type: i8.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5210
5453
  }
5211
5454
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPLookupWidgetEditComponent, decorators: [{
5212
5455
  type: Component,
@@ -5217,7 +5460,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
5217
5460
  <ax-select-box
5218
5461
  [dataSource]="vm()?.dataSource!"
5219
5462
  [ngModel]="selectedItems()"
5220
- [textField]="textField()"
5463
+ [textField]="displayField()"
5221
5464
  [valueField]="valueField()"
5222
5465
  [disabled]="disabled()"
5223
5466
  [multiple]="multiple()"
@@ -5231,9 +5474,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
5231
5474
  }
5232
5475
  </ax-select-box>
5233
5476
  } @else {
5477
+ {{selectedItemsText()}}
5234
5478
  <ax-tag-box
5235
5479
  [ngModel]="selectedItems()"
5236
- [textField]="textField()"
5480
+ [textField]="displayField()"
5237
5481
  [valueField]="valueField()"
5238
5482
  (onValueChanged)="handleValueChange($event)"
5239
5483
  [placeholder]="placeholder() | translate | async"
@@ -5547,7 +5791,7 @@ class AXPTagableBoxWidgetEditComponent extends AXPValueWidgetComponent {
5547
5791
  </ax-prefix>
5548
5792
  </ax-button>
5549
5793
  </div>
5550
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: AXTextBoxModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXFormModule }, { kind: "directive", type: i5$1.AXValidationRuleDirective, selector: "ax-validation-rule", inputs: ["rule", "options", "message", "disabled"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorClearButtonComponent, selector: "ax-clear-button", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXValidationModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3$1.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: AXSelectBoxModule }, { kind: "component", type: i7$1.AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "isItemTruncated", "showItemTooltip", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed", "onItemSelected", "onItemClick"] }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i5.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5794
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: AXTextBoxModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXFormModule }, { kind: "directive", type: i5$1.AXValidationRuleDirective, selector: "ax-validation-rule", inputs: ["rule", "options", "message", "disabled"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorClearButtonComponent, selector: "ax-clear-button", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXValidationModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3$1.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: AXSelectBoxModule }, { kind: "component", type: i7$1.AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "isItemTruncated", "showItemTooltip", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed"] }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i5.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5551
5795
  }
5552
5796
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPTagableBoxWidgetEditComponent, decorators: [{
5553
5797
  type: Component,