@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.
Files changed (41) hide show
  1. package/dist/base/flp.d.ts +1 -0
  2. package/dist/base/flp.js +49 -8
  3. package/dist/client/adp/controllers/AddFragment.controller.js +1 -27
  4. package/dist/client/adp/controllers/AddFragment.controller.ts +2 -24
  5. package/dist/client/cpe/changes/flex-change.js +46 -0
  6. package/dist/client/cpe/changes/flex-change.ts +49 -0
  7. package/dist/client/cpe/changes/index.js +12 -0
  8. package/dist/client/cpe/changes/index.ts +1 -0
  9. package/dist/client/cpe/changes/service.js +164 -0
  10. package/dist/client/cpe/changes/service.ts +264 -0
  11. package/dist/client/cpe/control-data.js +201 -0
  12. package/dist/client/cpe/control-data.ts +304 -0
  13. package/dist/client/cpe/documentation.js +166 -0
  14. package/dist/client/cpe/documentation.ts +166 -0
  15. package/dist/client/cpe/facade.js +95 -0
  16. package/dist/client/cpe/facade.ts +95 -0
  17. package/dist/client/cpe/init.js +62 -12
  18. package/dist/client/cpe/init.ts +70 -5
  19. package/dist/client/cpe/logger.js +32 -0
  20. package/dist/client/cpe/logger.ts +26 -0
  21. package/dist/client/cpe/outline/index.js +26 -0
  22. package/dist/client/cpe/outline/index.ts +34 -0
  23. package/dist/client/cpe/outline/nodes.js +58 -0
  24. package/dist/client/cpe/outline/nodes.ts +52 -0
  25. package/dist/client/cpe/outline/utils.js +38 -0
  26. package/dist/client/cpe/outline/utils.ts +29 -0
  27. package/dist/client/cpe/selection.js +169 -0
  28. package/dist/client/cpe/selection.ts +237 -0
  29. package/dist/client/cpe/types.js +6 -0
  30. package/dist/client/cpe/types.ts +53 -0
  31. package/dist/client/cpe/utils.js +50 -0
  32. package/dist/client/cpe/utils.ts +62 -0
  33. package/dist/client/flp/WorkspaceConnector.js +65 -0
  34. package/dist/client/flp/WorkspaceConnector.ts +66 -0
  35. package/dist/client/thirdparty/@sap-ux-private/control-property-editor-common.js +272 -0
  36. package/dist/types/index.d.ts +4 -0
  37. package/dist/ui5/middleware.js +20 -1
  38. package/package.json +4 -3
  39. package/templates/flp/editor.html +11 -15
  40. package/templates/flp/sandbox.html +2 -1
  41. package/templates/flp/workspaceConnector.js +0 -76
