@sapui5/sap.fe.core 1.136.10 → 1.136.11
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/package.json +1 -1
- package/src/sap/fe/core/.library +1 -1
- package/src/sap/fe/core/PageController.controller.js +10 -0
- package/src/sap/fe/core/PageController.controller.ts +3 -0
- package/src/sap/fe/core/controllerextensions/InternalRouting.js +23 -13
- package/src/sap/fe/core/controllerextensions/InternalRouting.ts +34 -13
- package/src/sap/fe/core/controllerextensions/routing/RouterProxy.js +7 -6
- package/src/sap/fe/core/controllerextensions/routing/RouterProxy.ts +8 -5
- package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DraftDataLossDialog.js +2 -1
- package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DraftDataLossDialog.tsx +1 -0
- package/src/sap/fe/core/converters/controls/Common/Action.js +15 -1
- package/src/sap/fe/core/converters/controls/Common/Action.ts +21 -1
- package/src/sap/fe/core/converters/controls/Common/Table.js +54 -46
- package/src/sap/fe/core/converters/controls/Common/Table.ts +65 -45
- package/src/sap/fe/core/converters/controls/Common/table/Columns.js +26 -6
- package/src/sap/fe/core/converters/controls/Common/table/Columns.ts +32 -10
- package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +12 -18
- package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +13 -27
- package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +5 -2
- package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +7 -1
- package/src/sap/fe/core/designtime/AnnotationBasedChanges.js +8 -3
- package/src/sap/fe/core/designtime/AnnotationBasedChanges.ts +7 -2
- package/src/sap/fe/core/fpm/manifest.json +1 -1
- package/src/sap/fe/core/helpers/AppStartupHelper.js +75 -18
- package/src/sap/fe/core/helpers/AppStartupHelper.ts +79 -25
- package/src/sap/fe/core/helpers/MetaModelFunction.js +10 -3
- package/src/sap/fe/core/helpers/MetaModelFunction.ts +9 -3
- package/src/sap/fe/core/library.js +1 -1
- package/src/sap/fe/core/messagebundle_es.properties +1 -1
- package/src/sap/fe/core/messagebundle_fr.properties +1 -1
- package/src/sap/fe/core/messagebundle_ko.properties +1 -1
- package/src/sap/fe/core/messagebundle_no.properties +2 -2
- package/src/sap/fe/core/services/RoutingServiceFactory.js +4 -2
- package/src/sap/fe/core/services/RoutingServiceFactory.ts +5 -2
- package/ui5.yaml +1 -0
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
getExpressionFromAnnotation,
|
|
30
30
|
ifElse,
|
|
31
31
|
isConstant,
|
|
32
|
+
isExpressionStaticallyResolvable,
|
|
32
33
|
not,
|
|
33
34
|
or,
|
|
34
35
|
pathInModel,
|
|
@@ -1231,8 +1232,7 @@ export function getSelectionMode(
|
|
|
1231
1232
|
visualizationPath: string,
|
|
1232
1233
|
converterContext: ConverterContext<PageContextPathTarget>,
|
|
1233
1234
|
isEntitySet: boolean,
|
|
1234
|
-
|
|
1235
|
-
deleteButtonVisibilityExpression?: BindingToolkitExpression<boolean>,
|
|
1235
|
+
deleteButtonVisibilityExpression: BindingToolkitExpression<boolean>,
|
|
1236
1236
|
massEditVisibilityExpression: BindingToolkitExpression<boolean> = constant(false),
|
|
1237
1237
|
cutButtonVisibilityExpression: BindingToolkitExpression<boolean> = constant(false)
|
|
1238
1238
|
): string | undefined {
|
|
@@ -1240,25 +1240,30 @@ export function getSelectionMode(
|
|
|
1240
1240
|
const tableType = tableManifestSettings.tableSettings?.type;
|
|
1241
1241
|
let selectionMode = tableManifestSettings.tableSettings?.selectionMode;
|
|
1242
1242
|
|
|
1243
|
-
//
|
|
1243
|
+
// NEW: derive deletable from path expression instead of targetCapabilities.isDeletable
|
|
1244
|
+
let pathDeletableExpression = isPathDeletable(converterContext.getDataModelObjectPath());
|
|
1245
|
+
if (!isExpressionStaticallyResolvable(pathDeletableExpression)) {
|
|
1246
|
+
// dynamic (depends on path/singleton) -> treat as "potentially deletable"
|
|
1247
|
+
pathDeletableExpression = constant(true);
|
|
1248
|
+
}
|
|
1249
|
+
const deletableStaticFalse = isConstant(pathDeletableExpression) && pathDeletableExpression.value === false;
|
|
1250
|
+
|
|
1251
|
+
// TreeTable: default to Multi if not set
|
|
1244
1252
|
if (tableType === "TreeTable" && !selectionMode) {
|
|
1245
1253
|
return SelectionMode.Multi;
|
|
1246
1254
|
}
|
|
1247
1255
|
|
|
1248
1256
|
// If the selection mode is forced to 'None' in the manifest/macro table parameters, we keep it unless here is a delete button
|
|
1249
1257
|
if (!lineItemAnnotation || selectionMode === SelectionMode.None) {
|
|
1250
|
-
|
|
1251
|
-
return compileExpression(ifElse(deleteButtonVisibilityExpression, constant(SelectionMode.Multi), constant(SelectionMode.None)));
|
|
1252
|
-
}
|
|
1253
|
-
return SelectionMode.None;
|
|
1258
|
+
return compileExpression(ifElse(deleteButtonVisibilityExpression, constant(SelectionMode.Multi), constant(SelectionMode.None)));
|
|
1254
1259
|
}
|
|
1255
1260
|
if (selectionMode === SelectionMode.ForceMulti) {
|
|
1256
1261
|
return SelectionMode.Multi;
|
|
1257
1262
|
} else if (selectionMode === SelectionMode.ForceSingle) {
|
|
1258
1263
|
return SelectionMode.Single;
|
|
1259
1264
|
}
|
|
1260
|
-
let
|
|
1261
|
-
|
|
1265
|
+
let hiddenBindingExpressions: BindingToolkitExpression<boolean>[] = [],
|
|
1266
|
+
visibleBindingExpressions: BindingToolkitExpression<boolean>[] = [];
|
|
1262
1267
|
const manifestActions = getActionsFromManifest(
|
|
1263
1268
|
converterContext.getManifestControlConfiguration<TableManifestConfiguration>(visualizationPath).actions,
|
|
1264
1269
|
converterContext,
|
|
@@ -1271,11 +1276,11 @@ export function getSelectionMode(
|
|
|
1271
1276
|
isParentDeletable = isPathDeletable(converterContext.getDataModelObjectPath());
|
|
1272
1277
|
parentEntitySetDeletable = isParentDeletable ? compileExpression(isParentDeletable, true) : isParentDeletable;
|
|
1273
1278
|
}
|
|
1274
|
-
const
|
|
1279
|
+
const massEditEnabled: boolean = !isConstant(massEditVisibilityExpression) || massEditVisibilityExpression.value !== false;
|
|
1275
1280
|
if (!selectionMode || selectionMode === SelectionMode.Auto) {
|
|
1276
1281
|
selectionMode = SelectionMode.Multi;
|
|
1277
1282
|
}
|
|
1278
|
-
if (
|
|
1283
|
+
if (massEditEnabled) {
|
|
1279
1284
|
// Override default selection mode when mass edit is visible
|
|
1280
1285
|
selectionMode = selectionMode === SelectionMode.Single ? SelectionMode.Single : SelectionMode.Multi;
|
|
1281
1286
|
}
|
|
@@ -1285,25 +1290,24 @@ export function getSelectionMode(
|
|
|
1285
1290
|
) {
|
|
1286
1291
|
return selectionMode;
|
|
1287
1292
|
}
|
|
1288
|
-
|
|
1293
|
+
hiddenBindingExpressions = getUIHiddenExpForActionsRequiringContext(
|
|
1289
1294
|
lineItemAnnotation,
|
|
1290
1295
|
converterContext.getEntityType(),
|
|
1291
1296
|
converterContext.getDataModelObjectPath()
|
|
1292
1297
|
);
|
|
1293
|
-
|
|
1298
|
+
visibleBindingExpressions = getVisibleExpForCustomActionsRequiringContext(manifestActions.actions);
|
|
1294
1299
|
// No action requiring a context:
|
|
1295
1300
|
if (
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
(cutButtonVisibilityExpression || deleteButtonVisibilityExpression ||
|
|
1301
|
+
hiddenBindingExpressions.length === 0 &&
|
|
1302
|
+
visibleBindingExpressions.length === 0 &&
|
|
1303
|
+
(cutButtonVisibilityExpression || deleteButtonVisibilityExpression || massEditEnabled)
|
|
1299
1304
|
) {
|
|
1300
1305
|
if (!isEntitySet) {
|
|
1301
|
-
//
|
|
1302
|
-
if (
|
|
1303
|
-
// Building expression for delete and mass edit
|
|
1306
|
+
// OP case:
|
|
1307
|
+
if (!deletableStaticFalse || parentEntitySetDeletable !== "false" || massEditEnabled) {
|
|
1304
1308
|
const buttonVisibilityExpression = or(
|
|
1305
1309
|
cutButtonVisibilityExpression || true,
|
|
1306
|
-
deleteButtonVisibilityExpression
|
|
1310
|
+
deleteButtonVisibilityExpression,
|
|
1307
1311
|
massEditVisibilityExpression
|
|
1308
1312
|
);
|
|
1309
1313
|
return compileExpression(
|
|
@@ -1314,23 +1318,19 @@ export function getSelectionMode(
|
|
|
1314
1318
|
ifElse(cutButtonVisibilityExpression, constant(SelectionMode.Single), constant(SelectionMode.None))
|
|
1315
1319
|
);
|
|
1316
1320
|
}
|
|
1317
|
-
// EntitySet deletable:
|
|
1318
|
-
} else if (bMassEditEnabled) {
|
|
1319
|
-
// example: LR scenario
|
|
1320
|
-
return selectionMode;
|
|
1321
|
-
} else if (targetCapabilities.isDeletable && deleteButtonVisibilityExpression) {
|
|
1322
|
-
return compileExpression(ifElse(deleteButtonVisibilityExpression, constant(selectionMode), constant(SelectionMode.None)));
|
|
1323
|
-
// EntitySet not deletable:
|
|
1324
1321
|
} else {
|
|
1325
|
-
|
|
1322
|
+
// EntitySet case:
|
|
1323
|
+
return compileExpression(
|
|
1324
|
+
ifElse(or(massEditEnabled, deleteButtonVisibilityExpression), constant(selectionMode), constant(SelectionMode.None))
|
|
1325
|
+
);
|
|
1326
1326
|
}
|
|
1327
1327
|
// There are actions requiring a context:
|
|
1328
1328
|
} else if (!isEntitySet) {
|
|
1329
|
-
//
|
|
1330
|
-
if (
|
|
1329
|
+
// OP case:
|
|
1330
|
+
if (!deletableStaticFalse || parentEntitySetDeletable !== "false" || massEditEnabled) {
|
|
1331
1331
|
// Use selectionMode in edit mode if delete is enabled or mass edit is visible
|
|
1332
1332
|
const editModebuttonVisibilityExpression = ifElse(
|
|
1333
|
-
|
|
1333
|
+
massEditEnabled && deletableStaticFalse,
|
|
1334
1334
|
massEditVisibilityExpression,
|
|
1335
1335
|
constant(true)
|
|
1336
1336
|
);
|
|
@@ -1339,7 +1339,7 @@ export function getSelectionMode(
|
|
|
1339
1339
|
and(UI.IsEditable, editModebuttonVisibilityExpression),
|
|
1340
1340
|
constant(selectionMode),
|
|
1341
1341
|
ifElse(
|
|
1342
|
-
or(...
|
|
1342
|
+
or(...hiddenBindingExpressions.concat(visibleBindingExpressions)),
|
|
1343
1343
|
constant(selectionMode),
|
|
1344
1344
|
constant(SelectionMode.None)
|
|
1345
1345
|
)
|
|
@@ -1348,23 +1348,23 @@ export function getSelectionMode(
|
|
|
1348
1348
|
} else {
|
|
1349
1349
|
return compileExpression(
|
|
1350
1350
|
ifElse(
|
|
1351
|
-
or(...
|
|
1351
|
+
or(...hiddenBindingExpressions.concat(visibleBindingExpressions)),
|
|
1352
1352
|
constant(selectionMode),
|
|
1353
1353
|
constant(SelectionMode.None)
|
|
1354
1354
|
)
|
|
1355
1355
|
);
|
|
1356
1356
|
}
|
|
1357
|
-
//EntitySet
|
|
1358
|
-
} else if (targetCapabilities.isDeletable || bMassEditEnabled) {
|
|
1359
|
-
// Example: LR scenario
|
|
1360
|
-
return selectionMode;
|
|
1361
|
-
//EntitySet not deletable:
|
|
1357
|
+
// EntitySet
|
|
1362
1358
|
} else {
|
|
1363
1359
|
return compileExpression(
|
|
1364
1360
|
ifElse(
|
|
1365
|
-
or(
|
|
1361
|
+
or(massEditEnabled, deleteButtonVisibilityExpression),
|
|
1366
1362
|
constant(selectionMode),
|
|
1367
|
-
|
|
1363
|
+
ifElse(
|
|
1364
|
+
or(...hiddenBindingExpressions.concat(visibleBindingExpressions), massEditVisibilityExpression),
|
|
1365
|
+
constant(selectionMode),
|
|
1366
|
+
constant(SelectionMode.None)
|
|
1367
|
+
)
|
|
1368
1368
|
)
|
|
1369
1369
|
);
|
|
1370
1370
|
}
|
|
@@ -2113,14 +2113,12 @@ export function getTableAnnotationConfiguration(
|
|
|
2113
2113
|
const hasAbsolutePath = navigationPropertyPath.length === 0;
|
|
2114
2114
|
const p13nMode = getP13nMode(visualizationPath, converterContext, tableManifestConfiguration);
|
|
2115
2115
|
const id = navigationPropertyPath ? getTableID(visualizationPath) : getTableID(converterContext.getContextPath(), "LineItem");
|
|
2116
|
-
const targetCapabilities = getCapabilityRestriction(converterContext);
|
|
2117
2116
|
const navigationTargetPath = getNavigationTargetPath(converterContext, navigationPropertyPath);
|
|
2118
2117
|
const selectionMode = getSelectionMode(
|
|
2119
2118
|
lineItemAnnotation,
|
|
2120
2119
|
visualizationPath,
|
|
2121
2120
|
converterContext,
|
|
2122
2121
|
hasAbsolutePath,
|
|
2123
|
-
targetCapabilities,
|
|
2124
2122
|
standardActionsConfiguration.deleteButtonVisibilityExpression,
|
|
2125
2123
|
standardActionsConfiguration.massEditButtonVisibilityExpression,
|
|
2126
2124
|
standardActionsConfiguration.cutButtonVisibilityExpression
|
|
@@ -2397,10 +2395,12 @@ function _useEnabledExpression(dataField: DataFieldForActionTypes, sEntityType:
|
|
|
2397
2395
|
function updateTreeTableManifestConfiguration(
|
|
2398
2396
|
tableConfiguration: TableControlConfiguration,
|
|
2399
2397
|
tableSettings: TableManifestSettingsConfiguration,
|
|
2400
|
-
converterContext: ConverterContext
|
|
2398
|
+
converterContext: ConverterContext,
|
|
2399
|
+
lineItemAnnotation: LineItem | undefined
|
|
2401
2400
|
): void {
|
|
2402
2401
|
const dataModelObjectPath = converterContext.getDataModelObjectPath();
|
|
2403
|
-
|
|
2402
|
+
const entityType = converterContext.getAnnotationEntityType(lineItemAnnotation);
|
|
2403
|
+
tableConfiguration.hierarchyQualifier = getHierarchyQualifier(entityType, tableSettings);
|
|
2404
2404
|
const hierarchyParentNavigationPropertyPath = getHierarchyParentNavigationPropertyPath(
|
|
2405
2405
|
dataModelObjectPath,
|
|
2406
2406
|
tableConfiguration.hierarchyQualifier!
|
|
@@ -2478,6 +2478,26 @@ function getOptimisticBatchSettingsFromManifest(tableManifestSettings: TableMani
|
|
|
2478
2478
|
return tableManifestSettings?.tableSettings?.disableRequestCache;
|
|
2479
2479
|
}
|
|
2480
2480
|
|
|
2481
|
+
function getHierarchyQualifier(entityType: EntityType, tableSettings: TableManifestSettingsConfiguration): string | undefined {
|
|
2482
|
+
if (tableSettings.hierarchyQualifier) {
|
|
2483
|
+
return tableSettings.hierarchyQualifier;
|
|
2484
|
+
}
|
|
2485
|
+
const aggregationAnnotations = entityType.annotations?.Aggregation;
|
|
2486
|
+
const hierarchyAnnotations = entityType.annotations?.Hierarchy;
|
|
2487
|
+
// We only check the hierarchyQualifier from the manifest when the tree table is specifically set, otherwise we get it from the annotations
|
|
2488
|
+
// if both annotations have the same qualifier, use it
|
|
2489
|
+
// If there is no qualifier or different qualifiers, the hierarchyQualifier remains undefined
|
|
2490
|
+
// Note: In case of multiple hierarchies with the same qualifier, the first one found will be used
|
|
2491
|
+
const qualifiedName =
|
|
2492
|
+
hierarchyAnnotations &&
|
|
2493
|
+
Object.keys(hierarchyAnnotations).find(
|
|
2494
|
+
(key) => key.includes("RecursiveHierarchy#") && aggregationAnnotations && Object.keys(aggregationAnnotations).includes(key)
|
|
2495
|
+
);
|
|
2496
|
+
if (qualifiedName) {
|
|
2497
|
+
return (hierarchyAnnotations as Record<string, { qualifier?: string }>)[qualifiedName]?.qualifier;
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2500
|
+
|
|
2481
2501
|
/**
|
|
2482
2502
|
* Gets the settings coming from the manifest related to the mass edit dialog.
|
|
2483
2503
|
* @param tableSettings The table configuration
|
|
@@ -2644,7 +2664,7 @@ export function getTableManifestConfiguration(
|
|
|
2644
2664
|
tableConfiguration.selectionChange = tableSettings.selectionChange;
|
|
2645
2665
|
tableConfiguration.rowPress = tableSettings.rowPress;
|
|
2646
2666
|
if (tableType === "TreeTable") {
|
|
2647
|
-
updateTreeTableManifestConfiguration(tableConfiguration, tableSettings, converterContext);
|
|
2667
|
+
updateTreeTableManifestConfiguration(tableConfiguration, tableSettings, converterContext, lineItemAnnotation);
|
|
2648
2668
|
}
|
|
2649
2669
|
|
|
2650
2670
|
if (tableSettings.headerVisible !== undefined) {
|