@sap-ux/preview-middleware 1.1.3 → 1.2.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 (37) hide show
  1. package/README.md +31 -29
  2. package/dist/base/config.d.ts +55 -2
  3. package/dist/base/config.js +158 -26
  4. package/dist/base/flp.d.ts +24 -0
  5. package/dist/base/flp.js +116 -18
  6. package/dist/client/adp/api-handler.js +5 -1
  7. package/dist/client/adp/api-handler.ts +11 -4
  8. package/dist/client/adp/controllers/ControllerExtension.controller.js +95 -35
  9. package/dist/client/adp/controllers/ControllerExtension.controller.ts +121 -42
  10. package/dist/client/adp/extend-controller.ts +1 -0
  11. package/dist/client/adp/quick-actions/common/add-controller-to-page.js +2 -2
  12. package/dist/client/adp/quick-actions/common/add-controller-to-page.ts +2 -2
  13. package/dist/client/adp/quick-actions/fe-v4/create-page-action.js +3 -2
  14. package/dist/client/adp/quick-actions/fe-v4/create-page-action.ts +3 -2
  15. package/dist/client/adp/quick-actions/fe-v4/create-table-action-config-change.js +3 -2
  16. package/dist/client/adp/quick-actions/fe-v4/create-table-action-config-change.ts +3 -2
  17. package/dist/client/adp/ui/ControllerExtension.fragment.xml +33 -6
  18. package/dist/client/adp/utils.js +73 -5
  19. package/dist/client/adp/utils.ts +84 -5
  20. package/dist/client/flp/WorkspaceConnector.js +7 -5
  21. package/dist/client/flp/WorkspaceConnector.ts +7 -5
  22. package/dist/client/flp/common.js +293 -1
  23. package/dist/client/flp/common.ts +344 -1
  24. package/dist/client/flp/sandbox1Init.js +187 -0
  25. package/dist/client/flp/sandbox1Init.ts +174 -0
  26. package/dist/client/flp/sandbox2AfterInit.js +66 -0
  27. package/dist/client/flp/sandbox2AfterInit.ts +63 -0
  28. package/dist/client/flp/sandbox2BeforeInit.js +67 -0
  29. package/dist/client/flp/sandbox2BeforeInit.ts +60 -0
  30. package/dist/client/messagebundle.properties +3 -0
  31. package/dist/types/index.d.ts +21 -0
  32. package/package.json +3 -3
  33. package/templates/flp/cdm.ejs +1 -1
  34. package/templates/flp/sandbox.ejs +1 -1
  35. package/templates/flp/sandbox2.ejs +12 -44
  36. package/dist/client/flp/init.js +0 -465
  37. package/dist/client/flp/init.ts +0 -498
