@sapui5/sap.ushell_abap 1.151.0 → 1.152.0

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 (33) hide show
  1. package/package.json +1 -1
  2. package/src/main/js/sap/ushell_abap/.library +1 -1
  3. package/src/main/js/sap/ushell_abap/adapters/abap/AdapterContainer.js +30 -31
  4. package/src/main/js/sap/ushell_abap/adapters/abap/AppStateAdapter.js +1 -1
  5. package/src/main/js/sap/ushell_abap/adapters/abap/ClientSideTargetResolutionAdapter.js +13 -18
  6. package/src/main/js/sap/ushell_abap/adapters/abap/CommonDataModelAdapter.js +1 -1
  7. package/src/main/js/sap/ushell_abap/adapters/abap/ConfigurationDefaultsAdapter.js +1 -1
  8. package/src/main/js/sap/ushell_abap/adapters/abap/ContainerAdapter.js +31 -41
  9. package/src/main/js/sap/ushell_abap/adapters/abap/FlpLaunchPageAdapter.js +430 -555
  10. package/src/main/js/sap/ushell_abap/adapters/abap/LaunchPageAdapter.js +1 -1
  11. package/src/main/js/sap/ushell_abap/adapters/abap/NavTargetResolutionAdapter.js +1 -1
  12. package/src/main/js/sap/ushell_abap/adapters/abap/NavTargetResolutionInternalAdapter.js +1 -1
  13. package/src/main/js/sap/ushell_abap/adapters/abap/PageBuildingAdapter.js +1 -1
  14. package/src/main/js/sap/ushell_abap/adapters/abap/PagePersistenceAdapter.js +1 -1
  15. package/src/main/js/sap/ushell_abap/adapters/abap/PersonalizationAdapter.js +1 -1
  16. package/src/main/js/sap/ushell_abap/adapters/abap/PersonalizationV2Adapter.js +1 -1
  17. package/src/main/js/sap/ushell_abap/adapters/abap/SearchAdapter.js +1 -1
  18. package/src/main/js/sap/ushell_abap/adapters/abap/SupportTicketAdapter.js +1 -1
  19. package/src/main/js/sap/ushell_abap/adapters/abap/Ui5ComponentLoaderAdapter.js +1 -1
  20. package/src/main/js/sap/ushell_abap/adapters/abap/UserInfoAdapter.js +119 -125
  21. package/src/main/js/sap/ushell_abap/adapters/hana/ContainerAdapter.js +27 -33
  22. package/src/main/js/sap/ushell_abap/bootstrap/PageSetsRequestHandler.js +25 -50
  23. package/src/main/js/sap/ushell_abap/bootstrap/SAPCompanionConditionSetter.js +1 -3
  24. package/src/main/js/sap/ushell_abap/integration/fileshares/NavTargetResolutionFileShareSupport.js +3 -1
  25. package/src/main/js/sap/ushell_abap/library.js +1 -1
  26. package/src/main/js/sap/ushell_abap/pbServices/ui2/Catalog.js +69 -43
  27. package/src/main/js/sap/ushell_abap/pbServices/ui2/Chip.js +53 -64
  28. package/src/main/js/sap/ushell_abap/pbServices/ui2/ODataWrapper.js +63 -78
  29. package/src/main/js/sap/ushell_abap/pbServices/ui2/Page.js +12 -15
  30. package/src/main/js/sap/ushell_abap/pbServices/ui2/contracts/configurationUi.js +10 -2
  31. package/src/main/js/sap/ushell_abap/services/NavigationDataProvider.js +4 -4
  32. package/src/main/js/sap/ushell_abap/ui5appruntime/AppInfoAdapter.js +19 -18
  33. package/ui5.yaml +1 -3
@@ -3,16 +3,17 @@
3
3
  /**
4
4
  * @fileoverview The Unified Shell's page building adapter for the ABAP platform. Private copy. Classical home page functions are deprecated.
5
5
  * @since 1.121
6
- * @version 1.151.0
6
+ * @version 1.152.0
7
7
  */
