@sap-ux/preview-middleware 1.1.2 → 1.2.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.
- package/README.md +31 -29
- package/dist/base/config.d.ts +55 -2
- package/dist/base/config.js +158 -26
- package/dist/base/flp.d.ts +24 -0
- package/dist/base/flp.js +116 -18
- package/dist/client/flp/WorkspaceConnector.js +7 -5
- package/dist/client/flp/WorkspaceConnector.ts +7 -5
- package/dist/client/flp/common.js +293 -1
- package/dist/client/flp/common.ts +344 -1
- package/dist/client/flp/sandbox1Init.js +187 -0
- package/dist/client/flp/sandbox1Init.ts +174 -0
- package/dist/client/flp/sandbox2AfterInit.js +66 -0
- package/dist/client/flp/sandbox2AfterInit.ts +63 -0
- package/dist/client/flp/sandbox2BeforeInit.js +67 -0
- package/dist/client/flp/sandbox2BeforeInit.ts +60 -0
- package/dist/types/index.d.ts +21 -0
- package/package.json +6 -6
- package/templates/flp/cdm.ejs +1 -1
- package/templates/flp/sandbox.ejs +1 -1
- package/templates/flp/sandbox2.ejs +12 -44
- package/dist/client/flp/init.js +0 -465
- package/dist/client/flp/init.ts +0 -498
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import Log from 'sap/base/Log';
|
|
2
|
+
import type AppLifeCycle from 'sap/ushell/services/AppLifeCycle';
|
|
3
|
+
import type { FlexSettings } from 'sap/ui/rta/RuntimeAuthoring';
|
|
4
|
+
import { SCENARIO, type Scenario } from '@sap-ux-private/control-property-editor-common';
|
|
5
|
+
import type Component from 'sap/ui/core/Component';
|
|
6
|
+
import IconPool from 'sap/ui/core/IconPool';
|
|
7
|
+
import ResourceBundle from 'sap/base/i18n/ResourceBundle';
|
|
8
|
+
import { getError } from '../utils/error.js';
|
|
9
|
+
import initConnectors from './initConnectors.js';
|
|
10
|
+
import { getUi5Version } from '../utils/version.js';
|
|
11
|
+
import { getManifestAppdescr } from '../adp/api-handler.js';
|
|
12
|
+
import {
|
|
13
|
+
addCardGenerationUserAction,
|
|
14
|
+
registerComponentDependencyPaths,
|
|
15
|
+
registerForControllerExtensionErrors,
|
|
16
|
+
resetAppState,
|
|
17
|
+
startRtaForAppInstance
|
|
18
|
+
} from './common.js';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Register SAP fonts that are also registered in a productive Fiori launchpad.
|
|
22
|
+
*/
|
|
23
|
+
export function registerSAPFonts() {
|
|
24
|
+
const fioriTheme = {
|
|
25
|
+
fontFamily: 'SAP-icons-TNT',
|
|
26
|
+
fontURI: sap.ui.require.toUrl('sap/tnt/themes/base/fonts/')
|
|
27
|
+
};
|
|
28
|
+
IconPool.registerFont(fioriTheme);
|
|
29
|
+
const suiteTheme = {
|
|
30
|
+
fontFamily: 'BusinessSuiteInAppSymbols',
|
|
31
|
+
fontURI: sap.ui.require.toUrl('sap/ushell/themes/base/fonts/')
|
|
32
|
+
};
|
|
33
|
+
IconPool.registerFont(suiteTheme);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Create Resource Bundle based on the scenario.
|
|
38
|
+
*
|
|
39
|
+
* @param scenario to be used for the resource bundle.
|
|
40
|
+
*/
|
|
41
|
+
export async function loadI18nResourceBundle(scenario: Scenario): Promise<ResourceBundle> {
|
|
42
|
+
if (scenario === SCENARIO.AdaptationProject) {
|
|
43
|
+
const manifest = await getManifestAppdescr();
|
|
44
|
+
const enhanceWith = (manifest.content as { texts: { i18n: string } }[])
|
|
45
|
+
.filter((content) => content.texts?.i18n)
|
|
46
|
+
.map((content) => ({ bundleUrl: `../${content.texts.i18n}` }));
|
|
47
|
+
return ResourceBundle.create({
|
|
48
|
+
url: '../i18n/i18n.properties',
|
|
49
|
+
enhanceWith
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return ResourceBundle.create({
|
|
53
|
+
url: 'i18n/i18n.properties'
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Read the application title from the resource bundle and set it as document title.
|
|
59
|
+
*
|
|
60
|
+
* @param resourceBundle resource bundle to read the title from.
|
|
61
|
+
* @param i18nKey optional parameter to define the i18n key to be used for the title.
|
|
62
|
+
*/
|
|
63
|
+
export function setI18nTitle(resourceBundle: ResourceBundle, i18nKey = 'appTitle') {
|
|
64
|
+
if (resourceBundle.hasText(i18nKey)) {
|
|
65
|
+
document.title = resourceBundle.getText(i18nKey) ?? document.title;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Apply additional configuration and initialize sandbox.
|
|
71
|
+
*
|
|
72
|
+
* @param params init parameters read from the script tag
|
|
73
|
+
* @param params.appUrls JSON containing a string array of application urls
|
|
74
|
+
* @param params.flex JSON containing the flex configuration
|
|
75
|
+
* @param params.customInit path to the custom init module to be called
|
|
76
|
+
* @param params.enhancedHomePage boolean indicating if enhanced homepage is enabled
|
|
77
|
+
* @returns promise
|
|
78
|
+
*/
|
|
79
|
+
export async function init({
|
|
80
|
+
appUrls,
|
|
81
|
+
flex,
|
|
82
|
+
customInit,
|
|
83
|
+
enhancedHomePage,
|
|
84
|
+
enableCardGenerator
|
|
85
|
+
}: {
|
|
86
|
+
appUrls?: string | null;
|
|
87
|
+
flex?: string | null;
|
|
88
|
+
customInit?: string | null;
|
|
89
|
+
enhancedHomePage?: boolean | null;
|
|
90
|
+
enableCardGenerator?: boolean;
|
|
91
|
+
}): Promise<void> {
|
|
92
|
+
const urlParams = new URLSearchParams(globalThis.location.search);
|
|
93
|
+
const container =
|
|
94
|
+
sap?.ushell?.Container ??
|
|
95
|
+
((await import('sap/ushell/Container')).default);
|
|
96
|
+
let scenario: string = '';
|
|
97
|
+
const ui5VersionInfo = await getUi5Version();
|
|
98
|
+
// Register RTA if configured
|
|
99
|
+
if (flex) {
|
|
100
|
+
registerForControllerExtensionErrors();
|
|
101
|
+
const flexSettings = JSON.parse(flex) as FlexSettings;
|
|
102
|
+
scenario = flexSettings.scenario;
|
|
103
|
+
container.attachRendererCreatedEvent(async function () {
|
|
104
|
+
const lifecycleService = await container.getServiceAsync<AppLifeCycle>('AppLifeCycle');
|
|
105
|
+
lifecycleService.attachAppLoaded((event) => {
|
|
106
|
+
// Prevent starting RTA when the FLP home component (#Shell-home) fires attachAppLoaded before the user navigates to the actual app.
|
|
107
|
+
if (!globalThis.location.hash || globalThis.location.hash.startsWith('#Shell-home')) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
startRtaForAppInstance(event.getParameter('componentInstance'), flexSettings, ui5VersionInfo);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
if (enableCardGenerator) {
|
|
115
|
+
container.attachRendererCreatedEvent(async function () {
|
|
116
|
+
const lifecycleService = await container.getServiceAsync<AppLifeCycle>('AppLifeCycle');
|
|
117
|
+
lifecycleService.attachAppLoaded((event) => {
|
|
118
|
+
const componentInstance = event.getParameter('componentInstance');
|
|
119
|
+
addCardGenerationUserAction(componentInstance as unknown as Component, container);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// reset app state if requested
|
|
125
|
+
if (urlParams.get('fiori-tools-iapp-state')?.toLocaleLowerCase() !== 'true') {
|
|
126
|
+
await resetAppState(container);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Load custom library paths if configured
|
|
130
|
+
if (appUrls) {
|
|
131
|
+
await registerComponentDependencyPaths((JSON.parse(appUrls) as string[]) ?? [], urlParams);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Load rta connector
|
|
135
|
+
await initConnectors();
|
|
136
|
+
|
|
137
|
+
// Load custom initialization module
|
|
138
|
+
if (customInit) {
|
|
139
|
+
sap.ui.require([customInit]);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// init
|
|
143
|
+
const resourceBundle = await loadI18nResourceBundle(scenario as Scenario);
|
|
144
|
+
setI18nTitle(resourceBundle);
|
|
145
|
+
registerSAPFonts();
|
|
146
|
+
|
|
147
|
+
if (enhancedHomePage) {
|
|
148
|
+
await container.init('cdm');
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const renderer =
|
|
152
|
+
ui5VersionInfo.major < 2 && !ui5VersionInfo.label?.includes('legacy-free')
|
|
153
|
+
? await container.createRenderer(undefined, true)
|
|
154
|
+
: await container.createRendererInternal(undefined, true);
|
|
155
|
+
renderer.placeAt('content');
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// 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
|
|
159
|
+
const bootstrapConfig = document.getElementById('sap-ui-bootstrap');
|
|
160
|
+
if (bootstrapConfig) {
|
|
161
|
+
// DO NOT refactor to top-level await. This module is loaded via sap.ui.define (AMD),
|
|
162
|
+
// and using `await` at the top level of an AMD module callback prevents sap.ui.define
|
|
163
|
+
// from completing module registration.
|
|
164
|
+
init({
|
|
165
|
+
appUrls: bootstrapConfig.dataset.openUxPreviewLibsManifests,
|
|
166
|
+
flex: bootstrapConfig.dataset.openUxPreviewFlexSettings,
|
|
167
|
+
customInit: bootstrapConfig.dataset.openUxPreviewCustomInit,
|
|
168
|
+
enhancedHomePage: !!bootstrapConfig.dataset.openUxPreviewEnhancedHomepage,
|
|
169
|
+
enableCardGenerator: !!bootstrapConfig.dataset.openUxPreviewEnableCardGenerator
|
|
170
|
+
}).catch((e) => {
|
|
171
|
+
const error = getError(e);
|
|
172
|
+
Log.error('Sandbox initialization failed: ' + error.message);
|
|
173
|
+
});
|
|
174
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
sap.ui.define(["./common", "./initConnectors", "../utils/version"], function (___commonjs, __initConnectors, ___utils_versionjs) {
|
|
4
|
+
"use strict";
|
|
5
|
+
|
|
6
|
+
function _interopRequireDefault(obj) {
|
|
7
|
+
return obj && obj.__esModule && typeof obj.default !== "undefined" ? obj.default : obj;
|
|
8
|
+
}
|
|
9
|
+
const addCardGenerationUserAction = ___commonjs["addCardGenerationUserAction"];
|
|
10
|
+
const registerForControllerExtensionErrors = ___commonjs["registerForControllerExtensionErrors"];
|
|
11
|
+
const resetAppState = ___commonjs["resetAppState"];
|
|
12
|
+
const startRtaForAppInstance = ___commonjs["startRtaForAppInstance"];
|
|
13
|
+
const initConnectors = _interopRequireDefault(__initConnectors);
|
|
14
|
+
const getUi5Version = ___utils_versionjs["getUi5Version"];
|
|
15
|
+
/**
|
|
16
|
+
* AfterFlpStart hook for FLP Sandbox 2.0.
|
|
17
|
+
* Called by the sandbox after the FLP renderer is fully up (Container initialized,
|
|
18
|
+
* renderer created and placed). Safe to use sap/ushell/Container at this point.
|
|
19
|
+
*/
|
|
20
|
+
async function execute() {
|
|
21
|
+
// eslint-disable-next-line @sap-ux/fiori-tools/sap-no-dom-access,@sap-ux/fiori-tools/sap-browser-api-warning
|
|
22
|
+
const bootstrapConfig = document.getElementById('sap-ui-bootstrap');
|
|
23
|
+
const flex = bootstrapConfig?.dataset.openUxPreviewFlexSettings;
|
|
24
|
+
const enableCardGenerator = !!bootstrapConfig?.dataset.openUxPreviewEnableCardGenerator;
|
|
25
|
+
const enhancedHomePage = !!bootstrapConfig?.dataset.openUxPreviewEnhancedHomepage;
|
|
26
|
+
const urlParams = new URLSearchParams(globalThis.location.search);
|
|
27
|
+
const container = sap.ushell.Container;
|
|
28
|
+
const ui5VersionInfo = await getUi5Version();
|
|
29
|
+
|
|
30
|
+
// Reset app state unless explicitly suppressed
|
|
31
|
+
if (urlParams.get('fiori-tools-iapp-state')?.toLocaleLowerCase() !== 'true') {
|
|
32
|
+
await resetAppState(container);
|
|
33
|
+
}
|
|
34
|
+
if (flex || enableCardGenerator) {
|
|
35
|
+
const lifecycleService = await container.getServiceAsync('AppLifeCycle');
|
|
36
|
+
if (flex) {
|
|
37
|
+
registerForControllerExtensionErrors();
|
|
38
|
+
const flexSettings = JSON.parse(flex);
|
|
39
|
+
lifecycleService.attachAppLoaded(event => {
|
|
40
|
+
// Prevent starting RTA when the FLP home component fires attachAppLoaded before the user navigates to the actual app
|
|
41
|
+
if (!globalThis.location.hash || globalThis.location.hash.startsWith('#Shell-home')) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
startRtaForAppInstance(event.getParameter('componentInstance'), flexSettings, ui5VersionInfo);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
if (enableCardGenerator) {
|
|
48
|
+
lifecycleService.attachAppLoaded(event => {
|
|
49
|
+
addCardGenerationUserAction(event.getParameter('componentInstance'), container);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Initialize RTA connectors
|
|
55
|
+
await initConnectors();
|
|
56
|
+
if (enhancedHomePage) {
|
|
57
|
+
await container.init('cdm');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
var __exports = {
|
|
61
|
+
__esModule: true
|
|
62
|
+
};
|
|
63
|
+
__exports.execute = execute;
|
|
64
|
+
return __exports;
|
|
65
|
+
});
|
|
66
|
+
//# sourceMappingURL=sandbox2AfterInit.js.map
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type AppLifeCycle from 'sap/ushell/services/AppLifeCycle';
|
|
2
|
+
import type Component from 'sap/ui/core/Component';
|
|
3
|
+
import type { FlexSettings } from 'sap/ui/rta/RuntimeAuthoring';
|
|
4
|
+
import {
|
|
5
|
+
addCardGenerationUserAction,
|
|
6
|
+
registerForControllerExtensionErrors,
|
|
7
|
+
resetAppState,
|
|
8
|
+
startRtaForAppInstance
|
|
9
|
+
} from './common.js';
|
|
10
|
+
import initConnectors from './initConnectors.js';
|
|
11
|
+
import { getUi5Version } from '../utils/version.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* AfterFlpStart hook for FLP Sandbox 2.0.
|
|
15
|
+
* Called by the sandbox after the FLP renderer is fully up (Container initialized,
|
|
16
|
+
* renderer created and placed). Safe to use sap/ushell/Container at this point.
|
|
17
|
+
*/
|
|
18
|
+
export async function execute(): Promise<void> {
|
|
19
|
+
// eslint-disable-next-line @sap-ux/fiori-tools/sap-no-dom-access,@sap-ux/fiori-tools/sap-browser-api-warning
|
|
20
|
+
const bootstrapConfig = document.getElementById('sap-ui-bootstrap');
|
|
21
|
+
const flex = bootstrapConfig?.dataset.openUxPreviewFlexSettings;
|
|
22
|
+
const enableCardGenerator = !!bootstrapConfig?.dataset.openUxPreviewEnableCardGenerator;
|
|
23
|
+
const enhancedHomePage = !!bootstrapConfig?.dataset.openUxPreviewEnhancedHomepage;
|
|
24
|
+
|
|
25
|
+
const urlParams = new URLSearchParams(globalThis.location.search);
|
|
26
|
+
const container = sap.ushell.Container;
|
|
27
|
+
const ui5VersionInfo = await getUi5Version();
|
|
28
|
+
|
|
29
|
+
// Reset app state unless explicitly suppressed
|
|
30
|
+
if (urlParams.get('fiori-tools-iapp-state')?.toLocaleLowerCase() !== 'true') {
|
|
31
|
+
await resetAppState(container);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (flex || enableCardGenerator) {
|
|
35
|
+
const lifecycleService = await container.getServiceAsync<AppLifeCycle>('AppLifeCycle');
|
|
36
|
+
if (flex) {
|
|
37
|
+
registerForControllerExtensionErrors();
|
|
38
|
+
const flexSettings = JSON.parse(flex) as FlexSettings;
|
|
39
|
+
lifecycleService.attachAppLoaded((event) => {
|
|
40
|
+
// Prevent starting RTA when the FLP home component fires attachAppLoaded before the user navigates to the actual app
|
|
41
|
+
if (!globalThis.location.hash || globalThis.location.hash.startsWith('#Shell-home')) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
startRtaForAppInstance(event.getParameter('componentInstance'), flexSettings, ui5VersionInfo);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
if (enableCardGenerator) {
|
|
48
|
+
lifecycleService.attachAppLoaded((event) => {
|
|
49
|
+
addCardGenerationUserAction(
|
|
50
|
+
event.getParameter('componentInstance') as unknown as Component,
|
|
51
|
+
container
|
|
52
|
+
);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Initialize RTA connectors
|
|
58
|
+
await initConnectors();
|
|
59
|
+
|
|
60
|
+
if (enhancedHomePage) {
|
|
61
|
+
await container.init('cdm');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
sap.ui.define(["./common"], function (___commonjs) {
|
|
4
|
+
"use strict";
|
|
5
|
+
|
|
6
|
+
const registerComponentDependencyPaths = ___commonjs["registerComponentDependencyPaths"];
|
|
7
|
+
/**
|
|
8
|
+
* Registers the ADP variant's `changes` namespace to resolve against the local dev server.
|
|
9
|
+
*
|
|
10
|
+
* In FLP Sandbox 2.0 the CDM registers the ADP variant component namespace (e.g. `adp/v2app`)
|
|
11
|
+
* against the backend URL so the base app Component/manifest load from the backend. That would
|
|
12
|
+
* also route flex-change resources (fragments, code extensions under `<namespace>/changes/...`)
|
|
13
|
+
* to the backend. This registers the more-specific `<namespace>/changes` sub-path to the local
|
|
14
|
+
* dev-server root so UI5's longest-prefix loader resolution serves those local files, matching
|
|
15
|
+
* Sandbox 1 behaviour. The base component namespace registration is left untouched.
|
|
16
|
+
*
|
|
17
|
+
* @param projectId the ADP variant id (e.g. `adp.v2app`), as provided in flexSettings
|
|
18
|
+
* @param baseUrl the local base URL prefix for the dev server (maybe empty)
|
|
19
|
+
*/
|
|
20
|
+
function registerAdpChangesResourceRoot(projectId, baseUrl = '') {
|
|
21
|
+
if (!projectId) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const namespace = `${projectId.replaceAll('.', '/')}/changes`;
|
|
25
|
+
const config = {
|
|
26
|
+
paths: {}
|
|
27
|
+
};
|
|
28
|
+
config.paths[namespace] = `${baseUrl}/changes`;
|
|
29
|
+
sap.ui.loader.config(config);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* BeforeFlpStart hook for FLP Sandbox 2.0.
|
|
34
|
+
* Called by the sandbox before the FLP starts. Must NOT require sap/ushell modules —
|
|
35
|
+
* Container is not yet initialized at this point (StartSandbox.js loads it after this hook).
|
|
36
|
+
*/
|
|
37
|
+
async function execute() {
|
|
38
|
+
// eslint-disable-next-line @sap-ux/fiori-tools/sap-no-dom-access,@sap-ux/fiori-tools/sap-browser-api-warning
|
|
39
|
+
const bootstrapConfig = document.getElementById('sap-ui-bootstrap');
|
|
40
|
+
const appUrls = bootstrapConfig?.dataset.openUxPreviewLibsManifests;
|
|
41
|
+
const customInit = bootstrapConfig?.dataset.openUxPreviewCustomInit;
|
|
42
|
+
const flex = bootstrapConfig?.dataset.openUxPreviewFlexSettings;
|
|
43
|
+
const baseUrl = bootstrapConfig?.dataset.openUxPreviewBaseUrl ?? '';
|
|
44
|
+
const urlParams = new URLSearchParams(globalThis.location.search);
|
|
45
|
+
|
|
46
|
+
// For ADP, register the variant's changes namespace locally so flex-change resources
|
|
47
|
+
// (fragments, code extensions) resolve against the dev server instead of the backend.
|
|
48
|
+
if (flex) {
|
|
49
|
+
const flexSettings = JSON.parse(flex);
|
|
50
|
+
if (flexSettings.projectId) {
|
|
51
|
+
registerAdpChangesResourceRoot(flexSettings.projectId, baseUrl);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (appUrls) {
|
|
55
|
+
await registerComponentDependencyPaths(JSON.parse(appUrls) ?? [], urlParams);
|
|
56
|
+
}
|
|
57
|
+
if (customInit) {
|
|
58
|
+
sap.ui.require([customInit]);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
var __exports = {
|
|
62
|
+
__esModule: true
|
|
63
|
+
};
|
|
64
|
+
__exports.execute = execute;
|
|
65
|
+
return __exports;
|
|
66
|
+
});
|
|
67
|
+
//# sourceMappingURL=sandbox2BeforeInit.js.map
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { FlexSettings } from 'sap/ui/rta/RuntimeAuthoring';
|
|
2
|
+
import { registerComponentDependencyPaths } from './common.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Registers the ADP variant's `changes` namespace to resolve against the local dev server.
|
|
6
|
+
*
|
|
7
|
+
* In FLP Sandbox 2.0 the CDM registers the ADP variant component namespace (e.g. `adp/v2app`)
|
|
8
|
+
* against the backend URL so the base app Component/manifest load from the backend. That would
|
|
9
|
+
* also route flex-change resources (fragments, code extensions under `<namespace>/changes/...`)
|
|
10
|
+
* to the backend. This registers the more-specific `<namespace>/changes` sub-path to the local
|
|
11
|
+
* dev-server root so UI5's longest-prefix loader resolution serves those local files, matching
|
|
12
|
+
* Sandbox 1 behaviour. The base component namespace registration is left untouched.
|
|
13
|
+
*
|
|
14
|
+
* @param projectId the ADP variant id (e.g. `adp.v2app`), as provided in flexSettings
|
|
15
|
+
* @param baseUrl the local base URL prefix for the dev server (maybe empty)
|
|
16
|
+
*/
|
|
17
|
+
function registerAdpChangesResourceRoot(projectId: string, baseUrl = ''): void {
|
|
18
|
+
if (!projectId) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const namespace = `${projectId.replaceAll('.', '/')}/changes`;
|
|
22
|
+
const config = {
|
|
23
|
+
paths: {} as Record<string, string>
|
|
24
|
+
};
|
|
25
|
+
config.paths[namespace] = `${baseUrl}/changes`;
|
|
26
|
+
sap.ui.loader.config(config);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* BeforeFlpStart hook for FLP Sandbox 2.0.
|
|
31
|
+
* Called by the sandbox before the FLP starts. Must NOT require sap/ushell modules —
|
|
32
|
+
* Container is not yet initialized at this point (StartSandbox.js loads it after this hook).
|
|
33
|
+
*/
|
|
34
|
+
export async function execute(): Promise<void> {
|
|
35
|
+
// eslint-disable-next-line @sap-ux/fiori-tools/sap-no-dom-access,@sap-ux/fiori-tools/sap-browser-api-warning
|
|
36
|
+
const bootstrapConfig = document.getElementById('sap-ui-bootstrap');
|
|
37
|
+
const appUrls = bootstrapConfig?.dataset.openUxPreviewLibsManifests;
|
|
38
|
+
const customInit = bootstrapConfig?.dataset.openUxPreviewCustomInit;
|
|
39
|
+
const flex = bootstrapConfig?.dataset.openUxPreviewFlexSettings;
|
|
40
|
+
const baseUrl = bootstrapConfig?.dataset.openUxPreviewBaseUrl ?? '';
|
|
41
|
+
|
|
42
|
+
const urlParams = new URLSearchParams(globalThis.location.search);
|
|
43
|
+
|
|
44
|
+
// For ADP, register the variant's changes namespace locally so flex-change resources
|
|
45
|
+
// (fragments, code extensions) resolve against the dev server instead of the backend.
|
|
46
|
+
if (flex) {
|
|
47
|
+
const flexSettings = JSON.parse(flex) as FlexSettings & { projectId?: string };
|
|
48
|
+
if (flexSettings.projectId) {
|
|
49
|
+
registerAdpChangesResourceRoot(flexSettings.projectId, baseUrl);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (appUrls) {
|
|
54
|
+
await registerComponentDependencyPaths((JSON.parse(appUrls) as string[]) ?? [], urlParams);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (customInit) {
|
|
58
|
+
sap.ui.require([customInit]);
|
|
59
|
+
}
|
|
60
|
+
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -62,6 +62,17 @@ export interface FlpConfig {
|
|
|
62
62
|
* Optional: if set to true then the new FLP homepage will be enabled
|
|
63
63
|
*/
|
|
64
64
|
enhancedHomePage?: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Optional: if set to true, opts in to the new FLP Sandbox when the UI5 version qualifies (>= 1.150).
|
|
67
|
+
* Defaults to false.
|
|
68
|
+
*/
|
|
69
|
+
useNewSandbox?: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Optional: if set to true, the new FLP Sandbox will navigate directly to the app on startup
|
|
72
|
+
* instead of showing the FLP home screen first. Only applies when the new Sandbox is active.
|
|
73
|
+
* Defaults to false.
|
|
74
|
+
*/
|
|
75
|
+
navigateToApp?: boolean;
|
|
65
76
|
}
|
|
66
77
|
/**
|
|
67
78
|
* Configration for the virtual test pages endpoints.
|
|
@@ -244,6 +255,16 @@ export declare const FLPHomePageDefaults: {
|
|
|
244
255
|
catalogId: string;
|
|
245
256
|
sectionId: string;
|
|
246
257
|
};
|
|
258
|
+
export type Ui5Version = {
|
|
259
|
+
major: number;
|
|
260
|
+
minor: number;
|
|
261
|
+
patch: number;
|
|
262
|
+
label?: string;
|
|
263
|
+
/**
|
|
264
|
+
* Indicates if the UI5 version is served from CDN.
|
|
265
|
+
*/
|
|
266
|
+
isCdn: boolean;
|
|
267
|
+
};
|
|
247
268
|
export interface MultiCardsPayload {
|
|
248
269
|
type: string;
|
|
249
270
|
manifest: CardManifest;
|
package/package.json
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"bugs": {
|
|
11
11
|
"url": "https://github.com/SAP/open-ux-tools/issues?q=is%3Aopen+is%3Aissue+label%3Abug+label%3Apreview-middleware"
|
|
12
12
|
},
|
|
13
|
-
"version": "1.
|
|
13
|
+
"version": "1.2.0",
|
|
14
14
|
"license": "Apache-2.0",
|
|
15
15
|
"author": "@SAP/ux-tools-team",
|
|
16
16
|
"main": "dist/index.js",
|
|
@@ -28,12 +28,12 @@
|
|
|
28
28
|
"mem-fs-editor": "9.4.0",
|
|
29
29
|
"qrcode": "1.5.4",
|
|
30
30
|
"@sap/bas-sdk": "3.13.10",
|
|
31
|
-
"@sap-ux/adp-tooling": "1.0.
|
|
31
|
+
"@sap-ux/adp-tooling": "1.0.43",
|
|
32
32
|
"@sap-ux/btp-utils": "2.0.6",
|
|
33
33
|
"@sap-ux/control-property-editor-sources": "npm:@sap-ux/control-property-editor@1.0.10",
|
|
34
34
|
"@sap-ux/feature-toggle": "1.0.5",
|
|
35
|
-
"@sap-ux/project-access": "2.1.10",
|
|
36
35
|
"@sap-ux/logger": "1.0.3",
|
|
36
|
+
"@sap-ux/project-access": "2.1.10",
|
|
37
37
|
"@sap-ux/system-access": "1.0.10",
|
|
38
38
|
"@sap-ux/i18n": "1.0.2"
|
|
39
39
|
},
|
|
@@ -54,11 +54,11 @@
|
|
|
54
54
|
"nock": "14.0.16",
|
|
55
55
|
"npm-run-all2": "9.0.2",
|
|
56
56
|
"supertest": "7.2.2",
|
|
57
|
-
"@private/preview-middleware-client": "npm:@sap-ux-private/preview-middleware-client@1.
|
|
57
|
+
"@private/preview-middleware-client": "npm:@sap-ux-private/preview-middleware-client@1.2.0",
|
|
58
|
+
"@sap-ux-private/playwright": "1.0.6",
|
|
58
59
|
"@sap-ux/axios-extension": "2.0.8",
|
|
59
60
|
"@sap-ux/store": "2.0.6",
|
|
60
|
-
"@sap-ux/ui5-info": "1.0.6"
|
|
61
|
-
"@sap-ux-private/playwright": "1.0.6"
|
|
61
|
+
"@sap-ux/ui5-info": "1.0.6"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
64
|
"express": "4"
|
package/templates/flp/cdm.ejs
CHANGED
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
data-sap-ui-xx-componentPreload="off"<%- ui5.bootstrapOptions %><% if (enableCardGenerator) { %>
|
|
44
44
|
data-open-ux-preview-enable-card-generator="<%- enableCardGenerator %>"
|
|
45
45
|
<% } %>
|
|
46
|
-
data-sap-ui-oninit="module:open/ux/preview/client/flp/
|
|
46
|
+
data-sap-ui-oninit="module:open/ux/preview/client/flp/sandbox1Init"<% if (locals.init) { %>
|
|
47
47
|
data-open-ux-preview-custom-init='<%- init %>'<% } if (locals.flexSettings) { %>
|
|
48
48
|
data-open-ux-preview-features='<%- JSON.stringify(features) %>'
|
|
49
49
|
data-open-ux-preview-flex-settings='<%- JSON.stringify(flexSettings) %>'<% } if (locals.locateReuseLibsScript) { %>
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
data-sap-ui-xx-componentPreload="off"<%- ui5.bootstrapOptions %><% if (enableCardGenerator) { %>
|
|
58
58
|
data-open-ux-preview-enable-card-generator="<%- enableCardGenerator %>"
|
|
59
59
|
<% } %>
|
|
60
|
-
data-sap-ui-oninit="module:open/ux/preview/client/flp/
|
|
60
|
+
data-sap-ui-oninit="module:open/ux/preview/client/flp/sandbox1Init"<% if (locals.init) { %>
|
|
61
61
|
data-open-ux-preview-custom-init='<%- init %>'<% } if (locals.flexSettings) { %>
|
|
62
62
|
data-open-ux-preview-features='<%- JSON.stringify(features) %>'
|
|
63
63
|
data-open-ux-preview-flex-settings='<%- JSON.stringify(flexSettings) %>'<% } if (locals.locateReuseLibsScript) { %>
|
|
@@ -8,63 +8,30 @@
|
|
|
8
8
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
9
9
|
<title>Local FLP Sandbox</title>
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
<% if (ui5.versionMajor === 1) { -%>
|
|
12
|
+
<!-- FLP Sandbox Boot task - registers ConfigurationProvider via xx-bootTask mechanism -->
|
|
13
|
+
<script src="<%- basePath %>/resources/sap/ushell/sandbox/SandboxBootTask.js"></script>
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
The fiori2 renderer will render the shell header allowing, for instance,
|
|
16
|
-
testing of additional application setting buttons.
|
|
17
|
-
|
|
18
|
-
The navigation target resolution service is configured in a way that the empty URL hash is
|
|
19
|
-
resolved to our own application.
|
|
20
|
-
|
|
21
|
-
This example uses relative path references for the SAPUI5 resources and test-resources;
|
|
22
|
-
it might be necessary to adapt them depending on the target runtime platform.
|
|
23
|
-
The sandbox platform is restricted to development or demo use cases and must NOT be used
|
|
24
|
-
for productive scenarios.
|
|
25
|
-
-->
|
|
26
|
-
<script type="text/javascript">
|
|
27
|
-
window["sap-ushell-config"] = {
|
|
28
|
-
defaultRenderer: "fiori2",
|
|
29
|
-
renderers: {
|
|
30
|
-
fiori2: {
|
|
31
|
-
componentData: {
|
|
32
|
-
config: {
|
|
33
|
-
search: "hidden",
|
|
34
|
-
enableSearch: false
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
applications: <%- JSON.stringify(apps) %>
|
|
40
|
-
};
|
|
41
|
-
</script>
|
|
42
|
-
|
|
43
|
-
<script src="<%- basePath %>/resources/sap/ushell/bootstrap/sandbox2.js" id="sap-ushell-bootstrap"></script>
|
|
44
|
-
<!-- Bootstrap the UI5 core library. 'data-sap-ui-frameOptions="allow"' is a NON-SECURE setting for test environments -->
|
|
15
|
+
<% } -%>
|
|
16
|
+
<!-- Bootstrap the UI5 core library. 'data-sap-ui-frame-options="allow"' is a NON-SECURE setting for test environments -->
|
|
45
17
|
<script id="sap-ui-bootstrap"
|
|
46
18
|
src="<%- basePath %>/resources/sap-ui-core.js"
|
|
47
|
-
data-sap-ui-libs="<%- ui5.libs %>"
|
|
48
19
|
data-sap-ui-async="true"
|
|
49
20
|
data-sap-ui-theme="<%- ui5.theme %>"
|
|
50
21
|
data-sap-ui-compat-version="edge"
|
|
51
|
-
data-sap-ui-language="en"
|
|
52
|
-
data-sap-ui-flexibility-services='<%- JSON.stringify(ui5.flex) %>'
|
|
53
22
|
data-sap-ui-resource-roots='<%- JSON.stringify(ui5.resources) %>'
|
|
54
|
-
data-sap-ui-frame-options="allow"
|
|
55
|
-
data-sap-ui-
|
|
23
|
+
data-sap-ui-frame-options="allow"<% if (ui5.versionMajor !== 1) { %>
|
|
24
|
+
data-sap-ui-boot-manifest="sap/ushell/sandbox/sandboxManifest.json"<% } %><%- ui5.bootstrapOptions %><% if (enableCardGenerator) { %>
|
|
56
25
|
data-open-ux-preview-enable-card-generator="<%- enableCardGenerator %>"
|
|
57
|
-
<% } %>
|
|
58
|
-
data-sap-ui-on-init="module:open/ux/preview/client/flp/init"<% if (locals.init) { %>
|
|
26
|
+
<% } %><% if (locals.init) { %>
|
|
59
27
|
data-open-ux-preview-custom-init='<%- init %>'<% } if (locals.flexSettings) { %>
|
|
60
28
|
data-open-ux-preview-features='<%- JSON.stringify(features) %>'
|
|
61
29
|
data-open-ux-preview-flex-settings='<%- JSON.stringify(flexSettings) %>'<% } if (locals.locateReuseLibsScript) { %>
|
|
62
30
|
data-open-ux-preview-libs-manifests='<%- JSON.stringify(Object.values(apps).map(app => app.url)) %>'<% } %>
|
|
63
31
|
data-open-ux-preview-base-url='<%- baseUrl %>'>
|
|
64
32
|
</script>
|
|
65
|
-
|
|
66
33
|
<% if (locals.flexSettings && flexSettings?.developerMode) { %>
|
|
67
|
-
|
|
34
|
+
<!-- Hides Rta native toolbar -->
|
|
68
35
|
<style>
|
|
69
36
|
#shell-header, .sapUiRtaToolbar {
|
|
70
37
|
visibility: hidden;
|
|
@@ -80,7 +47,8 @@
|
|
|
80
47
|
</head>
|
|
81
48
|
|
|
82
49
|
<!-- UI Content -->
|
|
83
|
-
<body class="sapUiBody"
|
|
50
|
+
<body class="sapUiBody">
|
|
51
|
+
<div id="canvas"></div>
|
|
84
52
|
</body>
|
|
85
53
|
|
|
86
|
-
</html>
|
|
54
|
+
</html>
|