@acorex/platform 20.9.27 → 20.9.29

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.
@@ -1,4 +1,4 @@
1
- import { mergeForeignKeyFieldIntoCreateActions, collectNestedCreateHiddenProperties, AXPEntityCommandScope, normalizeEntityDisplayTemplate, sanitizeResolvedEntityDisplayTitle, isUnresolvedEntityDisplayTemplate, AXPEntityDataSourceKeys, isCardFieldBadgeDisplay, resolveCardFieldBadgeColor, getEntityInfo, resolveEnabledMasterListLayouts, resolveDefaultMasterListLayout, AXPEntityEventsKeys, collectEntityListSortableFields, collectEntityListFilterDefinitions, parseDottedFieldPath, ENTITY_ROW_POPUP_TITLE_OPTION, resolveLookupWidgetCreateOptions, buildPageListWidgetName, AXPEntityQueryType, buildEntitySearchTitleContext } from '@acorex/platform/layout/entity-contracts';
1
+ import { mergeForeignKeyFieldIntoCreateActions, collectNestedCreateHiddenProperties, AXPEntityCommandScope, normalizeEntityDisplayTemplate, sanitizeResolvedEntityDisplayTitle, isUnresolvedEntityDisplayTemplate, AXPEntityDataSourceKeys, isCardFieldBadgeDisplay, resolveCardFieldBadgeColor, isEntityActionPermitted, getEntityInfo, resolveEnabledMasterListLayouts, resolveDefaultMasterListLayout, AXPEntityEventsKeys, collectEntityListSortableFields, collectEntityListFilterDefinitions, parseDottedFieldPath, ENTITY_ROW_POPUP_TITLE_OPTION, resolveLookupWidgetCreateOptions, buildPageListWidgetName, AXPEntityQueryType, buildEntitySearchTitleContext } from '@acorex/platform/layout/entity-contracts';
2
2
  export * from '@acorex/platform/layout/entity-contracts';
3
3
  export { collectNestedCreateHiddenProperties, entityDetailsCreateActions, entityDetailsCreateActionsDeferredParent, entityDetailsCrudActions, entityDetailsEditAction, entityDetailsNewEditAction, entityDetailsReferenceCondition, entityDetailsReferenceCreateActions, entityDetailsSimpleCondition, entityMasterBulkDeleteAction, entityMasterCreateAction, entityMasterCrudActions, entityMasterDeleteAction, entityMasterEditAction, entityMasterRecordActions, entityMasterViewAction, entityOverrideDetailsViewAction, mergeForeignKeyFieldIntoCreateActions } from '@acorex/platform/layout/entity-contracts';
4
4
  import { AXToastService } from '@acorex/components/toast';
