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

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 (36) hide show
  1. package/common/index.d.ts +23 -5
  2. package/core/index.d.ts +5 -1
  3. package/fesm2022/acorex-platform-common.mjs +3 -1
  4. package/fesm2022/acorex-platform-common.mjs.map +1 -1
  5. package/fesm2022/acorex-platform-core.mjs +4 -1
  6. package/fesm2022/acorex-platform-core.mjs.map +1 -1
  7. package/fesm2022/acorex-platform-layout-builder.mjs +8 -0
  8. package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
  9. package/fesm2022/acorex-platform-layout-components.mjs +4 -4
  10. package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
  11. package/fesm2022/acorex-platform-layout-entity.mjs +327 -44
  12. package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
  13. package/fesm2022/{acorex-platform-themes-default-entity-master-list-view.component-e3Lxk5ZT.mjs → acorex-platform-themes-default-entity-master-list-view.component-D3VUh8K8.mjs} +3 -2
  14. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-D3VUh8K8.mjs.map +1 -0
  15. package/fesm2022/{acorex-platform-themes-default-entity-master-single-view.component-CVaJzWb2.mjs → acorex-platform-themes-default-entity-master-single-view.component-BMkhNfF4.mjs} +3 -3
  16. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-BMkhNfF4.mjs.map +1 -0
  17. package/fesm2022/acorex-platform-themes-default.mjs +6 -6
  18. package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
  19. package/fesm2022/acorex-platform-themes-shared.mjs +1 -1
  20. package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
  21. package/fesm2022/{acorex-platform-widgets-checkbox-widget-column.component-BNBOATPB.mjs → acorex-platform-widgets-checkbox-widget-column.component-DeKpl0uK.mjs} +1 -2
  22. package/fesm2022/acorex-platform-widgets-checkbox-widget-column.component-DeKpl0uK.mjs.map +1 -0
  23. package/fesm2022/{acorex-platform-widgets-color-box-widget-designer.component-pYOQv5g8.mjs → acorex-platform-widgets-color-box-widget-designer.component-CohkI1w1.mjs} +2 -2
  24. package/fesm2022/acorex-platform-widgets-color-box-widget-designer.component-CohkI1w1.mjs.map +1 -0
  25. package/fesm2022/acorex-platform-widgets.mjs +212 -82
  26. package/fesm2022/acorex-platform-widgets.mjs.map +1 -1
  27. package/layout/builder/index.d.ts +3 -0
  28. package/layout/components/index.d.ts +1 -5
  29. package/layout/entity/index.d.ts +2 -3
  30. package/layout/views/index.d.ts +1 -0
  31. package/package.json +9 -9
  32. package/widgets/index.d.ts +17 -2
  33. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-e3Lxk5ZT.mjs.map +0 -1
  34. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-CVaJzWb2.mjs.map +0 -1
  35. package/fesm2022/acorex-platform-widgets-checkbox-widget-column.component-BNBOATPB.mjs.map +0 -1
  36. package/fesm2022/acorex-platform-widgets-color-box-widget-designer.component-pYOQv5g8.mjs.map +0 -1
@@ -971,6 +971,7 @@ class AXPEntityMasterCreateViewModel {
971
971
  const createProps = interfaces?.master?.create?.properties?.map(({ name }) => name) ?? [];
972
972
  const visibleProperties = properties.filter(({ groupId, schema, name }) => groupId && !schema.hidden && createProps.includes(name));
973
973
  const sections = interfaces?.master?.create?.sections?.filter(({ id }) => visibleProperties.some(({ groupId }) => groupId === id)) ?? [];
974
+ console.log({ sections, visibleProperties });
974
975
  return sections.map((section) => new AXPEntityCreateViewSectionViewModel(this.entityDef, section));
975
976
  }, ...(ngDevMode ? [{ debugName: "sections" }] : []));
976
977
  if (!initialData)
