@acorex/platform 20.9.38 → 20.9.39
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.
- package/fesm2022/acorex-platform-layout-entity-contracts.mjs +3 -2
- package/fesm2022/acorex-platform-layout-entity-contracts.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity.mjs +66 -21
- package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widgets.mjs +65 -8
- package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
- package/fesm2022/acorex-platform-themes-default.mjs +1 -1
- package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
- package/package.json +1 -1
- package/types/acorex-platform-layout-entity-contracts.d.ts +12 -3
- package/types/acorex-platform-layout-entity.d.ts +12 -2
- package/types/acorex-platform-layout-widgets.d.ts +8 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { mergeForeignKeyFieldIntoCreateActions, collectNestedCreateHiddenProperties, AXPEntityCommandScope, normalizeEntityDisplayTemplate, sanitizeResolvedEntityDisplayTitle, isUnresolvedEntityDisplayTemplate, resolveEntityListFilterContextField, resolveEntityListFilterQueryField, AXPEntityDataSourceKeys, isCardFieldBadgeDisplay, resolveCardFieldBadgeColor, isEntityActionPermitted, getEntityInfo, resolveEnabledMasterListLayouts, resolveDefaultMasterListLayout, AXPEntityEventsKeys, collectEntityListSortableFields, collectEntityListFilterDefinitions, parseDottedFieldPath, ENTITY_ROW_POPUP_TITLE_OPTION,
|
|
1
|
+
import { mergeForeignKeyFieldIntoCreateActions, collectNestedCreateHiddenProperties, AXPEntityCommandScope, normalizeEntityDisplayTemplate, sanitizeResolvedEntityDisplayTitle, isUnresolvedEntityDisplayTemplate, resolveEntityListFilterContextField, resolveEntityListFilterQueryField, AXPEntityDataSourceKeys, isCardFieldBadgeDisplay, resolveCardFieldBadgeColor, isEntityActionPermitted, getEntityInfo, resolveEnabledMasterListLayouts, resolveDefaultMasterListLayout, AXPEntityEventsKeys, collectEntityListSortableFields, collectEntityListFilterDefinitions, parseDottedFieldPath, ENTITY_ROW_POPUP_TITLE_OPTION, buildPageListWidgetName, resolveLookupWidgetCreateOptions, 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';
|
|
@@ -4552,12 +4552,14 @@ class AXPEntityListViewColumnViewModel {
|
|
|
4552
4552
|
this.width = this.column?.options?.width;
|
|
4553
4553
|
this.node = computed(() => {
|
|
4554
4554
|
const widget = this.property.schema.interface;
|
|
4555
|
+
// Column `visible` is resolved by the list viewmodel; do not forward expressions into widget options.
|
|
4556
|
+
const { visible: _columnVisible, ...columnOptions } = this.column?.options ?? {};
|
|
4555
4557
|
return {
|
|
4556
4558
|
path: this.column.options?.dataPath ?? this.name,
|
|
4557
4559
|
type: widget.type,
|
|
4558
4560
|
options: {
|
|
4559
4561
|
...widget?.options,
|
|
4560
|
-
...
|
|
4562
|
+
...columnOptions,
|
|
4561
4563
|
columnName: this.name,
|
|
4562
4564
|
// Include children from widget interface so column components can access them
|
|
4563
4565
|
...(widget.children ? { children: widget.children } : {}),
|
|
@@ -5587,7 +5589,7 @@ class AXPEntityMasterListViewModel {
|
|
|
5587
5589
|
if (shouldApplyViewState) {
|
|
5588
5590
|
this.view.set(nextView);
|
|
5589
5591
|
this.applyViewSorts();
|
|
5590
|
-
this.applyViewColumns();
|
|
5592
|
+
await this.applyViewColumns();
|
|
5591
5593
|
this.applyCardFields();
|
|
5592
5594
|
this.applyViewFilters();
|
|
5593
5595
|
this.resolvedListPaging.set(null);
|
|
@@ -5971,7 +5973,12 @@ class AXPEntityMasterListViewModel {
|
|
|
5971
5973
|
for (const column of next) {
|
|
5972
5974
|
const columnKey = column.column?.options?.dataPath ?? column.name;
|
|
5973
5975
|
column.width = defaultTo(columnWidthsMap.get(columnKey), column.column?.options?.width);
|
|
5974
|
-
|
|
5976
|
+
// Definition visibility (view.columns whitelist + options.visible) always wins for "hide".
|
|
5977
|
+
// Persisted settings may only further hide an already-allowed column.
|
|
5978
|
+
const definitionVisible = column.visible === true;
|
|
5979
|
+
const persistedVisible = columnVisibilityMap.get(columnKey);
|
|
5980
|
+
column.visible =
|
|
5981
|
+
definitionVisible && (persistedVisible === undefined ? true : persistedVisible !== false);
|
|
5975
5982
|
}
|
|
5976
5983
|
return next;
|
|
5977
5984
|
});
|
|
@@ -6107,7 +6114,7 @@ class AXPEntityMasterListViewModel {
|
|
|
6107
6114
|
const existingColumns = prev?.list?.views?.[this.view().name]?.columns;
|
|
6108
6115
|
const baseColumns = Array.isArray(existingColumns) && existingColumns.length
|
|
6109
6116
|
? existingColumns
|
|
6110
|
-
: this.
|
|
6117
|
+
: this.columns().map((c) => ({
|
|
6111
6118
|
name: c.column?.options?.dataPath ?? c.name,
|
|
6112
6119
|
visible: c.visible,
|
|
6113
6120
|
width: c.width,
|
|
@@ -6116,11 +6123,6 @@ class AXPEntityMasterListViewModel {
|
|
|
6116
6123
|
...c,
|
|
6117
6124
|
width: c.name === field ? columnSizeData.width : c.width,
|
|
6118
6125
|
}));
|
|
6119
|
-
const x = this.allAvailableColumns().map((c) => ({
|
|
6120
|
-
name: c.column?.options?.dataPath ?? c.name,
|
|
6121
|
-
visible: c.visible,
|
|
6122
|
-
width: c.width,
|
|
6123
|
-
}));
|
|
6124
6126
|
set(newSettings, `list.views.${this.view().name}.columns`, updatedColumns);
|
|
6125
6127
|
return newSettings;
|
|
6126
6128
|
});
|
|
@@ -6638,22 +6640,59 @@ class AXPEntityMasterListViewModel {
|
|
|
6638
6640
|
const relatedDef = this.getRegisteredEntity(related.entity);
|
|
6639
6641
|
return relatedDef?.properties?.find((property) => property.name === propertyName) ?? null;
|
|
6640
6642
|
}
|
|
6641
|
-
resetColumns() {
|
|
6642
|
-
this.applyViewColumns();
|
|
6643
|
+
async resetColumns() {
|
|
6644
|
+
await this.applyViewColumns();
|
|
6643
6645
|
}
|
|
6644
6646
|
async onColumnsChanged(columns) {
|
|
6645
6647
|
this.saveSettings('columnOrders', columns);
|
|
6646
6648
|
}
|
|
6647
|
-
|
|
6648
|
-
|
|
6649
|
-
|
|
6649
|
+
/**
|
|
6650
|
+
* Builds list columns for the active view:
|
|
6651
|
+
* - `view.columns` is a whitelist (empty = all columns)
|
|
6652
|
+
* - string `options.visible` is evaluated against the master-list scope
|
|
6653
|
+
*/
|
|
6654
|
+
async applyViewColumns() {
|
|
6655
|
+
const viewColumnNames = this.view().columns ?? [];
|
|
6656
|
+
const scope = this.createLogicExpressionScope(null);
|
|
6657
|
+
const cloned = await Promise.all(this.allAvailableColumns().map(async (c) => {
|
|
6650
6658
|
const column = this.entityDef.columns?.find((cc) => cc.name == c.name);
|
|
6651
6659
|
const col = new AXPEntityListViewColumnViewModel(c.property, column);
|
|
6652
|
-
|
|
6660
|
+
const expressionVisible = await this.resolveColumnVisibleExpression(col.visible, scope);
|
|
6661
|
+
const includedInView = viewColumnNames.length === 0 || viewColumnNames.some((name) => name === col.name);
|
|
6662
|
+
col.visible = includedInView && expressionVisible;
|
|
6653
6663
|
return col;
|
|
6654
|
-
});
|
|
6664
|
+
}));
|
|
6665
|
+
if (viewColumnNames.length > 0) {
|
|
6666
|
+
cloned.sort((a, b) => {
|
|
6667
|
+
const aIndex = viewColumnNames.indexOf(a.name);
|
|
6668
|
+
const bIndex = viewColumnNames.indexOf(b.name);
|
|
6669
|
+
const aOrder = aIndex === -1 ? Number.MAX_SAFE_INTEGER : aIndex;
|
|
6670
|
+
const bOrder = bIndex === -1 ? Number.MAX_SAFE_INTEGER : bIndex;
|
|
6671
|
+
return aOrder - bOrder;
|
|
6672
|
+
});
|
|
6673
|
+
}
|
|
6655
6674
|
this.columns.set(cloned);
|
|
6656
6675
|
}
|
|
6676
|
+
/**
|
|
6677
|
+
* Resolves column `options.visible` (boolean or expression) to a boolean for the current list scope.
|
|
6678
|
+
*/
|
|
6679
|
+
async resolveColumnVisibleExpression(visible, scope) {
|
|
6680
|
+
if (visible === false) {
|
|
6681
|
+
return false;
|
|
6682
|
+
}
|
|
6683
|
+
if (visible === true || visible == null || visible === '') {
|
|
6684
|
+
return true;
|
|
6685
|
+
}
|
|
6686
|
+
if (typeof visible === 'string') {
|
|
6687
|
+
if (!visible.includes('{{')) {
|
|
6688
|
+
const normalized = visible.trim().toLowerCase();
|
|
6689
|
+
return normalized !== 'false' && normalized !== '0';
|
|
6690
|
+
}
|
|
6691
|
+
const result = await this.expressionEvaluator.evaluate(visible, scope);
|
|
6692
|
+
return result !== false;
|
|
6693
|
+
}
|
|
6694
|
+
return Boolean(visible);
|
|
6695
|
+
}
|
|
6657
6696
|
onColumnsOrderChanged(event) {
|
|
6658
6697
|
const columns = [...this.columns()];
|
|
6659
6698
|
moveItemInArray(columns, event.previousIndex - 1, event.currentIndex - 1);
|
|
@@ -13131,6 +13170,7 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
|
|
|
13131
13170
|
/**
|
|
13132
13171
|
* Route `filters` apply only when the active details `page` matches this list's entity
|
|
13133
13172
|
* (e.g. WorkOrder filters must not affect FailureRegister on the same asset layout).
|
|
13173
|
+
* page-list sidebar pages use `page-list-{module.entity}` as their page id.
|
|
13134
13174
|
*/
|
|
13135
13175
|
shouldApplyRouteFilters() {
|
|
13136
13176
|
const pageId = this.route.snapshot.queryParamMap.get('page');
|
|
@@ -13142,7 +13182,7 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
|
|
|
13142
13182
|
return false;
|
|
13143
13183
|
}
|
|
13144
13184
|
const [, entityName] = entitySource.split('.');
|
|
13145
|
-
return !!entityName && pageId === entityName;
|
|
13185
|
+
return ((!!entityName && pageId === entityName) || pageId === buildPageListWidgetName(entitySource));
|
|
13146
13186
|
}
|
|
13147
13187
|
/**
|
|
13148
13188
|
* Merges route filters into related-entity toolbar filters (route wins per field).
|
|
@@ -23406,8 +23446,10 @@ class AXPPageListConverter extends AXPBaseRelatedEntityConverter {
|
|
|
23406
23446
|
hidden: true,
|
|
23407
23447
|
};
|
|
23408
23448
|
}) ?? []);
|
|
23449
|
+
// Unique from host overview page id (`entity.name`) so self-referential related lists navigate correctly.
|
|
23450
|
+
const pageId = buildPageListWidgetName(relatedEntity.entity);
|
|
23409
23451
|
return {
|
|
23410
|
-
id:
|
|
23452
|
+
id: pageId,
|
|
23411
23453
|
title: context.rootTitle ?? '',
|
|
23412
23454
|
label: relatedEntity.title,
|
|
23413
23455
|
icon: relatedEntity.icon || entityDef.icon,
|
|
@@ -24638,11 +24680,14 @@ class AXPLayoutAdapterFactory {
|
|
|
24638
24680
|
composePagesWithPositions(mainPage, relatedPages, entity) {
|
|
24639
24681
|
// Only consider related entities with layout types page-detail or page-list
|
|
24640
24682
|
const pageEntities = (entity?.relatedEntities || []).filter((re) => !re.hidden && (re.layout?.type === 'page-detail' || re.layout?.type === 'page-list'));
|
|
24641
|
-
// Build a map from
|
|
24683
|
+
// Build a map from page id to its layout config (order/position).
|
|
24684
|
+
// page-list ids use `page-list-{module.entity}` so they never collide with the host overview page.
|
|
24642
24685
|
const layoutConfigByEntity = {};
|
|
24643
24686
|
for (const re of pageEntities) {
|
|
24644
24687
|
const [, entityName] = (re.entity || '').split('.');
|
|
24645
|
-
const key =
|
|
24688
|
+
const key = re.layout?.type === 'page-list'
|
|
24689
|
+
? buildPageListWidgetName(re.entity)
|
|
24690
|
+
: entityName || re.entity;
|
|
24646
24691
|
layoutConfigByEntity[key] = { order: re.layout?.order, position: re.layout?.position };
|
|
24647
24692
|
}
|
|
24648
24693
|
// Nested pages from merge-detail (e.g. PartyContact from Party) have no layout config.
|