@sapui5/sap.ushell_abap 1.146.0 → 1.147.1

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 (61) hide show
  1. package/package.json +4 -4
  2. package/src/main/js/sap/ushell_abap/.library +1 -1
  3. package/src/main/js/sap/ushell_abap/adapters/abap/AdapterContainer.js +4 -5
  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 +10 -8
  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 +7 -4
  8. package/src/main/js/sap/ushell_abap/adapters/abap/ContainerAdapter.js +8 -10
  9. package/src/main/js/sap/ushell_abap/adapters/abap/FlpLaunchPageAdapter.js +148 -109
  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/hana/ContainerAdapter.js +1 -1
  21. package/src/main/js/sap/ushell_abap/bootstrap/BootTask/PrepareDirectAppStart.js +20 -0
  22. package/src/main/js/sap/ushell_abap/bootstrap/BootTask/RequestGroups.js +51 -0
  23. package/src/main/js/sap/ushell_abap/bootstrap/BootTask/RequestTargetMappings.js +29 -0
  24. package/src/main/js/sap/ushell_abap/bootstrap/BootTask.js +47 -0
  25. package/src/main/js/sap/ushell_abap/bootstrap/ConfigurationProvider.js +87 -0
  26. package/src/main/js/sap/ushell_abap/bootstrap/DirectAppStart.js +231 -0
  27. package/src/main/js/sap/ushell_abap/bootstrap/LoadLaunchpad/CreateRenderer.js +43 -0
  28. package/src/main/js/sap/ushell_abap/bootstrap/LoadLaunchpad/InitXhrLogon.js +148 -0
  29. package/src/main/js/sap/ushell_abap/bootstrap/LoadLaunchpad/RequestPages.js +86 -0
  30. package/src/main/js/sap/ushell_abap/bootstrap/LoadLaunchpad.js +63 -0
  31. package/src/main/js/sap/ushell_abap/bootstrap/LoadLaunchpadModule.js +11 -0
  32. package/src/main/js/sap/ushell_abap/bootstrap/PageSetsRequestHandler.js +247 -0
  33. package/src/main/js/sap/ushell_abap/bootstrap/PlatformConfig.js +385 -0
  34. package/src/main/js/sap/ushell_abap/bootstrap/{evo/SAPCompanionConditionSetter.js → SAPCompanionConditionSetter.js} +6 -4
  35. package/src/main/js/sap/ushell_abap/bootstrap/StartupRequestHandler.js +145 -0
  36. package/src/main/js/sap/ushell_abap/bootstrap/ThemeHandler.js +276 -0
  37. package/src/main/js/sap/ushell_abap/bootstrap/XhrFactory.js +69 -0
  38. package/src/main/js/sap/ushell_abap/bootstrap/{evo/XhrLogonEventHandler.js → XhrLogonEventHandler.js} +13 -7
  39. package/src/main/js/sap/ushell_abap/bootstrap/XhrLogonLibLoader.js +51 -0
  40. package/src/main/js/sap/ushell_abap/bootstrap/abap-def-dev.js +20 -0
  41. package/src/main/js/sap/ushell_abap/bootstrap/{evo/abap-def-loader.js → abap-def-loader.js} +2 -2
  42. package/src/main/js/sap/ushell_abap/bootstrap/abap-def.js +22 -0
  43. package/src/main/js/sap/ushell_abap/bootstrap/evo/abap.js +1 -1
  44. package/src/main/js/sap/ushell_abap/components/TCodeNavigation.js +3 -3
  45. package/src/main/js/sap/ushell_abap/library.js +1 -1
  46. package/src/main/js/sap/ushell_abap/pbServices/ui2/Contracts.js +33 -0
  47. package/ui5.yaml +7 -6
  48. package/src/main/js/sap/ushell_abap/bootstrap/evo/abap-def-dev.js +0 -42
  49. package/src/main/js/sap/ushell_abap/bootstrap/evo/abap-def.js +0 -45
  50. package/src/main/js/sap/ushell_abap/bootstrap/evo/abap.bootstrap.utils.js +0 -172
  51. package/src/main/js/sap/ushell_abap/bootstrap/evo/abap.configure.theme.js +0 -28
  52. package/src/main/js/sap/ushell_abap/bootstrap/evo/abap.configure.ushell.js +0 -181
  53. package/src/main/js/sap/ushell_abap/bootstrap/evo/abap.load.launchpad.js +0 -72
  54. package/src/main/js/sap/ushell_abap/bootstrap/evo/abap.request.pageset.js +0 -219
  55. package/src/main/js/sap/ushell_abap/bootstrap/evo/abap.request.startup.js +0 -154
  56. package/src/main/js/sap/ushell_abap/bootstrap/evo/abap.theme.handler.js +0 -79
  57. package/src/main/js/sap/ushell_abap/bootstrap/evo/abap.xhrlogon.LibLoader.js +0 -21
  58. package/src/main/js/sap/ushell_abap/bootstrap/evo/abap.xhrlogon.configure.js +0 -62
  59. package/src/main/js/sap/ushell_abap/bootstrap/evo/abap.xhrlogon.handler.js +0 -82
  60. package/src/main/js/sap/ushell_abap/bootstrap/evo/boottask.js +0 -944
  61. /package/src/main/js/sap/ushell_abap/bootstrap/{evo/abap.constants.js → abapConstants.js} +0 -0