@@ -0,0 +1,169 @@
1
+ 'use strict';
2
+ sap.ui.define([
3
+ 'open/ux/preview/client/thirdparty/@sap-ux-private/control-property-editor-common',
4
+ './control-data',
5
+ './utils',
6
+ 'sap/base/Log',
7
+ './documentation'
8
+ ], function (___sap_ux_private_control_property_editor_common, ___control_data, ___utils, Log, ___documentation) {
9
+ 'use strict';
10
+ const controlSelected = ___sap_ux_private_control_property_editor_common['controlSelected'];
11
+ const propertyChanged = ___sap_ux_private_control_property_editor_common['propertyChanged'];
12
+ const selectControl = ___sap_ux_private_control_property_editor_common['selectControl'];
13
+ const reportTelemetry = ___sap_ux_private_control_property_editor_common['reportTelemetry'];
14
+ const buildControlData = ___control_data['buildControlData'];
15
+ const getRuntimeControl = ___utils['getRuntimeControl'];
16
+ const getDocumentation = ___documentation['getDocumentation'];
17
+ function propertyChangeId(controlId, propertyName) {
18
+ return [
19
+ controlId,
20
+ propertyName
21
+ ].join(',');
22
+ }
23
+ function getPropertyDocument(property, ui5Type, document) {
24
+ return document?.[property.name] ? document[property.name] : {
25
+ defaultValue: property.defaultValue ?? '-',
26
+ description: '',
27
+ propertyName: property.name,
28
+ type: ui5Type ?? '-',
29
+ propertyType: ui5Type ?? '-'
30
+ };
31
+ }
32
+ async function addDocumentationForProperties(control, controlData) {
33
+ try {
34
+ const controlMetadata = control.getMetadata();
35
+ const allProperties = controlMetadata.getAllProperties();
36
+ const selectedControlName = controlMetadata.getName();
37
+ const selContLibName = controlMetadata.getLibraryName();
38
+ const document = await getDocumentation(selectedControlName, selContLibName);
39
+ controlData.properties.forEach(controlProp => {
40
+ const property = allProperties[controlProp.name];
41
+ controlProp.documentation = getPropertyDocument(property, controlProp.ui5Type, document);
42
+ });
43
+ } catch (e) {
44
+ Log.error('Document loading failed', e);
45
+ }
46
+ }
47
+ class SelectionService {
48
+ appliedChangeCache = new Map();
49
+ activeChangeHandlers = new Set();
50
+ constructor(rta, ui5) {
51
+ this.rta = rta;
52
+ this.ui5 = ui5;
53
+ }
54
+ async init(sendAction, subscribe) {
55
+ const eventOrigin = new Set();
56
+ const onselectionChange = this.createOnSelectionChangeHandler(sendAction, eventOrigin);
57
+ this.rta.attachSelectionChange(event => {
58
+ onselectionChange(event).catch(error => Log.error('Event interrupted: ', error));
59
+ });
60
+ subscribe(async action => {
61
+ if (selectControl.match(action)) {
62
+ const id = action.payload;
63
+ const control = this.ui5.getControlById(id);
64
+ if (!control) {
65
+ const component = this.ui5.getComponent(id);
66
+ if (component) {
67
+ const controlData = buildControlData(component);
68
+ await addDocumentationForProperties(component, controlData);
69
+ const controlSelectedAction = controlSelected(controlData);
70
+ sendAction(controlSelectedAction);
71
+ }
72
+ return;
73
+ }
74
+ eventOrigin.add('outline');
75
+ let controlOverlay = this.ui5.getOverlay(control);
76
+ const selectedOverlayControls = this.rta.getSelection() ?? [];
77
+ for (const selectedOverlayControl of selectedOverlayControls) {
78
+ selectedOverlayControl.setSelected(false);
79
+ }
80
+ if (!controlOverlay?.getDomRef()) {
81
+ controlOverlay = this.ui5.getClosestOverlayFor(control);
82
+ }
83
+ if (controlOverlay?.isSelectable()) {
84
+ controlOverlay.setSelected(true);
85
+ } else {
86
+ const controlData = buildControlData(control);
87
+ await addDocumentationForProperties(control, controlData);
88
+ const controlSelectedAction = controlSelected(controlData);
89
+ sendAction(controlSelectedAction);
90
+ }
91
+ }
92
+ });
93
+ }
94
+ applyControlPropertyChange(controlId, propertyName) {
95
+ const changeId = propertyChangeId(controlId, propertyName);
96
+ this.appliedChangeCache.set(changeId, Date.now());
97
+ }
98
+ createOnSelectionChangeHandler(sendAction, eventOrigin) {
99
+ return async event => {
100
+ const selection = event.getParameter('selection');
101
+ for (const dispose of this.activeChangeHandlers) {
102
+ dispose();
103
+ }
104
+ this.activeChangeHandlers.clear();
105
+ if (Array.isArray(selection) && selection.length === 1) {
106
+ const overlayControl = this.ui5.getControlById(selection[0].getId());
107
+ if (overlayControl) {
108
+ const runtimeControl = getRuntimeControl(overlayControl);
109
+ const controlName = runtimeControl.getMetadata().getName();
110
+ this.handlePropertyChanges(runtimeControl, sendAction);
111
+ try {
112
+ const isOutline = eventOrigin.has('outline');
113
+ const name = controlName.toLowerCase().startsWith('sap') ? controlName : 'Other Control Types';
114
+ if (isOutline) {
115
+ reportTelemetry({
116
+ category: 'Outline Selection',
117
+ controlName: name
118
+ });
119
+ } else {
120
+ reportTelemetry({
121
+ category: 'Overlay Selection',
122
+ controlName: name
123
+ });
124
+ }
125
+ } catch (error) {
126
+ Log.error('Failed to report telemetry', error);
127
+ } finally {
128
+ const controlData = buildControlData(runtimeControl, overlayControl);
129
+ await addDocumentationForProperties(runtimeControl, controlData);
130
+ const action = controlSelected(controlData);
131
+ sendAction(action);
132
+ eventOrigin.delete('outline');
133
+ }
134
+ }
135
+ }
136
+ };
137
+ }
138
+ handlePropertyChanges(runtimeControl, sendAction) {
139
+ const handler = e => {
140
+ const propertyName = e.getParameter('name');
141
+ const controlId = e.getParameter('id');
142
+ const changeId = propertyChangeId(controlId, propertyName);
143
+ const timestamp = this.appliedChangeCache.get(changeId);
144
+ if (timestamp) {
145
+ this.appliedChangeCache.delete(changeId);
146
+ return;
147
+ }
148
+ const info = runtimeControl.getBindingInfo(propertyName);
149
+ const newValue = info?.path ?? e.getParameter('newValue');
150
+ const change = propertyChanged({
151
+ controlId,
152
+ propertyName,
153
+ newValue
154
+ });
155
+ sendAction(change);
156
+ };
157
+ runtimeControl.attachEvent('_change', handler);
158
+ this.activeChangeHandlers.add(() => {
159
+ try {
160
+ runtimeControl.detachEvent('_change', handler);
161
+ } catch {
162
+ }
163
+ });
164
+ }
165
+ }
166
+ var __exports = { __esModule: true };
167
+ __exports.SelectionService = SelectionService;
168
+ return __exports;
169
+ });
@@ -0,0 +1,237 @@
1
+ import type { Control, ExternalAction } from '@sap-ux-private/control-property-editor-common';
2
+ import {
3
+ controlSelected,
4
+ propertyChanged,
5
+ selectControl,
6
+ reportTelemetry,
7
+ Properties
8
+ } from '@sap-ux-private/control-property-editor-common';
9
+ import { buildControlData } from './control-data';
10
+ import { getRuntimeControl, ManagedObjectMetadataProperties, PropertiesInfo } from './utils';
11
+ import type { ActionSenderFunction, Service, SubscribeFunction, UI5Facade } from './types';
12
+
13
+ import type Event from 'sap/ui/base/Event';
14
+ import type ElementOverlay from 'sap/ui/dt/ElementOverlay';
15
+ import type ManagedObject from 'sap/ui/base/ManagedObject';
16
+ import type { SelectionChangeEvent } from 'sap/ui/rta/RuntimeAuthoring';
17
+ import type RuntimeAuthoring from 'sap/ui/rta/RuntimeAuthoring';
18
+ import Log from 'sap/base/Log';
19
+ import { getDocumentation } from './documentation';
20
+
21
+ export interface PropertyChangeParams {
22
+ name: string;
23
+ id: string;
24
+ newValue: string;
25
+ }
26
+ export type PropertyChangeEvent = Event<PropertyChangeParams>;
27
+
28
+ /**
29
+ * Change id is a combination of controlId and propertyName.
30
+ *
31
+ * @param controlId unique identifier for a control.
32
+ * @param propertyName name of the control property.
33
+ * @returns string
34
+ */
35
+ function propertyChangeId(controlId: string, propertyName: string): string {
36
+ return [controlId, propertyName].join(',');
37
+ }
38
+
39
+ /**
40
+ * Return document of a property.
41
+ *
42
+ * @param property - control metadata props.
43
+ * @param ui5Type - ui5 type
44
+ * @param document - property that is ignored during design time
45
+ * @returns PropertiesInfo
46
+ */
47
+ function getPropertyDocument(
48
+ property: ManagedObjectMetadataProperties,
49
+ ui5Type?: string,
50
+ document?: Properties
51
+ ): PropertiesInfo {
52
+ return document?.[property.name]
53
+ ? document[property.name]
54
+ : ({
55
+ defaultValue: (property.defaultValue as string) ?? '-',
56
+ description: '',
57
+ propertyName: property.name,
58
+ type: ui5Type ?? '-',
59
+ propertyType: ui5Type ?? '-'
60
+ } as PropertiesInfo);
61
+ }
62
+
63
+ async function addDocumentationForProperties(control: ManagedObject, controlData: Control): Promise<void> {
64
+ try {
65
+ const controlMetadata = control.getMetadata();
66
+ const allProperties = controlMetadata.getAllProperties() as unknown as {
67
+ [name: string]: ManagedObjectMetadataProperties;
68
+ };
69
+ const selectedControlName = controlMetadata.getName();
70
+ const selContLibName = controlMetadata.getLibraryName();
71
+ // Add the control's properties
72
+ const document = await getDocumentation(selectedControlName, selContLibName);
73
+ controlData.properties.forEach((controlProp) => {
74
+ const property = allProperties[controlProp.name];
75
+ controlProp.documentation = getPropertyDocument(property, controlProp.ui5Type, document);
76
+ });
77
+ } catch (e) {
78
+ Log.error('Document loading failed', e);
79
+ }
80
+ }
81
+
82
+ /**
83
+ *
84
+ */
85
+ export class SelectionService implements Service {
86
+ private appliedChangeCache = new Map<string, number>();
87
+ private activeChangeHandlers = new Set<() => void>();
88
+ /**
89
+ *
90
+ * @param rta - rta object.
91
+ * @param ui5 - facade for ui5 framework methods
92
+ */
93
+ constructor(private readonly rta: RuntimeAuthoring, private readonly ui5: UI5Facade) {}
94
+
95
+ /**
96
+ * Initialize selection service.
97
+ *
98
+ * @param sendAction action sender function
99
+ * @param subscribe subscriber function
100
+ */
101
+ public async init(sendAction: ActionSenderFunction, subscribe: SubscribeFunction): Promise<void> {
102
+ const eventOrigin: Set<string> = new Set();
103
+ const onselectionChange = this.createOnSelectionChangeHandler(sendAction, eventOrigin);
104
+ this.rta.attachSelectionChange((event) => {
105
+ onselectionChange(event).catch((error) => Log.error('Event interrupted: ', error));
106
+ });
107
+ subscribe(async (action: ExternalAction): Promise<void> => {
108
+ if (selectControl.match(action)) {
109
+ const id = action.payload;
110
+ const control = this.ui5.getControlById(id);
111
+ if (!control) {
112
+ const component = this.ui5.getComponent(id);
113
+ if (component) {
114
+ const controlData = buildControlData(component);
115
+
116
+ // add document
117
+ await addDocumentationForProperties(component, controlData);
118
+ const controlSelectedAction = controlSelected(controlData);
119
+ sendAction(controlSelectedAction);
120
+ }
121
+ return;
122
+ }
123
+ eventOrigin.add('outline');
124
+ let controlOverlay = this.ui5.getOverlay(control);
125
+ const selectedOverlayControls = this.rta.getSelection() ?? [];
126
+ //remove previous selection
127
+ for (const selectedOverlayControl of selectedOverlayControls) {
128
+ selectedOverlayControl.setSelected(false); //deselect previously selected control
129
+ }
130
+
131
+ if (!controlOverlay?.getDomRef()) {
132
+ //look for closest control in order to highlight in UI the (without firing the selection event)
133
+ controlOverlay = this.ui5.getClosestOverlayFor(control);
134
+ }
135
+
136
+ if (controlOverlay?.isSelectable()) {
137
+ controlOverlay.setSelected(true); //highlight without firing event only if the layer is selectable
138
+ } else {
139
+ const controlData = buildControlData(control);
140
+ await addDocumentationForProperties(control, controlData);
141
+ const controlSelectedAction = controlSelected(controlData);
142
+ sendAction(controlSelectedAction);
143
+ }
144
+ }
145
+ });
146
+ }
147
+
148
+ /**
149
+ *
150
+ * @param controlId unique identifier for a control
151
+ * @param propertyName name of the control property.
152
+ */
153
+ public applyControlPropertyChange(controlId: string, propertyName: string): void {
154
+ const changeId = propertyChangeId(controlId, propertyName);
155
+ this.appliedChangeCache.set(changeId, Date.now());
156
+ }
157
+
158
+ /**
159
+ * Create handler for onSelectionChange.
160
+ *
161
+ * @param sendAction sending action method
162
+ * @param eventOrigin origin of the event.
163
+ * @returns (event: Event) => Promise<void>
164
+ */
165
+ private createOnSelectionChangeHandler(
166
+ sendAction: (action: ExternalAction) => void,
167
+ eventOrigin: Set<string>
168
+ ): (event: SelectionChangeEvent) => Promise<void> {
169
+ return async (event: SelectionChangeEvent): Promise<void> => {
170
+ const selection = event.getParameter('selection');
171
+ for (const dispose of this.activeChangeHandlers) {
172
+ dispose();
173
+ }
174
+ this.activeChangeHandlers.clear();
175
+ if (Array.isArray(selection) && selection.length === 1) {
176
+ const overlayControl = this.ui5.getControlById<ElementOverlay>(selection[0].getId());
177
+ if (overlayControl) {
178
+ const runtimeControl = getRuntimeControl(overlayControl);
179
+ const controlName = runtimeControl.getMetadata().getName();
180
+ this.handlePropertyChanges(runtimeControl, sendAction);
181
+ try {
182
+ const isOutline = eventOrigin.has('outline');
183
+ const name = controlName.toLowerCase().startsWith('sap') ? controlName : 'Other Control Types';
184
+ if (isOutline) {
185
+ reportTelemetry({ category: 'Outline Selection', controlName: name });
186
+ } else {
187
+ reportTelemetry({ category: 'Overlay Selection', controlName: name });
188
+ }
189
+ } catch (error) {
190
+ Log.error('Failed to report telemetry', error);
191
+ } finally {
192
+ const controlData = buildControlData(runtimeControl, overlayControl);
193
+ await addDocumentationForProperties(runtimeControl, controlData);
194
+ const action = controlSelected(controlData);
195
+ sendAction(action);
196
+ eventOrigin.delete('outline');
197
+ }
198
+ }
199
+ }
200
+ };
201
+ }
202
+
203
+ /**
204
+ *
205
+ * @param runtimeControl sap/ui/base/ManagedObject
206
+ * @param sendAction send action method.
207
+ */
208
+ private handlePropertyChanges(runtimeControl: ManagedObject, sendAction: (action: ExternalAction) => void): void {
209
+ const handler = (e: PropertyChangeEvent) => {
210
+ const propertyName = e.getParameter('name');
211
+ const controlId = e.getParameter('id');
212
+ const changeId = propertyChangeId(controlId, propertyName);
213
+ const timestamp = this.appliedChangeCache.get(changeId);
214
+ if (timestamp) {
215
+ // Change originated from control property editor, we do not need to notify it
216
+ this.appliedChangeCache.delete(changeId);
217
+ return;
218
+ }
219
+ const info: { path?: string } = runtimeControl.getBindingInfo(propertyName);
220
+ const newValue = info?.path ?? e.getParameter('newValue');
221
+ const change = propertyChanged({
222
+ controlId,
223
+ propertyName,
224
+ newValue
225
+ });
226
+ sendAction(change);
227
+ };
228
+ runtimeControl.attachEvent('_change', handler);
229
+ this.activeChangeHandlers.add(() => {
230
+ try {
231
+ runtimeControl.detachEvent('_change', handler);
232
+ } catch {
233
+ // control has already been cleaned up, nothing to do here
234
+ }
235
+ });
236
+ }
237
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,53 @@
1
+ import type { ExternalAction, IconDetails } from '@sap-ux-private/control-property-editor-common';
2
+ import type RuntimeAuthoring from 'sap/ui/rta/RuntimeAuthoring';
3
+ import type Element from 'sap/ui/core/Element';
4
+ import type { ID } from 'sap/ui/core/library';
5
+ import type ElementOverlay from 'sap/ui/dt/ElementOverlay';
6
+ import type Component from 'sap/ui/core/Component';
7
+
8
+ export interface UI5AdaptationOptions {
9
+ rta: RuntimeAuthoring;
10
+ }
11
+
12
+ export type PrimitiveTypes = 'boolean' | 'enum' | 'float' | 'string' | 'any';
13
+ export type PropertyValue = boolean | object | number | string;
14
+
15
+ export interface UI5ControlProperty {
16
+ defaultValue: unknown;
17
+ enumValues: { [key: string]: string } | null;
18
+ isArray: boolean;
19
+ isDeprecated: boolean;
20
+ isEnabled: boolean;
21
+ isIcon: boolean;
22
+ name: string;
23
+ primitiveType: string;
24
+ ui5Type: string | null;
25
+ value: PropertyValue;
26
+ }
27
+
28
+ export interface UI5ControlData {
29
+ allowIndexForDefaultAggregation: boolean;
30
+ defaultAggregation: string;
31
+ id: string;
32
+ properties: UI5ControlProperty[];
33
+ selectedControlChildren: string[];
34
+ selectedControlName: string;
35
+ targetAggregation: string[];
36
+ type: string;
37
+ }
38
+
39
+ export type ActionHandler = (action: ExternalAction) => Promise<void>;
40
+ export type ActionSenderFunction = (action: ExternalAction) => void;
41
+ export type SubscribeFunction = (handler: ActionHandler) => void;
42
+
43
+ export interface Service {
44
+ init(sendAction: ActionSenderFunction, subscribe: SubscribeFunction): void;
45
+ }
46
+
47
+ export interface UI5Facade {
48
+ getControlById: <T extends Element>(id: ID) => T | undefined;
49
+ getIcons: () => IconDetails[];
50
+ getComponent: <T extends Component>(id: ID) => T | undefined;
51
+ getOverlay: <T extends ElementOverlay>(control: Element) => T | undefined;
52
+ getClosestOverlayFor: <T extends ElementOverlay>(control: Element) => T | undefined;
53
+ }
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+
3
+ sap.ui.define([], function () {
4
+ "use strict";
5
+
6
+ /**
7
+ * Get runtime control.
8
+ *
9
+ * @param overlayControl - element overlay.
10
+ * @returns ManagedObject
11
+ */
12
+ function getRuntimeControl(overlayControl) {
13
+ let runtimeControl;
14
+ if (overlayControl.getElementInstance) {
15
+ runtimeControl = overlayControl.getElementInstance();
16
+ } else {
17
+ runtimeControl = overlayControl.getElement();
18
+ }
19
+ return runtimeControl;
20
+ }
21
+
22
+ /**
23
+ * Get library of a control name.
24
+ *
25
+ * @param controlName - name of the ui5 control eg: sap.m.Button.
26
+ * @returns Promise<string>
27
+ */
28
+ async function getLibrary(controlName) {
29
+ return new Promise(resolve => {
30
+ const controlPath = controlName.replace(/\./g, '/');
31
+ sap.ui.require([controlPath], control => {
32
+ const contMetadata = control.getMetadata();
33
+ // getLibraryName method does not exist on events
34
+ if (contMetadata?.getLibraryName) {
35
+ const contLibName = contMetadata.getLibraryName();
36
+ resolve(contLibName);
37
+ } else {
38
+ resolve(''); // return empty for events
39
+ }
40
+ });
41
+ });
42
+ }
43
+ var __exports = {
44
+ __esModule: true
45
+ };
46
+ __exports.getRuntimeControl = getRuntimeControl;
47
+ __exports.getLibrary = getLibrary;
48
+ return __exports;
49
+ });
50
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1,62 @@
1
+ import type ManagedObject from 'sap/ui/base/ManagedObject';
2
+ import type Control from 'sap/ui/core/Control';
3
+ import type ElementOverlay from 'sap/ui/dt/ElementOverlay';
4
+ import DataType from 'sap/ui/base/DataType';
5
+
6
+ export interface PropertiesInfo {
7
+ defaultValue: string;
8
+ description: string;
9
+ propertyName: string;
10
+ type: string;
11
+ propertyType: string | undefined;
12
+ }
13
+ export interface Properties {
14
+ [key: string]: PropertiesInfo;
15
+ }
16
+
17
+ export interface ManagedObjectMetadataProperties {
18
+ name: string;
19
+ defaultValue: string | null;
20
+ deprecated: boolean;
21
+ getType: () => DataType;
22
+ getName: () => string;
23
+ getDefaultValue: () => unknown;
24
+ }
25
+
26
+ /**
27
+ * Get runtime control.
28
+ *
29
+ * @param overlayControl - element overlay.
30
+ * @returns ManagedObject
31
+ */
32
+ export function getRuntimeControl(overlayControl: ElementOverlay): ManagedObject {
33
+ let runtimeControl;
34
+ if (overlayControl.getElementInstance) {
35
+ runtimeControl = overlayControl.getElementInstance();
36
+ } else {
37
+ runtimeControl = overlayControl.getElement();
38
+ }
39
+ return runtimeControl;
40
+ }
41
+
42
+ /**
43
+ * Get library of a control name.
44
+ *
45
+ * @param controlName - name of the ui5 control eg: sap.m.Button.
46
+ * @returns Promise<string>
47
+ */
48
+ export async function getLibrary(controlName: string): Promise<string> {
49
+ return new Promise((resolve) => {
50
+ const controlPath = controlName.replace(/\./g, '/');
51
+ sap.ui.require([controlPath], (control: Control) => {
52
+ const contMetadata = control.getMetadata();
53
+ // getLibraryName method does not exist on events
54
+ if (contMetadata?.getLibraryName) {
55
+ const contLibName = contMetadata.getLibraryName();
56
+ resolve(contLibName);
57
+ } else {
58
+ resolve(''); // return empty for events
59
+ }
60
+ });
61
+ });
62
+ }
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+
3
+ sap.ui.define(["sap/base/util/merge", "sap/ui/fl/write/api/connectors/ObjectStorageConnector", "sap/ui/fl/Layer", "sap/ui/VersionInfo"], function (merge, ObjectStorageConnector, Layer, VersionInfo) {
4
+ "use strict";
5
+
6
+ const path = '/preview/api/changes';
7
+ const connector = merge({}, ObjectStorageConnector, {
8
+ layers: [Layer.VENDOR, Layer.CUSTOMER_BASE],
9
+ storage: {
10
+ _itemsStoredAsObjects: true,
11
+ setItem: function (_key, change) {
12
+ return fetch(path, {
13
+ method: 'POST',
14
+ body: JSON.stringify(change, null, 2),
15
+ headers: {
16
+ 'content-type': 'application/json'
17
+ }
18
+ });
19
+ },
20
+ removeItem: function (key) {
21
+ return fetch(path, {
22
+ method: 'DELETE',
23
+ body: JSON.stringify({
24
+ fileName: key
25
+ }),
26
+ headers: {
27
+ 'content-type': 'application/json'
28
+ }
29
+ });
30
+ },
31
+ clear: function () {
32
+ // not implemented
33
+ },
34
+ getItem: function (_key) {
35
+ // not implemented
36
+ },
37
+ getItems: async function () {
38
+ const response = await fetch(path, {
39
+ method: 'GET',
40
+ headers: {
41
+ 'content-type': 'application/json'
42
+ }
43
+ });
44
+ const changes = await response.json();
45
+ return changes;
46
+ }
47
+ },
48
+ loadFeatures: async function () {
49
+ const features = await ObjectStorageConnector.loadFeatures();
50
+ const ui5Version = await VersionInfo.load();
51
+ const [majorVersion, minorVersion] = ui5Version.version.split('.').map(v => parseInt(v, 10));
52
+ features.isVariantAdaptationEnabled = majorVersion >= 1 && minorVersion >= 90;
53
+ const bootstrapConfig = document.getElementById('sap-ui-bootstrap');
54
+ if (bootstrapConfig) {
55
+ const settings = bootstrapConfig.getAttribute('data-open-ux-preview-flex-settings');
56
+ if (settings && JSON.parse(settings).developerMode) {
57
+ features.isVariantAdaptationEnabled = false;
58
+ }
59
+ }
60
+ return features;
61
+ }
62
+ });
63
+ return connector;
64
+ });
65
+ //# sourceMappingURL=WorkspaceConnector.js.map