8
8
  sap.ui.define([
9
9
  "sap/ui/thirdparty/URI",
10
10
  "sap/ushell/components/cards/ManifestPropertyHelper",
11
- "sap/ui/thirdparty/jquery",
12
11
  "sap/base/util/ObjectPath",
13
12
  "sap/base/util/isEmptyObject",
14
13
  "sap/m/GenericTile",
15
14
  "sap/ushell/base/SAPBusinessClientEnablement",
15
+ "sap/ushell/base/promisify",
16
+ "sap/ushell/base/requireAsync",
16
17
  "sap/ushell/Config",
17
18
  "sap/base/util/deepExtend",
18
19
  "sap/ushell/utils/chipsUtils",
@@ -27,11 +28,12 @@ sap.ui.define([
27
28
  ], (
28
29
  URI,
29
30
  ManifestPropertyHelper,
30
- jQuery,
31
31
  ObjectPath,
32
32
  isEmptyObject,
33
33
  GenericTile,
34
34
  SAPBusinessClientEnablement,
35
+ promisify,
36
+ requireAsync,
35
37
  Config,
36
38
  deepExtend,
37
39
  chipsUtils,
@@ -82,8 +84,8 @@ sap.ui.define([
82
84
  */
83
85
  function LaunchPageAdapter (oUnused, sParameter, oAdapterConfiguration) {
84
86
  let bCatalogsValid; // undefined = not yet valid
85
- let oGetGroupsDeferred; // used to synchronize parallel getGroups-requests
86
- let oGetCatalogsDeferred; // used to synchronize parallel getCatalog-requests
87
+ let pGetGroupsResolver; // { promise, resolve, reject } used to synchronize parallel getGroups-requests
88
+ let pGetCatalogsHandle; // { promise, resolve, reject } — used to synchronize parallel getCatalog-requests
87
89
 
88
90
  // Stores a boolean that indicates whether a target mapping is supported on the current device.
89
91
  // One should use makeTargetMappingSupportKey to store and retrieve values to/from this map.
@@ -360,29 +362,28 @@ sap.ui.define([
360
362
  *
361
363
  * @param {string[]} aHiddenGroupsIDs The input parameter must be of type array, containing the IDs of the
362
364
  * groups that should be set hidden. In case an empty array is provided all groups should be changed to visible.
363
- * @returns {jQuery.Promise} Resolves once the group is hidden.
365
+ * @returns {Promise} Resolves once the group is hidden.
364
366
  * @private
365
367
  * @deprecated since 1.120
366
368
  */
367
369
  this.hideGroups = function (aHiddenGroupsIDs) {
368
- const oDeferred = new jQuery.Deferred();
369
-
370
370
  if (!aHiddenGroupsIDs || !(aHiddenGroupsIDs instanceof Array)) {
371
- oDeferred.reject(new Error("Input parameter must be of type Array."));
372
- } else {
371
+ return Promise.reject(new Error("Input parameter must be of type Array."));
372
+ }
373
+
374
+ return new Promise((resolve, reject) => {
373
375
  const oConf = JSON.parse(that._oCurrentPageSet.getConfiguration() || "{}");
374
376
 
375
377
  // Replace the hidden groups array on the current configuration with the new hidden groups array
376
378
  oConf.hiddenGroups = aHiddenGroupsIDs;
377
379
  that._oCurrentPageSet.setConfiguration(
378
380
  JSON.stringify(oConf),
379
- /* fnSuccess */oDeferred.resolve.bind(oDeferred),
381
+ /* fnSuccess */resolve,
380
382
  /* fnFailure */(sErrorMessage) => {
381
- oDeferred.reject(new Error(sErrorMessage));
383
+ reject(new Error(sErrorMessage));
382
384
  }
383
385
  );
384
- }
385
- return oDeferred.promise();
386
+ });
386
387
  };
387
388
 
388
389
  /**
@@ -519,13 +520,10 @@ sap.ui.define([
519
520
  function loadDependenciesAndTriggerChipInstanceLoad (oChipInstance) {
520
521
  // append the promise for loading to the instance, but only as long as loading is
521
522
  // pending. Note: will be used by getTileView
522
- oChipInstance._loadingDeferred = new jQuery.Deferred(); // used for KPI tiles and custom tiles
523
- oChipInstance.$loadingPromise = oChipInstance._loadingDeferred.promise();
524
- that._aOtherChipsPromises.push(new Promise((resolve, reject) => {
525
- oChipInstance.$loadingPromise
526
- .done(resolve)
527
- .fail(reject);
528
- }));
523
+ // used for KPI tiles and custom tiles; $loadingPromise is a native Promise
524
+ oChipInstance._loadingDeferred = Promise.withResolvers();
525
+ oChipInstance.$loadingPromise = oChipInstance._loadingDeferred.promise;
526
+ that._aOtherChipsPromises.push(oChipInstance.$loadingPromise);
529
527
 
530
528
  if (window["sap-ui-debug"] === true) {
531
529
  LaunchPageAdapter.prototype._triggerChipInstanceLoad(oChipInstance);
@@ -536,7 +534,7 @@ sap.ui.define([
536
534
  // even more round trips; in practice, chances are high that the homepage will contain some non-KPI custom tiles,
537
535
  // so core-ext-light will probably be loaded in most cases
538
536
  // see internal BCP 1770271005
539
- sap.ui.require(["sap/ushell/EventHub"], (oEventHub) => {
537
+ requireAsync(["sap/ushell/EventHub"]).then(([oEventHub]) => {
540
538
  const oCoreResourcesComplementEvent = oEventHub.on("CoreResourcesComplementLoaded");
541
539
 
542
540
  oCoreResourcesComplementEvent.do((oEvent) => {
@@ -602,7 +600,7 @@ sap.ui.define([
602
600
  * This method reads all target mappings for the current user via
603
601
  * a) a compactTM promise if present in config
604
602
  * b) xor a start_up service call with tm_compact=true
605
- * @returns {jQuery.Promise} Resolves to an array
603
+ * @returns {Promise} Resolves to an object
606
604
  * <pre>
607
605
  * [
608
606
  * {
@@ -614,9 +612,7 @@ sap.ui.define([
614
612
  * ]
615
613
  * </pre>
616
614
  */
617
- LaunchPageAdapter.prototype._readTargetMappings = function () {
618
- const oDeferred = new jQuery.Deferred();
619
-
615
+ LaunchPageAdapter.prototype._readTargetMappings = async function () {
620
616
  function formatResult (oStartupData) {
621
617
  const aRes = [];
622
618
  const oTargetMappings = oStartupData.targetMappings || oStartupData || {};
@@ -631,16 +627,10 @@ sap.ui.define([
631
627
  }
632
628
 
633
629
  if (ObjectPath.get("compactTMPromise", oAdapterConfig)) {
634
- oAdapterConfig.compactTMPromise
635
- .then((oResult) => {
636
- const aRes = formatResult(oResult || {});
637
- oDeferred.resolve({ results: aRes });
638
- })
639
- .catch((oError) => {
640
- oDeferred.reject(oError);
641
- });
642
- return oDeferred.promise();
630
+ const oResult = await oAdapterConfig.compactTMPromise;
631
+ return { results: formatResult(oResult || {}) };
643
632
  }
633
+
644
634
  const oTargetMappingsConfig = ObjectPath.create("services.targetMappings", oAdapterConfig);
645
635
  const sCacheId = oTargetMappingsConfig.cacheId || "";
646
636
  let sUrl = `/sap/bc/ui2/start_up?so=%2A&action=%2A&tm-compact=true&shellType=${SAPBusinessClientEnablement.getShellType()}&depth=0`;
@@ -653,20 +643,20 @@ sap.ui.define([
653
643
  sUrl += `${sUrl.indexOf("?") < 0 ? "?" : "&"}sap-ui2-cache-disable=${sUI2CacheDisable}`;
654
644
  }
655
645
 
656
- Utils.get(
657
- sUrl,
658
- false, /* xml=*/
659
- (sDirectStartResult) => {
660
- const oDirectStartResult = JSON.parse(sDirectStartResult);
661
- const oDirectStartTargetMappings = oDirectStartResult.targetMappings || {};
662
- const aRes = formatResult(oDirectStartTargetMappings);
663
- oDeferred.resolve({ results: aRes });
664
- },
665
- (sErrorMessage) => {
666
- oDeferred.reject(new Error(sErrorMessage));
667
- }
668
- );
669
- return oDeferred.promise();
646
+ return new Promise((resolve, reject) => {
647
+ Utils.get(
648
+ sUrl,
649
+ false, /* xml=*/
650
+ (sDirectStartResult) => {
651
+ const oDirectStartResult = JSON.parse(sDirectStartResult);
652
+ const oDirectStartTargetMappings = oDirectStartResult.targetMappings || {};
653
+ resolve({ results: formatResult(oDirectStartTargetMappings) });
654
+ },
655
+ (sErrorMessage) => {
656
+ reject(new Error(sErrorMessage));
657
+ }
658
+ );
659
+ });
670
660
  };
671
661
 
672
662
  /**
@@ -1233,93 +1223,88 @@ sap.ui.define([
1233
1223
  };
1234
1224
 
1235
1225
  /**
1236
- * Lazily initializes <code>_oCurrentPageSet</code> and returns a jQuery promise resolving with it.
1237
- * Parallel calls are deduplicated. Subsequent calls return the already-resolved promise.
1226
+ * Lazily initializes <code>_oCurrentPageSet</code> and returns a Promise resolving with it.
1227
+ * Parallel calls are deduplicated. Subsequent calls return the already-settled promise.
1238
1228
  *
1239
- * @returns {jQuery.Promise<sap.ushell_abap.pbServices.ui2.PageSet>} Resolves with the current page set object.
1229
+ * @returns {Promise<sap.ushell_abap.pbServices.ui2.PageSet>} Resolves with the current page set object.
1240
1230
  * @private
1241
1231
  */
1242
1232
  this._getPageSet = function () {
1243
- if (this._oGetPageSetDeferred) {
1244
- return this._oGetPageSetDeferred.promise();
1233
+ if (this._pGetPageSet) {
1234
+ return this._pGetPageSet;
1245
1235
  }
1246
1236
 
1247
- this._oGetPageSetDeferred = new jQuery.Deferred();
1237
+ this._pGetPageSet = Promise.resolve().then(async () => {
1238
+ const PageBuildingService = await Container.getServiceAsync("PageBuilding");
1239
+ const fnReadPageSet = PageBuildingService.getFactory().getPageBuildingService().readPageSet;
1248
1240
 
1249
- Container.getServiceAsync("PageBuilding")
1250
- .then((PageBuildingService) => {
1251
- const fnReadPageSet = PageBuildingService.getFactory().getPageBuildingService().readPageSet;
1241
+ if (oLaunchPageServiceConfig && oLaunchPageServiceConfig.cacheId) {
1242
+ // add PageSet cache buster token if configured
1243
+ fnReadPageSet.cacheBusterTokens
1244
+ .put(sDEFAULT_PAGE_ID, oLaunchPageServiceConfig.cacheId);
1245
+ }
1246
+ if (oLaunchPageServiceConfig && oLaunchPageServiceConfig["sap-ui2-cache-disable"] && fnReadPageSet) {
1247
+ const oAppendedParameters = fnReadPageSet.appendedParameters || {};
1248
+ oAppendedParameters["sap-ui2-cache-disable"] = oLaunchPageServiceConfig["sap-ui2-cache-disable"];
1249
+ fnReadPageSet.appendedParameters = oAppendedParameters;
1250
+ }
1252
1251
 
1253
- if (oLaunchPageServiceConfig && oLaunchPageServiceConfig.cacheId) {
1254
- // add PageSet cache buster token if configured
1255
- fnReadPageSet.cacheBusterTokens
1256
- .put(sDEFAULT_PAGE_ID, oLaunchPageServiceConfig.cacheId);
1257
- }
1258
- if (oLaunchPageServiceConfig && oLaunchPageServiceConfig["sap-ui2-cache-disable"] && fnReadPageSet) {
1259
- const oAppendedParameters = fnReadPageSet.appendedParameters || {};
1260
- oAppendedParameters["sap-ui2-cache-disable"] = oLaunchPageServiceConfig["sap-ui2-cache-disable"];
1261
- fnReadPageSet.appendedParameters = oAppendedParameters;
1262
- }
1252
+ /*
1253
+ * In spaces mode we will create an empty page inside an empty pageSet.
1254
+ * This is needed because the appfinder and search integration request the classic homepage content
1255
+ * which is not available in spaces mode.
1256
+ * For consistency reasons it should then also not be available from the search results.
1257
+ * The empty pageSet has all needed functions the real pageSet has.
1258
+ * Functions which should not be used in spaces mode throw an error
1259
+ */
1260
+ if (Config.last("/core/spaces/enabled")) {
1261
+ const oFactory = PageBuildingService.getFactory();
1263
1262
 
1264
- /*
1265
- * In spaces mode we will create an empty page inside an empty pageSet.
1266
- * This is needed because the appfinder and search integration request the classic homepage content
1267
- * which is not available in spaces mode.
1268
- * For consistency reasons it should then also not be available from the search results.
1269
- * The empty pageSet has all needed functions the real pageSet has.
1270
- * Functions which should not be used in spaces mode throw an error
1271
- */
1272
- if (Config.last("/core/spaces/enabled")) {
1273
- const oFactory = PageBuildingService.getFactory();
1263
+ const oFakeDefaultPage = new Page(oFactory, {
1264
+ id: PAGE_ID_WITHOUT_TM
1265
+ });
1274
1266
 
1275
- const oFakeDefaultPage = new Page(oFactory, {
1276
- id: PAGE_ID_WITHOUT_TM
1277
- });
1267
+ this._oCurrentPageSet = {
1268
+ getDefaultPage: function () {
1269
+ return oFakeDefaultPage;
1270
+ },
1271
+ getPages: function () {
1272
+ return [oFakeDefaultPage];
1273
+ },
1274
+ appendPage: function () {
1275
+ throw new Error("Not implemented in Pages Runtime");
1276
+ },
1277
+ isPageRemovable: function () {
1278
+ return false;
1279
+ },
1280
+ removePage: function () {
1281
+ throw new Error("Not implemented in Pages Runtime");
1282
+ },
1283
+ isPageResettable: function () {
1284
+ return true;
1285
+ },
1286
+ resetPage: function () {
1287
+ },
1288
+ getConfiguration: function () {
1289
+ return "{}";
1290
+ },
1291
+ setConfiguration: function () {
1292
+ },
1293
+ filter: function () {
1294
+ }
1295
+ };
1278
1296
 
1279
- this._oCurrentPageSet = {
1280
- getDefaultPage: function () {
1281
- return oFakeDefaultPage;
1282
- },
1283
- getPages: function () {
1284
- return [oFakeDefaultPage];
1285
- },
1286
- appendPage: function () {
1287
- throw new Error("Not implemented in Pages Runtime");
1288
- },
1289
- isPageRemovable: function () {
1290
- return false;
1291
- },
1292
- removePage: function () {
1293
- throw new Error("Not implemented in Pages Runtime");
1294
- },
1295
- isPageResettable: function () {
1296
- return true;
1297
- },
1298
- resetPage: function () {
1299
- },
1300
- getConfiguration: function () {
1301
- return "{}";
1302
- },
1303
- setConfiguration: function () {
1304
- },
1305
- filter: function () {
1306
- }
1307
- };
1297
+ return this._oCurrentPageSet;
1298
+ }
1308
1299
 
1309
- this._oGetPageSetDeferred.resolve(this._oCurrentPageSet);
1310
- } else {
1311
- PageBuildingService.getPageSet(sDEFAULT_PAGE_ID)
1312
- .fail(this._oGetPageSetDeferred.reject.bind(this._oGetPageSetDeferred))
1313
- .done((oPageSet) => {
1314
- this._oCurrentPageSet = oPageSet;
1315
- // remove unsupported pages before loading their chip instances
1316
- this._oCurrentPageSet.filter([sDEFAULT_PAGE_ID], [sDEFAULT_CATALOG_ID]);
1317
- this._oGetPageSetDeferred.resolve(oPageSet);
1318
- });
1319
- }
1320
- });
1300
+ const oPageSet = await promisify(PageBuildingService.getPageSet(sDEFAULT_PAGE_ID));
1301
+ this._oCurrentPageSet = oPageSet;
1302
+ // remove unsupported pages before loading their chip instances
1303
+ this._oCurrentPageSet.filter([sDEFAULT_PAGE_ID], [sDEFAULT_CATALOG_ID]);
1304
+ return oPageSet;
1305
+ });
1321
1306
 
1322
- return this._oGetPageSetDeferred.promise();
1307
+ return this._pGetPageSet;
1323
1308
  };
1324
1309
 
1325
1310
  /**
@@ -1328,52 +1313,52 @@ sap.ui.define([
1328
1313
  *
1329
1314
  * The first group in this list is considered the default group.
1330
1315
  *
1331
- * @returns {jQuery.Promise<sap.ushell_abap.pbServices.ui2.Page[]>} Resolves the list of group.
1316
+ * @returns {Promise<sap.ushell_abap.pbServices.ui2.Page[]>} Resolves the list of group.
1332
1317
  * @since 1.11.0
1333
1318
  * @deprecated since 1.120
1334
1319
  */
1335
1320
  this.getGroups = function () {
1336
1321
  if (this._bPageSetFullyLoaded) {
1337
1322
  // return the already known page set (the order is recomputed because the page set might have changed it since last call)
1338
- return new jQuery.Deferred().resolve(getOrderedPages()).promise();
1323
+ return Promise.resolve(getOrderedPages());
1339
1324
  }
1340
- if (!oGetGroupsDeferred) {
1341
- // start a new request and remember it in oGetGroupsDeferred, so that parallel calls don't start another one
1342
- oGetGroupsDeferred = new jQuery.Deferred();
1325
+ if (!pGetGroupsResolver) {
1326
+ // start a new request and remember it, so that parallel calls don't start another one
1327
+ pGetGroupsResolver = Promise.withResolvers();
1343
1328
 
1344
1329
  // The target mappings are used in the classic homepage and in spaces mode.
1345
1330
  const oMappingPromise = this._loadTargetMappings();
1346
1331
 
1347
1332
  this._getPageSet()
1348
- .done((oPageSet) => {
1333
+ .then((oPageSet) => {
1349
1334
  if (Config.last("/core/spaces/enabled")) {
1350
- oGetGroupsDeferred.resolve([]);
1335
+ pGetGroupsResolver.resolve([]);
1351
1336
  } else {
1352
- const oChipsLoadedDeferred = new jQuery.Deferred();
1337
+ const { promise: pChipsLoaded, resolve: resolveChipsLoaded } = Promise.withResolvers();
1353
1338
 
1354
1339
  // Trigger load of all CHIP instances, but wait for the locals only
1355
1340
  this._loadApplaunchersAndDelayLoadingOfOtherChips(
1356
1341
  oPageSet.getPages(),
1357
- oChipsLoadedDeferred.resolve.bind(oChipsLoadedDeferred)
1342
+ resolveChipsLoaded
1358
1343
  );
1359
1344
 
1360
- jQuery.when(oMappingPromise, oChipsLoadedDeferred)
1361
- .done(() => {
1345
+ Promise.all([oMappingPromise, pChipsLoaded])
1346
+ .then(() => {
1362
1347
  this._bPageSetFullyLoaded = true;
1363
1348
 
1364
1349
  if (Log.getLevel() >= Log.Level.DEBUG) { // sap-ui-debug = true
1365
1350
  this._findAndReportTileErrors(oPageSet.getPages(), oTargetMappingSupport);
1366
1351
  }
1367
1352
 
1368
- oGetGroupsDeferred.resolve(getOrderedPages());
1353
+ pGetGroupsResolver.resolve(getOrderedPages());
1369
1354
  })
1370
- .fail(oGetGroupsDeferred.reject.bind(oGetGroupsDeferred));
1355
+ .catch(pGetGroupsResolver.reject);
1371
1356
  }
1372
1357
  })
1373
- .fail(oGetGroupsDeferred.reject.bind(oGetGroupsDeferred));
1358
+ .catch(pGetGroupsResolver.reject);
1374
1359
  }
1375
1360
 
1376
- return oGetGroupsDeferred.promise();
1361
+ return pGetGroupsResolver.promise;
1377
1362
  };
1378
1363
 
1379
1364
  /**
@@ -1388,7 +1373,7 @@ sap.ui.define([
1388
1373
  return this._oTargetMappingPromise;
1389
1374
  }
1390
1375
  this._oTargetMappingPromise = this._readTargetMappings()
1391
- .done((oTargetMappings) => {
1376
+ .then((oTargetMappings) => {
1392
1377
  const sFormFactor = Utils.getFormFactor();
1393
1378
 
1394
1379
  oTargetMappings.results.forEach((oTargetMapping) => {
@@ -1402,6 +1387,7 @@ sap.ui.define([
1402
1387
  oTargetMappingSupport.get(sKey)
1403
1388
  || !!(oTargetMapping.formFactors && oTargetMapping.formFactors[sFormFactor]));
1404
1389
  });
1390
+ this._bTargetMappingsLoaded = true;
1405
1391
  });
1406
1392
 
1407
1393
  return this._oTargetMappingPromise;
@@ -1416,34 +1402,26 @@ sap.ui.define([
1416
1402
  * @deprecated since 1.120
1417
1403
  */
1418
1404
  this.getGroupsAndWaitForAllChips = function () {
1419
- return new Promise((resolve, reject) => {
1420
- that.getGroups()
1421
- .done(resolve)
1422
- .fail(reject);
1423
- }).then((aGroups) => {
1424
- return Promise.allSettled(that._aOtherChipsPromises)
1425
- .then(() => {
1426
- return aGroups;
1427
- });
1428
- });
1405
+ return that.getGroups()
1406
+ .then((aGroups) => {
1407
+ return Promise.allSettled(that._aOtherChipsPromises)
1408
+ .then(() => {
1409
+ return aGroups;
1410
+ });
1411
+ });
1429
1412
  };
1430
1413
 
1431
1414
  /**
1432
1415
  * Returns the default group.
1433
1416
  *
1434
- * @returns {jQuery.Promise<sap.ushell_abap.pbServices.ui2.Page>} Resolves the default group.
1417
+ * @returns {Promise<sap.ushell_abap.pbServices.ui2.Page>} Resolves the default group.
1435
1418
  * @since 1.11.0
1436
1419
  * @deprecated since 1.120
1437
1420
  */
1438
- this.getDefaultGroup = function () {
1439
- const oDeferred = new jQuery.Deferred();
1440
-
1441
- this.getGroups().done(() => {
1442
- // TODO test if getGroups()[0] is faster than getDefaultPage
1443
- oDeferred.resolve(that._oCurrentPageSet.getDefaultPage());
1444
- }).fail(oDeferred.reject.bind(oDeferred));
1445
-
1446
- return oDeferred.promise();
1421
+ this.getDefaultGroup = async function () {
1422
+ // TODO test if getGroups()[0] is faster than getDefaultPage
1423
+ await this.getGroups();
1424
+ return that._oCurrentPageSet.getDefaultPage();
1447
1425
  };
1448
1426
 
1449
1427
  /**
@@ -1523,87 +1501,77 @@ sap.ui.define([
1523
1501
  *
1524
1502
  * Intention: the page builder adds this group to the end of the home screen.
1525
1503
  *
1526
- * In case of error it gets the consistent backend state of all groups as array of <code>sap.ushell_abap.pbServices.ui2.Page</code>.
1527
- *
1528
1504
  * @param {string} sTitle the title of the new group
1529
- * @returns {jQuery.Promise<sap.ushell_abap.pbServices.ui2.Page>} Resolves once the group was added.
1505
+ * @returns {Promise<sap.ushell_abap.pbServices.ui2.Page>} Resolves once the group was added.
1530
1506
  * @since 1.11.0
1531
1507
  * @deprecated since 1.120
1532
1508
  */
1533
1509
  this.addGroup = function (sTitle) {
1534
- const oDeferred = new jQuery.Deferred();
1535
-
1536
- that._oCurrentPageSet.appendPage(sTitle, sDEFAULT_CATALOG_ID,
1537
- oDeferred.resolve.bind(oDeferred),
1538
- (sErrorMessage) => {
1539
- oDeferred.reject(new Error(sErrorMessage), getOrderedPages());
1540
- });
1541
-
1542
- return oDeferred.promise();
1510
+ return new Promise((resolve, reject) => {
1511
+ that._oCurrentPageSet.appendPage(sTitle, sDEFAULT_CATALOG_ID,
1512
+ resolve,
1513
+ (sErrorMessage) => {
1514
+ reject(new Error(sErrorMessage));
1515
+ });
1516
+ });
1543
1517
  };
1544
1518
 
1545
1519
  /**
1546
1520
  * Removes a group.
1547
1521
  *
1548
- * In case of error it gets the consistent backend state of all groups as array of <code>sap.ushell_abap.pbServices.ui2.Page</code>.
1549
- *
1550
1522
  * @param {object} oGroup the group to be removed
1551
- * @returns {jQuery.Promise} Resolves once the group was removed.
1523
+ * @returns {Promise} Resolves once the group was removed.
1552
1524
  * @since 1.11.0
1553
1525
  * @deprecated since 1.120
1554
1526
  */
1555
1527
  this.removeGroup = function (oGroup) {
1556
- const oDeferred = new jQuery.Deferred();
1528
+ if (!that._oCurrentPageSet.isPageRemovable(oGroup)) {
1529
+ return Promise.reject(new Error("Group is not removable"));
1530
+ }
1557
1531
 
1558
- if (that._oCurrentPageSet.isPageRemovable(oGroup)) {
1532
+ return new Promise((resolve, reject) => {
1559
1533
  that._oCurrentPageSet.removePage(
1560
1534
  oGroup,
1561
- oDeferred.resolve.bind(oDeferred),
1535
+ resolve,
1562
1536
  (sErrorMessage) => {
1563
1537
  Log.error(`Failed to remove group '${oGroup.toString()}'`, sErrorMessage, sCOMPONENT);
1564
- oDeferred.reject(new Error(sErrorMessage), getOrderedPages());
1538
+ reject(new Error(sErrorMessage));
1565
1539
  }
1566
1540
  );
1567
- } else {
1568
- oDeferred.reject(new Error("Group is not removable"), getOrderedPages());
1569
- }
1570
- return oDeferred.promise();
1541
+ });
1571
1542
  };
1572
1543
 
1573
1544
  /**
1574
1545
  * Resets a group. Only groups can be reset for which <code>isGroupRemovable</code> returns false.
1575
1546
  * For others the fail handler is called.
1576
1547
  *
1577
- * In case of error it gets the consistent backend state of all groups as array of <code>sap.ushell_abap.pbServices.ui2.Page</code>.
1578
- *
1579
1548
  * @param {sap.ushell_abap.pbServices.ui2.Page} oGroup the group to be reset
1580
- * @returns {jQuery.Promise} Resolves once the group was reset.
1549
+ * @returns {Promise} Resolves once the group was reset.
1581
1550
  * @since 1.11.0
1582
1551
  * @deprecated since 1.120
1583
1552
  */
1584
1553
  this.resetGroup = function (oGroup) {
1585
- const oDeferred = new jQuery.Deferred();
1586
- const that = this;
1587
-
1588
1554
  if (that._oCurrentPageSet.isPageRemovable(oGroup)) {
1589
1555
  // pages which are removable should be removed and cannot be reset
1590
- oDeferred.reject(new Error("Group is not removable"), getOrderedPages());
1591
- } else if (that._oCurrentPageSet.isPageResettable(oGroup)) {
1556
+ return Promise.reject(new Error("Group is not removable"));
1557
+ }
1558
+
1559
+ if (that._oCurrentPageSet.isPageResettable(oGroup)) {
1592
1560
  // pages which are resettable should be reset
1593
- that._oCurrentPageSet.resetPage(
1594
- oGroup,
1595
- () => {
1596
- that._loadApplaunchersAndDelayLoadingOfOtherChips([oGroup], oDeferred.resolve.bind(oDeferred, oGroup));
1597
- },
1598
- (sErrorMessage) => {
1599
- oDeferred.reject(new Error("Failed to reset group"), getOrderedPages());
1600
- });
1601
- } else {
1602
- // on all other pages an reset has simply no effect
1603
- oDeferred.resolve(oGroup);
1561
+ return new Promise((resolve, reject) => {
1562
+ that._oCurrentPageSet.resetPage(
1563
+ oGroup,
1564
+ () => {
1565
+ that._loadApplaunchersAndDelayLoadingOfOtherChips([oGroup], () => resolve(oGroup));
1566
+ },
1567
+ () => {
1568
+ reject(new Error("Failed to reset group"));
1569
+ });
1570
+ });
1604
1571
  }
1605
1572
 
1606
- return oDeferred.promise();
1573
+ // on all other pages a reset has simply no effect
1574
+ return Promise.resolve(oGroup);
1607
1575
  };
1608
1576
 
1609
1577
  /**
@@ -1667,7 +1635,7 @@ sap.ui.define([
1667
1635
  * @since 1.21.0
1668
1636
  */
1669
1637
  this.isTileIntentSupported = function (oTile) {
1670
- if (!this._oTargetMappingPromise || this._oTargetMappingPromise.state() !== "resolved") {
1638
+ if (!this._bTargetMappingsLoaded) {
1671
1639
  Log.error("isTileIntentSupported might return wrong results as data loading hasn't finished yet!", "sap.ushell_abap.adapters.abap.LaunchPageAdapter");
1672
1640
  }
1673
1641
 
@@ -1837,127 +1805,109 @@ sap.ui.define([
1837
1805
 
1838
1806
  /**
1839
1807
  * Moves a group to a new index.
1840
- * In case of error it gets the consistent backend state of all groups as array of <code>sap.ushell_abap.pbServices.ui2.Page</code>.
1841
1808
  *
1842
1809
  * @param {object} oGroup the group to be moved
1843
1810
  * @param {int} iNewIndex the new index for the group
1844
- * @returns {jQuery.Promise} Resolves once the group was moved.
1811
+ * @returns {Promise} Resolves once the group was moved.
1845
1812
  * @since 1.11.0
1846
1813
  * @deprecated since 1.120
1847
1814
  */
1848
- this.moveGroup = function (oGroup, iNewIndex) {
1815
+ this.moveGroup = async function (oGroup, iNewIndex) {
1849
1816
  // see wiki UICEI/PageSets+and+Groups#PageSetsandGroups-Rearrangegroupsonthehomepage
1850
- const oDeferred = new jQuery.Deferred();
1817
+ const aPages = await this.getGroups();
1818
+ const iIndex = aPages.indexOf(oGroup);
1851
1819
 
1852
- function updateConfiguration (aPages) {
1853
- const aIds = [];
1820
+ aPages.splice(iIndex, 1);
1821
+ aPages.splice(iNewIndex, 0, oGroup);
1854
1822
 
1855
- aPages.forEach((oPage) => {
1856
- aIds.push(oPage.getId());
1857
- });
1823
+ const aIds = aPages.map((oPage) => oPage.getId());
1858
1824
 
1859
- // save new order without overwriting other parts of the configuration
1860
- const oConf = JSON.parse(that._oCurrentPageSet.getConfiguration() || "{}");
1861
- oConf.order = aIds;
1825
+ // save new order without overwriting other parts of the configuration
1826
+ const oConf = JSON.parse(that._oCurrentPageSet.getConfiguration() || "{}");
1827
+ oConf.order = aIds;
1828
+
1829
+ return new Promise((resolve, reject) => {
1862
1830
  that._oCurrentPageSet.setConfiguration(JSON.stringify(oConf),
1863
- oDeferred.resolve.bind(oDeferred),
1831
+ resolve,
1864
1832
  (sErrorMessage) => {
1865
- oDeferred.reject(new Error(sErrorMessage), getOrderedPages());
1833
+ reject(new Error(sErrorMessage));
1866
1834
  });
1867
- }
1868
-
1869
- this.getGroups().done((aPages) => {
1870
- const iIndex = aPages.indexOf(oGroup);
1871
-
1872
- aPages.splice(iIndex, 1);
1873
- aPages.splice(iNewIndex, 0, oGroup);
1874
- updateConfiguration(aPages);
1875
1835
  });
1876
-
1877
- return oDeferred.promise();
1878
1836
  };
1879
1837
 
1880
1838
  /**
1881
1839
  * Sets a new title to an existing group.
1882
- * In case of error it gets the old title.
1883
1840
  *
1884
1841
  * @param {object} oGroup the group we need to set the title
1885
1842
  * @param {string} sNewTitle the new title of the group
1886
- * @returns {jQuery.Promise} Resolves once the group title was set.
1843
+ * @returns {Promise} Resolves once the group title was set.
1887
1844
  * @since 1.11.0
1888
1845
  * @deprecated since 1.120
1889
1846
  */
1890
1847
  this.setGroupTitle = function (oGroup, sNewTitle) {
1891
- const oDeferred = new jQuery.Deferred();
1892
-
1893
- oGroup.setTitle(sNewTitle,
1894
- oDeferred.resolve.bind(oDeferred),
1895
- (sErrorMessage) => {
1896
- oDeferred.reject(new Error("Failed to set group title"), oGroup.getTitle());
1897
- });
1898
-
1899
- return oDeferred.promise();
1848
+ return new Promise((resolve, reject) => {
1849
+ oGroup.setTitle(sNewTitle,
1850
+ resolve,
1851
+ () => {
1852
+ reject(new Error("Failed to set group title"));
1853
+ });
1854
+ });
1900
1855
  };
1901
1856
 
1902
1857
  /**
1903
1858
  * Adds a tile to the end of a group. The group is optional. If no group is given, use the default group.
1904
- * In case of error it gets the consistent backend state of all groups as array of <code>sap.ushell_abap.pbServices.ui2.Page</code>.
1905
1859
  *
1906
1860
  * @param {sap.ushell_abap.pbServices.ui2.ChipInstance} oCatalogTile an 'anonymous' catalog tile from the catalog browser
1907
1861
  * @param {sap.ushell_abap.pbServices.ui2.Page} [oGroup] the group
1908
- * @returns {jQuery.Promise<sap.ushell_abap.pbServices.ui2.ChipInstance>} Resolves once the tile was added.
1862
+ * @returns {Promise<sap.ushell_abap.pbServices.ui2.ChipInstance>} Resolves once the tile was added.
1909
1863
  * @since 1.11.0
1910
1864
  * @deprecated since 1.120
1911
1865
  */
1912
1866
  this.addTile = function (oCatalogTile, oGroup) {
1913
- const oDeferred = new jQuery.Deferred();
1914
1867
  const oChip = oCatalogTile.getChip(); // unwrap (see wrapAsChipInstances)
1915
1868
 
1916
1869
  if (oCatalogTile.isStub()) {
1917
1870
  // this is a "Cannot load tile" tile, this should not be added to the group
1918
1871
  // BCP 1670300106
1919
- oDeferred.reject(new Error("Tile was not added to the group as the tile failed loading"), getOrderedPages());
1920
- } else {
1921
- if (!oGroup) {
1922
- oGroup = that._oCurrentPageSet.getDefaultPage();
1923
- }
1872
+ return Promise.reject(new Error("Tile was not added to the group as the tile failed loading"));
1873
+ }
1874
+
1875
+ if (!oGroup) {
1876
+ oGroup = that._oCurrentPageSet.getDefaultPage();
1877
+ }
1924
1878
 
1879
+ return new Promise((resolve, reject) => {
1925
1880
  oGroup.addChipInstance(oChip,
1926
- oDeferred.resolve.bind(oDeferred),
1881
+ resolve,
1927
1882
  (sErrorMessage) => {
1928
- oDeferred.reject(new Error(sErrorMessage), getOrderedPages());
1883
+ reject(new Error(sErrorMessage));
1929
1884
  }
1930
1885
  );
1931
- }
1932
-
1933
- return oDeferred.promise();
1886
+ });
1934
1887
  };
1935
1888
 
1936
1889
  /**
1937
1890
  * Removes the given tile from the given group.
1938
- * In case of error it gets the consistent backend state of all groups as array of <code>sap.ushell_abap.pbServices.ui2.Page</code>.
1939
1891
  *
1940
1892
  * @param {sap.ushell_abap.pbServices.ui2.Page} oGroup the group containing the tile
1941
1893
  * @param {sap.ushell_abap.pbServices.ui2.ChipInstance} oTile the tile
1942
- * @returns {jQuery.Promise} Resolves once the tile was removed.
1894
+ * @returns {Promise} Resolves once the tile was removed.
1943
1895
  * @since 1.11.0
1944
1896
  * @deprecated since 1.120
1945
1897
  */
1946
1898
  this.removeTile = function (oGroup, oTile) {
1947
- const oDeferred = new jQuery.Deferred();
1948
-
1949
- oGroup.removeChipInstance(oTile,
1950
- oDeferred.resolve.bind(oDeferred),
1951
- (sErrorMessage) => {
1952
- oDeferred.reject(new Error(sErrorMessage), getOrderedPages());
1953
- }
1954
- );
1955
- return oDeferred.promise();
1899
+ return new Promise((resolve, reject) => {
1900
+ oGroup.removeChipInstance(oTile,
1901
+ resolve,
1902
+ (sErrorMessage) => {
1903
+ reject(new Error(sErrorMessage));
1904
+ }
1905
+ );
1906
+ });
1956
1907
  };
1957
1908
 
1958
1909
  /**
1959
1910
  * Moves a tile to another location in the same or a different group.
1960
- * In case of error it gets the consistent backend state of all groups as array of <code>sap.ushell_abap.pbServices.ui2.Page</code>.
1961
1911
  *
1962
1912
  * @param {sap.ushell_abap.pbServices.ui2.ChipInstance} oTile the tile to be moved
1963
1913
  * @param {int} iSourceIndex the index in the source group
@@ -1966,17 +1916,17 @@ sap.ui.define([
1966
1916
  * @param {sap.ushell_abap.pbServices.ui2.Page} oSourceGroup the tile's group
1967
1917
  * @param {sap.ushell_abap.pbServices.ui2.Page} [oTargetGroup] the group the tile will be placed in or tile's group if not supplied
1968
1918
  * @param {string} [sNewTileType] (added with 1.60) The new type of the tile
1969
- * @returns {jQuery.Promise} Resolves once the tile was moved.
1919
+ * @returns {Promise} Resolves once the tile was moved.
1970
1920
  * @since 1.11.0
1971
1921
  * @deprecated since 1.120
1972
1922
  */
1973
1923
  this.moveTile = function (oTile, iSourceIndex, iTargetIndex, oSourceGroup, oTargetGroup, sNewTileType) {
1974
- const oDeferred = new jQuery.Deferred();
1924
+ const { promise, resolve, reject } = Promise.withResolvers();
1975
1925
  const bIsWrapperOnly = this._isWrapperOnly(oTile);
1976
1926
  const oBagsContents = new Utils.Map();
1977
1927
  let oCreatedChipInstance;
1978
1928
  function fnFailure (sErrorMessage) {
1979
- oDeferred.reject(new Error(sErrorMessage), getOrderedPages());
1929
+ reject(new Error(sErrorMessage));
1980
1930
  }
1981
1931
  let iCalls = 2;
1982
1932
 
@@ -1987,7 +1937,7 @@ sap.ui.define([
1987
1937
  // oNewChipInstance needs to be cached for the removeChipInstance call
1988
1938
  oCreatedChipInstance = oCreatedChipInstance || oNewChipInstance;
1989
1939
  if (iCalls <= 0) {
1990
- oDeferred.resolve(oCreatedChipInstance);
1940
+ resolve(oCreatedChipInstance);
1991
1941
  }
1992
1942
  }
1993
1943
 
@@ -2003,12 +1953,12 @@ sap.ui.define([
2003
1953
  if (iSourceIndex < 0) {
2004
1954
  Log.error("moveTile: tile not found in source group", null, sCOMPONENT);
2005
1955
  fnFailure("moveTile: tile not found in source group");
2006
- return oDeferred.promise();
1956
+ return promise;
2007
1957
  }
2008
1958
 
2009
1959
  if (oSourceGroup === oTargetGroup) {
2010
1960
  addToLayout(oSourceLayout, oTile.getId(), iTargetIndex, sNewTileType);
2011
- oSourceGroup.setLayout(JSON.stringify(oSourceLayout), oDeferred.resolve.bind(oDeferred, oTile), fnFailure);
1961
+ oSourceGroup.setLayout(JSON.stringify(oSourceLayout), () => resolve(oTile), fnFailure);
2012
1962
  } else {
2013
1963
  Container.getServiceAsync("PageBuilding")
2014
1964
  .then((PageBuildingService) => {
@@ -2075,7 +2025,7 @@ sap.ui.define([
2075
2025
  });
2076
2026
  }
2077
2027
 
2078
- return oDeferred.promise();
2028
+ return promise;
2079
2029
  };
2080
2030
 
2081
2031
  /**
@@ -2163,84 +2113,81 @@ sap.ui.define([
2163
2113
  * Note: this function became async since 1.23.0.
2164
2114
  *
2165
2115
  * @param {sap.ushell_abap.pbServices.ui2.ChipInstance} oTile The tile's chip data
2166
- * @returns {jQuery.Promise<sap.ui.core.Control>} Resolves an instance of sap.m.GenericTile.
2116
+ * @returns {Promise<sap.ui.core.Control>} Resolves an instance of sap.m.GenericTile.
2167
2117
  * @since 1.11.0
2168
2118
  * @deprecated since 1.120
2169
2119
  */
2170
2120
  this.getTileView = function (oTile) {
2171
- const that = this;
2172
- const oDeferred = new jQuery.Deferred();
2121
+ return new Promise((resolve, reject) => {
2122
+ function doReject (oError) {
2123
+ Log.error("Tile not successfully loaded:", oError, sCOMPONENT);
2124
+ reject(oError);
2125
+ }
2173
2126
 
2174
- function doReject (oError) {
2175
- Log.error("Tile not successfully loaded:", oError, sCOMPONENT);
2176
- oDeferred.reject(oError);
2177
- }
2127
+ function doResolve () {
2128
+ let sTileType;
2178
2129
 
2179
- function doResolve () {
2180
- let sTileType;
2130
+ // if needed, notify the tile in which way it shall display itself
2131
+ const oTypesContract = oTile.getContract("types");
2132
+ if (oTypesContract) {
2133
+ // set the tile type before getting the view
2134
+ // note: the contract caches the new type until the handler is attached
2135
+ sTileType = that.getTileType(oTile);
2136
+ oTypesContract.setType(sTileType);
2137
+ }
2181
2138
 
2182
- // if needed, notify the tile in which way it shall display itself
2183
- const oTypesContract = oTile.getContract("types");
2184
- if (oTypesContract) {
2185
- // set the tile type before getting the view
2186
- // note: the contract caches the new type until the handler is attached
2187
- sTileType = that.getTileType(oTile);
2188
- oTypesContract.setType(sTileType);
2189
- }
2139
+ oTile.getImplementationAsSapui5Async()
2140
+ .then((oView) => {
2141
+ if (sTileType === "link") {
2142
+ if (!oView.hasModel()) {
2143
+ oView = oView.getComponentInstance().getRootControl();
2144
+ }
2145
+ const oViewModel = oView.getModel();
2146
+ const oViewController = oView.getController();
2147
+
2148
+ const sUrl = oViewModel && oViewModel.getProperty ? oViewModel.getProperty("/nav/navigation_target_url") : undefined;
2149
+ const oLinkTile = new GenericTile({
2150
+ mode: "{view>/mode}",
2151
+ header: "{view>/config/display_title_text}",
2152
+ subheader: "{view>/config/display_subtitle_text}",
2153
+ sizeBehavior: "{view>/sizeBehavior}",
2154
+ size: "Auto",
2155
+ url: oViewController.formatters && oViewController.formatters.leanURL(sUrl),
2156
+ press: [oViewController.onPress, oViewController]
2157
+ });
2190
2158
 
2191
- oTile.getImplementationAsSapui5Async()
2192
- .then((oView) => {
2193
- if (sTileType === "link") {
2194
- if (!oView.hasModel()) {
2195
- oView = oView.getComponentInstance().getRootControl();
2159
+ oLinkTile.setModel(oViewModel, "view");
2160
+ resolve(oLinkTile);
2161
+ return;
2196
2162
  }
2197
- const oViewModel = oView.getModel();
2198
- const oViewController = oView.getController();
2199
-
2200
- const sUrl = oViewModel && oViewModel.getProperty ? oViewModel.getProperty("/nav/navigation_target_url") : undefined;
2201
- const oLinkTile = new GenericTile({
2202
- mode: "{view>/mode}",
2203
- header: "{view>/config/display_title_text}",
2204
- subheader: "{view>/config/display_subtitle_text}",
2205
- sizeBehavior: "{view>/sizeBehavior}",
2206
- size: "Auto",
2207
- url: oViewController.formatters && oViewController.formatters.leanURL(sUrl),
2208
- press: [oViewController.onPress, oViewController]
2209
- });
2210
2163
 
2211
- oLinkTile.setModel(oViewModel, "view");
2212
- oDeferred.resolve(oLinkTile);
2213
- return;
2214
- }
2215
-
2216
- oDeferred.resolve(oView);
2217
- })
2218
- .catch(doReject);
2219
- }
2220
-
2221
- if (!oTile.$loadingPromise) { // loading resolved or failed
2222
- if (!oTile.isStub()) { // success
2223
- // call getImplementationAsSapui5Async async for non-AppLaunchers and resolves.
2224
- // For AppLaunchers, there is an optimization (requested by RT) to call it sync
2225
- // as the resources are already bundled and loaded at startup.
2226
- // Although they are called sync the view creation is still async
2227
- Utils.callHandler(doResolve, doReject, /* async */!isAppLauncher(oTile));
2228
- } else { // failed
2229
- doReject(new Error("Tile failed to load - tile is still a stub"));
2164
+ resolve(oView);
2165
+ })
2166
+ .catch(doReject);
2230
2167
  }
2231
- } else { // loading pending
2232
- oTile.$loadingPromise
2233
- .fail(doReject)
2234
- .done(() => {
2235
- try {
2236
- doResolve();
2237
- } catch (oError) {
2238
- doReject((oError));
2239
- }
2240
- });
2241
- }
2242
2168
 
2243
- return oDeferred.promise();
2169
+ if (!oTile.$loadingPromise) { // loading resolved or failed
2170
+ if (!oTile.isStub()) { // success
2171
+ // call getImplementationAsSapui5Async async for non-AppLaunchers and resolves.
2172
+ // For AppLaunchers, there is an optimization (requested by RT) to call it sync
2173
+ // as the resources are already bundled and loaded at startup.
2174
+ // Although they are called sync the view creation is still async
2175
+ Utils.callHandler(doResolve, doReject, /* async */!isAppLauncher(oTile));
2176
+ } else { // failed
2177
+ doReject(new Error("Tile failed to load - tile is still a stub"));
2178
+ }
2179
+ } else { // loading pending
2180
+ oTile.$loadingPromise
2181
+ .then(() => {
2182
+ try {
2183
+ doResolve();
2184
+ } catch (oError) {
2185
+ doReject(oError);
2186
+ }
2187
+ })
2188
+ .catch(doReject);
2189
+ }
2190
+ });
2244
2191
  };
2245
2192
 
2246
2193
  /**
@@ -2291,7 +2238,7 @@ sap.ui.define([
2291
2238
 
2292
2239
  if (bOldVisibility === undefined) {
2293
2240
  // attach handler, but only once.
2294
- oTile.$loadingPromise.done(() => {
2241
+ oTile.$loadingPromise.then(() => {
2295
2242
  const oVisibleContract = oTile.getContract("visible");
2296
2243
  if (oVisibleContract) {
2297
2244
  // tile uses visibility contract and sets the latest visibility
@@ -2362,85 +2309,78 @@ sap.ui.define([
2362
2309
  * this is handled gracefully by providing a "dummy" empty catalog (with ID instead of title).
2363
2310
  * Use {@link getCatalogError} to check if a (remote) catalog could not be loaded from the backend.
2364
2311
  * <p>
2365
- * Care has been taken to make sure that progress notifications are sent reliably for each single catalog,
2366
- * i.e. attaching a <code>progress</code> handler gives you the same possibilities as attaching a <code>done</code> handler,
2367
- * but with the advantage of improved responsiveness.
2312
+ * Progress notifications are sent per catalog by the service layer (FlpLaunchPage), which
2313
+ * iterates the resolved array. The adapter resolves with the full catalogs array at once.
2368
2314
  *
2369
2315
  * @example
2370
2316
  * sap.ushell.Container.getServiceAsync("LaunchPage")
2371
2317
  * .then(function (LaunchPageService) {
2372
2318
  * LaunchPageService.getCatalogs()
2373
- * .fail(function (sErrorMessage) { // string
2319
+ * .catch(function (oError) {
2374
2320
  * // handle error situation
2375
2321
  * })
2376
- * .progress(function (oCatalog) { // object
2377
- * // do s.th. with single catalog
2378
- * })
2379
- * .done(function (aCatalogs) { // object[]
2322
+ * .then(function (aCatalogs) { // object[]
2380
2323
  * aCatalogs.forEach(function (oCatalog) {
2381
2324
  * // do s.th. with single catalog
2382
2325
  * });
2383
2326
  * });
2384
2327
  * });
2385
2328
  *
2386
- * @returns {jQuery.Promise} Resolves an array of black-box catalog objects is provided (which might be empty).
2387
- * In case of failure, an error message is passed. Progress notifications are sent for each single catalog,
2388
- * providing a single black-box catalog object each time.
2329
+ * @returns {Promise} Resolves with an array of black-box catalog objects (which might be empty).
2330
+ * In case of failure, the promise is rejected with an error.
2389
2331
  * @since 1.11.0
2390
2332
  */
2391
2333
  this.getCatalogs = function () {
2392
- let oDeferred;
2393
- const oOldGetCatalogsDeferred = oGetCatalogsDeferred;
2334
+ const oOldHandle = pGetCatalogsHandle;
2394
2335
  const bRefreshRequired = bCatalogsValid === false;
2395
2336
 
2396
- // Note: bCatalogsValid can be undefined, false, true
2397
- if (oOldGetCatalogsDeferred && !oOldGetCatalogsDeferred.$notified && !bRefreshRequired) {
2398
- // re-use existing Deferred object; we cannot miss any notifications!
2399
- oDeferred = oOldGetCatalogsDeferred;
2400
- } else {
2401
- oGetCatalogsDeferred = new jQuery.Deferred();
2402
- oDeferred = oGetCatalogsDeferred;
2403
- oDeferred
2404
- .done(() => {
2405
- if (oDeferred === oGetCatalogsDeferred) {
2406
- // only the last call is allowed to change "global" variables
2407
- bCatalogsValid = true;
2408
- }
2409
- })
2410
- .always(() => {
2411
- if (oDeferred === oGetCatalogsDeferred) {
2412
- // only the last call is allowed to change "global" variables
2413
- oGetCatalogsDeferred = null;
2414
- }
2415
- });
2337
+ // Note: bCatalogsValid can be undefined, false, true.
2338
+ // Concurrent calls share the in-flight promise; a refresh forces a new load after the
2339
+ // current one settles.
2340
+ if (oOldHandle && !bRefreshRequired) {
2341
+ return oOldHandle.promise;
2342
+ }
2343
+
2344
+ const oHandle = Promise.withResolvers();
2345
+ pGetCatalogsHandle = oHandle;
2416
2346
 
2417
- if (oOldGetCatalogsDeferred) {
2418
- if (bRefreshRequired) {
2419
- bCatalogsValid = undefined; // not yet valid, refresh is in progress...
2347
+ oHandle.promise
2348
+ .then(() => {
2349
+ if (oHandle === pGetCatalogsHandle) {
2350
+ // only the last call is allowed to change "global" variables
2351
+ bCatalogsValid = true;
2420
2352
  }
2421
- // if we cannot reuse the old Deferred object, wait until it is done;
2422
- // after invalidation, wait until old operations are complete and then start a new roundtrip
2423
- oOldGetCatalogsDeferred
2424
- .always(() => {
2425
- this._startLoading(oDeferred, bRefreshRequired);
2426
- });
2427
- } else {
2428
- this._startLoading(oDeferred, bRefreshRequired);
2429
- }
2353
+ })
2354
+ .finally(() => {
2355
+ if (oHandle === pGetCatalogsHandle) {
2356
+ // only the last call is allowed to change "global" variables
2357
+ pGetCatalogsHandle = null;
2358
+ }
2359
+ });
2360
+
2361
+ if (oOldHandle) {
2362
+ // refresh required: wait until old load completes, then start a new roundtrip
2363
+ bCatalogsValid = undefined; // not yet valid, refresh is in progress...
2364
+ oOldHandle.promise
2365
+ .finally(() => {
2366
+ this._startLoading(oHandle, bRefreshRequired);
2367
+ });
2368
+ } else {
2369
+ this._startLoading(oHandle, bRefreshRequired);
2430
2370
  }
2431
2371
 
2432
- return oDeferred.promise();
2372
+ return oHandle.promise;
2433
2373
  };
2434
2374
 
2435
2375
  /**
2436
2376
  * Resolves the promise to return the user's catalogs by refreshing the first remote catalog found, failing gracefully.
2437
2377
  *
2438
- * @param {jQuery.Deferred} oDeferred A jQuery.Deferred to be resolved, rejected or notified.
2378
+ * @param {{promise: Promise, resolve: function, reject: function}} oHandle A Promise.withResolvers() handle to be resolved or rejected.
2439
2379
  * @param {sap.ushell_abap.pbServices.ui2.PageSet} oPageSet The page set containing the default page with allCatalogs.
2440
2380
  * @returns {Promise<sap.ushell.services.PageBuilding>} A promise that is resolved once the PageBuilding service is retrieved.
2441
2381
  * @private
2442
2382
  */
2443
- this._refreshRemoteCatalogs = function (oDeferred, oPageSet) {
2383
+ this._refreshRemoteCatalogs = function (oHandle, oPageSet) {
2444
2384
  return Container.getServiceAsync("PageBuilding")
2445
2385
  .then((PageBuildingService) => {
2446
2386
  let iPendingRequests = 0;
@@ -2458,32 +2398,25 @@ sap.ui.define([
2458
2398
  oWrappedCatalog.tiles = wrapAsChipInstances(oFactory, oCatalog.getChips());
2459
2399
  // TODO oRemoteCatalogWrapper.errorMessage once wrappers are cached
2460
2400
 
2461
- oDeferred.notify(oWrappedCatalog);
2462
-
2463
2401
  iPendingRequests -= 1;
2464
2402
  if (iPendingRequests <= 0) {
2465
- oDeferred.resolve(aWrappedCatalogs);
2403
+ oHandle.resolve(aWrappedCatalogs);
2466
2404
  }
2467
2405
  }, (sErrorMessage) => {
2468
2406
  // log errors, but do not fail
2469
2407
  Log.error(`Failed to load catalog: ${sErrorMessage}`, oCatalog.toString(), sCOMPONENT);
2470
2408
  oWrappedCatalog.errorMessage = sErrorMessage || "Error"; // not undefined!
2471
2409
 
2472
- oDeferred.notify(oWrappedCatalog);
2473
-
2474
2410
  iPendingRequests -= 1;
2475
2411
  if (iPendingRequests <= 0) {
2476
- oDeferred.resolve(aWrappedCatalogs);
2412
+ oHandle.resolve(aWrappedCatalogs);
2477
2413
  }
2478
2414
  });
2479
- } else {
2480
- oDeferred.notify(oWrappedCatalog);
2481
- oDeferred.$notified = true; // notifications have already been sent
2482
2415
  }
2483
2416
  });
2484
2417
 
2485
2418
  if (iPendingRequests <= 0) {
2486
- oDeferred.resolve(aWrappedCatalogs);
2419
+ oHandle.resolve(aWrappedCatalogs);
2487
2420
  }
2488
2421
  });
2489
2422
  };
@@ -2491,60 +2424,56 @@ sap.ui.define([
2491
2424
  /**
2492
2425
  * Resolves the promise to return the user's catalogs...by just knowing them already.
2493
2426
  *
2494
- * @param {jQuery.Deferred} oDeferred A jQuery.Deferred to be resolved, rejected or notified.
2427
+ * @param {{promise: Promise, resolve: function, reject: function}} oHandle A Promise.withResolvers() handle to be resolved or rejected.
2495
2428
  * @param {sap.ushell_abap.pbServices.ui2.PageSet} oPageSet The page set containing the default page with allCatalogs.
2496
2429
  * @returns {Promise<sap.ushell.services.PageBuilding>} A promise that is resolved once the PageBuilding service is retrieved.
2497
2430
  * @private
2498
2431
  */
2499
- this._useKnownCatalogs = function (oDeferred, oPageSet) {
2432
+ this._useKnownCatalogs = function (oHandle, oPageSet) {
2500
2433
  return Container.getServiceAsync("PageBuilding")
2501
2434
  .then((PageBuildingService) => {
2502
2435
  const aWrappedCatalogs = wrapCatalogs(PageBuildingService.getFactory(), oPageSet);
2503
2436
 
2504
- aWrappedCatalogs.forEach((oWrappedCatalog) => {
2505
- oDeferred.notify(oWrappedCatalog);
2506
- });
2507
-
2508
- oDeferred.resolve(aWrappedCatalogs);
2437
+ oHandle.resolve(aWrappedCatalogs);
2509
2438
  });
2510
2439
  };
2511
2440
 
2512
2441
  /**
2513
2442
  * Resolves the promise to return the user's catalogs either by loading them, refreshing them, or just knowing them already.
2514
2443
  *
2515
- * @param {jQuery.Deferred} oDeferred A jQuery.Deferred to be resolved, rejected or notified.
2444
+ * @param {{promise: Promise, resolve: function, reject: function}} oHandle A Promise.withResolvers() handle to be resolved or rejected.
2516
2445
  * @param {boolean} bRefreshRequired Whether or not the catalogs should be loaded again.
2517
2446
  * @private
2518
2447
  */
2519
- this._doGetCatalogs = function (oDeferred, bRefreshRequired) {
2448
+ this._doGetCatalogs = function (oHandle, bRefreshRequired) {
2520
2449
  this._getPageSet()
2521
- .done((oPageSet) => {
2450
+ .then((oPageSet) => {
2522
2451
  const oAllCatalogs = oPageSet.getDefaultPage().getAllCatalogs();
2523
2452
  if (oAllCatalogs.isStub()) {
2524
2453
  oAllCatalogs.load(() => {
2525
- this._refreshRemoteCatalogs(oDeferred, oPageSet);
2454
+ this._refreshRemoteCatalogs(oHandle, oPageSet);
2526
2455
  }, (sErrorMessage) => {
2527
- oDeferred.reject(new Error(sErrorMessage));
2456
+ oHandle.reject(new Error(sErrorMessage));
2528
2457
  }, "type eq 'CATALOG_PAGE' or type eq 'H' or type eq 'SM_CATALOG' or type eq 'REMOTE'", true, "title", true);
2529
2458
  } else if (bRefreshRequired) {
2530
- this._refreshRemoteCatalogs(oDeferred, oPageSet);
2459
+ this._refreshRemoteCatalogs(oHandle, oPageSet);
2531
2460
  } else {
2532
- this._useKnownCatalogs(oDeferred, oPageSet);
2461
+ this._useKnownCatalogs(oHandle, oPageSet);
2533
2462
  }
2534
2463
  })
2535
- .fail((oError) => {
2536
- oDeferred.reject(oError);
2464
+ .catch((oError) => {
2465
+ oHandle.reject(oError);
2537
2466
  });
2538
2467
  };
2539
2468
 
2540
2469
  /**
2541
2470
  * Starts loading of catalogs, after parallel calls and invalidation have been taken care of.
2542
2471
  *
2543
- * @param {jQuery.Deferred} oDeferred A jQuery.Deferred to be resolved, rejected or notified.
2472
+ * @param {{promise: Promise, resolve: function, reject: function}} oHandle A Promise.withResolvers() handle to be resolved or rejected.
2544
2473
  * @param {boolean} bRefreshRequired Whether or not the catalogs should be loaded again.
2545
2474
  * @private
2546
2475
  */
2547
- this._startLoading = function (oDeferred, bRefreshRequired) {
2476
+ this._startLoading = function (oHandle, bRefreshRequired) {
2548
2477
  let oPromise;
2549
2478
 
2550
2479
  if (oLaunchPageServiceConfig && oLaunchPageServiceConfig.cacheId) {
@@ -2561,7 +2490,7 @@ sap.ui.define([
2561
2490
  oCacheTokens.put(PAGE_ID_WITHOUT_TM, oLaunchPageServiceConfig.cacheId);
2562
2491
  }
2563
2492
  })
2564
- .catch(oDeferred.reject);
2493
+ .catch(oHandle.reject);
2565
2494
  } else {
2566
2495
  oPromise = Promise.resolve();
2567
2496
  }
@@ -2573,16 +2502,16 @@ sap.ui.define([
2573
2502
  */
2574
2503
  if (!that._bPageSetFullyLoaded) {
2575
2504
  this.getGroups()
2576
- .done(() => {
2577
- this._doGetCatalogs(oDeferred, bRefreshRequired);
2505
+ .then(() => {
2506
+ this._doGetCatalogs(oHandle, bRefreshRequired);
2578
2507
  })
2579
- .fail(oDeferred.reject);
2508
+ .catch(oHandle.reject);
2580
2509
  return;
2581
2510
  }
2582
2511
 
2583
- this._doGetCatalogs(oDeferred, bRefreshRequired);
2512
+ this._doGetCatalogs(oHandle, bRefreshRequired);
2584
2513
  })
2585
- .catch(oDeferred.reject);
2514
+ .catch(oHandle.reject);
2586
2515
  };
2587
2516
 
2588
2517
  /**
@@ -2656,40 +2585,39 @@ sap.ui.define([
2656
2585
  * Returns the catalog's tiles.
2657
2586
  *
2658
2587
  * @param {object} oConfigCatalog the catalog
2659
- * @returns {jQuery.Promise<sap.ushell_abap.pbServices.ui2.Chip[]>} Resolves the catalog tiles.
2588
+ * @returns {Promise<sap.ushell_abap.pbServices.ui2.Chip[]>} Resolves the catalog tiles.
2660
2589
  * @since 1.11.0
2661
2590
  */
2662
2591
  this.getCatalogTiles = function (oConfigCatalog) {
2663
- const oDeferred = new jQuery.Deferred();
2664
- let iAsyncCount = 0;
2592
+ return new Promise((resolve) => {
2593
+ let iAsyncCount = 0;
2665
2594
 
2666
- function onLoaded () {
2667
- iAsyncCount -= 1;
2595
+ function onLoaded () {
2596
+ iAsyncCount -= 1;
2668
2597
 
2669
- if (iAsyncCount === 0) {
2670
- oDeferred.resolve(oConfigCatalog.tiles);
2598
+ if (iAsyncCount === 0) {
2599
+ resolve(oConfigCatalog.tiles);
2600
+ }
2671
2601
  }
2672
- }
2673
2602
 
2674
- function onFailure (oCatalogTile, sErrorMessage) {
2675
- // log errors, but do not fail
2676
- Log.error(`Failed to load catalog tile: ${sErrorMessage}`, oCatalogTile.toString(), sCOMPONENT);
2677
- onLoaded();
2678
- }
2679
-
2680
- for (let i = 0; i < oConfigCatalog.tiles.length; i += 1) {
2681
- const oChipInstance = oConfigCatalog.tiles[i];
2682
- if (oChipInstance.isStub()) {
2683
- iAsyncCount += 1;
2684
- oChipInstance.load(onLoaded, onFailure.bind(null, oChipInstance));
2603
+ function onFailure (oCatalogTile, sErrorMessage) {
2604
+ // log errors, but do not fail
2605
+ Log.error(`Failed to load catalog tile: ${sErrorMessage}`, oCatalogTile.toString(), sCOMPONENT);
2606
+ onLoaded();
2685
2607
  }
2686
- }
2687
2608
 
2688
- if (iAsyncCount === 0) {
2689
- oDeferred.resolve(oConfigCatalog.tiles);
2690
- }
2609
+ for (let i = 0; i < oConfigCatalog.tiles.length; i += 1) {
2610
+ const oChipInstance = oConfigCatalog.tiles[i];
2611
+ if (oChipInstance.isStub()) {
2612
+ iAsyncCount += 1;
2613
+ oChipInstance.load(onLoaded, onFailure.bind(null, oChipInstance));
2614
+ }
2615
+ }
2691
2616
 
2692
- return oDeferred.promise();
2617
+ if (iAsyncCount === 0) {
2618
+ resolve(oConfigCatalog.tiles);
2619
+ }
2620
+ });
2693
2621
  };
2694
2622
 
2695
2623
  /**
@@ -2819,19 +2747,17 @@ sap.ui.define([
2819
2747
  *
2820
2748
  * @param {sap.ui2.ChipInstance} oCatalogTile the catalog tile
2821
2749
  * @param {boolean} bPreview return the tile in preview mode, default is true
2822
- * @returns {jQuery.Promise<sap.ui.core.Control>} the UI5 representation of the catalog tile
2750
+ * @returns {Promise<sap.ui.core.Control>} the UI5 representation of the catalog tile
2823
2751
  * @since 1.97.0
2824
2752
  * @private
2825
2753
  */
2826
- this.getCatalogTileViewControl = function (oCatalogTile, bPreview) {
2827
- const oDeferred = new jQuery.Deferred();
2754
+ this.getCatalogTileViewControl = async function (oCatalogTile, bPreview) {
2828
2755
  bPreview = typeof bPreview !== "undefined" ? bPreview : true;
2829
2756
  const sTitle = this.getCatalogTileTitle(oCatalogTile);
2830
2757
 
2831
2758
  if (oCatalogTile.isStub()) {
2832
2759
  Log.warning("CHIP (instance) is just a stub!", oCatalogTile.toString(true), sCOMPONENT);
2833
- oDeferred.resolve(this._createErrorTile(sTitle, "CHIP was just a stub!"));
2834
- return oDeferred.promise();
2760
+ return this._createErrorTile(sTitle, "CHIP was just a stub!");
2835
2761
  }
2836
2762
 
2837
2763
  if (bPreview) {
@@ -2839,19 +2765,16 @@ sap.ui.define([
2839
2765
  if (oPreviewContract) {
2840
2766
  oPreviewContract.setEnabled(true);
2841
2767
  } else {
2842
- oDeferred.resolve(this._createPreviewTile(sTitle));
2843
- return oDeferred.promise();
2768
+ return this._createPreviewTile(sTitle);
2844
2769
  }
2845
2770
  }
2846
2771
 
2847
- oCatalogTile.getImplementationAsSapui5Async()
2848
- .catch((oError) => {
2849
- Log.error(`Cannot get catalog tile view as SAPUI5: ${oError.message || oError}`, oError.stack, sCOMPONENT);
2850
- return this._createErrorTile(sTitle, (oError.message || oError));
2851
- })
2852
- .then(oDeferred.resolve);
2853
-
2854
- return oDeferred.promise();
2772
+ try {
2773
+ return await oCatalogTile.getImplementationAsSapui5Async();
2774
+ } catch (oError) {
2775
+ Log.error(`Cannot get catalog tile view as SAPUI5: ${oError.message || oError}`, oError.stack, sCOMPONENT);
2776
+ return this._createErrorTile(sTitle, (oError.message || oError));
2777
+ }
2855
2778
  };
2856
2779
 
2857
2780
  /**
@@ -3053,7 +2976,7 @@ sap.ui.define([
3053
2976
  * Unsupported parameters will be ignored.
3054
2977
  * @param {string} oParameters.title The title of the bookmark.
3055
2978
  * @param {string} oParameters.url The URL of the bookmark. If the target application shall run in
3056
- * the Shell the URL has to be in the format <code>"#SO-Action~Context?P1=a&P2=x&/route?RPV=1"</code>
2979
+ * the Shell the URL has to be in the format <code>"#SO-Action?P1=a&P2=x&/route?RPV=1"</code>
3057
2980
  * @param {string} [oParameters.icon] The icon URL of the bookmark (e.g. <code>"sap-icon://home"</code>).
3058
2981
  * @param {string} [oParameters.info] The information text of the bookmark.
3059
2982
  * @param {string} [oParameters.subtitle] The subtitle of the bookmark.
@@ -3063,12 +2986,12 @@ sap.ui.define([
3063
2986
  * @param {string} [oParameters.numberUnit] The unit for the number retrieved from <code>serviceUrl</code>.
3064
2987
  * @param {object} [oGroup=DefaultGroup] Group to which the bookmark will be added to.
3065
2988
  * If not given the default group {@link #getDefaultGroup} is used.
3066
- * @returns {jQuery.Promise} Resolves once the bookmark was added.
2989
+ * @returns {Promise} Resolves once the bookmark was added.
3067
2990
  * @see sap.ushell.services.URLParsing#getShellHash
3068
2991
  * @since 1.11.0
3069
2992
  * @deprecated since 1.120
3070
2993
  */
3071
- this.addBookmark = function (oParameters, oGroup) {
2994
+ this.addBookmark = async function (oParameters, oGroup) {
3072
2995
  let sChipId = sSTATIC_BASE_CHIP_ID;
3073
2996
  let oConfiguration = {
3074
2997
  display_icon_url: oParameters.icon || "",
@@ -3076,7 +2999,6 @@ sap.ui.define([
3076
2999
  display_subtitle_text: oParameters.subtitle || "",
3077
3000
  display_title_text: oParameters.title
3078
3001
  };
3079
- const oDeferred = new jQuery.Deferred();
3080
3002
 
3081
3003
  const oBags = {
3082
3004
  tileProperties: {
@@ -3107,22 +3029,14 @@ sap.ui.define([
3107
3029
  if (oGroup && !(oGroup instanceof Page)) {
3108
3030
  // same behavior like addCatalogTileToGroup of the Bookmark service:
3109
3031
  // if the group is unknown don't use the default group but reject.
3110
- oDeferred.reject(new Error("The given object is not a group"));
3111
- return oDeferred.promise();
3032
+ throw new Error("The given object is not a group");
3112
3033
  }
3113
3034
 
3114
3035
  oConfiguration = {
3115
3036
  tileConfiguration: JSON.stringify(oConfiguration)
3116
3037
  };
3117
3038
 
3118
- this._createBookmarkTile(sChipId, oParameters.url, oConfiguration, oBags, oParameters.title, oGroup)
3119
- .then(() => {
3120
- oDeferred.resolve();
3121
- })
3122
- .catch((oError) => {
3123
- oDeferred.reject(oError);
3124
- });
3125
- return oDeferred.promise();
3039
+ await this._createBookmarkTile(sChipId, oParameters.url, oConfiguration, oBags, oParameters.title, oGroup);
3126
3040
  };
3127
3041
 
3128
3042
  /**
@@ -3156,31 +3070,22 @@ sap.ui.define([
3156
3070
  * </pre>
3157
3071
  * @param {object} oGroup The group where the bookmark should be added
3158
3072
  *
3159
- * @returns {jQuery.Promise} Resolves with the resulting tile or rejects in case of an error
3073
+ * @returns {Promise} Resolves with the resulting tile or rejects in case of an error
3160
3074
  *
3161
3075
  * @private
3162
3076
  * @since 1.83.0
3163
3077
  * @deprecated since 1.120
3164
3078
  */
3165
- this.addCustomBookmark = function (oBookmarkConfig, oGroup) {
3079
+ this.addCustomBookmark = async function (oBookmarkConfig, oGroup) {
3166
3080
  const oChipConfig = oBookmarkConfig.vizConfig["sap.flp"].chipConfig;
3167
- const oDeferred = new jQuery.Deferred();
3168
3081
 
3169
3082
  if (oGroup && !(oGroup instanceof Page)) {
3170
3083
  // same behavior like addCatalogTileToGroup of the Bookmark service:
3171
3084
  // if the group is unknown don't use the default group but reject.
3172
- oDeferred.reject(new Error("The given object is not a group"));
3173
- return oDeferred.promise();
3085
+ throw new Error("The given object is not a group");
3174
3086
  }
3175
3087
 
3176
- this._createBookmarkTile(oChipConfig.chipId, oBookmarkConfig.url, oChipConfig.configuration, oChipConfig.bags, oBookmarkConfig.title, oGroup)
3177
- .then(() => {
3178
- oDeferred.resolve();
3179
- })
3180
- .catch((oError) => {
3181
- oDeferred.reject(oError);
3182
- });
3183
- return oDeferred.promise();
3088
+ await this._createBookmarkTile(oChipConfig.chipId, oBookmarkConfig.url, oChipConfig.configuration, oChipConfig.bags, oBookmarkConfig.title, oGroup);
3184
3089
  };
3185
3090
 
3186
3091
  /**
@@ -3431,47 +3336,32 @@ sap.ui.define([
3431
3336
  *
3432
3337
  * @param {string} sUrl The URL of the bookmarks to be visited, exactly as specified to {@link #addBookmark}.
3433
3338
  * @param {function(sap.ushell_abap.pbServices.ui2.ChipInstance)} [fnVisitor] The asynchronous visitor function returning a
3434
- * <code>jQuery.Deferred</code> object's promise.
3339
+ * Promise.
3435
3340
  * In case of success, no details are expected. In case of failure, an error message is passed.
3436
- * @returns {jQuery.Promise} Resolves the count of visited bookmarks is provided (which might be zero).
3341
+ * @returns {Promise} Resolves the count of visited bookmarks is provided (which might be zero).
3437
3342
  * In case of failure, an error message is passed.
3438
3343
  * @see #addBookmark
3439
3344
  * @since 1.17.1
3440
3345
  * @deprecated since 1.120
3441
3346
  */
3442
- LaunchPageAdapter.prototype._visitBookmarks = function (sUrl, fnVisitor) {
3443
- const aDeferreds = [];
3444
- const oDeferred = new jQuery.Deferred();
3445
-
3446
- that.getGroupsAndWaitForAllChips()
3447
- .then((aGroups) => {
3448
- let iCount = 0;
3449
- aGroups.forEach((oGroup) => {
3450
- oGroup.getChipInstances().forEach((oChipInstance) => {
3451
- if (that._isBookmarkFor(oChipInstance, sUrl)) {
3452
- iCount += 1;
3453
- if (fnVisitor) {
3454
- aDeferreds.push(fnVisitor(oChipInstance));
3455
- }
3456
- }
3457
- });
3458
- });
3459
- if (aDeferreds.length === 0) {
3460
- oDeferred.resolve(iCount);
3461
- } else {
3462
- jQuery.when.apply(jQuery, aDeferreds)
3463
- .fail((oError) => {
3464
- oDeferred.reject(oError);
3465
- })
3466
- .done(() => {
3467
- oDeferred.resolve(iCount);
3468
- });
3347
+ LaunchPageAdapter.prototype._visitBookmarks = async function (sUrl, fnVisitor) {
3348
+ const aGroups = await that.getGroupsAndWaitForAllChips();
3349
+ const aPromises = [];
3350
+ let iCount = 0;
3351
+
3352
+ aGroups.forEach((oGroup) => {
3353
+ oGroup.getChipInstances().forEach((oChipInstance) => {
3354
+ if (that._isBookmarkFor(oChipInstance, sUrl)) {
3355
+ iCount += 1;
3356
+ if (fnVisitor) {
3357
+ aPromises.push(fnVisitor(oChipInstance));
3358
+ }
3469
3359
  }
3470
- })
3471
- .catch((oError) => {
3472
- oDeferred.reject(oError);
3473
3360
  });
3474
- return oDeferred.promise();
3361
+ });
3362
+
3363
+ await Promise.all(aPromises);
3364
+ return iCount;
3475
3365
  };
3476
3366
 
3477
3367
  /**
@@ -3497,30 +3387,23 @@ sap.ui.define([
3497
3387
  if (!oIdentifier.chipId) {
3498
3388
  throw new Error("_visitCustomBookmarks: Required parameter is missing: oIdentifier.chipId");
3499
3389
  }
3500
- return new Promise((resolve, reject) => {
3501
- this.getGroups()
3502
- .fail(reject)
3503
- .done((aGroups) => {
3504
- const aPromises = [];
3505
- let iCount = 0;
3506
-
3507
- aGroups.forEach((oGroup) => {
3508
- oGroup.getChipInstances().forEach((oChipInstance) => {
3509
- if (LaunchPageAdapter.prototype._isBookmarkFor(oChipInstance, oIdentifier)) {
3510
- iCount += 1;
3511
- if (fnVisitor) {
3512
- aPromises.push(fnVisitor(oChipInstance));
3513
- }
3390
+ return this.getGroups()
3391
+ .then((aGroups) => {
3392
+ const aPromises = [];
3393
+ let iCount = 0;
3394
+
3395
+ aGroups.forEach((oGroup) => {
3396
+ oGroup.getChipInstances().forEach((oChipInstance) => {
3397
+ if (LaunchPageAdapter.prototype._isBookmarkFor(oChipInstance, oIdentifier)) {
3398
+ iCount += 1;
3399
+ if (fnVisitor) {
3400
+ aPromises.push(fnVisitor(oChipInstance));
3514
3401
  }
3515
- });
3402
+ }
3516
3403
  });
3517
- Promise.all(aPromises)
3518
- .then(() => {
3519
- resolve(iCount);
3520
- })
3521
- .catch(reject);
3522
3404
  });
3523
- });
3405
+ return Promise.all(aPromises).then(() => iCount);
3406
+ });
3524
3407
  };
3525
3408
 
3526
3409
  /**
@@ -3530,7 +3413,7 @@ sap.ui.define([
3530
3413
  * This is a potentially asynchronous operation in case the user's pages have not yet been loaded completely!
3531
3414
  *
3532
3415
  * @param {string} sUrl The URL of the bookmarks to be counted, exactly as specified to {@link #addBookmark}.
3533
- * @returns {jQuery.Promise} Resolves the count of existing bookmarks is provided (which might be zero).
3416
+ * @returns {Promise} Resolves the count of existing bookmarks is provided (which might be zero).
3534
3417
  * In case of failure, an error message is passed.
3535
3418
  * @see #addBookmark
3536
3419
  * @since 1.17.1
@@ -3567,7 +3450,7 @@ sap.ui.define([
3567
3450
  * Deletes <b>all</b> bookmarks pointing to the given URL from all of the user's pages.
3568
3451
  *
3569
3452
  * @param {string} sUrl The URL of the bookmarks to be deleted, exactly as specified to {@link #addBookmark}.
3570
- * @returns {jQuery.Promise} Resolves the number of deleted bookmarks is provided (which might be zero).
3453
+ * @returns {Promise} Resolves the number of deleted bookmarks is provided (which might be zero).
3571
3454
  * In case of failure, an error message is passed.
3572
3455
  * @see #addBookmark
3573
3456
  * @see #countBookmarks
@@ -3576,12 +3459,11 @@ sap.ui.define([
3576
3459
  */
3577
3460
  this.deleteBookmarks = function (sUrl) {
3578
3461
  return LaunchPageAdapter.prototype._visitBookmarks(sUrl, (oChipInstance) => {
3579
- const oDeferred = new jQuery.Deferred();
3580
- oChipInstance.remove(oDeferred.resolve.bind(oDeferred),
3581
- (sErrorMessage) => {
3582
- oDeferred.reject(new Error(sErrorMessage));
3462
+ return new Promise((resolve, reject) => {
3463
+ oChipInstance.remove(resolve, (sErrorMessage) => {
3464
+ reject(new Error(sErrorMessage));
3583
3465
  });
3584
- return oDeferred.promise();
3466
+ });
3585
3467
  });
3586
3468
  };
3587
3469
 
@@ -3622,7 +3504,7 @@ sap.ui.define([
3622
3504
  * @param {string} sUrl The URL of the bookmarks to be updated, exactly as specified to {@link #addBookmark}.
3623
3505
  * In case you need to update the URL itself, pass the old one here and the new one as <code>oParameters.url</code>!
3624
3506
  * @param {object} oParameters The bookmark parameters as documented in {@link #addBookmark}.
3625
- * @returns {jQuery.Promise} Resolves the number of updated bookmarks is provided (which might be zero).
3507
+ * @returns {Promise} Resolves the number of updated bookmarks is provided (which might be zero).
3626
3508
  * In case of failure, an error message is passed.
3627
3509
  * @see #addBookmark
3628
3510
  * @see #countBookmarks
@@ -3633,7 +3515,6 @@ sap.ui.define([
3633
3515
  this.updateBookmarks = function (sUrl, oParameters) {
3634
3516
  return LaunchPageAdapter.prototype._visitBookmarks(sUrl, (oChipInstance) => {
3635
3517
  const oTileConfiguration = getAppLauncherTileConfiguration(oChipInstance);
3636
- const oDeferred = new jQuery.Deferred();
3637
3518
 
3638
3519
  // do only the update for properties which changed
3639
3520
  const oBags = {
@@ -3666,7 +3547,7 @@ sap.ui.define([
3666
3547
 
3667
3548
  const oConfiguration = {};
3668
3549
 
3669
- this._getTileTargetConfiguration(oParameters.url || oTileConfiguration.navigation_target_url)
3550
+ return this._getTileTargetConfiguration(oParameters.url || oTileConfiguration.navigation_target_url)
3670
3551
  .then((oNavigationConfiguration) => {
3671
3552
  // merge navigation properties on top of the provided configuration
3672
3553
  oNewTileConfiguration = deepExtend({}, oNewTileConfiguration, oNavigationConfiguration);
@@ -3687,13 +3568,7 @@ sap.ui.define([
3687
3568
  if (aUpdatedBags.length) {
3688
3569
  oChipInstance.getContract("bag").fireBagsUpdated(aUpdatedBags);
3689
3570
  }
3690
- oDeferred.resolve();
3691
- })
3692
- .catch((oError) => {
3693
- oDeferred.reject(oError);
3694
3571
  });
3695
-
3696
- return oDeferred.promise();
3697
3572
  });
3698
3573
  };
3699
3574