@@ -1992,7 +1993,6 @@ class AXPEntityMasterSingleViewGroupViewModel {
1992
1993
  this.group = this.entity.groups?.find((c) => c.id == this.section.id);
1993
1994
  this.name = signal(this.group.id, ...(ngDevMode ? [{ debugName: "name" }] : []));
1994
1995
  this.isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
1995
- this.type = signal(this.section.type ?? 'section', ...(ngDevMode ? [{ debugName: "type" }] : []));
1996
1996
  this.title = computed(() => {
1997
1997
  return this.group.title ?? this.group.id;
1998
1998
  }, ...(ngDevMode ? [{ debugName: "title" }] : []));
@@ -2578,6 +2578,7 @@ class AXPLayoutAdapterBuilder {
2578
2578
  }
2579
2579
  build() {
2580
2580
  return {
2581
+ name: `${this.entity?.module}.${this.entity?.name}`,
2581
2582
  title: `${this.entity?.interfaces?.master?.single?.title}`,
2582
2583
  label: this.entity?.formats.plural,
2583
2584
  actions: [],
@@ -2606,7 +2607,7 @@ class AXPLayoutAdapterBuilder {
2606
2607
  command: {
2607
2608
  name: 'navigate',
2608
2609
  options: {
2609
- path: `/${session.application?.name}/m/${moduleName}/e/${entityName}/${this.rootContext.id}/view`,
2610
+ path: `/${session.application?.name}/m/${moduleName}/e/${entityName}/${this.rootContext.id}/new-view`,
2610
2611
  },
2611
2612
  },
2612
2613
  },
@@ -2784,7 +2785,20 @@ class AXPBaseRelatedEntityConverter {
2784
2785
  class AXPPageDetailsConverter extends AXPBaseRelatedEntityConverter {
2785
2786
  async convert(relatedEntity, context) {
2786
2787
  const { entityDef } = await this.getEntityDefinition(relatedEntity, context.entityResolver);
2787
- const helpers = this.createEntityHelpers(entityDef);
2788
+ const baseHelpers = this.createEntityHelpers(entityDef);
2789
+ // If referenced strategy with mapping and detail type, exclude mapped properties from UI
2790
+ const p = relatedEntity?.persistence || {};
2791
+ const strategy = p.strategy || 'embedded';
2792
+ const mappedTargets = Object.keys(p.map || {}).map((k) => (k || '').split('.')[0]);
2793
+ const helpers = {
2794
+ ...baseHelpers,
2795
+ getPropertyByGroupId: (groupId) => {
2796
+ const props = baseHelpers.getPropertyByGroupId(groupId) ?? [];
2797
+ if (strategy !== 'referenced' || mappedTargets.length === 0)
2798
+ return props;
2799
+ return props.filter((prop) => !mappedTargets.includes(prop?.name));
2800
+ },
2801
+ };
2788
2802
  const evaluateExpressions = async (actionData) => {
2789
2803
  const scope = {
2790
2804
  context: {
@@ -3043,7 +3057,20 @@ class AXPPageListConverter extends AXPBaseRelatedEntityConverter {
3043
3057
  class AXPTabDetailsConverter extends AXPBaseRelatedEntityConverter {
3044
3058
  async convert(relatedEntity, context) {
3045
3059
  const { entityDef } = await this.getEntityDefinition(relatedEntity, context.entityResolver);
3046
- const helpers = this.createEntityHelpers(entityDef);
3060
+ const baseHelpers = this.createEntityHelpers(entityDef);
3061
+ // If referenced strategy with mapping and detail type, exclude mapped properties from UI
3062
+ const p = relatedEntity?.persistence || {};
3063
+ const strategy = p.strategy || 'embedded';
3064
+ const mappedTargets = Object.keys(p.map || {}).map((k) => (k || '').split('.')[0]);
3065
+ const helpers = {
3066
+ ...baseHelpers,
3067
+ getPropertyByGroupId: (groupId) => {
3068
+ const props = baseHelpers.getPropertyByGroupId(groupId) ?? [];
3069
+ if (strategy !== 'referenced' || mappedTargets.length === 0)
3070
+ return props;
3071
+ return props.filter((prop) => !mappedTargets.includes(prop?.name));
3072
+ },
3073
+ };
3047
3074
  return {
3048
3075
  id: entityDef?.name ?? '',
3049
3076
  title: relatedEntity.title ?? entityDef?.title ?? '',
@@ -3145,41 +3172,252 @@ class AXPMainEntityContentBuilder {
3145
3172
  this.workflowService = inject(AXPWorkflowService);
3146
3173
  this.commandService = inject(AXPCommandService);
3147
3174
  }
3148
- async build(entity, rootContext, dependencies) {
3175
+ async build(entity, rootContext, dependencies, rootTitle) {
3149
3176
  const groups = entity?.groups ?? [];
3150
3177
  const singleInterface = entity?.interfaces?.master?.single;
3178
+ // Accumulate groups from main and merge-detail related entities for validation/title lookup
3179
+ const allGroups = [...groups];
3180
+ // Prepare merge-details structures (sections and properties per section)
3181
+ const mergeDetailEntities = entity?.relatedEntities?.filter((re) => !re.hidden && re.layout?.type === 'merge-detail');
3182
+ const mainPropsByGroup = (entity?.properties ?? []).reduce((acc, p) => {
3183
+ if (!acc[p.groupId])
3184
+ acc[p.groupId] = [];
3185
+ acc[p.groupId].push(p);
3186
+ return acc;
3187
+ }, {});
3188
+ // Will hold merged properties per group (section)
3189
+ const mergedPropsByGroup = { ...mainPropsByGroup };
3190
+ // Collect sections from main interface (validated later) and related ones for ordering
3191
+ const mainSections = singleInterface?.sections ?? [];
3192
+ // Track extra sections with entity-level ordering context
3193
+ const beforeExtraSections = [];
3194
+ const middleExtraSections = [];
3195
+ const afterExtraSections = [];
3196
+ const beforeExtraIds = new Set();
3197
+ const middleExtraIds = new Set();
3198
+ const afterExtraIds = new Set();
3199
+ // Effective order overrides for main sections when merged with BEFORE related entities
3200
+ let beforeOverrideSectionOrders = {};
3201
+ // Collect tab-list tabs from merge-detail related entities to merge with main tabs
3202
+ const nestedTabListTabs = [];
3203
+ // Helper to append related-only sections into before/after buckets
3204
+ const queueRelatedSection = (section, position, entityOrder) => {
3205
+ if (!section)
3206
+ return;
3207
+ if (position === 'before') {
3208
+ if (!beforeExtraIds.has(section.id)) {
3209
+ beforeExtraIds.add(section.id);
3210
+ beforeExtraSections.push({ section, entityOrder });
3211
+ }
3212
+ }
3213
+ else if (position === 'middle') {
3214
+ if (!middleExtraIds.has(section.id)) {
3215
+ middleExtraIds.add(section.id);
3216
+ middleExtraSections.push({ section });
3217
+ }
3218
+ }
3219
+ else {
3220
+ if (!afterExtraIds.has(section.id)) {
3221
+ afterExtraIds.add(section.id);
3222
+ afterExtraSections.push({ section, entityOrder });
3223
+ }
3224
+ }
3225
+ };
3226
+ // Resolve and merge merge-detail entities
3227
+ // Sort related entities by position group then by layout.order
3228
+ if (mergeDetailEntities?.length && dependencies?.entityResolver) {
3229
+ const beforeEntities = (mergeDetailEntities || [])
3230
+ .filter((re) => (re.layout?.position ?? 'middle') === 'before')
3231
+ .sort((a, b) => (a.layout?.order ?? Number.MAX_SAFE_INTEGER) - (b.layout?.order ?? Number.MAX_SAFE_INTEGER));
3232
+ const middleEntities = (mergeDetailEntities || []).filter((re) => (re.layout?.position ?? 'middle') === 'middle');
3233
+ const afterEntities = (mergeDetailEntities || [])
3234
+ .filter((re) => (re.layout?.position ?? 'middle') === 'after')
3235
+ .sort((a, b) => (a.layout?.order ?? Number.MAX_SAFE_INTEGER) - (b.layout?.order ?? Number.MAX_SAFE_INTEGER));
3236
+ const processRelated = async (relatedEntity) => {
3237
+ try {
3238
+ const [moduleName, entityName] = relatedEntity.entity.split('.');
3239
+ const entityDef = await dependencies.entityResolver.resolve(moduleName, entityName);
3240
+ if (!entityDef) {
3241
+ return;
3242
+ }
3243
+ const relSingle = entityDef?.interfaces?.master?.single;
3244
+ const relGroups = entityDef?.groups ?? [];
3245
+ // Merge related groups into allGroups (avoid duplicates by id)
3246
+ for (const rg of relGroups) {
3247
+ if (!allGroups.some((g) => g.id === rg.id)) {
3248
+ allGroups.push(rg);
3249
+ }
3250
+ }
3251
+ // Collect nested tab-list related entities from this merge-detail entity and convert to tabs
3252
+ try {
3253
+ const nestedTabListEntities = entityDef?.relatedEntities?.filter((re) => !re.hidden && (!re.layout?.type || re.layout?.type === 'tab-list'));
3254
+ if (nestedTabListEntities?.length) {
3255
+ const converter = this.relatedEntityConverterFactory.createTabListConverter();
3256
+ const nestedDataPath = relatedEntity?.persistence?.dataPath || entityName;
3257
+ const nestedContext = get(rootContext, nestedDataPath) ?? rootContext;
3258
+ for (const nre of nestedTabListEntities) {
3259
+ try {
3260
+ const tab = await converter.convert(nre, {
3261
+ entityResolver: dependencies.entityResolver,
3262
+ expressionEvaluator: dependencies.expressionEvaluator,
3263
+ // Evaluate conditions relative to the merge-detail entity's dataPath
3264
+ context: nestedContext,
3265
+ });
3266
+ nestedTabListTabs.push(tab);
3267
+ }
3268
+ catch { }
3269
+ }
3270
+ }
3271
+ }
3272
+ catch { }
3273
+ // Build related props map per group with metadata: __dataPath and __layout
3274
+ // If referenced strategy with mapping, exclude mapped target property names from UI props
3275
+ const p = relatedEntity?.persistence || {};
3276
+ const strategy = p.strategy || 'embedded';
3277
+ const mappedTargets = Object.keys(p.map || {}).map((k) => (k || '').split('.')[0]);
3278
+ const relPropsByGroup = (entityDef?.properties ?? []).reduce((acc, p) => {
3279
+ if (strategy === 'referenced' &&
3280
+ (relatedEntity?.layout?.type === 'merge-detail' ||
3281
+ relatedEntity?.layout?.type === 'page-detail' ||
3282
+ relatedEntity?.layout?.type === 'tab-detail') &&
3283
+ mappedTargets.includes(p.name)) {
3284
+ return acc; // skip mapped properties
3285
+ }
3286
+ if (!acc[p.groupId])
3287
+ acc[p.groupId] = [];
3288
+ // Clone shallow to not mutate original definitions
3289
+ const propClone = { ...p };
3290
+ propClone.__dataPath = relatedEntity?.persistence?.dataPath || entityName;
3291
+ propClone.__layout = relSingle?.properties?.find((x) => x.name === p.name)?.layout;
3292
+ acc[p.groupId].push(propClone);
3293
+ return acc;
3294
+ }, {});
3295
+ // Merge properties by section id
3296
+ const position = relatedEntity.layout?.position ?? 'middle';
3297
+ const entityOrder = relatedEntity.layout?.order ?? Number.MAX_SAFE_INTEGER;
3298
+ const relSections = (relSingle?.sections ?? []).filter((s) => relGroups.some((g) => g.id === s.id));
3299
+ for (const rs of relSections) {
3300
+ const sectionId = rs.id;
3301
+ const mainHasSection = !!mainSections?.some((s) => s.id === sectionId);
3302
+ const relProps = relPropsByGroup[sectionId] ?? [];
3303
+ if (mainHasSection) {
3304
+ const current = mergedPropsByGroup[sectionId] ?? [];
3305
+ mergedPropsByGroup[sectionId] =
3306
+ position === 'before' ? [...relProps, ...current] : [...current, ...relProps];
3307
+ // Capture override order for main section when position is 'before'
3308
+ if (position === 'before') {
3309
+ const order = rs?.order ?? 0;
3310
+ const prev = beforeOverrideSectionOrders[sectionId] ?? Number.MAX_SAFE_INTEGER;
3311
+ beforeOverrideSectionOrders[sectionId] = Math.min(prev, order);
3312
+ }
3313
+ }
3314
+ else {
3315
+ // Section isn't in main; queue section for rendering and set its props
3316
+ if (!mergedPropsByGroup[sectionId]) {
3317
+ mergedPropsByGroup[sectionId] = [];
3318
+ }
3319
+ mergedPropsByGroup[sectionId] =
3320
+ position === 'before'
3321
+ ? [...(relProps ?? []), ...(mergedPropsByGroup[sectionId] ?? [])]
3322
+ : [...(mergedPropsByGroup[sectionId] ?? []), ...(relProps ?? [])];
3323
+ queueRelatedSection(rs, position, entityOrder);
3324
+ }
3325
+ }
3326
+ }
3327
+ catch {
3328
+ // Silently ignore failures to resolve or merge
3329
+ }
3330
+ };
3331
+ // Process BEFORE entities first (sorted), then AFTER entities
3332
+ for (const re of beforeEntities) {
3333
+ await processRelated(re);
3334
+ }
3335
+ for (const re of middleEntities) {
3336
+ await processRelated(re);
3337
+ }
3338
+ for (const re of afterEntities) {
3339
+ await processRelated(re);
3340
+ }
3341
+ }
3151
3342
  const getGroupById = (id) => {
3152
3343
  return groups.find((s) => s.id === id);
3153
3344
  };
3154
3345
  const filterValidSections = (sections) => {
3155
3346
  return (sections?.filter((section) => {
3156
- return groups.some((group) => group.id === section.id);
3347
+ return allGroups.some((group) => group.id === section.id);
3157
3348
  }) ?? []);
3158
3349
  };
3350
+ // Utility: sort related-only sections by entity order then section order
3351
+ const sortRelatedSections = (sections) => [...(sections ?? [])]
3352
+ .filter((e) => !!e?.section)
3353
+ .sort((a, b) => {
3354
+ const ae = a.entityOrder ?? Number.MAX_SAFE_INTEGER;
3355
+ const be = b.entityOrder ?? Number.MAX_SAFE_INTEGER;
3356
+ if (ae !== be)
3357
+ return ae - be;
3358
+ const ao = a.section?.order ?? 0;
3359
+ const bo = b.section?.order ?? 0;
3360
+ return ao - bo;
3361
+ })
3362
+ .map((e) => e.section);
3363
+ // Determine effective order for main sections: if any BEFORE related merged that section, use its order; otherwise keep main order
3364
+ const computeEffectiveMainOrder = (s) => {
3365
+ const defaultOrder = s?.order ?? 0;
3366
+ const beforeOverride = beforeOverrideSectionOrders?.[s?.id ?? ''];
3367
+ return beforeOverride != null ? beforeOverride : defaultOrder;
3368
+ };
3369
+ // Build combined section list:
3370
+ // 1) related-before (entity-sorted)
3371
+ // 2) middle block: main sections + related-middle-only sections sorted by their section.order (with effective order for main)
3372
+ // 3) related-after (entity-sorted)
3373
+ const beforeSections = sortRelatedSections(beforeExtraSections);
3374
+ const mainSectionsList = [...filterValidSections(mainSections)];
3375
+ const middleOnlySections = middleExtraSections.map((e) => e.section);
3376
+ const middleBlock = [...mainSectionsList, ...middleOnlySections].sort((a, b) => {
3377
+ const ao = computeEffectiveMainOrder(a);
3378
+ const bo = computeEffectiveMainOrder(b);
3379
+ return ao - bo;
3380
+ });
3381
+ const afterSections = sortRelatedSections(afterExtraSections);
3382
+ const combinedSections = [...beforeSections, ...middleBlock, ...afterSections];
3383
+ // Debug: Log final sorted sections for verification
3384
+ try {
3385
+ const beforeEntityOrderMap = new Map(beforeExtraSections.map((e) => [e.section?.id, e.entityOrder ?? Number.MAX_SAFE_INTEGER]));
3386
+ const afterEntityOrderMap = new Map(afterExtraSections.map((e) => [e.section?.id, e.entityOrder ?? Number.MAX_SAFE_INTEGER]));
3387
+ const debugSections = [
3388
+ ...beforeSections.map((s) => ({
3389
+ bucket: 'before',
3390
+ id: s?.id,
3391
+ sectionOrder: s?.order ?? 0,
3392
+ entityOrder: beforeEntityOrderMap.get(s?.id) ?? Number.MAX_SAFE_INTEGER,
3393
+ })),
3394
+ ...middleBlock.map((s) => ({
3395
+ bucket: 'middle',
3396
+ id: s?.id,
3397
+ sectionOrder: s?.order ?? 0,
3398
+ effectiveOrder: computeEffectiveMainOrder(s),
3399
+ })),
3400
+ ...afterSections.map((s) => ({
3401
+ bucket: 'after',
3402
+ id: s?.id,
3403
+ sectionOrder: s?.order ?? 0,
3404
+ entityOrder: afterEntityOrderMap.get(s?.id) ?? Number.MAX_SAFE_INTEGER,
3405
+ })),
3406
+ ];
3407
+ // eslint-disable-next-line no-console
3408
+ console.debug('[AXP] merge-details sorted sections', debugSections);
3409
+ }
3410
+ catch { }
3159
3411
  // Create expression evaluator for actions
3160
3412
  const evaluateExpressions = dependencies?.expressionEvaluator
3161
3413
  ? this.createExpressionEvaluator(rootContext, dependencies.expressionEvaluator)
3162
3414
  : null;
3163
3415
  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);
3416
+ return (mergedPropsByGroup[groupId] ?? []);
3180
3417
  };
3181
- const getPropertyLayout = (name) => {
3182
- return singleInterface?.properties?.find((p) => p.name === name)?.layout;
3418
+ const getPropertyLayout = (name, prop) => {
3419
+ // Prefer per-property layout (for merged related props), fallback to main entity layout
3420
+ return prop?.__layout ?? singleInterface?.properties?.find((p) => p.name === name)?.layout;
3183
3421
  };
3184
3422
  // Get related entities for tabs
3185
3423
  const tabDetailEntities = entity?.relatedEntities?.filter((re) => !re.hidden && re.layout?.type === 'tab-detail');
@@ -3189,9 +3427,11 @@ class AXPMainEntityContentBuilder {
3189
3427
  const tabListTabs = await this.buildTabLists(tabListEntities ?? [], rootContext, dependencies);
3190
3428
  // Build actions from single interface
3191
3429
  const actions = this.buildActions(entity, singleInterface);
3430
+ console.log({ rootContext, dependencies });
3192
3431
  return {
3193
3432
  id: entity?.name ?? '',
3194
- title: singleInterface?.title ?? entity?.formats.individual ?? '',
3433
+ // title: singleInterface?.title ?? entity?.formats.individual ?? '',
3434
+ title: rootTitle ?? entity?.formats.individual,
3195
3435
  label: entity?.formats.displayName ?? singleInterface?.title ?? '',
3196
3436
  icon: entity?.icon,
3197
3437
  actions: await this.buildEvaluatedActions(actions, evaluateExpressions),
@@ -3278,7 +3518,7 @@ class AXPMainEntityContentBuilder {
3278
3518
  };
3279
3519
  }
3280
3520
  },
3281
- tabs: [...tabDetailTabs, ...tabListTabs],
3521
+ tabs: [...tabDetailTabs, ...tabListTabs, ...nestedTabListTabs],
3282
3522
  content: [
3283
3523
  {
3284
3524
  type: 'grid-layout',
@@ -3292,7 +3532,7 @@ class AXPMainEntityContentBuilder {
3292
3532
  },
3293
3533
  },
3294
3534
  },
3295
- children: await Promise.all(filterValidSections(singleInterface?.sections ?? []).map(async (s) => ({
3535
+ children: await Promise.all(combinedSections.map(async (s) => ({
3296
3536
  type: 'grid-item-layout',
3297
3537
  name: s.id,
3298
3538
  options: {
@@ -3304,9 +3544,10 @@ class AXPMainEntityContentBuilder {
3304
3544
  {
3305
3545
  type: 'fieldset-layout',
3306
3546
  options: {
3307
- title: getGroupById(s.id)?.title ?? '',
3547
+ title: allGroups.find((g) => g.id === s.id)?.title ?? '',
3308
3548
  collapsible: true,
3309
3549
  isOpen: !s.collapsed,
3550
+ look: 'card'
3310
3551
  },
3311
3552
  children: [
3312
3553
  {
@@ -3321,14 +3562,16 @@ class AXPMainEntityContentBuilder {
3321
3562
  },
3322
3563
  },
3323
3564
  children: (await getVisiblePropertyByGroupId(s.id)).map((p) => {
3324
- const layout = getPropertyLayout(p.name);
3565
+ const layout = getPropertyLayout(p.name, p);
3566
+ const prefixed = p.__dataPath ? `${p.__dataPath}.${p.name}` : p.name;
3325
3567
  return {
3326
3568
  type: 'grid-item-layout',
3327
- name: p.name,
3569
+ name: prefixed,
3328
3570
  options: {
3329
3571
  colSpan: layout?.positions?.lg?.colSpan,
3330
3572
  colStart: layout?.positions?.lg?.colStart,
3331
3573
  colEnd: layout?.positions?.lg?.colEnd,
3574
+ hidden: p.schema.hidden,
3332
3575
  },
3333
3576
  children: [
3334
3577
  {
@@ -3340,8 +3583,8 @@ class AXPMainEntityContentBuilder {
3340
3583
  children: [
3341
3584
  {
3342
3585
  type: p.schema.interface?.type ?? '',
3343
- path: p.name,
3344
- name: p.name,
3586
+ path: prefixed,
3587
+ name: prefixed,
3345
3588
  defaultValue: p.schema.defaultValue,
3346
3589
  children: p.schema.interface?.children,
3347
3590
  triggers: p.schema.interface?.triggers,
@@ -3352,6 +3595,8 @@ class AXPMainEntityContentBuilder {
3352
3595
  message: c.message,
3353
3596
  options: c.options,
3354
3597
  })),
3598
+ // Attach dataPath for merged properties to be available in widgets/options if needed
3599
+ dataPath: p.__dataPath,
3355
3600
  }),
3356
3601
  },
3357
3602
  ],
@@ -3506,10 +3751,11 @@ class AXPLayoutAdapterFactory {
3506
3751
  return await fn(id);
3507
3752
  }
3508
3753
  async buildMainPage(entity, rootContext, dependencies) {
3509
- return this.mainEntityContentBuilder.build(entity, rootContext, dependencies);
3754
+ return this.mainEntityContentBuilder.build(entity, rootContext, dependencies, await this.getRootTitle(entity, rootContext, dependencies));
3510
3755
  }
3511
3756
  async buildRelatedPages(entity, rootContext, dependencies) {
3512
3757
  const pages = [];
3758
+ const rootTitle = await this.getRootTitle(entity, rootContext, dependencies);
3513
3759
  // Page Details
3514
3760
  const pageDetailEntities = entity?.relatedEntities?.filter((re) => !re.hidden && re.layout?.type === 'page-detail');
3515
3761
  for (const relatedEntity of pageDetailEntities || []) {
@@ -3517,7 +3763,7 @@ class AXPLayoutAdapterFactory {
3517
3763
  pages.push(await converter.convert(relatedEntity, {
3518
3764
  ...dependencies,
3519
3765
  context: rootContext,
3520
- rootTitle: await this.getRootTitle(entity, rootContext, dependencies),
3766
+ rootTitle: rootTitle,
3521
3767
  }));
3522
3768
  }
3523
3769
  // Page Lists
@@ -3527,9 +3773,43 @@ class AXPLayoutAdapterFactory {
3527
3773
  pages.push(await converter.convert(relatedEntity, {
3528
3774
  ...dependencies,
3529
3775
  context: rootContext,
3530
- rootTitle: await this.getRootTitle(entity, rootContext, dependencies),
3776
+ rootTitle: rootTitle,
3531
3777
  }));
3532
3778
  }
3779
+ // Include nested page-related entities from merge-detail related entities
3780
+ const mergeDetailEntities = entity?.relatedEntities?.filter((re) => !re.hidden && re.layout?.type === 'merge-detail');
3781
+ for (const mergeRelated of mergeDetailEntities || []) {
3782
+ try {
3783
+ const [moduleName, childEntityName] = (mergeRelated.entity || '').split('.');
3784
+ const childEntity = await dependencies.entityResolver.resolve(moduleName, childEntityName);
3785
+ if (!childEntity) {
3786
+ continue;
3787
+ }
3788
+ const nestedDataPath = mergeRelated?.persistence?.dataPath || childEntityName;
3789
+ const nestedContext = get(rootContext, nestedDataPath) ?? rootContext;
3790
+ const nestedPageDetailEntities = childEntity?.relatedEntities?.filter((re) => !re.hidden && re.layout?.type === 'page-detail');
3791
+ for (const nestedRelated of nestedPageDetailEntities || []) {
3792
+ const converter = this.relatedEntityConverterFactory.createPageDetailsConverter();
3793
+ pages.push(await converter.convert(nestedRelated, {
3794
+ ...dependencies,
3795
+ context: nestedContext,
3796
+ rootTitle: rootTitle,
3797
+ }));
3798
+ }
3799
+ const nestedPageListEntities = childEntity?.relatedEntities?.filter((re) => !re.hidden && re.layout?.type === 'page-list');
3800
+ for (const nestedRelated of nestedPageListEntities || []) {
3801
+ const converter = this.relatedEntityConverterFactory.createPageListConverter();
3802
+ pages.push(await converter.convert(nestedRelated, {
3803
+ ...dependencies,
3804
+ context: nestedContext,
3805
+ rootTitle: rootTitle,
3806
+ }));
3807
+ }
3808
+ }
3809
+ catch {
3810
+ // Silently ignore failures for nested page inclusions
3811
+ }
3812
+ }
3533
3813
  return pages;
3534
3814
  }
3535
3815
  composePagesWithPositions(mainPage, relatedPages, entity) {
@@ -5389,6 +5669,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
5389
5669
  }
5390
5670
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPLookupWidgetEditComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
5391
5671
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: AXPLookupWidgetEditComponent, isStandalone: true, selector: "axp-lookup-widget-edit", viewQueries: [{ propertyName: "textbox", first: true, predicate: AXTagBoxComponent, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
5672
+ @if(vm()) {
5392
5673
  @if (look() == 'select') {
5393
5674
  <ax-select-box
5394
5675
  [dataSource]="vm()?.dataSource!"
@@ -5407,7 +5688,6 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
5407
5688
  }
5408
5689
  </ax-select-box>
5409
5690
  } @else {
5410
- {{selectedItemsText()}}
5411
5691
  <ax-tag-box
5412
5692
  [ngModel]="selectedItems()"
5413
5693
  [textField]="displayField()"
@@ -5447,15 +5727,17 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
5447
5727
  </ax-suffix>
5448
5728
  </ax-tag-box>
5449
5729
  }
5730
+ }
5450
5731
  `, 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:
5451
5732
  //
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 }); }
5733
+ 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 }); }
5453
5734
  }
5454
5735
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPLookupWidgetEditComponent, decorators: [{
5455
5736
  type: Component,
5456
5737
  args: [{
5457
5738
  selector: 'axp-lookup-widget-edit',
5458
5739
  template: `
5740
+ @if(vm()) {
5459
5741
  @if (look() == 'select') {
5460
5742
  <ax-select-box
5461
5743
  [dataSource]="vm()?.dataSource!"
@@ -5474,7 +5756,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
5474
5756
  }
5475
5757
  </ax-select-box>
5476
5758
  } @else {
5477
- {{selectedItemsText()}}
5478
5759
  <ax-tag-box
5479
5760
  [ngModel]="selectedItems()"
5480
5761
  [textField]="displayField()"
@@ -5514,6 +5795,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
5514
5795
  </ax-suffix>
5515
5796
  </ax-tag-box>
5516
5797
  }
5798
+ }
5517
5799
  `,
5518
5800
  changeDetection: ChangeDetectionStrategy.OnPush,
5519
5801
  imports: [
@@ -5791,7 +6073,7 @@ class AXPTagableBoxWidgetEditComponent extends AXPValueWidgetComponent {
5791
6073
  </ax-prefix>
5792
6074
  </ax-button>
5793
6075
  </div>
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 }); }
6076
+ `, 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 }); }
5795
6077
  }
5796
6078
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPTagableBoxWidgetEditComponent, decorators: [{
5797
6079
  type: Component,
@@ -6399,7 +6681,7 @@ class AXPShowDetailViewAction extends AXPWorkflowAction {
6399
6681
  const [module, entity] = context.getVariable('entity').split('.');
6400
6682
  const { id } = context.getVariable('data');
6401
6683
  const newPayload = {
6402
- commands: `/${this.sessionService.application?.name}/m/${module}/e/${entity}/${id}/view`,
6684
+ commands: `/${this.sessionService.application?.name}/m/${module}/e/${entity}/${id}/new-view`,
6403
6685
  };
6404
6686
  context.setVariable('payload', newPayload);
6405
6687
  this.navigation.execute(context);
@@ -6860,7 +7142,7 @@ function entityDetailsSimpleCondition(fk) {
6860
7142
  value: '{{context.eval("id")}}',
6861
7143
  };
6862
7144
  }
6863
- function entityDetailsReferenceCondition() {
7145
+ function entityDetailsReferenceCondition(type) {
6864
7146
  return [
6865
7147
  {
6866
7148
  name: 'reference.id',
@@ -6870,7 +7152,7 @@ function entityDetailsReferenceCondition() {
6870
7152
  {
6871
7153
  name: 'reference.type',
6872
7154
  operator: { type: 'equal' },
6873
- value: '{{context.eval("entityName")}}',
7155
+ value: type,
6874
7156
  },
6875
7157
  ];
6876
7158
  }
@@ -6880,6 +7162,7 @@ function entityDetailsEditAction() {
6880
7162
  command: 'quick-modify-entity',
6881
7163
  priority: 'secondary',
6882
7164
  type: 'update',
7165
+ default: true,
6883
7166
  scope: AXPEntityCommandScope.Individual,
6884
7167
  };
6885
7168
  }
@@ -6896,7 +7179,7 @@ function entityOverrideDetailsViewAction() {
6896
7179
  function entityDetailsCrudActions(parentId) {
6897
7180
  return [entityDetailsCreateActions(parentId), entityDetailsEditAction(), entityOverrideDetailsViewAction()];
6898
7181
  }
6899
- function entityDetailsReferenceCreateActions() {
7182
+ function entityDetailsReferenceCreateActions(type) {
6900
7183
  return [
6901
7184
  {
6902
7185
  title: '@general:actions.create.title',
@@ -6909,7 +7192,7 @@ function entityDetailsReferenceCreateActions() {
6909
7192
  data: {
6910
7193
  reference: {
6911
7194
  id: '{{context.eval("id")}}',
6912
- type: '{{context.eval("entityName")}}',
7195
+ type: type,
6913
7196
  },
6914
7197
  },
6915
7198
  },