@@ -1,4 +1,65 @@
1
- import type { FlexSettings } from 'sap/ui/rta/RuntimeAuthoring';
1
+ import Log from 'sap/base/Log';
2
+ import type { InitRtaScript, RTAPlugin, StartAdaptation } from 'sap/ui/rta/api/startAdaptation';
3
+ import { MessageBarType } from '@sap-ux-private/control-property-editor-common';
4
+ import type { FlexSettings, RTAOptions } from 'sap/ui/rta/RuntimeAuthoring';
5
+ import type AppState from 'sap/ushell/services/AppState';
6
+ import type Component from 'sap/ui/core/Component';
7
+ import type Extension from 'sap/ushell/services/Extension';
8
+ import type { CardGeneratorType } from 'sap/cards/ap/generator';
9
+ import { getError } from '../utils/error.js';
10
+ import { isLowerThanMinimalUi5Version, type Ui5VersionInfo } from '../utils/version.js';
11
+ import { sendInfoCenterMessage } from '../utils/info-center-message.js';
12
+
13
+ type GlobalErrorEvent = ErrorEvent | PromiseRejectionEvent;
14
+
15
+ const CONTROLLER_EXTENSION_PATH_REGEX = /\/changes\/coding\/.+\.(js|ts)/;
16
+
17
+ /**
18
+ * Extracts an Error object from a global error event.
19
+ * Handles both synchronous errors (ErrorEvent) and unhandled promise rejections (PromiseRejectionEvent).
20
+ *
21
+ * @param {GlobalErrorEvent} event - The global error or unhandled rejection event.
22
+ * @returns {Error | undefined} The extracted Error instance, or undefined if no Error could be extracted.
23
+ */
24
+ function extractError(event: GlobalErrorEvent): Error | undefined {
25
+ if ('error' in event && event.error instanceof Error) {
26
+ return event.error;
27
+ }
28
+ if ('reason' in event && event.reason instanceof Error) {
29
+ return event.reason;
30
+ }
31
+ return undefined;
32
+ }
33
+
34
+ /**
35
+ * Reports controller extension errors to the Info Center.
36
+ * Filters events by checking if the stack trace contains 'ControllerExtension',
37
+ * and sends matching errors as error-level messages to the Info Center panel.
38
+ *
39
+ * @param {GlobalErrorEvent} event - The global error or unhandled rejection event.
40
+ */
41
+ const reportControllerExtensionErrorToInfoCenter: (event: GlobalErrorEvent) => void = (event) => {
42
+ const error = extractError(event);
43
+ const stackTrace = error?.stack ?? '';
44
+ if (!CONTROLLER_EXTENSION_PATH_REGEX.test(stackTrace)) {
45
+ return;
46
+ }
47
+ void sendInfoCenterMessage({
48
+ title: { key: 'CONTROLLER_EXTENSION_UNHANDLED_ERROR_TITLE' },
49
+ description: error?.message ?? '',
50
+ type: MessageBarType.error,
51
+ details: stackTrace
52
+ });
53
+ };
54
+
55
+ /**
56
+ * Registers global event listeners for uncaught errors and unhandled promise rejections
57
+ * to detect and report controller extension errors to the Info Center.
58
+ */
59
+ export function registerForControllerExtensionErrors(): void {
60
+ globalThis.addEventListener('error', reportControllerExtensionErrorToInfoCenter);
61
+ globalThis.addEventListener('unhandledrejection', reportControllerExtensionErrorToInfoCenter);
62
+ }
2
63
 
