@sapui5/sap.fe.core 1.92.0 → 1.93.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 (84) hide show
  1. package/package.json +2 -3
  2. package/src/sap/fe/core/.library +1 -1
  3. package/src/sap/fe/core/AnnotationHelper.js +2 -2
  4. package/src/sap/fe/core/AppComponent.js +21 -1
  5. package/src/sap/fe/core/CommonUtils.js +130 -48
  6. package/src/sap/fe/core/ExtensionAPI.js +238 -226
  7. package/src/sap/fe/core/PageController.js +5 -2
  8. package/src/sap/fe/core/TemplateComponent.js +1 -0
  9. package/src/sap/fe/core/TransactionHelper.js +35 -8
  10. package/src/sap/fe/core/actions/draft.js +1 -1
  11. package/src/sap/fe/core/actions/messageHandling.js +18 -6
  12. package/src/sap/fe/core/actions/operations.js +17 -41
  13. package/src/sap/fe/core/controllerextensions/EditFlow.js +127 -43
  14. package/src/sap/fe/core/controllerextensions/InternalRouting.js +11 -11
  15. package/src/sap/fe/core/controllerextensions/KPIManagement.js +417 -0
  16. package/src/sap/fe/core/controllerextensions/KPIManagement.ts +399 -0
  17. package/src/sap/fe/core/controllerextensions/PageReady.js +2 -3
  18. package/src/sap/fe/core/controllerextensions/PageReady.ts +1 -1
  19. package/src/sap/fe/core/controllerextensions/Share.js +102 -66
  20. package/src/sap/fe/core/controllerextensions/SideEffects.js +60 -14
  21. package/src/sap/fe/core/controllerextensions/SideEffects.ts +53 -12
  22. package/src/sap/fe/core/controllerextensions/ViewState.js +18 -18
  23. package/src/sap/fe/core/controls/filterbar/FilterContainer.js +13 -0
  24. package/src/sap/fe/core/controls/filterbar/VisualFilter.js +68 -2
  25. package/src/sap/fe/core/converters/ConverterContext.js +15 -1
  26. package/src/sap/fe/core/converters/ConverterContext.ts +11 -0
  27. package/src/sap/fe/core/converters/ManifestSettings.js +1 -1
  28. package/src/sap/fe/core/converters/ManifestSettings.ts +14 -2
  29. package/src/sap/fe/core/converters/ManifestWrapper.js +14 -14
  30. package/src/sap/fe/core/converters/ManifestWrapper.ts +13 -12
  31. package/src/sap/fe/core/converters/MetaModelConverter.js +32 -2
  32. package/src/sap/fe/core/converters/MetaModelConverter.ts +39 -2
  33. package/src/sap/fe/core/converters/annotations/DataField.js +10 -6
  34. package/src/sap/fe/core/converters/annotations/DataField.ts +9 -5
  35. package/src/sap/fe/core/converters/common/AnnotationConverter.js +14 -4
  36. package/src/sap/fe/core/converters/controls/Common/Action.js +25 -15
  37. package/src/sap/fe/core/converters/controls/Common/Action.ts +33 -19
  38. package/src/sap/fe/core/converters/controls/Common/Criticality.js +50 -0
  39. package/src/sap/fe/core/converters/controls/Common/Criticality.ts +33 -0
  40. package/src/sap/fe/core/converters/controls/Common/Form.js +2 -3
  41. package/src/sap/fe/core/converters/controls/Common/Form.ts +1 -2
  42. package/src/sap/fe/core/converters/controls/Common/KPI.js +181 -0
  43. package/src/sap/fe/core/converters/controls/Common/KPI.ts +220 -0
  44. package/src/sap/fe/core/converters/controls/Common/Table.js +121 -59
  45. package/src/sap/fe/core/converters/controls/Common/Table.ts +130 -62
  46. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.js +5 -4
  47. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.ts +9 -3
  48. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.js +62 -7
  49. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +58 -6
  50. package/src/sap/fe/core/converters/helpers/Aggregation.js +86 -11
  51. package/src/sap/fe/core/converters/helpers/Aggregation.ts +79 -8
  52. package/src/sap/fe/core/converters/helpers/BindingHelper.js +44 -2
  53. package/src/sap/fe/core/converters/helpers/BindingHelper.ts +43 -2
  54. package/src/sap/fe/core/converters/helpers/ID.js +3 -1
  55. package/src/sap/fe/core/converters/helpers/ID.ts +1 -0
  56. package/src/sap/fe/core/converters/helpers/IssueManager.js +8 -2
  57. package/src/sap/fe/core/converters/helpers/IssueManager.ts +7 -1
  58. package/src/sap/fe/core/converters/helpers/SelectionVariantHelper.js +93 -0
  59. package/src/sap/fe/core/converters/helpers/SelectionVariantHelper.ts +92 -0
  60. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +102 -23
  61. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +111 -17
  62. package/src/sap/fe/core/converters/templates/ListReportConverter.js +44 -5
  63. package/src/sap/fe/core/converters/templates/ListReportConverter.ts +39 -2
  64. package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +41 -30
  65. package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +47 -30
  66. package/src/sap/fe/core/designtime/AppComponent.designtime.js +4 -1
  67. package/src/sap/fe/core/formatters/CriticalityFormatter.js +77 -0
  68. package/src/sap/fe/core/formatters/CriticalityFormatter.ts +58 -0
  69. package/src/sap/fe/core/formatters/KPIFormatter.js +103 -0
  70. package/src/sap/fe/core/formatters/KPIFormatter.ts +88 -0
  71. package/src/sap/fe/core/fpm/manifest.json +1 -3
  72. package/src/sap/fe/core/helpers/BindingExpression.js +161 -97
  73. package/src/sap/fe/core/helpers/BindingExpression.ts +188 -117
  74. package/src/sap/fe/core/library.js +1 -1
  75. package/src/sap/fe/core/messagebundle.properties +45 -1
  76. package/src/sap/fe/core/services/AsyncComponentServiceFactory.js +3 -1
  77. package/src/sap/fe/core/services/AsyncComponentServiceFactory.ts +3 -0
  78. package/src/sap/fe/core/services/RoutingServiceFactory.js +30 -8
  79. package/src/sap/fe/core/services/SideEffectsServiceFactory.js +16 -4
  80. package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +13 -3
  81. package/src/sap/fe/core/templating/DataModelPathHelper.js +7 -3
  82. package/src/sap/fe/core/templating/DataModelPathHelper.ts +7 -2
  83. package/src/sap/fe/core/templating/UIFormatters.js +1 -5
  84. package/src/sap/fe/core/templating/UIFormatters.ts +0 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sapui5/sap.fe.core",
