@sap-ux/preview-middleware 0.6.2 → 0.7.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/dist/base/flp.d.ts +1 -0
- package/dist/base/flp.js +49 -8
- package/dist/client/adp/controllers/AddFragment.controller.js +1 -27
- package/dist/client/adp/controllers/AddFragment.controller.ts +2 -24
- package/dist/client/cpe/changes/flex-change.js +46 -0
- package/dist/client/cpe/changes/flex-change.ts +49 -0
- package/dist/client/cpe/changes/index.js +12 -0
- package/dist/client/cpe/changes/index.ts +1 -0
- package/dist/client/cpe/changes/service.js +164 -0
- package/dist/client/cpe/changes/service.ts +264 -0
- package/dist/client/cpe/control-data.js +201 -0
- package/dist/client/cpe/control-data.ts +304 -0
- package/dist/client/cpe/documentation.js +166 -0
- package/dist/client/cpe/documentation.ts +166 -0
- package/dist/client/cpe/facade.js +95 -0
- package/dist/client/cpe/facade.ts +95 -0
- package/dist/client/cpe/init.js +62 -12
- package/dist/client/cpe/init.ts +70 -5
- package/dist/client/cpe/logger.js +32 -0
- package/dist/client/cpe/logger.ts +26 -0
- package/dist/client/cpe/outline/index.js +26 -0
- package/dist/client/cpe/outline/index.ts +34 -0
- package/dist/client/cpe/outline/nodes.js +58 -0
- package/dist/client/cpe/outline/nodes.ts +52 -0
- package/dist/client/cpe/outline/utils.js +38 -0
- package/dist/client/cpe/outline/utils.ts +29 -0
- package/dist/client/cpe/selection.js +169 -0
- package/dist/client/cpe/selection.ts +237 -0
- package/dist/client/cpe/types.js +6 -0
- package/dist/client/cpe/types.ts +53 -0
- package/dist/client/cpe/utils.js +50 -0
- package/dist/client/cpe/utils.ts +62 -0
- package/dist/client/flp/WorkspaceConnector.js +65 -0
- package/dist/client/flp/WorkspaceConnector.ts +66 -0
- package/dist/client/thirdparty/@sap-ux-private/control-property-editor-common.js +272 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/ui5/middleware.js +20 -1
- package/package.json +4 -3
- package/templates/flp/editor.html +11 -15
- package/templates/flp/sandbox.html +2 -1
- package/templates/flp/workspaceConnector.js +0 -76
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
sap.ui.define(["sap/ui/core/Component", "sap/ui/dt/OverlayRegistry", "sap/ui/dt/OverlayUtil", "sap/ui/core/IconPool"], function (Component, OverlayRegistry, OverlayUtil, IconPool) {
|
|
4
|
+
"use strict";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Gets control by id.
|
|
8
|
+
*
|
|
9
|
+
* @param id unique identifier for control
|
|
10
|
+
* @returns Element | undefined
|
|
11
|
+
*/
|
|
12
|
+
function getControlById(id) {
|
|
13
|
+
return sap.ui.getCore().byId(id);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Gets Component by id.
|
|
18
|
+
*
|
|
19
|
+
* @param id - unique identifier for control
|
|
20
|
+
* @returns Component | undefined
|
|
21
|
+
*/
|
|
22
|
+
function getComponent(id) {
|
|
23
|
+
if (Component?.get) {
|
|
24
|
+
return Component.get(id);
|
|
25
|
+
} else {
|
|
26
|
+
// Older version must be still supported until maintenance period.
|
|
27
|
+
return sap.ui.getCore().getComponent(id); // NOSONAR
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Gets overlay for control.
|
|
33
|
+
*
|
|
34
|
+
* @param control ui5 control
|
|
35
|
+
* @returns ElementOverlay | undefined
|
|
36
|
+
*/
|
|
37
|
+
function getOverlay(control) {
|
|
38
|
+
return OverlayRegistry.getOverlay(control);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Gets ClosestOverlay for control.
|
|
43
|
+
*
|
|
44
|
+
* @param control ui5 control
|
|
45
|
+
* @returns ElementOverlay | undefined
|
|
46
|
+
*/
|
|
47
|
+
function getClosestOverlayFor(control) {
|
|
48
|
+
return OverlayUtil.getClosestOverlayFor(control);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Get ui5 icons.
|
|
53
|
+
*
|
|
54
|
+
* @returns IconDetails[]
|
|
55
|
+
*/
|
|
56
|
+
function getIcons() {
|
|
57
|
+
return IconPool.getIconNames('undefined').map(icon => {
|
|
58
|
+
const iconInfo = IconPool.getIconInfo(icon);
|
|
59
|
+
return {
|
|
60
|
+
name: icon.toLowerCase(),
|
|
61
|
+
content: iconInfo.content,
|
|
62
|
+
fontFamily: iconInfo.fontFamily
|
|
63
|
+
};
|
|
64
|
+
}).sort((item1, item2) => {
|
|
65
|
+
if (item1.name < item2.name) {
|
|
66
|
+
return -1;
|
|
67
|
+
}
|
|
68
|
+
if (item1.name > item2.name) {
|
|
69
|
+
return 1;
|
|
70
|
+
}
|
|
71
|
+
return 0;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* A facade for UI5 framework methods.
|
|
77
|
+
*
|
|
78
|
+
* @returns UI5Facade
|
|
79
|
+
*/
|
|
80
|
+
function createUi5Facade() {
|
|
81
|
+
return {
|
|
82
|
+
getControlById,
|
|
83
|
+
getIcons,
|
|
84
|
+
getComponent,
|
|
85
|
+
getOverlay,
|
|
86
|
+
getClosestOverlayFor
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
var __exports = {
|
|
90
|
+
__esModule: true
|
|
91
|
+
};
|
|
92
|
+
__exports.createUi5Facade = createUi5Facade;
|
|
93
|
+
return __exports;
|
|
94
|
+
});
|
|
95
|
+
//# sourceMappingURL=facade.js.map
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type { IconDetails } from '@sap-ux-private/control-property-editor-common';
|
|
2
|
+
import type { UI5Facade } from './types';
|
|
3
|
+
import Component from 'sap/ui/core/Component';
|
|
4
|
+
import type Element from 'sap/ui/core/Element';
|
|
5
|
+
import type ElementOverlay from 'sap/ui/dt/ElementOverlay';
|
|
6
|
+
import type { ID } from 'sap/ui/core/library';
|
|
7
|
+
import OverlayRegistry from 'sap/ui/dt/OverlayRegistry';
|
|
8
|
+
import OverlayUtil from 'sap/ui/dt/OverlayUtil';
|
|
9
|
+
import IconPool from 'sap/ui/core/IconPool';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Gets control by id.
|
|
13
|
+
*
|
|
14
|
+
* @param id unique identifier for control
|
|
15
|
+
* @returns Element | undefined
|
|
16
|
+
*/
|
|
17
|
+
function getControlById<T extends Element>(id: ID): T | undefined {
|
|
18
|
+
return sap.ui.getCore().byId(id) as T;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Gets Component by id.
|
|
23
|
+
*
|
|
24
|
+
* @param id - unique identifier for control
|
|
25
|
+
* @returns Component | undefined
|
|
26
|
+
*/
|
|
27
|
+
function getComponent<T extends Component>(id: ID): T | undefined {
|
|
28
|
+
if (Component?.get) {
|
|
29
|
+
return Component.get(id) as T;
|
|
30
|
+
} else {
|
|
31
|
+
// Older version must be still supported until maintenance period.
|
|
32
|
+
return sap.ui.getCore().getComponent(id) as T; // NOSONAR
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Gets overlay for control.
|
|
38
|
+
*
|
|
39
|
+
* @param control ui5 control
|
|
40
|
+
* @returns ElementOverlay | undefined
|
|
41
|
+
*/
|
|
42
|
+
function getOverlay<T extends ElementOverlay>(control: Element): T | undefined {
|
|
43
|
+
return OverlayRegistry.getOverlay(control) as T;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Gets ClosestOverlay for control.
|
|
48
|
+
*
|
|
49
|
+
* @param control ui5 control
|
|
50
|
+
* @returns ElementOverlay | undefined
|
|
51
|
+
*/
|
|
52
|
+
function getClosestOverlayFor<T extends ElementOverlay>(control: Element): T | undefined {
|
|
53
|
+
return OverlayUtil.getClosestOverlayFor(control) as T;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Get ui5 icons.
|
|
58
|
+
*
|
|
59
|
+
* @returns IconDetails[]
|
|
60
|
+
*/
|
|
61
|
+
function getIcons(): IconDetails[] {
|
|
62
|
+
return IconPool.getIconNames('undefined')
|
|
63
|
+
.map((icon: string) => {
|
|
64
|
+
const iconInfo = IconPool.getIconInfo(icon) as IconDetails;
|
|
65
|
+
return {
|
|
66
|
+
name: icon.toLowerCase(),
|
|
67
|
+
content: iconInfo.content,
|
|
68
|
+
fontFamily: iconInfo.fontFamily
|
|
69
|
+
} as IconDetails;
|
|
70
|
+
})
|
|
71
|
+
.sort((item1: IconDetails, item2: IconDetails) => {
|
|
72
|
+
if (item1.name < item2.name) {
|
|
73
|
+
return -1;
|
|
74
|
+
}
|
|
75
|
+
if (item1.name > item2.name) {
|
|
76
|
+
return 1;
|
|
77
|
+
}
|
|
78
|
+
return 0;
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* A facade for UI5 framework methods.
|
|
84
|
+
*
|
|
85
|
+
* @returns UI5Facade
|
|
86
|
+
*/
|
|
87
|
+
export function createUi5Facade(): UI5Facade {
|
|
88
|
+
return {
|
|
89
|
+
getControlById,
|
|
90
|
+
getIcons,
|
|
91
|
+
getComponent,
|
|
92
|
+
getOverlay,
|
|
93
|
+
getClosestOverlayFor
|
|
94
|
+
};
|
|
95
|
+
}
|
package/dist/client/cpe/init.js
CHANGED
|
@@ -1,12 +1,62 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
sap
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
sap.ui.define([
|
|
3
|
+
'open/ux/preview/client/thirdparty/@sap-ux-private/control-property-editor-common',
|
|
4
|
+
'./outline/index',
|
|
5
|
+
'./facade',
|
|
6
|
+
'./selection',
|
|
7
|
+
'./changes/service',
|
|
8
|
+
'./documentation',
|
|
9
|
+
'sap/base/Log',
|
|
10
|
+
'./logger'
|
|
11
|
+
], function (___sap_ux_private_control_property_editor_common, ___outline_index, ___facade, ___selection, ___changes_service, ___documentation, Log, ___logger) {
|
|
12
|
+
'use strict';
|
|
13
|
+
const startPostMessageCommunication = ___sap_ux_private_control_property_editor_common['startPostMessageCommunication'];
|
|
14
|
+
const iconsLoaded = ___sap_ux_private_control_property_editor_common['iconsLoaded'];
|
|
15
|
+
const enableTelemetry = ___sap_ux_private_control_property_editor_common['enableTelemetry'];
|
|
16
|
+
const initOutline = ___outline_index['initOutline'];
|
|
17
|
+
const createUi5Facade = ___facade['createUi5Facade'];
|
|
18
|
+
const SelectionService = ___selection['SelectionService'];
|
|
19
|
+
const ChangeService = ___changes_service['ChangeService'];
|
|
20
|
+
const loadDefaultLibraries = ___documentation['loadDefaultLibraries'];
|
|
21
|
+
const logger = ___logger['logger'];
|
|
22
|
+
function init(rta) {
|
|
23
|
+
Log.info('Initializing Control Property Editor');
|
|
24
|
+
const flexSettings = rta.getFlexSettings();
|
|
25
|
+
if (flexSettings.telemetry === true) {
|
|
26
|
+
enableTelemetry();
|
|
27
|
+
}
|
|
28
|
+
const ui5 = createUi5Facade();
|
|
29
|
+
const actionHandlers = [];
|
|
30
|
+
function subscribe(handler) {
|
|
31
|
+
actionHandlers.push(handler);
|
|
32
|
+
}
|
|
33
|
+
const selectionService = new SelectionService(rta, ui5);
|
|
34
|
+
const changesService = new ChangeService({ rta }, ui5, selectionService);
|
|
35
|
+
const services = [
|
|
36
|
+
selectionService,
|
|
37
|
+
changesService
|
|
38
|
+
];
|
|
39
|
+
try {
|
|
40
|
+
loadDefaultLibraries();
|
|
41
|
+
const {sendAction} = startPostMessageCommunication(window.parent, async function onAction(action) {
|
|
42
|
+
for (const handler of actionHandlers) {
|
|
43
|
+
try {
|
|
44
|
+
await handler(action);
|
|
45
|
+
} catch (error) {
|
|
46
|
+
Log.error('Handler Failed: ', error);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}, logger);
|
|
50
|
+
for (const service of services) {
|
|
51
|
+
service.init(sendAction, subscribe);
|
|
52
|
+
}
|
|
53
|
+
initOutline(rta, ui5, sendAction).catch(error => Log.error('Error during initialization of Control Property Editor', error));
|
|
54
|
+
const icons = ui5.getIcons();
|
|
55
|
+
sendAction(iconsLoaded(icons));
|
|
56
|
+
} catch (error) {
|
|
57
|
+
Log.error('Error during initialization of Control Property Editor', error);
|
|
58
|
+
}
|
|
59
|
+
return Promise.resolve();
|
|
60
|
+
}
|
|
61
|
+
return init;
|
|
62
|
+
});
|
package/dist/client/cpe/init.ts
CHANGED
|
@@ -1,7 +1,72 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { ExternalAction } from '@sap-ux-private/control-property-editor-common';
|
|
2
|
+
import {
|
|
3
|
+
startPostMessageCommunication,
|
|
4
|
+
iconsLoaded,
|
|
5
|
+
enableTelemetry
|
|
6
|
+
} from '@sap-ux-private/control-property-editor-common';
|
|
2
7
|
import type RuntimeAuthoring from 'sap/ui/rta/RuntimeAuthoring';
|
|
3
8
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
9
|
+
import type { ActionHandler, Service } from './types';
|
|
10
|
+
import { initOutline } from './outline/index';
|
|
11
|
+
import { createUi5Facade } from './facade';
|
|
12
|
+
import { SelectionService } from './selection';
|
|
13
|
+
import { ChangeService } from './changes/service';
|
|
14
|
+
import { loadDefaultLibraries } from './documentation';
|
|
15
|
+
import Log from 'sap/base/Log';
|
|
16
|
+
import { logger } from './logger';
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
export default function init(rta: RuntimeAuthoring): Promise<void> {
|
|
20
|
+
Log.info('Initializing Control Property Editor');
|
|
21
|
+
|
|
22
|
+
// enable telemetry if requested
|
|
23
|
+
const flexSettings = rta.getFlexSettings();
|
|
24
|
+
if (flexSettings.telemetry === true) {
|
|
25
|
+
enableTelemetry();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const ui5 = createUi5Facade();
|
|
29
|
+
const actionHandlers: ActionHandler[] = [];
|
|
30
|
+
/**
|
|
31
|
+
*
|
|
32
|
+
* @param handler action handler
|
|
33
|
+
*/
|
|
34
|
+
function subscribe(handler: ActionHandler): void {
|
|
35
|
+
actionHandlers.push(handler);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const selectionService = new SelectionService(rta, ui5);
|
|
39
|
+
|
|
40
|
+
const changesService = new ChangeService({ rta }, ui5, selectionService);
|
|
41
|
+
const services: Service[] = [selectionService, changesService];
|
|
42
|
+
try {
|
|
43
|
+
loadDefaultLibraries();
|
|
44
|
+
const { sendAction } = startPostMessageCommunication<ExternalAction>(
|
|
45
|
+
window.parent,
|
|
46
|
+
async function onAction(action) {
|
|
47
|
+
for (const handler of actionHandlers) {
|
|
48
|
+
try {
|
|
49
|
+
await handler(action);
|
|
50
|
+
} catch (error) {
|
|
51
|
+
Log.error('Handler Failed: ', error);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
logger
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
for (const service of services) {
|
|
59
|
+
service.init(sendAction, subscribe);
|
|
60
|
+
}
|
|
61
|
+
// For initOutline to complete the RTA needs to already running (to access RTA provided services).
|
|
62
|
+
// That can only happen if the plugin initialization has completed.
|
|
63
|
+
initOutline(rta, ui5, sendAction).catch((error) =>
|
|
64
|
+
Log.error('Error during initialization of Control Property Editor', error)
|
|
65
|
+
);
|
|
66
|
+
const icons = ui5.getIcons();
|
|
67
|
+
sendAction(iconsLoaded(icons));
|
|
68
|
+
} catch (error) {
|
|
69
|
+
Log.error('Error during initialization of Control Property Editor', error);
|
|
70
|
+
}
|
|
71
|
+
return Promise.resolve();
|
|
72
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
sap.ui.define(["sap/base/Log"], function (Log) {
|
|
4
|
+
"use strict";
|
|
5
|
+
|
|
6
|
+
function getString(message) {
|
|
7
|
+
if (typeof message === 'object') {
|
|
8
|
+
return message.toString();
|
|
9
|
+
}
|
|
10
|
+
return message;
|
|
11
|
+
}
|
|
12
|
+
const logger = {
|
|
13
|
+
info: message => {
|
|
14
|
+
Log.info(getString(message));
|
|
15
|
+
},
|
|
16
|
+
debug: message => {
|
|
17
|
+
Log.debug(getString(message));
|
|
18
|
+
},
|
|
19
|
+
warn: message => {
|
|
20
|
+
Log.warning(getString(message));
|
|
21
|
+
},
|
|
22
|
+
error: message => {
|
|
23
|
+
Log.error(getString(message));
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
var __exports = {
|
|
27
|
+
__esModule: true
|
|
28
|
+
};
|
|
29
|
+
__exports.logger = logger;
|
|
30
|
+
return __exports;
|
|
31
|
+
});
|
|
32
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import Log from 'sap/base/Log';
|
|
2
|
+
import { Logger } from '@sap-ux-private/control-property-editor-common';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
function getString(message: string | object): string {
|
|
6
|
+
if (typeof message === 'object') {
|
|
7
|
+
return message.toString();
|
|
8
|
+
}
|
|
9
|
+
return message;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const logger: Logger = {
|
|
13
|
+
info: (message: string | object) => {
|
|
14
|
+
Log.info(getString(message));
|
|
15
|
+
},
|
|
16
|
+
debug: (message: string | object) => {
|
|
17
|
+
Log.debug(getString(message));
|
|
18
|
+
},
|
|
19
|
+
warn: (message: string | object) => {
|
|
20
|
+
Log.warning(getString(message));
|
|
21
|
+
},
|
|
22
|
+
error: (message: string | object) => {
|
|
23
|
+
Log.error(getString(message));
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
sap.ui.define([
|
|
3
|
+
'open/ux/preview/client/thirdparty/@sap-ux-private/control-property-editor-common',
|
|
4
|
+
'./nodes',
|
|
5
|
+
'sap/base/Log'
|
|
6
|
+
], function (___sap_ux_private_control_property_editor_common, ___nodes, Log) {
|
|
7
|
+
'use strict';
|
|
8
|
+
const outlineChanged = ___sap_ux_private_control_property_editor_common['outlineChanged'];
|
|
9
|
+
const transformNodes = ___nodes['transformNodes'];
|
|
10
|
+
async function initOutline(rta, ui5, sendAction) {
|
|
11
|
+
const outline = await rta.getService('outline');
|
|
12
|
+
async function syncOutline() {
|
|
13
|
+
try {
|
|
14
|
+
const viewNodes = await outline.get();
|
|
15
|
+
const outlineNodes = await transformNodes(ui5, viewNodes);
|
|
16
|
+
sendAction(outlineChanged(outlineNodes));
|
|
17
|
+
} catch (error) {
|
|
18
|
+
Log.error('Outline sync failed!', error);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
outline.attachEvent('update', syncOutline);
|
|
22
|
+
}
|
|
23
|
+
var __exports = { __esModule: true };
|
|
24
|
+
__exports.initOutline = initOutline;
|
|
25
|
+
return __exports;
|
|
26
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ExternalAction } from '@sap-ux-private/control-property-editor-common';
|
|
2
|
+
import { outlineChanged } from '@sap-ux-private/control-property-editor-common';
|
|
3
|
+
|
|
4
|
+
import type RuntimeAuthoring from 'sap/ui/rta/RuntimeAuthoring';
|
|
5
|
+
import type OutlineService from 'sap/ui/rta/command/OutlineService';
|
|
6
|
+
|
|
7
|
+
import type { UI5Facade } from '../types';
|
|
8
|
+
import { transformNodes } from './nodes';
|
|
9
|
+
import Log from 'sap/base/Log';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
*
|
|
13
|
+
* @param rta runtimeAuthoring object.
|
|
14
|
+
* @param ui5 - facade for ui5 framework methods
|
|
15
|
+
* @param sendAction send action method.
|
|
16
|
+
*/
|
|
17
|
+
export async function initOutline(
|
|
18
|
+
rta: RuntimeAuthoring,
|
|
19
|
+
ui5: UI5Facade,
|
|
20
|
+
sendAction: (action: ExternalAction) => void
|
|
21
|
+
): Promise<void> {
|
|
22
|
+
const outline = await rta.getService<OutlineService>('outline');
|
|
23
|
+
async function syncOutline() {
|
|
24
|
+
try {
|
|
25
|
+
const viewNodes = await outline.get();
|
|
26
|
+
const outlineNodes = await transformNodes(ui5, viewNodes);
|
|
27
|
+
|
|
28
|
+
sendAction(outlineChanged(outlineNodes));
|
|
29
|
+
} catch (error) {
|
|
30
|
+
Log.error('Outline sync failed!', error);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
outline.attachEvent('update', syncOutline);
|
|
34
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
sap.ui.define(["./utils"], function (___utils) {
|
|
4
|
+
"use strict";
|
|
5
|
+
|
|
6
|
+
const isEditable = ___utils["isEditable"];
|
|
7
|
+
function getAdditionalData(ui5, id) {
|
|
8
|
+
const control = ui5.getControlById(id);
|
|
9
|
+
if (control?.getMetadata().getProperty('text')) {
|
|
10
|
+
const text = control.getProperty('text');
|
|
11
|
+
if (typeof text === 'string' && text.trim() !== '') {
|
|
12
|
+
return {
|
|
13
|
+
text
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return {};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Transform node.
|
|
22
|
+
*
|
|
23
|
+
* @param ui5 - facade for ui5 framework methods
|
|
24
|
+
* @param input outline view node
|
|
25
|
+
* @param getAdditionalData gets additional data for give control id.
|
|
26
|
+
* @returns Promise<OutlineNode[]>
|
|
27
|
+
*/
|
|
28
|
+
async function transformNodes(ui5, input) {
|
|
29
|
+
const stack = [...input];
|
|
30
|
+
const items = [];
|
|
31
|
+
while (stack.length) {
|
|
32
|
+
const current = stack.shift();
|
|
33
|
+
const editable = await isEditable(ui5, current?.id);
|
|
34
|
+
if (current?.type === 'element') {
|
|
35
|
+
const children = (current.elements ?? []).flatMap(element => element.type === 'aggregation' ? element.elements ?? [] : []);
|
|
36
|
+
const {
|
|
37
|
+
text
|
|
38
|
+
} = getAdditionalData(ui5, current.id);
|
|
39
|
+
const node = {
|
|
40
|
+
controlId: current.id,
|
|
41
|
+
controlType: current.technicalName,
|
|
42
|
+
name: text ?? current.technicalName.split('.').slice(-1)[0],
|
|
43
|
+
editable,
|
|
44
|
+
visible: current.visible ?? true,
|
|
45
|
+
children: await transformNodes(ui5, children)
|
|
46
|
+
};
|
|
47
|
+
items.push(node);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return items;
|
|
51
|
+
}
|
|
52
|
+
var __exports = {
|
|
53
|
+
__esModule: true
|
|
54
|
+
};
|
|
55
|
+
__exports.transformNodes = transformNodes;
|
|
56
|
+
return __exports;
|
|
57
|
+
});
|
|
58
|
+
//# sourceMappingURL=nodes.js.map
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { OutlineNode } from '@sap-ux-private/control-property-editor-common';
|
|
2
|
+
import { isEditable } from './utils';
|
|
3
|
+
import type { OutlineViewNode } from 'sap/ui/rta/command/OutlineService';
|
|
4
|
+
import { UI5Facade } from '../types';
|
|
5
|
+
|
|
6
|
+
function getAdditionalData(ui5: UI5Facade, id: string): { text?: string } {
|
|
7
|
+
const control = ui5.getControlById(id);
|
|
8
|
+
if (control?.getMetadata().getProperty('text')) {
|
|
9
|
+
const text = control.getProperty('text');
|
|
10
|
+
if (typeof text === 'string' && text.trim() !== '') {
|
|
11
|
+
return {
|
|
12
|
+
text
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return {};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Transform node.
|
|
21
|
+
*
|
|
22
|
+
* @param ui5 - facade for ui5 framework methods
|
|
23
|
+
* @param input outline view node
|
|
24
|
+
* @param getAdditionalData gets additional data for give control id.
|
|
25
|
+
* @returns Promise<OutlineNode[]>
|
|
26
|
+
*/
|
|
27
|
+
export async function transformNodes(ui5: UI5Facade, input: OutlineViewNode[]): Promise<OutlineNode[]> {
|
|
28
|
+
const stack = [...input];
|
|
29
|
+
const items: OutlineNode[] = [];
|
|
30
|
+
while (stack.length) {
|
|
31
|
+
const current = stack.shift();
|
|
32
|
+
const editable = await isEditable(ui5, current?.id);
|
|
33
|
+
if (current?.type === 'element') {
|
|
34
|
+
const children = (current.elements ?? []).flatMap((element: OutlineViewNode) =>
|
|
35
|
+
element.type === 'aggregation' ? element.elements ?? [] : []
|
|
36
|
+
);
|
|
37
|
+
const { text } = getAdditionalData(ui5, current.id);
|
|
38
|
+
|
|
39
|
+
const node: OutlineNode = {
|
|
40
|
+
controlId: current.id,
|
|
41
|
+
controlType: current.technicalName,
|
|
42
|
+
name: text ?? current.technicalName.split('.').slice(-1)[0],
|
|
43
|
+
editable,
|
|
44
|
+
visible: current.visible ?? true,
|
|
45
|
+
children: await transformNodes(ui5, children)
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
items.push(node);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return items;
|
|
52
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
sap.ui.define(["../control-data", "../utils", "sap/ui/dt/OverlayUtil", "sap/ui/dt/OverlayRegistry"], function (___control_data, ___utils, OverlayUtil, OverlayRegistry) {
|
|
4
|
+
"use strict";
|
|
5
|
+
|
|
6
|
+
const buildControlData = ___control_data["buildControlData"];
|
|
7
|
+
const getRuntimeControl = ___utils["getRuntimeControl"];
|
|
8
|
+
const isEditable = function (ui5) {
|
|
9
|
+
let id = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
|
|
10
|
+
let editable = false;
|
|
11
|
+
const control = ui5.getControlById(id);
|
|
12
|
+
if (!control) {
|
|
13
|
+
const component = ui5.getComponent(id);
|
|
14
|
+
if (component) {
|
|
15
|
+
return editable;
|
|
16
|
+
}
|
|
17
|
+
} else {
|
|
18
|
+
let controlOverlay = OverlayRegistry.getOverlay(control);
|
|
19
|
+
if (!controlOverlay?.getDomRef()) {
|
|
20
|
+
//look for closest control
|
|
21
|
+
controlOverlay = OverlayUtil.getClosestOverlayFor(control);
|
|
22
|
+
}
|
|
23
|
+
if (controlOverlay) {
|
|
24
|
+
const runtimeControl = getRuntimeControl(controlOverlay);
|
|
25
|
+
const controlData = buildControlData(runtimeControl, controlOverlay);
|
|
26
|
+
const prop = controlData.properties.find(item => item.isEnabled === true);
|
|
27
|
+
editable = prop !== undefined;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return editable;
|
|
31
|
+
};
|
|
32
|
+
var __exports = {
|
|
33
|
+
__esModule: true
|
|
34
|
+
};
|
|
35
|
+
__exports.isEditable = isEditable;
|
|
36
|
+
return __exports;
|
|
37
|
+
});
|
|
38
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { buildControlData } from '../control-data';
|
|
2
|
+
import { getRuntimeControl } from '../utils';
|
|
3
|
+
import OverlayUtil from 'sap/ui/dt/OverlayUtil';
|
|
4
|
+
import OverlayRegistry from 'sap/ui/dt/OverlayRegistry';
|
|
5
|
+
import type { UI5Facade } from '../types';
|
|
6
|
+
|
|
7
|
+
export const isEditable = (ui5: UI5Facade, id = ''): boolean => {
|
|
8
|
+
let editable = false;
|
|
9
|
+
const control = ui5.getControlById(id);
|
|
10
|
+
if (!control) {
|
|
11
|
+
const component = ui5.getComponent(id);
|
|
12
|
+
if (component) {
|
|
13
|
+
return editable;
|
|
14
|
+
}
|
|
15
|
+
} else {
|
|
16
|
+
let controlOverlay = OverlayRegistry.getOverlay(control);
|
|
17
|
+
if (!controlOverlay?.getDomRef()) {
|
|
18
|
+
//look for closest control
|
|
19
|
+
controlOverlay = OverlayUtil.getClosestOverlayFor(control);
|
|
20
|
+
}
|
|
21
|
+
if (controlOverlay) {
|
|
22
|
+
const runtimeControl = getRuntimeControl(controlOverlay);
|
|
23
|
+
const controlData = buildControlData(runtimeControl, controlOverlay);
|
|
24
|
+
const prop = controlData.properties.find((item) => item.isEnabled === true);
|
|
25
|
+
editable = prop !== undefined;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return editable;
|
|
29
|
+
};
|