3
64
  export interface FlexChange {
4
65
  [key: string]: string | object | undefined;
@@ -11,6 +72,150 @@ export interface FlexChange {
11
72
 
12
73
  export const CHANGES_API_PATH = '/preview/api/changes';
13
74
 
75
+ /**
76
+ * SAPUI5 delivered namespaces from https://ui5.sap.com/#/api/sap
77
+ */
78
+ const UI5_LIBS = [
79
+ 'sap.apf',
80
+ 'sap.base',
81
+ 'sap.chart',
82
+ 'sap.collaboration',
83
+ 'sap.f',
84
+ 'sap.fe',
85
+ 'sap.fileviewer',
86
+ 'sap.gantt',
87
+ 'sap.landvisz',
88
+ 'sap.m',
89
+ 'sap.ndc',
90
+ 'sap.ovp',
91
+ 'sap.rules',
92
+ 'sap.suite',
93
+ 'sap.tnt',
94
+ 'sap.ui',
95
+ 'sap.uiext',
96
+ 'sap.ushell',
97
+ 'sap.uxap',
98
+ 'sap.viz',
99
+ 'sap.webanalytics',
100
+ 'sap.zen'
101
+ ];
102
+
103
+ interface Manifest {
104
+ ['sap.ui5']?: {
105
+ dependencies?: {
106
+ libs: Record<string, unknown>;
107
+ components: Record<string, unknown>;
108
+ };
109
+ componentUsages?: Record<string, { name: string }>;
110
+ };
111
+ }
112
+
113
+ type AppIndexData = Record<
114
+ string,
115
+ {
116
+ dependencies?: {
117
+ url?: string;
118
+ type?: string;
119
+ componentId: string;
120
+ }[];
121
+ }
122
+ >;
123
+
124
+ /**
125
+ * Check whether a specific dependency is a custom library, and if yes, add it to the map.
126
+ *
127
+ * @param dependency dependency from the manifest
128
+ * @param customLibs map containing the required custom libraries
129
+ */
130
+ function addKeys(dependency: Record<string, unknown>, customLibs: Record<string, true>): void {
131
+ Object.keys(dependency).forEach(function (key) {
132
+ if (
133
+ !UI5_LIBS.some(function (substring) {
134
+ return key === substring || key.startsWith(substring + '.');
135
+ })
136
+ ) {
137
+ customLibs[key] = true;
138
+ }
139
+ });
140
+ }
141
+
142
+ /**
143
+ * Check whether a specific ComponentUsage is a custom component, and if yes, add it to the map.
144
+ *
145
+ * @param compUsages ComponentUsage from the manifest
146
+ * @param customLibs map containing the required custom libraries
147
+ */
148
+ function getComponentUsageNames(compUsages: Record<string, { name: string }>, customLibs: Record<string, true>): void {
149
+ const compNames = Object.keys(compUsages).map(function (compUsageKey: string) {
150
+ return compUsages[compUsageKey].name;
151
+ });
152
+ compNames.forEach(function (key) {
153
+ if (
154
+ !UI5_LIBS.some(function (substring) {
155
+ return key === substring || key.startsWith(substring + '.');
156
+ })
157
+ ) {
158
+ customLibs[key] = true;
159
+ }
160
+ });
161
+ }
162
+
163
+ /**
164
+ * Fetch the manifest for all the given application urls and generate a string containing all required custom library ids.
165
+ *
166
+ * @param appUrls urls pointing to included applications
167
+ * @returns Promise of a comma separated list of all required libraries.
168
+ */
169
+ async function getManifestLibs(appUrls: string[]): Promise<string> {
170
+ const result = {} as Record<string, true>;
171
+ const promises = [];
172
+ for (const url of appUrls) {
173
+ promises.push(
174
+ fetch(`${url}/manifest.json`).then(async (resp) => {
175
+ const manifest = (await resp.json()) as Manifest;
176
+ if (manifest) {
177
+ if (manifest['sap.ui5']?.dependencies) {
178
+ if (manifest['sap.ui5'].dependencies.libs) {
179
+ addKeys(manifest['sap.ui5'].dependencies.libs, result);
180
+ }
181
+ if (manifest['sap.ui5'].dependencies.components) {
182
+ addKeys(manifest['sap.ui5'].dependencies.components, result);
183
+ }
184
+ }
185
+ if (manifest['sap.ui5']?.componentUsages) {
186
+ getComponentUsageNames(manifest['sap.ui5'].componentUsages, result);
187
+ }
188
+ }
189
+ })
190
+ );
191
+ }
192
+ return Promise.all(promises).then(() => Object.keys(result).join(','));
193
+ }
194
+
195
+ /**
196
+ * Register the custom libraries and their url with the UI5 loader.
197
+ *
198
+ * @param dataFromAppIndex data returned from the app index service
199
+ */
200
+ function registerModules(dataFromAppIndex: AppIndexData) {
201
+ Object.keys(dataFromAppIndex).forEach(function (moduleDefinitionKey) {
202
+ const moduleDefinition = dataFromAppIndex[moduleDefinitionKey];
203
+ if (moduleDefinition?.dependencies) {
204
+ moduleDefinition.dependencies.forEach(function (dependency) {
205
+ if (dependency.url && dependency.url.length > 0 && dependency.type === 'UI5LIB') {
206
+ Log.info('Registering Library ' + dependency.componentId + ' from server ' + dependency.url);
207
+ const compId = dependency.componentId.replaceAll('.', '/');
208
+ const config = {
209
+ paths: {} as Record<string, string>
210
+ };
211
+ config.paths[compId] = dependency.url;
212
+ sap.ui.loader.config(config);
213
+ }
214
+ });
215
+ }
216
+ });
217
+ }
218
+
14
219
  /**
15
220
  * Retrieves Flex settings from a 'sap-ui-bootstrap' element's data attribute.
16
221
  * Parses the 'data-open-ux-preview-flex-settings' attribute as JSON.
@@ -26,3 +231,141 @@ export function getFlexSettings(): FlexSettings | undefined {
26
231
  }
27
232
  return result;
28
233
  }
234
+
235
+ /**
236
+ * Fetch the app state from the given application urls, then reset the app state.
237
+ *
238
+ * @param container the UShell container
239
+ */
240
+ export async function resetAppState(container: typeof sap.ushell.Container): Promise<void> {
241
+ const urlParams = new URLSearchParams(globalThis.location.hash);
242
+ const appStateValue = urlParams.get('sap-iapp-state') ?? urlParams.get('/?sap-iapp-state');
243
+ if (appStateValue) {
244
+ const appStateService = await container.getServiceAsync<AppState>('AppState');
245
+ appStateService.deleteAppState(appStateValue);
246
+ }
247
+ }
248
+
249
+ /**
250
+ * Fetch the manifest from the given application urls, then parse them for custom libs, and finally request their urls.
251
+ *
252
+ * @param appUrls application urls
253
+ * @param urlParams URLSearchParams object
254
+ * @returns returns a promise when the registration is completed.
255
+ */
256
+ export async function registerComponentDependencyPaths(appUrls: string[], urlParams: URLSearchParams): Promise<void> {
257
+ const libs = await getManifestLibs(appUrls);
258
+ if (libs && libs.length > 0) {
259
+ let url = '/sap/bc/ui2/app_index/ui5_app_info?id=' + encodeURIComponent(libs);
260
+ const sapClient = urlParams.get('sap-client');
261
+ if (sapClient?.length === 3 && /^\d+$/.test(sapClient)) {
262
+ url = url + '&sap-client=' + sapClient;
263
+ }
264
+ const response = await fetch(url);
265
+ try {
266
+ registerModules((await response.json()) as AppIndexData);
267
+ } catch (error) {
268
+ Log.error(`Registering of reuse libs failed. Error:${error}`);
269
+ }
270
+ }
271
+ }
272
+
273
+ /**
274
+ * Handle higher layer changes when starting UI Adaptation.
275
+ * When RTA detects higher layer changes an error with Reload triggered text is thrown, the RTA instance is destroyed and the application is reloaded.
276
+ * For UI5 version lower than 1.84.0 RTA is showing a popup with notification text about the detection of higher layer changes.
277
+ *
278
+ * @param error the error thrown when there are higher layer changes when starting UI Adaptation.
279
+ * @param ui5VersionInfo ui5 version info
280
+ */
281
+ export async function handleHigherLayerChanges(error: unknown, ui5VersionInfo: Ui5VersionInfo): Promise<void> {
282
+ const err = getError(error);
283
+ if (err.message.includes('Reload triggered')) {
284
+ if (!isLowerThanMinimalUi5Version(ui5VersionInfo, { major: 1, minor: 84 })) {
285
+ await sendInfoCenterMessage({
286
+ title: { key: 'HIGHER_LAYER_CHANGES_TITLE' },
287
+ description: { key: 'HIGHER_LAYER_CHANGES_INFO_MESSAGE' },
288
+ type: MessageBarType.warning
289
+ });
290
+ }
291
+ globalThis.location.reload();
292
+ }
293
+ }
294
+
295
+ /**
296
+ * Starts UI adaptation (RTA) for the given component instance.
297
+ * Contains the inner logic shared between sandbox 1 (sandbox1Init.ts) and sandbox 2 (sandbox2AfterInit.ts).
298
+ *
299
+ * @param view - the component instance returned by AppLifeCycle attachAppLoaded
300
+ * @param flexSettings - the parsed flex settings
301
+ * @param ui5VersionInfo - current UI5 version
302
+ */
303
+ export function startRtaForAppInstance(
304
+ view: unknown,
305
+ flexSettings: FlexSettings,
306
+ ui5VersionInfo: Ui5VersionInfo
307
+ ): void {
308
+ const { pluginScript, ...flexSettingsWithoutPlugin } = flexSettings;
309
+ const libs: string[] = [];
310
+
311
+ if (isLowerThanMinimalUi5Version(ui5VersionInfo, { major: 1, minor: 72 })) {
312
+ libs.push('open/ux/preview/client/flp/initRta');
313
+ } else {
314
+ libs.push('sap/ui/rta/api/startAdaptation');
315
+ }
316
+
317
+ if (pluginScript) {
318
+ libs.push(pluginScript as string);
319
+ }
320
+
321
+ const options: RTAOptions = {
322
+ rootControl: view,
323
+ validateAppVersion: false,
324
+ flexSettings: flexSettingsWithoutPlugin
325
+ };
326
+
327
+ sap.ui.require(
328
+ libs,
329
+ async function (startAdaptation: StartAdaptation | InitRtaScript, pluginScript: RTAPlugin) {
330
+ try {
331
+ await startAdaptation(options, pluginScript);
332
+ } catch (error) {
333
+ await sendInfoCenterMessage({
334
+ title: { key: 'FLP_ADAPTATION_START_FAILED_TITLE' },
335
+ description: getError(error).message,
336
+ type: MessageBarType.error
337
+ });
338
+ await handleHigherLayerChanges(error, ui5VersionInfo);
339
+ }
340
+ }
341
+ );
342
+ }
343
+
344
+ /**
345
+ * Dynamically adds a "Generate Card" action to the SAP Fiori Launchpad for the given component instance.
346
+ *
347
+ * @param componentInstance - The component instance for which the card generation action is added.
348
+ * @param container - The SAP Fiori Launchpad container used to access services.
349
+ */
350
+ export function addCardGenerationUserAction(
351
+ componentInstance: Component,
352
+ container: typeof sap.ushell.Container
353
+ ): void {
354
+ sap.ui.require(['sap/cards/ap/generator/CardGenerator'], async (CardGenerator: CardGeneratorType) => {
355
+ const extensionService = await container.getServiceAsync<Extension>('Extension');
356
+ const controlProperties = {
357
+ icon: 'sap-icon://add',
358
+ id: 'generate_card',
359
+ text: 'Generate Card',
360
+ tooltip: 'Generate Card',
361
+ press: () => {
362
+ CardGenerator.initializeAsync(componentInstance);
363
+ }
364
+ };
365
+ const parameters = {
366
+ controlType: 'sap.ushell.ui.launchpad.ActionItem'
367
+ };
368
+ const generateCardAction = await extensionService.createUserAction(controlProperties, parameters);
369
+ generateCardAction.showForCurrentApp();
370
+ });
371
+ }
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+
3
+ sap.ui.define(["sap/base/Log", "open/ux/preview/client/thirdparty/@sap-ux-private/control-property-editor-common", "sap/ui/core/IconPool", "sap/base/i18n/ResourceBundle", "../utils/error", "./initConnectors", "../utils/version", "../adp/api-handler", "./common"], function (Log, ___sap_ux_private_control_property_editor_common, IconPool, ResourceBundle, ___utils_errorjs, __initConnectors, ___utils_versionjs, ___adp_api_handlerjs, ___commonjs) {
4
+ "use strict";
5
+
6
+ function _interopRequireDefault(obj) {
7
+ return obj && obj.__esModule && typeof obj.default !== "undefined" ? obj.default : obj;
8
+ }
9
+ function __ui5_require_async(path) {
10
+ return new Promise(function (resolve, reject) {
11
+ sap.ui.require([path], function (module) {
12
+ if (!(module && module.__esModule)) {
13
+ module = module === null || !(typeof module === "object" && path.endsWith("/library")) ? {
14
+ default: module
15
+ } : module;
16
+ Object.defineProperty(module, "__esModule", {
17
+ value: true
18
+ });
19
+ }
20
+ resolve(module);
21
+ }, function (err) {
22
+ reject(err);
23
+ });
24
+ });
25
+ }
26
+ const SCENARIO = ___sap_ux_private_control_property_editor_common["SCENARIO"];
27
+ const getError = ___utils_errorjs["getError"];
28
+ const initConnectors = _interopRequireDefault(__initConnectors);
29
+ const getUi5Version = ___utils_versionjs["getUi5Version"];
30
+ const getManifestAppdescr = ___adp_api_handlerjs["getManifestAppdescr"];
31
+ const addCardGenerationUserAction = ___commonjs["addCardGenerationUserAction"];
32
+ const registerComponentDependencyPaths = ___commonjs["registerComponentDependencyPaths"];
33
+ const registerForControllerExtensionErrors = ___commonjs["registerForControllerExtensionErrors"];
34
+ const resetAppState = ___commonjs["resetAppState"];
35
+ const startRtaForAppInstance = ___commonjs["startRtaForAppInstance"];
36
+ /**
37
+ * Register SAP fonts that are also registered in a productive Fiori launchpad.
38
+ */
39
+ function registerSAPFonts() {
40
+ const fioriTheme = {
41
+ fontFamily: 'SAP-icons-TNT',
42
+ fontURI: sap.ui.require.toUrl('sap/tnt/themes/base/fonts/')
43
+ };
44
+ IconPool.registerFont(fioriTheme);
45
+ const suiteTheme = {
46
+ fontFamily: 'BusinessSuiteInAppSymbols',
47
+ fontURI: sap.ui.require.toUrl('sap/ushell/themes/base/fonts/')
48
+ };
49
+ IconPool.registerFont(suiteTheme);
50
+ }
51
+
52
+ /**
53
+ * Create Resource Bundle based on the scenario.
54
+ *
55
+ * @param scenario to be used for the resource bundle.
56
+ */
57
+ async function loadI18nResourceBundle(scenario) {
58
+ if (scenario === SCENARIO.AdaptationProject) {
59
+ const manifest = await getManifestAppdescr();
60
+ const enhanceWith = manifest.content.filter(content => content.texts?.i18n).map(content => ({
61
+ bundleUrl: `../${content.texts.i18n}`
62
+ }));
63
+ return ResourceBundle.create({
64
+ url: '../i18n/i18n.properties',
65
+ enhanceWith
66
+ });
67
+ }
68
+ return ResourceBundle.create({
69
+ url: 'i18n/i18n.properties'
70
+ });
71
+ }
72
+
73
+ /**
74
+ * Read the application title from the resource bundle and set it as document title.
75
+ *
76
+ * @param resourceBundle resource bundle to read the title from.
77
+ * @param i18nKey optional parameter to define the i18n key to be used for the title.
78
+ */
79
+ function setI18nTitle(resourceBundle, i18nKey = 'appTitle') {
80
+ if (resourceBundle.hasText(i18nKey)) {
81
+ document.title = resourceBundle.getText(i18nKey) ?? document.title;
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Apply additional configuration and initialize sandbox.
87
+ *
88
+ * @param params init parameters read from the script tag
89
+ * @param params.appUrls JSON containing a string array of application urls
90
+ * @param params.flex JSON containing the flex configuration
91
+ * @param params.customInit path to the custom init module to be called
92
+ * @param params.enhancedHomePage boolean indicating if enhanced homepage is enabled
93
+ * @returns promise
94
+ */
95
+ async function init({
96
+ appUrls,
97
+ flex,
98
+ customInit,
99
+ enhancedHomePage,
100
+ enableCardGenerator
101
+ }) {
102
+ const urlParams = new URLSearchParams(globalThis.location.search);
103
+ const container = sap?.ushell?.Container ?? (await __ui5_require_async('sap/ushell/Container')).default;
104
+ let scenario = '';
105
+ const ui5VersionInfo = await getUi5Version();
106
+ // Register RTA if configured
107
+ if (flex) {
108
+ registerForControllerExtensionErrors();
109
+ const flexSettings = JSON.parse(flex);
110
+ scenario = flexSettings.scenario;
111
+ container.attachRendererCreatedEvent(async function () {
112
+ const lifecycleService = await container.getServiceAsync('AppLifeCycle');
113
+ lifecycleService.attachAppLoaded(event => {
114
+ // Prevent starting RTA when the FLP home component (#Shell-home) fires attachAppLoaded before the user navigates to the actual app.
115
+ if (!globalThis.location.hash || globalThis.location.hash.startsWith('#Shell-home')) {
116
+ return;
117
+ }
118
+ startRtaForAppInstance(event.getParameter('componentInstance'), flexSettings, ui5VersionInfo);
119
+ });
120
+ });
121
+ }
122
+ if (enableCardGenerator) {
123
+ container.attachRendererCreatedEvent(async function () {
124
+ const lifecycleService = await container.getServiceAsync('AppLifeCycle');
125
+ lifecycleService.attachAppLoaded(event => {
126
+ const componentInstance = event.getParameter('componentInstance');
127
+ addCardGenerationUserAction(componentInstance, container);
128
+ });
129
+ });
130
+ }
131
+
132
+ // reset app state if requested
133
+ if (urlParams.get('fiori-tools-iapp-state')?.toLocaleLowerCase() !== 'true') {
134
+ await resetAppState(container);
135
+ }
136
+
137
+ // Load custom library paths if configured
138
+ if (appUrls) {
139
+ await registerComponentDependencyPaths(JSON.parse(appUrls) ?? [], urlParams);
140
+ }
141
+
142
+ // Load rta connector
143
+ await initConnectors();
144
+
145
+ // Load custom initialization module
146
+ if (customInit) {
147
+ sap.ui.require([customInit]);
148
+ }
149
+
150
+ // init
151
+ const resourceBundle = await loadI18nResourceBundle(scenario);
152
+ setI18nTitle(resourceBundle);
153
+ registerSAPFonts();
154
+ if (enhancedHomePage) {
155
+ await container.init('cdm');
156
+ }
157
+ const renderer = ui5VersionInfo.major < 2 && !ui5VersionInfo.label?.includes('legacy-free') ? await container.createRenderer(undefined, true) : await container.createRendererInternal(undefined, true);
158
+ renderer.placeAt('content');
159
+ }
160
+
161
+ // eslint-disable-next-line @sap-ux/fiori-tools/sap-no-dom-access,@sap-ux/fiori-tools/sap-browser-api-warning, @sap-ux/fiori-tools/sap-no-global-variable
162
+ const bootstrapConfig = document.getElementById('sap-ui-bootstrap');
163
+ if (bootstrapConfig) {
164
+ // DO NOT refactor to top-level await. This module is loaded via sap.ui.define (AMD),
165
+ // and using `await` at the top level of an AMD module callback prevents sap.ui.define
166
+ // from completing module registration.
167
+ init({
168
+ appUrls: bootstrapConfig.dataset.openUxPreviewLibsManifests,
169
+ flex: bootstrapConfig.dataset.openUxPreviewFlexSettings,
170
+ customInit: bootstrapConfig.dataset.openUxPreviewCustomInit,
171
+ enhancedHomePage: !!bootstrapConfig.dataset.openUxPreviewEnhancedHomepage,
172
+ enableCardGenerator: !!bootstrapConfig.dataset.openUxPreviewEnableCardGenerator
173
+ }).catch(e => {
174
+ const error = getError(e);
175
+ Log.error('Sandbox initialization failed: ' + error.message);
176
+ });
177
+ }
178
+ var __exports = {
179
+ __esModule: true
180
+ };
181
+ __exports.registerSAPFonts = registerSAPFonts;
182
+ __exports.loadI18nResourceBundle = loadI18nResourceBundle;
183
+ __exports.setI18nTitle = setI18nTitle;
184
+ __exports.init = init;
185
+ return __exports;
186
+ });
187
+ //# sourceMappingURL=sandbox1Init.js.map