@@ -4384,6 +4384,7 @@ class AXPEntityCommandTriggerViewModel {
4384
4384
  this.disabled = action.disabled ?? false;
4385
4385
  this.default = action.default ?? false;
4386
4386
  this.shortcuts = action.shortcuts;
4387
+ this.permissions = action.permissions;
4387
4388
  this.scope = action.scope;
4388
4389
  this.order = action.order ?? 0;
4389
4390
  this.isChild = isChild;
@@ -4478,6 +4479,7 @@ class AXPEntityDetailListViewModel {
4478
4479
  this.expressionEvaluator = this.injector.get(AXPExpressionEvaluatorService);
4479
4480
  this.queryExecutor = this.injector.get(AXPQueryExecutor);
4480
4481
  this.settingsService = this.injector.get(AXPSettingsService);
4482
+ this.session = this.injector.get(AXPSessionService);
4481
4483
  this.destroyed = new Subject();
4482
4484
  this.showRowIndexColumnEnabled = signal(false, ...(ngDevMode ? [{ debugName: "showRowIndexColumnEnabled" }] : /* istanbul ignore next */ []));
4483
4485
  this.lastAppliedFilterKey = null;
@@ -4576,20 +4578,27 @@ class AXPEntityDetailListViewModel {
4576
4578
  return [...additionalActions, ...mergedActions];
4577
4579
  }, ...(ngDevMode ? [{ debugName: "allActions" }] : /* istanbul ignore next */ []));
4578
4580
  this.selectedScopeActionsCount = computed(() => {
4579
- return this.allActions().filter((a) => a.scope == AXPEntityCommandScope.Selected).length;
4581
+ return this.allActions().filter((a) => a.scope == AXPEntityCommandScope.Selected &&
4582
+ isEntityActionPermitted(a, (...keys) => this.session.authorize(...keys))).length;
4580
4583
  }, ...(ngDevMode ? [{ debugName: "selectedScopeActionsCount" }] : /* istanbul ignore next */ []));
4581
4584
  this.primaryActions = computed(() => {
4582
4585
  return this.allActions().filter((a) => a.priority == 'primary' &&
4586
+ isEntityActionPermitted(a, (...keys) => this.session.authorize(...keys)) &&
4583
4587
  ((a.scope == AXPEntityCommandScope.Selected && this.hasSelectedItems()) ||
4584
4588
  (a.scope == AXPEntityCommandScope.TypeLevel && !this.hasSelectedItems())));
4585
4589
  }, ...(ngDevMode ? [{ debugName: "primaryActions" }] : /* istanbul ignore next */ []));
4586
4590
  this.secondaryActions = computed(() => {
4587
4591
  return this.allActions().filter((a) => a.priority == 'secondary' &&
4592
+ isEntityActionPermitted(a, (...keys) => this.session.authorize(...keys)) &&
4588
4593
  ((a.scope == AXPEntityCommandScope.Selected && this.hasSelectedItems()) ||
4589
4594
  (a.scope == AXPEntityCommandScope.TypeLevel && !this.hasSelectedItems())));
4590
4595
  }, ...(ngDevMode ? [{ debugName: "secondaryActions" }] : /* istanbul ignore next */ []));
4591
- this.primaryRowActions = computed(() => this.allActions().filter((a) => a.scope == AXPEntityCommandScope.Individual && a.priority === 'primary'), ...(ngDevMode ? [{ debugName: "primaryRowActions" }] : /* istanbul ignore next */ []));
4592
- this.secondaryRowActions = computed(() => this.allActions().filter((a) => a.scope == AXPEntityCommandScope.Individual && a.priority === 'secondary'), ...(ngDevMode ? [{ debugName: "secondaryRowActions" }] : /* istanbul ignore next */ []));
4596
+ this.primaryRowActions = computed(() => this.allActions().filter((a) => a.scope == AXPEntityCommandScope.Individual &&
4597
+ a.priority === 'primary' &&
4598
+ isEntityActionPermitted(a, (...keys) => this.session.authorize(...keys))), ...(ngDevMode ? [{ debugName: "primaryRowActions" }] : /* istanbul ignore next */ []));
4599
+ this.secondaryRowActions = computed(() => this.allActions().filter((a) => a.scope == AXPEntityCommandScope.Individual &&
4600
+ a.priority === 'secondary' &&
4601
+ isEntityActionPermitted(a, (...keys) => this.session.authorize(...keys))), ...(ngDevMode ? [{ debugName: "secondaryRowActions" }] : /* istanbul ignore next */ []));
4593
4602
  //****************** Filter ******************//
4594
4603
  this.inlineFilters = {
4595
4604
  field: null,
@@ -4754,6 +4763,9 @@ class AXPEntityDetailListViewModel {
4754
4763
  ((a.scope == AXPEntityCommandScope.Selected && this.hasSelectedItems()) ||
4755
4764
  (a.scope == AXPEntityCommandScope.TypeLevel && !this.hasSelectedItems())))
4756
4765
  .map(async (a) => {
4766
+ if (!isEntityActionPermitted(a, (...keys) => this.session.authorize(...keys))) {
4767
+ return null;
4768
+ }
4757
4769
  const isHidden = await this.evaluateExpressions(a.hidden);
4758
4770
  if (isHidden)
4759
4771
  return null;
@@ -4772,6 +4784,9 @@ class AXPEntityDetailListViewModel {
4772
4784
  ((a.scope == AXPEntityCommandScope.Selected && this.hasSelectedItems()) ||
4773
4785
  (a.scope == AXPEntityCommandScope.TypeLevel && !this.hasSelectedItems())))
4774
4786
  .map(async (a) => {
4787
+ if (!isEntityActionPermitted(a, (...keys) => this.session.authorize(...keys))) {
4788
+ return null;
4789
+ }
4775
4790
  const isHidden = await this.evaluateExpressions(a.hidden);
4776
4791
  if (isHidden)
4777
4792
  return null;
@@ -5636,9 +5651,12 @@ class AXPEntityMasterListViewModel {
5636
5651
  return flatten(this.allActions());
5637
5652
  }, ...(ngDevMode ? [{ debugName: "flattenedActions" }] : /* istanbul ignore next */ []));
5638
5653
  this.selectedScopeActionsCount = computed(() => {
5639
- return this.allActions().filter((a) => a.scope == AXPEntityCommandScope.Selected).length;
5654
+ return this.allActions().filter((a) => a.scope == AXPEntityCommandScope.Selected &&
5655
+ isEntityActionPermitted(a, (...keys) => this.session.authorize(...keys))).length;
5640
5656
  }, ...(ngDevMode ? [{ debugName: "selectedScopeActionsCount" }] : /* istanbul ignore next */ []));
5641
- this.primaryRowActions = computed(() => this.allActions().filter((a) => a.scope == AXPEntityCommandScope.Individual && a.priority === 'primary'), ...(ngDevMode ? [{ debugName: "primaryRowActions" }] : /* istanbul ignore next */ []));
5657
+ this.primaryRowActions = computed(() => this.allActions().filter((a) => a.scope == AXPEntityCommandScope.Individual &&
5658
+ a.priority === 'primary' &&
5659
+ isEntityActionPermitted(a, (...keys) => this.session.authorize(...keys))), ...(ngDevMode ? [{ debugName: "primaryRowActions" }] : /* istanbul ignore next */ []));
5642
5660
  //****************** Filter ******************//
5643
5661
  this.filterQueries = signal([], ...(ngDevMode ? [{ debugName: "filterQueries" }] : /* istanbul ignore next */ []));
5644
5662
  this.allAvailableColumns = () => {
@@ -6142,13 +6160,17 @@ class AXPEntityMasterListViewModel {
6142
6160
  ((a.scope == AXPEntityCommandScope.Selected && this.hasSelectedItems()) ||
6143
6161
  (a.scope == AXPEntityCommandScope.TypeLevel && !this.hasSelectedItems())))
6144
6162
  .map(async (a) => {
6163
+ if (!isEntityActionPermitted(a, (...keys) => this.session.authorize(...keys))) {
6164
+ return null;
6165
+ }
6145
6166
  const isHidden = await this.expressionEvaluator.evaluate(a.hidden, scope);
6146
6167
  if (isHidden)
6147
6168
  return null;
6148
6169
  const disabled = await this.expressionEvaluator.evaluate(a.disabled, scope);
6149
6170
  const name = await this.resolveTriggerName(a.name, null);
6150
6171
  const title = await this.resolveTitleExpression(a.title, null);
6151
- return { ...a, disabled, name, title };
6172
+ const items = a.items?.filter((child) => isEntityActionPermitted(child, (...keys) => this.session.authorize(...keys)));
6173
+ return { ...a, disabled, name, title, items };
6152
6174
  }));
6153
6175
  return actions.filter(Boolean);
6154
6176
  }
@@ -6159,13 +6181,17 @@ class AXPEntityMasterListViewModel {
6159
6181
  ((a.scope == AXPEntityCommandScope.Selected && this.hasSelectedItems()) ||
6160
6182
  (a.scope == AXPEntityCommandScope.TypeLevel && !this.hasSelectedItems())))
6161
6183
  .map(async (a) => {
6184
+ if (!isEntityActionPermitted(a, (...keys) => this.session.authorize(...keys))) {
6185
+ return null;
6186
+ }
6162
6187
  const isHidden = await this.expressionEvaluator.evaluate(a.hidden, scope);
6163
6188
  if (isHidden)
6164
6189
  return null;
6165
6190
  const disabled = await this.expressionEvaluator.evaluate(a.disabled, scope);
6166
6191
  const name = await this.resolveTriggerName(a.name, null);
6167
6192
  const title = await this.resolveTitleExpression(a.title, null);
6168
- return { ...a, disabled, name, title };
6193
+ const items = a.items?.filter((child) => isEntityActionPermitted(child, (...keys) => this.session.authorize(...keys)));
6194
+ return { ...a, disabled, name, title, items };
6169
6195
  }));
6170
6196
  return actions.filter(Boolean);
6171
6197
  }
@@ -6174,6 +6200,9 @@ class AXPEntityMasterListViewModel {
6174
6200
  const actions = await Promise.all(this.allActions()
6175
6201
  .filter((a) => a.scope === AXPEntityCommandScope.Individual && a.priority === 'secondary')
6176
6202
  .map(async (a) => {
6203
+ if (!isEntityActionPermitted(a, (...keys) => this.session.authorize(...keys))) {
6204
+ return null;
6205
+ }
6177
6206
  const isHidden = await this.expressionEvaluator.evaluate(a.hidden, scope);
6178
6207
  if (isHidden)
6179
6208
  return null;
@@ -7470,7 +7499,9 @@ class AXPEntityMasterSingleViewModel {
7470
7499
  this.updateTrigger = this._updateTrigger.asReadonly();
7471
7500
  this.context = signal(cloneDeep(this.entityData), ...(ngDevMode ? [{ debugName: "context" }] : /* istanbul ignore next */ []));
7472
7501
  this.actions = computed(() => {
7473
- return (this.entityDef.interfaces?.master?.single?.actions?.map((tr) => new AXPEntityCommandTriggerViewModel(this.entityDef, tr)) ?? []);
7502
+ return (this.entityDef.interfaces?.master?.single?.actions
7503
+ ?.map((tr) => new AXPEntityCommandTriggerViewModel(this.entityDef, tr))
7504
+ .filter((a) => isEntityActionPermitted(a, (...keys) => this.session.authorize(...keys))) ?? []);
7474
7505
  }, ...(ngDevMode ? [{ debugName: "actions" }] : /* istanbul ignore next */ []));
7475
7506
  this.primaryActions = computed(() => {
7476
7507
  return this.actions().filter((c) => c.priority == 'primary');
@@ -12221,6 +12252,7 @@ class AXPEntityListTableService {
12221
12252
  this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
12222
12253
  this.settings = inject(AXPSettingsService);
12223
12254
  this.columnWidthService = inject(AXPColumnWidthService);
12255
+ this.session = inject(AXPSessionService);
12224
12256
  this.evaluateExpressions = async (options, data) => {
12225
12257
  if (!options) {
12226
12258
  return {};
@@ -12336,7 +12368,8 @@ class AXPEntityListTableService {
12336
12368
  createRowCommands(actions, priority) {
12337
12369
  return actions
12338
12370
  .filter((action) => action.scope === AXPEntityCommandScope.Individual && // Only individual actions
12339
- action.priority === priority)
12371
+ action.priority === priority &&
12372
+ isEntityActionPermitted(action, (...keys) => this.session.authorize(...keys)))
12340
12373
  .map((action) => ({
12341
12374
  name: action.name,
12342
12375
  text: action.title,
@@ -12363,7 +12396,8 @@ class AXPEntityListTableService {
12363
12396
  */
12364
12397
  hasSelectedScopeActions(entity) {
12365
12398
  const actions = entity.interfaces?.master?.list?.actions || [];
12366
- return actions.some((action) => action.scope === AXPEntityCommandScope.Selected);
12399
+ return actions.some((action) => action.scope === AXPEntityCommandScope.Selected &&
12400
+ isEntityActionPermitted(action, (...keys) => this.session.authorize(...keys)));
12367
12401
  }
12368
12402
  /**
12369
12403
  * Handle execution of a row command (shared by double-click and command handlers)
@@ -12643,6 +12677,7 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
12643
12677
  this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
12644
12678
  this.columnWidthService = inject(AXPColumnWidthService);
12645
12679
  this.route = inject(ActivatedRoute);
12680
+ this.session = inject(AXPSessionService);
12646
12681
  this.isMounted = signal(false, ...(ngDevMode ? [{ debugName: "isMounted" }] : /* istanbul ignore next */ []));
12647
12682
  this.entity = signal(null, ...(ngDevMode ? [{ debugName: "entity" }] : /* istanbul ignore next */ []));
12648
12683
  this.listNode = signal(null, ...(ngDevMode ? [{ debugName: "listNode" }] : /* istanbul ignore next */ []));
@@ -12687,7 +12722,7 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
12687
12722
  return !usedOverrideActions.has(actionKey);
12688
12723
  })
12689
12724
  .map((action) => new AXPEntityCommandTriggerViewModel(this.entity(), action));
12690
- return [...additionalActions, ...mergedActions];
12725
+ return [...additionalActions, ...mergedActions].filter((a) => isEntityActionPermitted(a, (...keys) => this.session.authorize(...keys)));
12691
12726
  }, ...(ngDevMode ? [{ debugName: "allActions" }] : /* istanbul ignore next */ []));
12692
12727
  this.primaryActions = computed(() => {
12693
12728
  const actions = this.allActions()
@@ -23081,6 +23116,10 @@ class AXPPageDetailsConverter extends AXPBaseRelatedEntityConverter {
23081
23116
  }
23082
23117
 
23083
23118
  class AXPPageListConverter extends AXPBaseRelatedEntityConverter {
23119
+ constructor(session) {
23120
+ super();
23121
+ this.session = session;
23122
+ }
23084
23123
  async convert(relatedEntity, context) {
23085
23124
  const { entityDef } = await this.getEntityDefinition(relatedEntity, context.entityResolver);
23086
23125
  const evaluateExpressions = async (actionData) => {
@@ -23119,7 +23158,9 @@ class AXPPageListConverter extends AXPBaseRelatedEntityConverter {
23119
23158
  /** List-only page: scoped filters are system state, not user edits. */
23120
23159
  isReadonly: true,
23121
23160
  actions: this.mergeActions(entityDef, actions)
23122
- ?.filter((a) => a.priority === 'primary' && !a.isChild)
23161
+ ?.filter((a) => a.priority === 'primary' &&
23162
+ !a.isChild &&
23163
+ isEntityActionPermitted(a, (...keys) => this.session.authorize(...keys)))
23123
23164
  ?.map((a) => {
23124
23165
  return {
23125
23166
  ...a,
@@ -23338,7 +23379,7 @@ class AXPPageListConverter extends AXPBaseRelatedEntityConverter {
23338
23379
  return !usedOverrideActions.has(actionKey);
23339
23380
  })
23340
23381
  .map((action) => new AXPEntityCommandTriggerViewModel(entityDef, action));
23341
- return [...additionalActions, ...mergedActions];
23382
+ return [...additionalActions, ...mergedActions].filter((a) => isEntityActionPermitted(a, (...keys) => this.session.authorize(...keys)));
23342
23383
  }
23343
23384
  }
23344
23385
 
@@ -23433,12 +23474,15 @@ class AXPTabListConverter extends AXPBaseRelatedEntityConverter {
23433
23474
  }
23434
23475
 
23435
23476
  class AXPRelatedEntityConverterFactory {
23477
+ constructor() {
23478
+ this.session = inject(AXPSessionService);
23479
+ }
23436
23480
  createConverter(type) {
23437
23481
  switch (type) {
23438
23482
  case 'page-detail':
23439
23483
  return new AXPPageDetailsConverter();
23440
23484
  case 'page-list':
23441
- return new AXPPageListConverter();
23485
+ return new AXPPageListConverter(this.session);
23442
23486
  case 'tab-detail':
23443
23487
  return new AXPTabDetailsConverter();
23444
23488
  case 'tab-list':