3
- "version": "1.92.0",
3
+ "version": "1.93.3",
4
4
  "description": "SAPUI5 Library sap.fe.core",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "author": "SAP SE (https://www.sap.com)",
@@ -22,7 +22,6 @@
22
22
  "devDependencies": {
23
23
  "@babel/cli": "7.8.4",
24
24
  "@ui5/cli": "^2.10.0",
25
- "copyfiles": "2.2.0",
26
- "yarn": "1.22.10"
25
+ "copyfiles": "2.2.0"
27
26
  }
28
27
  }
@@ -6,7 +6,7 @@
6
6
  <copyright>SAP UI development toolkit for HTML5 (SAPUI5)
7
7
  (c) Copyright 2009-2021 SAP SE. All rights reserved
8
8
  </copyright>
9
- <version>1.92.0</version>
9
+ <version>1.93.3</version>
10
10
 
11
11
  <documentation>UI5 library: sap.fe.core</documentation>
12
12
 
@@ -362,8 +362,8 @@ sap.ui.define(
362
362
  buildActionWrapper: function(oAction, oThis) {
363
363
  var aParams = [
364
364
  "$event",
365
- CommonHelper.addSingleQuotes(oAction.handlerModule),
366
- CommonHelper.addSingleQuotes(oAction.handlerMethod)
365
+ CommonHelper.addSingleQuotes(oAction.handlerModule, true),
366
+ CommonHelper.addSingleQuotes(oAction.handlerMethod, true)
367
367
  ];
368
368
 
369
369
  if (oThis && oThis.id) {
@@ -21,6 +21,7 @@ sap.ui.define(
21
21
  "sap/ui/core/Component",
22
22
  "sap/fe/core/TemplateComponent",
23
23
  "sap/fe/core/helpers/ModelHelper",
24
+ "sap/fe/macros/internal/valuehelp/ValueListHelper",
24
25
  "sap/fe/core/converters/MetaModelConverter"
25
26
  ],
26
27
  function(
@@ -37,6 +38,7 @@ sap.ui.define(
37
38
  Component,
38
39
  TemplateComponent,
39
40
  ModelHelper,
41
+ ValueListHelper,
40
42
  MetaModelConverter
41
43
  ) {
42
44
  "use strict";
@@ -96,6 +98,7 @@ sap.ui.define(
96
98
  */
97
99
  var AppComponent = UIComponent.extend("sap.fe.core.AppComponent", {
98
100
  metadata: {
101
+ interfaces: ["sap.ui.core.IAsyncContentCreation"],
99
102
  config: {
100
103
  fullWidth: true
101
104
  },
@@ -163,6 +166,7 @@ sap.ui.define(
163
166
  library: "sap.fe.core"
164
167
  },
165
168
 
169
+ instanceMap: {},
166
170
  /**
167
171
  * @private
168
172
  * @name sap.fe.core.AppComponent.getMetadata
@@ -317,6 +321,7 @@ sap.ui.define(
317
321
  // the init function configures the routing according to the settings above
318
322
  // it will call the createContent function to instantiate the RootView and add it to the UIComponent aggregations
319
323
  UIComponent.prototype.init.apply(that, arguments);
324
+ AppComponent.prototype.instanceMap[this.getId()] = this;
320
325
  },
321
326
  onServicesStarted: function() {
322
327
  //router must be started once the rootcontainer is initialized
@@ -379,7 +384,22 @@ sap.ui.define(
379
384
  // LEAKS, with workaround for some Flex / MDC issue
380
385
  try {
381
386
  // // This one is only a leak if you don't go back to the same component in the long run
382
- // delete sap.ui.fl.FlexControllerFactory._componentInstantiationPromises[this.getId()];
387
+ //delete sap.ui.fl.FlexControllerFactory._componentInstantiationPromises[this.getId()];
388
+
389
+ ValueListHelper.initializeCachedValueHelp();
390
+
391
+ delete AppComponent.prototype.instanceMap[this.getId()];
392
+ var sCurrentComponentName = this.getMetadata().getName();
393
+ var bHasOtherComponent = false;
394
+ Object.keys(AppComponent.prototype.instanceMap).forEach(function(instanceID) {
395
+ if (AppComponent.prototype.instanceMap[instanceID].getMetadata().getName() === sCurrentComponentName) {
396
+ bHasOtherComponent = true;
397
+ }
398
+ });
399
+ if (!bHasOtherComponent) {
400
+ sap.ui.fl.apply._internal.flexState.FlexState.clearState(sCurrentComponentName);
401
+ }
402
+
383
403
  // var oRegistry = sap.ui.mdc.p13n.Engine.getInstance()._getRegistry();
384
404
  // Object.keys(oRegistry).forEach(function(sKey) {
385
405
  // Object.keys(oRegistry[sKey].controller).forEach(function(sControllerKey) {
@@ -942,26 +942,54 @@ sap.ui.define(
942
942
  var aApplicable = [],
943
943
  aNotApplicable = [];
944
944
  var sProperty = oActionOperationAvailableMap[sAction];
945
- for (var i = 0; i < aSelectedContexts.length; i++) {
946
- var oSelectedContext = aSelectedContexts[i];
947
- if (oSelectedContext) {
948
- var oContextData = oSelectedContext.getObject();
949
- if (sProperty === null && !!oContextData["#" + sAction]) {
950
- //look for action advertisement if present and its value is not null
951
- oInternalModelContext
952
- .getModel()
953
- .setProperty(oInternalModelContext.getPath() + "/dynamicActions/" + sAction + "/bEnabled", true);
954
- break;
955
- } else if (oSelectedContext.getObject(sProperty)) {
956
- oInternalModelContext
957
- .getModel()
958
- .setProperty(oInternalModelContext.getPath() + "/dynamicActions/" + sAction + "/bEnabled", true);
959
- aApplicable.push(oSelectedContext);
960
- } else {
961
- aNotApplicable.push(oSelectedContext);
945
+ if (typeof sProperty === "object" && sProperty !== null && sProperty !== undefined) {
946
+ for (var i = 0; i < aSelectedContexts.length; i++) {
947
+ var oSelectedContext = aSelectedContexts[i];
948
+ if (oSelectedContext) {
949
+ var oContextData = oSelectedContext.getObject();
950
+ var oTransformedBinding = BindingExpression.transformRecursively(
951
+ sProperty,
952
+ "Binding",
953
+ // eslint-disable-next-line no-loop-func
954
+ function(oBindingExpression) {
955
+ return BindingExpression.constant(oContextData[oBindingExpression.path]);
956
+ },
957
+ true
958
+ );
959
+ var sResult = BindingExpression.compileBinding(oTransformedBinding);
960
+ if (sResult === "true") {
961
+ oInternalModelContext
962
+ .getModel()
963
+ .setProperty(oInternalModelContext.getPath() + "/dynamicActions/" + sAction + "/bEnabled", true);
964
+ aApplicable.push(oSelectedContext);
965
+ } else {
966
+ aNotApplicable.push(oSelectedContext);
967
+ }
968
+ }
969
+ }
970
+ } else {
971
+ for (var i = 0; i < aSelectedContexts.length; i++) {
972
+ var oSelectedContext = aSelectedContexts[i];
973
+ if (oSelectedContext) {
974
+ var oContextData = oSelectedContext.getObject();
975
+ if (sProperty === null && !!oContextData["#" + sAction]) {
976
+ //look for action advertisement if present and its value is not null
977
+ oInternalModelContext
978
+ .getModel()
979
+ .setProperty(oInternalModelContext.getPath() + "/dynamicActions/" + sAction + "/bEnabled", true);
980
+ break;
981
+ } else if (oSelectedContext.getObject(sProperty)) {
982
+ oInternalModelContext
983
+ .getModel()
984
+ .setProperty(oInternalModelContext.getPath() + "/dynamicActions/" + sAction + "/bEnabled", true);
985
+ aApplicable.push(oSelectedContext);
986
+ } else {
987
+ aNotApplicable.push(oSelectedContext);
988
+ }
962
989
  }
963
990
  }
964
991
  }
992
+
965
993
  oInternalModelContext
966
994
  .getModel()
967
995
  .setProperty(oInternalModelContext.getPath() + "/dynamicActions/" + sAction + "/aApplicable", aApplicable);
@@ -1223,11 +1251,10 @@ sap.ui.define(
1223
1251
 
1224
1252
  aSelectOptionsPropertyNames.forEach(function(sSelectOption) {
1225
1253
  if (sSelectOption.indexOf(".") > 0 && !sSelectOption.includes("$Parameter")) {
1226
- var sFullContextPath = !sSelectOption.includes(sContextPath.replace("/", ""))
1227
- ? sContextPath + "/" + sSelectOption.replaceAll(".", "/")
1228
- : "/" + sSelectOption.replaceAll(".", "/");
1229
- // check if the full path, eg SalesOrderManage._Item.Material exists in the metamodel
1230
- if (oMetaModel.getObject(sFullContextPath)) {
1254
+ var sFullContextPath = ("/" + sSelectOption.replaceAll(".", "/")).startsWith(sContextPath)
1255
+ ? "/" + sSelectOption.replaceAll(".", "/")
1256
+ : sContextPath + "/" + sSelectOption.replaceAll(".", "/"); // check if the full path, eg SalesOrderManage._Item.Material exists in the metamodel
1257
+ if (oMetaModel.getObject(sFullContextPath.replace("P_", ""))) {
1231
1258
  _createConditionsForNavProperties(
1232
1259
  sFullContextPath,
1233
1260
  sContextPath,
@@ -1252,21 +1279,20 @@ sap.ui.define(
1252
1279
  ) {
1253
1280
  var aNavObjectNames = sSelectOption.split(".");
1254
1281
  // Eg: "SalesOrderManage._Item._Material.Material" or "_Item.Material"
1255
- if (sSelectOption.includes(sMainEntitySetPath.replace("/", ""))) {
1256
- aNavObjectNames.shift();
1282
+ if (("/" + sSelectOption.replaceAll(".", "/")).startsWith(sMainEntitySetPath)) {
1283
+ var sFullPath = ("/" + sSelectOption).replaceAll(".", "/"),
1284
+ sNavPath = sFullPath.replace(sMainEntitySetPath + "/", "");
1285
+ aNavObjectNames = sNavPath.split("/");
1257
1286
  }
1258
1287
  var sConditionPath = "";
1259
- var sContextPath = sSelectOption.includes(sMainEntitySetPath.replace("/", ""))
1260
- ? sMainEntitySetPath
1261
- : "/" + sSelectOption.split(".")[0]; // /SalesOrderManage
1262
1288
  var sPropertyName = aNavObjectNames[aNavObjectNames.length - 1]; // Material from SalesOrderManage._Item.Material
1263
1289
  for (var i = 0; i < aNavObjectNames.length - 1; i++) {
1264
- if (oMetaModel.getObject(sContextPath + "/" + aNavObjectNames[i]).$isCollection) {
1290
+ if (oMetaModel.getObject(sMainEntitySetPath + "/" + aNavObjectNames[i].replace("P_", "")).$isCollection) {
1265
1291
  sConditionPath = sConditionPath + aNavObjectNames[i] + "*/"; // _Item*/ in case of 1:n cardinality
1266
1292
  } else {
1267
1293
  sConditionPath = sConditionPath + aNavObjectNames[i] + "/"; // _Item/ in case of 1:1 cardinality
1268
1294
  }
1269
- sContextPath = sContextPath + "/" + aNavObjectNames[i];
1295
+ sMainEntitySetPath = sMainEntitySetPath + "/" + aNavObjectNames[i];
1270
1296
  }
1271
1297
  var sNavPropertyPath = sFullContextPath.slice(0, sFullContextPath.lastIndexOf("/")),
1272
1298
  oValidProperties = CommonUtils.getContextPathProperties(oMetaModel, sNavPropertyPath),
@@ -1274,24 +1300,40 @@ sap.ui.define(
1274
1300
  var sSelectOptionName = sPropertyName;
1275
1301
  if (oValidProperties[sPropertyName]) {
1276
1302
  sSelectOptionName = sPropertyName;
1277
- } else if (
1278
- oValidProperties["P_" + sPropertyName] &&
1279
- aSelectOptionsPropertyNames.includes(oValidProperties["P_" + sPropertyName].slice(2, sPropertyName.length))
1280
- ) {
1281
- sSelectOptionName = sPropertyName.slice(2, sPropertyName.length);
1303
+ } else if (sPropertyName.startsWith("P_") && oValidProperties[sPropertyName.replace("P_", "")]) {
1304
+ sSelectOptionName = sPropertyName.replace("P_", "");
1305
+ } else if (oValidProperties["P_" + sPropertyName] && aSelectOptionsPropertyNames.includes("P_" + sPropertyName)) {
1306
+ sSelectOptionName = "P_" + sPropertyName;
1307
+ }
1308
+ if (sPropertyName.startsWith("P_") && oConditions[sConditionPath + sSelectOptionName]) {
1309
+ // if there is no SalesOrderManage._Item.Material yet in the oConditions
1310
+ return;
1311
+ } else if (!sPropertyName.startsWith("P_") && oConditions[sConditionPath + sSelectOptionName]) {
1312
+ delete oConditions[sConditionPath + sSelectOptionName];
1313
+ addSelectOptionsToConditions(
1314
+ sNavPropertyPath,
1315
+ oSelectionVariant,
1316
+ sSelectOption,
1317
+ oConditions,
1318
+ sConditionPath,
1319
+ sSelectOptionName,
1320
+ oValidProperties,
1321
+ oMetaModel,
1322
+ false
1323
+ );
1324
+ } else {
1325
+ addSelectOptionsToConditions(
1326
+ sNavPropertyPath,
1327
+ oSelectionVariant,
1328
+ sSelectOption,
1329
+ oConditions,
1330
+ sConditionPath,
1331
+ sSelectOptionName,
1332
+ oValidProperties,
1333
+ oMetaModel,
1334
+ false
1335
+ );
1282
1336
  }
1283
-
1284
- addSelectOptionsToConditions(
1285
- sNavPropertyPath,
1286
- oSelectionVariant,
1287
- sSelectOption,
1288
- oConditions,
1289
- sConditionPath,
1290
- sSelectOptionName,
1291
- oValidProperties,
1292
- oMetaModel,
1293
- false
1294
- );
1295
1337
  }
1296
1338
 
1297
1339
  /**
@@ -1316,13 +1358,14 @@ sap.ui.define(
1316
1358
  * @param {object} oSelectionVariant Instance of {@link sap.fe.navigation.SelectionVariant} SelectionVariant to be used.
1317
1359
  * @param {object} mFilters Conditons to be added to the SelectionVariant
1318
1360
  * @param {object} oTargetInfo Object returned after selection variant from the table is prepared.
1361
+ * @param {object} oFilterInfo Object containing the converted FilterBar filters
1319
1362
  * @returns {object} Instance of {@link sap.fe.navigation.SelectionVariant} SelectionVariant with the conditions.
1320
1363
  * @private
1321
1364
  * @ui5-restricted
1322
1365
  * @example <code>
1323
1366
  * </code>
1324
1367
  */
1325
- function addExternalStateFiltersToSelectionVariant(oSelectionVariant, mFilters, oTargetInfo) {
1368
+ function addExternalStateFiltersToSelectionVariant(oSelectionVariant, mFilters, oTargetInfo, oFilterInfo) {
1326
1369
  var sFilter,
1327
1370
  sLow = "",
1328
1371
  sHigh = null;
@@ -1353,6 +1396,10 @@ sap.ui.define(
1353
1396
  case "EQ":
1354
1397
  oSelectOptionState.option = sOperator;
1355
1398
  break;
1399
+ case "TODAY":
1400
+ case "DATE":
1401
+ oSelectOptionState.option = "EQ";
1402
+ break;
1356
1403
  case "EEQ":
1357
1404
  oSelectOptionState.option = "EQ";
1358
1405
  break;
@@ -1412,6 +1459,13 @@ sap.ui.define(
1412
1459
  var oFilter = aFilters[item];
1413
1460
  sLow = (oFilter.values[0] && oFilter.values[0].toString()) || "";
1414
1461
  sHigh = (oFilter.values[1] && oFilter.values[1].toString()) || null;
1462
+ if (oFilter.operator === "TODAY" || oFilter.operator === "DATE") {
1463
+ var aFilter = oFilterInfo[0].aFilters.filter(function(oFilter) {
1464
+ return oFilter.sPath === sFilter;
1465
+ });
1466
+ sLow = aFilter[0].oValue1 || "";
1467
+ sHigh = null;
1468
+ }
1415
1469
  var oSelectOptionValues = fnGetSignAndOption(oFilter.operator, sLow, sHigh);
1416
1470
  if (oSelectOptionValues.option) {
1417
1471
  oSelectionVariant.addSelectOption(
@@ -1751,7 +1805,7 @@ sap.ui.define(
1751
1805
  for (var iLinkCount = 0; iLinkCount < aLinks[i][0].length; iLinkCount++) {
1752
1806
  _oLink = aLinks[i][0][iLinkCount];
1753
1807
  _sLinkIntent = _oLink && _oLink.intent.split("-")[1];
1754
- if (!(sCurrentHash === _sLinkIntent)) {
1808
+ if (!(_oLink && _oLink.intent && _oLink.intent.indexOf(sCurrentHash) === 0)) {
1755
1809
  hasTargetsNotFiltered = true;
1756
1810
  if (!bIntentHasActions(_sLinkIntent, aSemanticObjects[k].unavailableActions)) {
1757
1811
  aFinalLinks[i].push(_oLink);
@@ -2051,6 +2105,33 @@ sap.ui.define(
2051
2105
  }
2052
2106
  }
2053
2107
 
2108
+ /**
2109
+ * Method which returns a promise that resolves to a singleton property value.
2110
+ *
2111
+ * @param {string} sPath Absolute path to the singleton property
2112
+ * @param {object} oModel Instance of the OData V4 model
2113
+ * @returns {Promise} A promise which resolves to the property value for a singleton, otherwise null.
2114
+ */
2115
+ function requestSingletonProperty(sPath, oModel) {
2116
+ if (!sPath || !oModel) {
2117
+ return Promise.resolve(null);
2118
+ }
2119
+
2120
+ var oMetaModel = oModel.getMetaModel();
2121
+ // Find the underlying entity set from the property path and check whether it is a singleton.
2122
+ var aParts = sPath.split("/").filter(Boolean),
2123
+ sPropertyName = aParts.pop(),
2124
+ sNavigationPath = aParts.join("/"),
2125
+ oEntitySet = sNavigationPath && oMetaModel.getObject("/" + sNavigationPath);
2126
+ if (oEntitySet && oEntitySet.$kind === "Singleton") {
2127
+ var sSingletonName = aParts[aParts.length - 1],
2128
+ oPropertyBinding = oModel.bindProperty("/" + sSingletonName + "/" + sPropertyName);
2129
+ return oPropertyBinding.requestValue();
2130
+ }
2131
+
2132
+ return Promise.resolve(null);
2133
+ }
2134
+
2054
2135
  function loadMacroLibrary() {
2055
2136
  return new Promise(function(resolve, reject) {
2056
2137
  sap.ui.require(["sap/fe/macros/macroLibrary"], function(/*macroLibrary*/) {
@@ -2101,6 +2182,7 @@ sap.ui.define(
2101
2182
  getSearchRestrictions: getSearchRestrictions,
2102
2183
  getFilterRestrictionsByPath: getFilterRestrictionsByPath,
2103
2184
  getSpecificAllowedExpression: getSpecificAllowedExpression,
2185
+ requestSingletonProperty: requestSingletonProperty,
2104
2186
  templateControlFragment: templateControlFragment,
2105
2187
  FilterRestrictions: {
2106
2188
  REQUIRED_PROPERTIES: "RequiredProperties",