@@ -0,0 +1,385 @@
1
+ // Copyright (c) 2009-2026 SAP SE, All Rights Reserved
2
+
3
+ sap.ui.define([
4
+ "sap/base/Log",
5
+ "sap/ushell_abap/bootstrap/BootTask",
6
+ "sap/ushell_abap/bootstrap/ThemeHandler",
7
+ "sap/ushell/base/requireAsync",
8
+ "sap/ushell/bootstrap/Config",
9
+ "sap/base/util/ObjectPath"
10
+ ], (
11
+ Log,
12
+ BootTask,
13
+ ThemeHandler,
14
+ requireAsync,
15
+ BootstrapConfig,
16
+ ObjectPath
17
+ ) => {
18
+ "use strict";
19
+
20
+ /**
21
+ * @alias sap.ushell_abap.bootstrap.PlatformConfig
22
+ * @namespace
23
+ * @description ABAP platform configuration. Responsible for applying ABAP-specific settings to the ushell configuration,
24
+ * determining the active theme and theme roots, and providing the merged UI5 configuration for the ABAP platform.
25
+ *
26
+ * @since 1.147.0
27
+ * @private
28
+ */
29
+ class PlatformConfig {
30
+ /**
31
+ * Reads the messages array from the ushell config and logs error/warning
32
+ * messages from the ABAP server to the browser console.
33
+ *
34
+ * @since 1.147.0
35
+ * @private
36
+ */
37
+ #logServerSideMessages () {
38
+ const oUshellConfig = BootstrapConfig.get();
39
+ const sComponent = "ABAP Server Error Messages";
40
+ const aMessages = oUshellConfig.messages;
41
+ if (aMessages && aMessages.length > 0) {
42
+ for (let i = 0; i < aMessages.length; i += 1) {
43
+ if (aMessages[i].severity === "error") {
44
+ Log.error(aMessages[i].text, null, sComponent);
45
+ } else if (aMessages[i].severity === "warning") {
46
+ Log.warning(aMessages[i].text, null, sComponent);
47
+ }
48
+ }
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Sets the isLanguagePersonalized property based on the PREFERRED_LOGON_LANGUAGE
54
+ * value in the user profile.
55
+ *
56
+ * @since 1.147.0
57
+ * @private
58
+ */
59
+ #adaptLanguageConfig () {
60
+ const oUshellConfig = BootstrapConfig.get();
61
+ const aUserProfile = ObjectPath.get("startupConfig.userProfile", oUshellConfig) || [];
62
+ const oPreferredLanguage = aUserProfile.filter((oProfile) => {
63
+ return oProfile.id === "PREFERRED_LOGON_LANGUAGE";
64
+ })[0];
65
+ if (oPreferredLanguage && oPreferredLanguage.value !== undefined) {
66
+ const bIsLanguagePersonalized = oPreferredLanguage.value !== "";
67
+ ObjectPath.set("startupConfig.isLanguagePersonalized", bIsLanguagePersonalized, oUshellConfig);
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Configures IANA timezone settings based on server configuration.
73
+ * Sets defaults for timeZone and timeZoneFromServerInUI5 if not already defined.
74
+ *
75
+ * @since 1.147.0
76
+ * @private
77
+ */
78
+ #setIanaSettings () {
79
+ const oUshellConfig = BootstrapConfig.get();
80
+
81
+ // IANA Timezone support based on server config
82
+ let bTimeZoneIana = ObjectPath.get("ui5.timeZoneFromServerInUI5", oUshellConfig);
83
+ if (bTimeZoneIana === undefined) {
84
+ bTimeZoneIana = false;
85
+ ObjectPath.set("startupConfig.timeZoneFromServerInUI5", bTimeZoneIana, oUshellConfig);
86
+ ObjectPath.set("ushell.ui5.timeZoneFromServerInUI5", bTimeZoneIana);
87
+ }
88
+ let sTimeZoneIana = ObjectPath.get("startupConfig.timeZone", oUshellConfig);
89
+ if (sTimeZoneIana === undefined) {
90
+ sTimeZoneIana = "";
91
+ ObjectPath.set("startupConfig.timeZone", sTimeZoneIana, oUshellConfig);
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Copies the startupConfig to the Container adapter config path.
97
+ * Preserves any pre-existing systemProperties so they are not overwritten.
98
+ *
99
+ * @since 1.147.0
100
+ * @private
101
+ */
102
+ #setStartupConfigAsContainerAdapterConfig () {
103
+ const oUshellConfig = BootstrapConfig.get();
104
+ const oStartUpConfig = ObjectPath.get("startupConfig", oUshellConfig);
105
+ if (!oStartUpConfig) {
106
+ return;
107
+ }
108
+
109
+ // first store systemProperties if they exist, as they should not be overridden by startupConfig
110
+ const oSystemProperties = ObjectPath.get("services.Container.adapter.config.systemProperties", oUshellConfig);
111
+
112
+ ObjectPath.set("services.Container.adapter.config", oStartUpConfig, oUshellConfig);
113
+
114
+ if (oSystemProperties) {
115
+ ObjectPath.set("services.Container.adapter.config.systemProperties", oSystemProperties, oUshellConfig);
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Activates FLP spaces (based on pages and sections therein)
121
+ * or the classic homepage mode (based on app groups)
122
+ * by setting the configuration switch <code>config.ushell.spaces.enabled</code> .
123
+ *
124
+ * @since 1.147.0
125
+ * @private
126
+ */
127
+ #setSpacesOrHomepageMode () {
128
+ const oUshellConfig = BootstrapConfig.get();
129
+ // Check if user is allowed to configure FLP spaces or homepage mode, and if so consider it
130
+ const bSpacesConfigurableByUser = ObjectPath.get("ushell.spaces.configurable", oUshellConfig);
131
+ if (bSpacesConfigurableByUser) {
132
+ // Check if spaces have been activated by the user
133
+ const oContainerAdapterConfig = ObjectPath.get("services.Container.adapter.config", oUshellConfig);
134
+ const aUserProfileItems = ObjectPath.get("userProfile", oContainerAdapterConfig) || [];
135
+ const oSpacesProfile = aUserProfileItems.filter((property) => {
136
+ return property.id === "SPACES_ENABLEMENT";
137
+ })[0];
138
+ const sSpacesEnabledByUser = oSpacesProfile && oSpacesProfile.value;
139
+
140
+ // If the user hasn't chosen any setting yet the personalization is undefined
141
+ // and the admin setting isn't overwritten
142
+ if (sSpacesEnabledByUser === "true") {
143
+ ObjectPath.set("ushell.spaces.enabled", true, oUshellConfig);
144
+ } else if (sSpacesEnabledByUser === "false") {
145
+ ObjectPath.set("ushell.spaces.enabled", false, oUshellConfig);
146
+ }
147
+ }
148
+
149
+ if (ObjectPath.get("ushell.spaces.enabled", oUshellConfig)) {
150
+ // Use CDM adapters in case the user views a sap ushell page
151
+ ObjectPath.set("services.CommonDataModel.adapter.module", "sap.ushell.adapters.cdm.PagesCommonDataModelAdapter", oUshellConfig);
152
+ // VisualizationDataProvider and LaunchPageAdapter should have the same configuration
153
+ const oLaunchPageAdapterConfig = ObjectPath.get("services.LaunchPage.adapter.config", oUshellConfig) || {};
154
+ ObjectPath.set("services.VisualizationDataProvider.adapter.config", oLaunchPageAdapterConfig, oUshellConfig);
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Enables or disables the SupportTicket service based on the service config.
160
+ * Does not enable the service if it is already explicitly disabled.
161
+ *
162
+ * @since 1.147.0
163
+ * @private
164
+ */
165
+ #enableSupportTicket () {
166
+ const oUshellConfig = BootstrapConfig.get();
167
+
168
+ // write the support ticket service enablement to the bootstrap config;
169
+ // do not enable if already disabled, but disable if not available in backend
170
+ const vSupportTicketEnabled = ObjectPath.get("services.SupportTicket.config.enabled", oUshellConfig);
171
+ if (vSupportTicketEnabled !== false) { // default true
172
+ const oContainerAdapterConfig = ObjectPath.get("services.Container.adapter.config", oUshellConfig);
173
+ ObjectPath.set("services.SupportTicket.config.enabled", oContainerAdapterConfig.isEmbReportingActive === true, oUshellConfig);
174
+ }
175
+ }
176
+
177
+ /**
178
+ * Writes service endpoint URLs (targetMappings, pageBuilding, personalization)
179
+ * from the Container adapter config into the respective service adapter configurations.
180
+ *
181
+ * @since 1.147.0
182
+ * @private
183
+ */
184
+ #setServiceEndpoints () {
185
+ const oUshellConfig = BootstrapConfig.get();
186
+ const oContainerAdapterConfig = ObjectPath.get("services.Container.adapter.config", oUshellConfig);
187
+ const oTargetMappingEndpoint = ObjectPath.get("services.targetMappings", oContainerAdapterConfig);
188
+ const oPageBuildingEndpoint = ObjectPath.get("services.pbFioriHome", oContainerAdapterConfig);
189
+ const oPersonalizationEndpoint = ObjectPath.get("services.personalization", oContainerAdapterConfig);
190
+
191
+ const oTmpConfig = {};
192
+
193
+ ObjectPath.set("services.ClientSideTargetResolution.adapter.config.services.targetMappings", oTargetMappingEndpoint, oTmpConfig);
194
+
195
+ ObjectPath.set("services.LaunchPage.adapter.config.services.targetMappings", oTargetMappingEndpoint, oTmpConfig);
196
+ ObjectPath.set("services.LaunchPage.adapter.config.services.launchPage", oPageBuildingEndpoint, oTmpConfig);
197
+
198
+ // this service reuses the LaunchPageAdapter internally
199
+ ObjectPath.set("services.VisualizationDataProvider.adapter.module", "sap.ushell_abap.adapters.abap.FlpLaunchPageAdapter", oTmpConfig);
200
+ ObjectPath.set("services.VisualizationDataProvider.adapter.config.services.targetMappings", oTargetMappingEndpoint, oTmpConfig);
201
+ ObjectPath.set("services.VisualizationDataProvider.adapter.config.services.launchPage", oPageBuildingEndpoint, oTmpConfig);
202
+
203
+ ObjectPath.set("services.PageBuilding.adapter.config.services.pageBuilding", oPageBuildingEndpoint, oTmpConfig);
204
+
205
+ ObjectPath.set("services.Personalization.adapter.config.services.personalization", oPersonalizationEndpoint, oTmpConfig);
206
+
207
+ const oMigrationConfig = BootstrapConfig.getV2MigrationConfig(oTmpConfig);
208
+ BootstrapConfig.extendConfig(oUshellConfig, oMigrationConfig, true);
209
+ BootstrapConfig.extendConfig(oUshellConfig, oTmpConfig, true);
210
+ }
211
+
212
+ /**
213
+ * NavigationDataProvider and ClientSideTargetResolution both create a ClientSideTargetResolutionAdapter instance.
214
+ * These should use the same config object (not copies) as the request promises are stored
215
+ * in the config and need to be accessible for all instances.
216
+ *
217
+ * @since 1.147.0
218
+ * @private
219
+ */
220
+ #shareClientSideTargetResolutionAdapterConfig () {
221
+ const oUshellConfig = BootstrapConfig.get();
222
+
223
+ const oClientSideTargetResolutionAdapterConfig = ObjectPath.get("services.ClientSideTargetResolution.adapter.config", oUshellConfig) || {};
224
+ ObjectPath.set("services.ClientSideTargetResolution.adapter.config", oClientSideTargetResolutionAdapterConfig, oUshellConfig);
225
+ ObjectPath.set("services.NavigationDataProvider.adapter.config", oClientSideTargetResolutionAdapterConfig, oUshellConfig);
226
+ }
227
+
228
+ /**
229
+ * Sanitizes the plugins configuration by ensuring that formFactors are set consistently.
230
+ *
231
+ * @since 1.147.0
232
+ * @private
233
+ */
234
+ #sanitizePluginsConfiguration () {
235
+ const oUshellConfig = BootstrapConfig.get();
236
+ const oPlugins = ObjectPath.get("bootstrapPlugins", oUshellConfig) || {};
237
+
238
+ Object.keys(oPlugins).forEach((sPluginId) => {
239
+ const oPluginConfig = oPlugins[sPluginId];
240
+ // some plugins don't have formFactors configuration and should be loaded for any device type
241
+ if (oPluginConfig.hasOwnProperty("formFactors")) {
242
+ const oFormFactors = oPluginConfig.formFactors;
243
+ const oDeviceTypes = {};
244
+ oDeviceTypes.desktop = oFormFactors.desktop || false;
245
+ oDeviceTypes.tablet = oFormFactors.tablet || false;
246
+ oDeviceTypes.phone = oFormFactors.phone || false;
247
+ oPluginConfig.deviceTypes = oDeviceTypes;
248
+ delete oPluginConfig.formFactors;
249
+ }
250
+ });
251
+ }
252
+
253
+ /**
254
+ * Applies ABAP specific configuration to the ushell config
255
+ *
256
+ * @since 1.147.0
257
+ * @private
258
+ */
259
+ configureUshell () {
260
+ // Write any warnings and errors related to server-side config to console.
261
+ this.#logServerSideMessages();
262
+
263
+ this.#adaptLanguageConfig();
264
+ this.#setIanaSettings();
265
+ this.#setStartupConfigAsContainerAdapterConfig();
266
+
267
+ // now only access to the startupConfig should happen via the Container adapter config
268
+
269
+ ThemeHandler.setBootThemeInUserConfig();
270
+ this.#setSpacesOrHomepageMode();
271
+ this.#setServiceEndpoints();
272
+ this.#shareClientSideTargetResolutionAdapterConfig();
273
+ this.#enableSupportTicket();
274
+ this.#sanitizePluginsConfiguration();
275
+ }
276
+
277
+ /**
278
+ * Returns the ABAP platform-specific UI5 configuration.
279
+ * Respects the sap-locale URL parameter to skip local settings.
280
+ *
281
+ * @returns {object} UI5 configuration with camelCase keys (sapUiLanguage, sapUiABAPDateFormat, sapUiTheme, etc.)
282
+ *
283
+ * @since 1.147.0
284
+ * @private
285
+ */
286
+ getUI5Config () {
287
+ const oUshellConfig = BootstrapConfig.get();
288
+ const { theme, themeRoots } = ThemeHandler.getUI5ConfigTheme();
289
+
290
+ const oContainerAdapterConfig = ObjectPath.get("services.Container.adapter.config", oUshellConfig) || {};
291
+ const sCalendarWeekNumbering = oContainerAdapterConfig.calendarWeekNumbering || "Default";
292
+ let sLanguage = oContainerAdapterConfig.languageBcp47 || oContainerAdapterConfig.language;
293
+ let sLegacyDateFormat = oContainerAdapterConfig.dateFormat;
294
+ let sLegacyNumberFormat = oContainerAdapterConfig.numberFormat === "" ? " " : oContainerAdapterConfig.numberFormat;
295
+ let sLegacyTimeFormat = oContainerAdapterConfig.timeFormat;
296
+
297
+ const oUrlParameters = new URLSearchParams(this.getWindowLocationSearch());
298
+ const bSkipLocalSettings = !!oUrlParameters.get("sap-locale");
299
+ if (bSkipLocalSettings) {
300
+ sLanguage = undefined;
301
+ sLegacyDateFormat = undefined;
302
+ sLegacyNumberFormat = undefined;
303
+ sLegacyTimeFormat = undefined;
304
+ }
305
+
306
+ const bUseTimeZoneIana = oContainerAdapterConfig.timeZoneFromServerInUI5;
307
+ let sTimeZoneIana = oContainerAdapterConfig.timeZone;
308
+ if (bUseTimeZoneIana && oContainerAdapterConfig.timeZone !== "") {
309
+ sTimeZoneIana = oContainerAdapterConfig.timeZone;
310
+ }
311
+
312
+ return {
313
+ sapUiLanguage: sLanguage,
314
+ sapUiABAPDateFormat: sLegacyDateFormat,
315
+ sapUiABAPNumberFormat: sLegacyNumberFormat,
316
+ sapUiABAPTimeFormat: sLegacyTimeFormat,
317
+ sapUiTimezone: sTimeZoneIana,
318
+ sapUiCalendarWeekNumbering: sCalendarWeekNumbering,
319
+ sapUiTheme: theme,
320
+ sapUiThemeRoots: themeRoots,
321
+ /**
322
+ * @deprecated since 1.120
323
+ */
324
+ sapUiXxBootTask: BootTask.run.bind(BootTask),
325
+ sapUiOnInit: "module:sap/ushell_abap/bootstrap/LoadLaunchpadModule"
326
+ };
327
+ }
328
+
329
+ /**
330
+ * Applies additional UI5 settings that require async API calls.
331
+ * Sets Islamic calendar customizing data, language with ABAP language code,
332
+ * and custom currencies.
333
+ *
334
+ * @returns {Promise} Resolves when all settings have been applied
335
+ *
336
+ * @since 1.147.0
337
+ * @private
338
+ */
339
+ async setUI5Settings () {
340
+ const oUshellConfig = BootstrapConfig.get();
341
+ const oContainerAdapterConfig = ObjectPath.get("services.Container.adapter.config", oUshellConfig) || {};
342
+
343
+ const [
344
+ Formatting,
345
+ Localization
346
+ ] = await requireAsync([
347
+ "sap/base/i18n/Formatting",
348
+ "sap/base/i18n/Localization"
349
+ ]);
350
+
351
+ const sLegacyDateCalendarCustomizing = oContainerAdapterConfig.tislcal;
352
+ const sLanguage = oContainerAdapterConfig.languageBcp47 || oContainerAdapterConfig.language;
353
+ const sABAPLanguage = oContainerAdapterConfig.language;
354
+ const oCurrencyFormats = oContainerAdapterConfig.currencyFormats;
355
+
356
+ if (sLegacyDateCalendarCustomizing) {
357
+ Formatting.setCustomIslamicCalendarData(sLegacyDateCalendarCustomizing);
358
+ }
359
+
360
+ if (sABAPLanguage) { // only set abap language if it is provided, the regular language was already configured
361
+ Localization.setLanguage(sLanguage, sABAPLanguage);
362
+ }
363
+
364
+ // Copy currency formats, if provided, to the UI5 custom currencies format settings
365
+ if (typeof oCurrencyFormats === "object") {
366
+ Formatting.addCustomCurrencies(oCurrencyFormats);
367
+ }
368
+ }
369
+
370
+ /**
371
+ * Returns the window.location.search string.
372
+ * Extracted as a method to allow stubbing in tests.
373
+ *
374
+ * @returns {string} The query string portion of the URL
375
+ *
376
+ * @since 1.147.0
377
+ * @private
378
+ */
379
+ getWindowLocationSearch () {
380
+ return window.location.search;
381
+ }
382
+ }
383
+
384
+ return new PlatformConfig();
385
+ });
@@ -7,10 +7,12 @@
7
7
  */
8
8
  sap.ui.define([
9
9
  "sap/base/Log",
10
- "sap/base/util/Deferred"
10
+ "sap/base/util/Deferred",
11
+ "sap/ushell/bootstrap/Config"
11
12
  ], (
12
13
  Log,
13
- Deferred
14
+ Deferred,
15
+ BootstrapConfig
14
16
  ) => {
15
17
  "use strict";
16
18
 
@@ -24,7 +26,7 @@ sap.ui.define([
24
26
 
25
27
  // The ushell config is not yet prepared when the module is loaded, therefore set only on "run", not earlier
26
28
  if (Setter._ushellConfig === undefined) {
27
- Setter._ushellConfig = window["sap-ushell-config"];
29
+ Setter._ushellConfig = BootstrapConfig.get();
28
30
  }
29
31
 
30
32
  function fnTryToSetConditions () {
@@ -40,7 +42,7 @@ sap.ui.define([
40
42
  oConditions.FLPClientRole = Setter._ushellConfig.startupConfig.clientRole;
41
43
 
42
44
  window.Help4.API.setConditions(oConditions);
43
- Log.info(`Conditions transferred to SAP Compagnion / SAP Help: ${JSON.stringify(oConditions)}`);
45
+ Log.info(`Conditions transferred to SAP Companion / SAP Help: ${JSON.stringify(oConditions)}`);
44
46
  return true;
45
47
  }
46
48
  return false;
@@ -0,0 +1,145 @@
1
+ // Copyright (c) 2009-2026 SAP SE, All Rights Reserved
2
+ sap.ui.define([
3
+ "sap/ushell_abap/bootstrap/XhrFactory",
4
+ "sap/ushell/bootstrap/Config",
5
+ "sap/base/util/ObjectPath",
6
+ "sap/ushell_abap/pbServices/ui2/Utils",
7
+ "sap/ushell/base/SAPBusinessClientEnablement"
8
+ ], (
9
+ XhrFactory,
10
+ BootstrapConfig,
11
+ ObjectPath,
12
+ ui2Utils,
13
+ SAPBusinessClientEnablement
14
+ ) => {
15
+ "use strict";
16
+
17
+ class StartupRequestHandler {
18
+ /**
19
+ * Performs the start-up request.
20
+ * @param {string} sQuery
21
+ * String which is added to the "/sap/bc/ui2/start_up?"
22
+ * @param {string[]} aParametersFromUrl
23
+ * The List of parameters which should be copied to the requested url
24
+ *
25
+ * @returns {Promise}
26
+ * Result of the GET request should be resolved
27
+ */
28
+ #requestStartup (sQuery, aParametersFromUrl) {
29
+ const oUshellConfig = BootstrapConfig.get();
30
+ const oContainerAdapterConfig = ObjectPath.get("services.Container.adapter.config", oUshellConfig);
31
+
32
+ let sRequestUrl = "/sap/bc/ui2/start_up?";
33
+ const mParameterMap = ui2Utils.getParameterMap();
34
+
35
+ if (sQuery) {
36
+ sRequestUrl += `${sQuery}&`;
37
+ }
38
+
39
+ /**
40
+ * Copies the URL parameter with the given name from <code>mParameterMap</code> to
41
+ * <code>sRequestUrl</code>.
42
+ *
43
+ * @param {string} sName
44
+ * URL parameter name
45
+ * @private
46
+ */
47
+ function copyParameter (sName) {
48
+ const sValue = mParameterMap[sName];
49
+ if (sValue) {
50
+ sRequestUrl += `${sName}=${encodeURIComponent(sValue[0])}&`;
51
+ }
52
+ }
53
+
54
+ aParametersFromUrl.forEach(copyParameter);
55
+ sRequestUrl += `shellType=${SAPBusinessClientEnablement.getShellType()}&depth=0`;
56
+ sRequestUrl += this.#getCacheIdAsQueryParameter(oContainerAdapterConfig);
57
+ const oXhr = XhrFactory.createAndOpen(sRequestUrl, oContainerAdapterConfig); // XMLHttpRequest + headers
58
+
59
+ return new Promise((resolve, reject) => {
60
+ ui2Utils.get(
61
+ sRequestUrl,
62
+ false, /* xml=*/
63
+ (sStartupCallResult) => {
64
+ try {
65
+ const oStartupResult = JSON.parse(sStartupCallResult);
66
+ resolve(oStartupResult);
67
+ } catch (oError) {
68
+ reject(oError);
69
+ }
70
+ },
71
+ (sErrorMessage) => {
72
+ reject(new Error(sErrorMessage));
73
+ },
74
+ oXhr
75
+ );
76
+ });
77
+ }
78
+
79
+ /**
80
+ * Performs the full start-up request (so=%2A&action=%2A).
81
+ *
82
+ * @param {boolean} bNoOData
83
+ * If Odata is not allowed. If true - return rejected promise.
84
+ *
85
+ * @returns {Promise}
86
+ * Result of the GET request should be resolved
87
+ */
88
+ async requestFullTM () {
89
+ const oResult = await this.#requestStartup("so=%2A&action=%2A&systemAliasesFormat=object", ["sap-language", "sap-client", "sap-ui2-cache-disable"]);
90
+
91
+ if (oResult) {
92
+ if (oResult.client) { // double check we get the correct response
93
+ // TODO: move this to integration test perhaps
94
+ throw new Error("A start up response was returned in a target mappings request.");
95
+ }
96
+ return oResult;
97
+ }
98
+
99
+ return {};
100
+ }
101
+
102
+ /**
103
+ * Performs an extra request to retrieve a direct Start Request.
104
+ *
105
+ * @param {sap.ushell.services.URLParsing.DecomposedHash} oParsedHash
106
+ * The parsed shell hash object. The object must contain semanticObject and action
107
+ * @param {object} oInitialKeys
108
+ * The parameters which should be copied to the requested url
109
+ *
110
+ * @returns {Promise}
111
+ * Result of the GET request should be resolved
112
+ */
113
+ async requestDirectStart (oParsedHash, oInitialKeys) {
114
+ const sFormFactor = ui2Utils.getFormFactor();
115
+ let sQueryPath = "";
116
+
117
+ sQueryPath = `so=${oParsedHash.semanticObject}&action=${oParsedHash.action}`;
118
+ sQueryPath += "&systemAliasesFormat=object";
119
+ Object.keys(oInitialKeys).forEach((sKey) => {
120
+ sQueryPath += `&${sKey}=${oInitialKeys[sKey]}`;
121
+ });
122
+ if (sFormFactor) {
123
+ sQueryPath += `&formFactor=${encodeURIComponent(sFormFactor)}`;
124
+ }
125
+
126
+ return this.#requestStartup(sQueryPath, ["sap-language", "sap-client"]);
127
+ }
128
+
129
+ /**
130
+ * Get cacheId from startup config and return it as query parameter like "&sap-cache-id=xxxx"
131
+ * If cacheId not found in config, return empty string
132
+ * @param {object} oContainerAdapterConfig startup config
133
+ * @returns {string} "&sap-cache-id=xxxx" if found, otherwise ""
134
+ */
135
+ #getCacheIdAsQueryParameter (oContainerAdapterConfig) {
136
+ const sCacheId = ObjectPath.get("services.targetMappings.cacheId", oContainerAdapterConfig);
137
+ if (typeof sCacheId === "string") {
138
+ return `&sap-cache-id=${sCacheId}`;
139
+ }
140
+ return "";
141
+ }
142
+ }
143
+
144
+ return new StartupRequestHandler();
145
+ });