@sap-ux/preview-middleware 0.23.47 → 0.23.49
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/client/adp/command-executor.js +99 -66
- package/dist/client/adp/controllers/AddCustomFragment.controller.js +120 -102
- package/dist/client/adp/controllers/AddFragment.controller.js +189 -163
- package/dist/client/adp/controllers/AddSubpage.controller.js +146 -137
- package/dist/client/adp/controllers/AddTableColumnFragments.controller.js +230 -188
- package/dist/client/adp/controllers/BaseDialog.controller.js +187 -164
- package/dist/client/adp/controllers/ControllerExtension.controller.js +329 -253
- package/dist/client/adp/controllers/ExtensionPoint.controller.js +158 -114
- package/dist/client/adp/extension-point.js +81 -60
- package/dist/client/adp/init.js +100 -99
- package/dist/client/adp/quick-actions/common/add-new-annotation-file.js +165 -147
- package/dist/client/adp/quick-actions/enablement-validator.js +0 -4
- package/dist/client/adp/quick-actions/fe-v2/create-table-custom-column.js +105 -100
- package/dist/client/adp/quick-actions/simple-quick-action-base.js +44 -40
- package/dist/client/adp/quick-actions/table-quick-action-base.js +309 -266
- package/dist/client/adp/sync-views-utils.js +119 -83
- package/dist/client/cpe/changes/flex-change.js +64 -48
- package/dist/client/cpe/changes/service.js +492 -367
- package/dist/client/cpe/communication-service.js +41 -29
- package/dist/client/cpe/connector-service.js +87 -64
- package/dist/client/cpe/context-menu-service.js +87 -74
- package/dist/client/cpe/control-data.js +353 -263
- package/dist/client/cpe/documentation.js +183 -126
- package/dist/client/cpe/init.js +69 -75
- package/dist/client/cpe/outline/service.js +60 -45
- package/dist/client/cpe/quick-actions/quick-action-definition.js +0 -4
- package/dist/client/cpe/quick-actions/quick-action-service.js +154 -129
- package/dist/client/cpe/rta-service.js +91 -69
- package/dist/client/cpe/selection.js +239 -187
- package/dist/client/cpe/types.js +0 -4
- package/dist/client/flp/init.js +403 -296
- package/dist/client/manifest.json +7 -4
- package/dist/client/thirdparty/@sap-ux-private/control-property-editor-common.js +444 -370
- package/dist/client/utils/info-center-message.js +59 -31
- package/dist/client/utils/version.js +128 -72
- package/package.json +3 -3
|
@@ -1,386 +1,511 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
sap.ui.define(["open/ux/preview/client/thirdparty/@sap-ux-private/control-property-editor-common", "sap/base/Log", "../../i18n", "../../utils/additional-change-info", "../../utils/core", "../../utils/error", "../../utils/info-center-message", "../rta-service", "./flex-change", "./generic-change"], function (___sap_ux_private_control_property_editor_common, Log, ____i18n, ____utils_additional_change_info, ____utils_core, ____utils_error, ____utils_info_center_message, ___rta_service, ___flex_change, ___generic_change) {
|
|
4
|
+
"use strict";
|
|
5
|
+
|
|
6
|
+
const changeProperty = ___sap_ux_private_control_property_editor_common["changeProperty"];
|
|
7
|
+
const changeStackModified = ___sap_ux_private_control_property_editor_common["changeStackModified"];
|
|
8
|
+
const deletePropertyChanges = ___sap_ux_private_control_property_editor_common["deletePropertyChanges"];
|
|
9
|
+
const FlexChangesEndPoints = ___sap_ux_private_control_property_editor_common["FlexChangesEndPoints"];
|
|
10
|
+
const GENERIC_CHANGE_KIND = ___sap_ux_private_control_property_editor_common["GENERIC_CHANGE_KIND"];
|
|
11
|
+
const MessageBarType = ___sap_ux_private_control_property_editor_common["MessageBarType"];
|
|
12
|
+
const PENDING_CHANGE_TYPE = ___sap_ux_private_control_property_editor_common["PENDING_CHANGE_TYPE"];
|
|
13
|
+
const propertyChangeFailed = ___sap_ux_private_control_property_editor_common["propertyChangeFailed"];
|
|
14
|
+
const reloadApplication = ___sap_ux_private_control_property_editor_common["reloadApplication"];
|
|
15
|
+
const save = ___sap_ux_private_control_property_editor_common["save"];
|
|
16
|
+
const setApplicationRequiresReload = ___sap_ux_private_control_property_editor_common["setApplicationRequiresReload"];
|
|
17
|
+
const UNKNOWN_CHANGE_KIND = ___sap_ux_private_control_property_editor_common["UNKNOWN_CHANGE_KIND"];
|
|
18
|
+
const getTextBundle = ____i18n["getTextBundle"];
|
|
19
|
+
const setAdditionalChangeInfo = ____utils_additional_change_info["setAdditionalChangeInfo"];
|
|
20
|
+
const getControlById = ____utils_core["getControlById"];
|
|
21
|
+
const isA = ____utils_core["isA"];
|
|
22
|
+
const getError = ____utils_error["getError"];
|
|
23
|
+
const sendInfoCenterMessage = ____utils_info_center_message["sendInfoCenterMessage"];
|
|
24
|
+
const modeAndStackChangeHandler = ___rta_service["modeAndStackChangeHandler"];
|
|
25
|
+
const applyChange = ___flex_change["applyChange"];
|
|
26
|
+
const GENERIC_CHANGE_HANDLER = ___generic_change["GENERIC_CHANGE_HANDLER"];
|
|
27
|
+
const getControlIdByChange = ___generic_change["getControlIdByChange"];
|
|
28
|
+
const getFlexObject = ___generic_change["getFlexObject"];
|
|
29
|
+
const TITLE_MAP = {
|
|
30
|
+
appdescr_app_addAnnotationsToOData: 'Add New Annotation File'
|
|
31
|
+
};
|
|
32
|
+
const STACK_CHANGE_EVENT = 'STACK_CHANGED';
|
|
33
|
+
/**
|
|
34
|
+
* Modify rta message.
|
|
35
|
+
*
|
|
36
|
+
* @param errorMessage error message to be replaced
|
|
37
|
+
* @param id - control id
|
|
38
|
+
* @param type - control type
|
|
39
|
+
* @returns string
|
|
40
|
+
*/
|
|
41
|
+
function modifyRTAErrorMessage(errorMessage, id, type) {
|
|
42
|
+
return errorMessage.replace('Error: Applying property changes failed:', '').replace(`${type}#${id}`, '');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* A Class of ChangeService
|
|
47
|
+
*/
|
|
48
|
+
class ChangeService extends EventTarget {
|
|
49
|
+
savedChanges = [];
|
|
50
|
+
changesRequiringReload = 0;
|
|
51
|
+
pendingChanges = [];
|
|
52
|
+
changedFiles = {};
|
|
53
|
+
eventStack = [];
|
|
54
|
+
pendingConfigChangeMap = (() => new Map())();
|
|
55
|
+
configPropertyControlIdMap = (() => new Map())();
|
|
56
|
+
/**
|
|
57
|
+
*
|
|
58
|
+
* @param options ui5 adaptation options.
|
|
59
|
+
* @param ui5 facade for ui5 framework methods.
|
|
60
|
+
* @param selectionService selection service instance.
|
|
61
|
+
*/
|
|
62
|
+
constructor(options) {
|
|
63
|
+
super();
|
|
64
|
+
this.options = options;
|
|
42
65
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
type: MessageBarType.error
|
|
75
|
-
});
|
|
76
|
-
const propertyChangeFailedAction = propertyChangeFailed({
|
|
77
|
-
...action.payload,
|
|
78
|
-
errorMessage
|
|
79
|
-
});
|
|
80
|
-
sendAction(propertyChangeFailedAction);
|
|
81
|
-
}
|
|
82
|
-
} else if (deletePropertyChanges.match(action)) {
|
|
83
|
-
await this.deleteChange(action.payload.controlId, action.payload.propertyName, action.payload.fileName);
|
|
84
|
-
} else if (reloadApplication.match(action)) {
|
|
85
|
-
this.sendAction(setApplicationRequiresReload(false));
|
|
86
|
-
} else if (save.match(action)) {
|
|
87
|
-
this.changesRequiringReload = 0;
|
|
88
|
-
this.sendAction(setApplicationRequiresReload(false));
|
|
89
|
-
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Initializes change service.
|
|
69
|
+
*
|
|
70
|
+
* @param sendAction action sender function
|
|
71
|
+
* @param subscribe subscriber function
|
|
72
|
+
*/
|
|
73
|
+
async init(sendAction, subscribe) {
|
|
74
|
+
this.sendAction = sendAction;
|
|
75
|
+
subscribe(async action => {
|
|
76
|
+
if (changeProperty.match(action)) {
|
|
77
|
+
try {
|
|
78
|
+
await applyChange(this.options, action.payload);
|
|
79
|
+
} catch (exception) {
|
|
80
|
+
// send error information
|
|
81
|
+
let name = '';
|
|
82
|
+
const id = action.payload.controlId || '';
|
|
83
|
+
const control = sap.ui.getCore().byId(id);
|
|
84
|
+
if (control) {
|
|
85
|
+
name = control.getMetadata().getName();
|
|
86
|
+
}
|
|
87
|
+
const error = getError(exception);
|
|
88
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
89
|
+
const modifiedMessage = modifyRTAErrorMessage(error.toString(), id, name);
|
|
90
|
+
const errorMessage = modifiedMessage || `RTA Exception applying expression "${action.payload.value}"`;
|
|
91
|
+
await sendInfoCenterMessage({
|
|
92
|
+
title: {
|
|
93
|
+
key: 'CHANGE_CREATION_FAILED_TITLE'
|
|
94
|
+
},
|
|
95
|
+
description: errorMessage,
|
|
96
|
+
type: MessageBarType.error
|
|
90
97
|
});
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
async fetchSavedChanges() {
|
|
105
|
-
this.changedFiles = {};
|
|
106
|
-
const savedChangesResponse = await fetch(FlexChangesEndPoints.changes + `?_=${ Date.now() }`);
|
|
107
|
-
const savedChanges = await savedChangesResponse.json();
|
|
108
|
-
const textBundle = await getTextBundle();
|
|
109
|
-
const changes = (await Promise.all(Object.keys(savedChanges ?? {}).map(async key => {
|
|
110
|
-
const change = savedChanges[key];
|
|
111
|
-
try {
|
|
112
|
-
const handler = GENERIC_CHANGE_HANDLER[change.changeType];
|
|
113
|
-
if (this.isGenericChange(change)) {
|
|
114
|
-
const {
|
|
115
|
-
properties,
|
|
116
|
-
changeTitle,
|
|
117
|
-
controlId,
|
|
118
|
-
changeType: type,
|
|
119
|
-
subtitle
|
|
120
|
-
} = await handler(change, {
|
|
121
|
-
textBundle,
|
|
122
|
-
appComponent: this.options.rta.getRootControlInstance(),
|
|
123
|
-
configPropertyControlIdMap: this.configPropertyControlIdMap
|
|
124
|
-
});
|
|
125
|
-
this.changedFiles[change.fileName] = change;
|
|
126
|
-
return {
|
|
127
|
-
kind: GENERIC_CHANGE_KIND,
|
|
128
|
-
type: 'saved',
|
|
129
|
-
fileName: change.fileName,
|
|
130
|
-
...subtitle && { subtitle },
|
|
131
|
-
changeType: type ?? change.changeType,
|
|
132
|
-
timestamp: new Date(change.creation).getTime(),
|
|
133
|
-
...controlId && { controlId },
|
|
134
|
-
properties,
|
|
135
|
-
title: textBundle.getText(changeTitle)
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
throw new Error('Unknown change type');
|
|
139
|
-
} catch (error) {
|
|
140
|
-
const flexObject = await getFlexObject(change);
|
|
141
|
-
const selectorId = await getControlIdByChange(flexObject, this.options.rta.getRootControlInstance());
|
|
142
|
-
if (change.fileName) {
|
|
143
|
-
this.changedFiles[change.fileName] = change;
|
|
144
|
-
const unknownChange = {
|
|
145
|
-
type: 'saved',
|
|
146
|
-
kind: 'unknown',
|
|
147
|
-
changeType: change.changeType,
|
|
148
|
-
fileName: change.fileName,
|
|
149
|
-
timestamp: new Date(change.creation).getTime()
|
|
150
|
-
};
|
|
151
|
-
if (change.creation) {
|
|
152
|
-
unknownChange.timestamp = new Date(change.creation).getTime();
|
|
153
|
-
}
|
|
154
|
-
if (selectorId) {
|
|
155
|
-
const controlChange = {
|
|
156
|
-
...unknownChange,
|
|
157
|
-
kind: 'control',
|
|
158
|
-
controlId: selectorId
|
|
159
|
-
};
|
|
160
|
-
return controlChange;
|
|
161
|
-
}
|
|
162
|
-
return unknownChange;
|
|
163
|
-
}
|
|
164
|
-
return undefined;
|
|
165
|
-
}
|
|
166
|
-
}))).filter(change => !!change).sort((a, b) => b.timestamp - a.timestamp);
|
|
167
|
-
this.savedChanges = changes;
|
|
168
|
-
}
|
|
169
|
-
async deleteChange(controlId, propertyName, fileName) {
|
|
170
|
-
const filesToDelete = this.savedChanges.filter(change => {
|
|
171
|
-
if (fileName) {
|
|
172
|
-
return fileName === change.fileName;
|
|
173
|
-
}
|
|
174
|
-
if (change.kind === 'control') {
|
|
175
|
-
return change.controlId === controlId;
|
|
176
|
-
}
|
|
177
|
-
return false;
|
|
178
|
-
}).map(change => fetch(FlexChangesEndPoints.changes, {
|
|
179
|
-
method: 'DELETE',
|
|
180
|
-
headers: { 'Content-Type': 'application/json' },
|
|
181
|
-
body: JSON.stringify({ fileName: change.fileName })
|
|
182
|
-
}));
|
|
183
|
-
await Promise.all(filesToDelete).catch(error => Log.error(getError(error).message));
|
|
184
|
-
await this.fetchSavedChanges();
|
|
185
|
-
this.updateStack();
|
|
98
|
+
const propertyChangeFailedAction = propertyChangeFailed({
|
|
99
|
+
...action.payload,
|
|
100
|
+
errorMessage
|
|
101
|
+
});
|
|
102
|
+
sendAction(propertyChangeFailedAction);
|
|
103
|
+
}
|
|
104
|
+
} else if (deletePropertyChanges.match(action)) {
|
|
105
|
+
await this.deleteChange(action.payload.controlId, action.payload.propertyName, action.payload.fileName);
|
|
106
|
+
} else if (reloadApplication.match(action)) {
|
|
107
|
+
this.sendAction(setApplicationRequiresReload(false));
|
|
108
|
+
} else if (save.match(action)) {
|
|
109
|
+
this.changesRequiringReload = 0;
|
|
110
|
+
this.sendAction(setApplicationRequiresReload(false));
|
|
186
111
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
});
|
|
248
|
-
this.dispatchEvent(stackChangeEvent);
|
|
249
|
-
}
|
|
250
|
-
this.updateStack();
|
|
251
|
-
handleStackChange();
|
|
112
|
+
});
|
|
113
|
+
await this.fetchSavedChanges();
|
|
114
|
+
this.updateStack();
|
|
115
|
+
this.options.rta.attachUndoRedoStackModified(this.createOnStackChangeHandler());
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Send update to the editor with modified stack.
|
|
120
|
+
*
|
|
121
|
+
* @param pendingChanges Changes that are waiting to be saved
|
|
122
|
+
*/
|
|
123
|
+
updateStack() {
|
|
124
|
+
this.sendAction(changeStackModified({
|
|
125
|
+
saved: this.savedChanges ?? [],
|
|
126
|
+
pending: this.pendingChanges ?? []
|
|
127
|
+
}));
|
|
128
|
+
}
|
|
129
|
+
isGenericChange(change) {
|
|
130
|
+
return change.changeType === 'appdescr_app_addAnnotationsToOData' || change.changeType === 'rename' || change.changeType === 'moveControls' || change.changeType === 'addXML' || change.changeType === 'propertyChange' || change.changeType === 'propertyBindingChange' || change.changeType === 'appdescr_fe_changePageConfiguration' || change.changeType === 'appdescr_ui_generic_app_changePageConfiguration';
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Fetches saved changes from the workspace and sorts them.
|
|
135
|
+
*/
|
|
136
|
+
async fetchSavedChanges() {
|
|
137
|
+
this.changedFiles = {};
|
|
138
|
+
const savedChangesResponse = await fetch(FlexChangesEndPoints.changes + `?_=${Date.now()}`);
|
|
139
|
+
const savedChanges = await savedChangesResponse.json();
|
|
140
|
+
const textBundle = await getTextBundle();
|
|
141
|
+
const changes = (await Promise.all(Object.keys(savedChanges ?? {}).map(async key => {
|
|
142
|
+
const change = savedChanges[key];
|
|
143
|
+
try {
|
|
144
|
+
const handler = GENERIC_CHANGE_HANDLER[change.changeType];
|
|
145
|
+
if (this.isGenericChange(change)) {
|
|
146
|
+
const {
|
|
147
|
+
properties,
|
|
148
|
+
changeTitle,
|
|
149
|
+
controlId,
|
|
150
|
+
changeType: type,
|
|
151
|
+
subtitle
|
|
152
|
+
} = await handler(change, {
|
|
153
|
+
textBundle,
|
|
154
|
+
appComponent: this.options.rta.getRootControlInstance(),
|
|
155
|
+
configPropertyControlIdMap: this.configPropertyControlIdMap
|
|
156
|
+
});
|
|
157
|
+
this.changedFiles[change.fileName] = change;
|
|
158
|
+
return {
|
|
159
|
+
kind: GENERIC_CHANGE_KIND,
|
|
160
|
+
type: 'saved',
|
|
161
|
+
fileName: change.fileName,
|
|
162
|
+
...(subtitle && {
|
|
163
|
+
subtitle
|
|
164
|
+
}),
|
|
165
|
+
changeType: type ?? change.changeType,
|
|
166
|
+
timestamp: new Date(change.creation).getTime(),
|
|
167
|
+
...(controlId && {
|
|
168
|
+
controlId
|
|
169
|
+
}),
|
|
170
|
+
properties,
|
|
171
|
+
title: textBundle.getText(changeTitle)
|
|
252
172
|
};
|
|
173
|
+
}
|
|
174
|
+
throw new Error('Unknown change type');
|
|
175
|
+
} catch (error) {
|
|
176
|
+
// Gracefully handle change files with invalid content
|
|
177
|
+
const flexObject = await getFlexObject(change);
|
|
178
|
+
const selectorId = await getControlIdByChange(flexObject, this.options.rta.getRootControlInstance());
|
|
179
|
+
if (change.fileName) {
|
|
180
|
+
this.changedFiles[change.fileName] = change;
|
|
181
|
+
const unknownChange = {
|
|
182
|
+
type: 'saved',
|
|
183
|
+
kind: 'unknown',
|
|
184
|
+
changeType: change.changeType,
|
|
185
|
+
fileName: change.fileName,
|
|
186
|
+
timestamp: new Date(change.creation).getTime()
|
|
187
|
+
};
|
|
188
|
+
if (change.creation) {
|
|
189
|
+
unknownChange.timestamp = new Date(change.creation).getTime();
|
|
190
|
+
}
|
|
191
|
+
if (selectorId) {
|
|
192
|
+
const controlChange = {
|
|
193
|
+
...unknownChange,
|
|
194
|
+
kind: 'control',
|
|
195
|
+
controlId: selectorId
|
|
196
|
+
};
|
|
197
|
+
return controlChange;
|
|
198
|
+
}
|
|
199
|
+
return unknownChange;
|
|
200
|
+
}
|
|
201
|
+
return undefined;
|
|
253
202
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
203
|
+
}))).filter(change => !!change).sort((a, b) => b.timestamp - a.timestamp);
|
|
204
|
+
this.savedChanges = changes;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
*
|
|
209
|
+
* @param controlId unique identifier for a control
|
|
210
|
+
* @param propertyName name of the property change to be deleted
|
|
211
|
+
* @param fileName name of the file.
|
|
212
|
+
*/
|
|
213
|
+
async deleteChange(controlId, propertyName, fileName) {
|
|
214
|
+
const filesToDelete = this.savedChanges.filter(change => {
|
|
215
|
+
if (fileName) {
|
|
216
|
+
return fileName === change.fileName;
|
|
257
217
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
await this.fetchSavedChanges();
|
|
261
|
-
this.updateStack();
|
|
218
|
+
if (change.kind === 'control') {
|
|
219
|
+
return change.controlId === controlId;
|
|
262
220
|
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
221
|
+
return false;
|
|
222
|
+
}).map(change => fetch(FlexChangesEndPoints.changes, {
|
|
223
|
+
method: 'DELETE',
|
|
224
|
+
headers: {
|
|
225
|
+
'Content-Type': 'application/json'
|
|
226
|
+
},
|
|
227
|
+
body: JSON.stringify({
|
|
228
|
+
fileName: change.fileName
|
|
229
|
+
})
|
|
230
|
+
}));
|
|
231
|
+
await Promise.all(filesToDelete).catch(error => Log.error(getError(error).message));
|
|
232
|
+
await this.fetchSavedChanges();
|
|
233
|
+
this.updateStack();
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Handler for undo/redo stack change.
|
|
238
|
+
*
|
|
239
|
+
* @param sendAction send action method
|
|
240
|
+
* @returns (event: sap.ui.base.Event) => Promise<void>
|
|
241
|
+
*/
|
|
242
|
+
createOnStackChangeHandler() {
|
|
243
|
+
const handleStackChange = modeAndStackChangeHandler(this.sendAction, this.options.rta);
|
|
244
|
+
return async event => {
|
|
245
|
+
const pendingChanges = [];
|
|
246
|
+
this.eventStack.push(event);
|
|
247
|
+
const stack = this.options.rta.getCommandStack();
|
|
248
|
+
const allCommands = stack.getCommands();
|
|
249
|
+
const executedCommands = stack.getAllExecutedCommands();
|
|
250
|
+
const allCommandsFlattened = allCommands.flatMap(command => typeof command.getCommands === 'function' ? command.getCommands() : [command]);
|
|
251
|
+
const activeCommandCount = allCommandsFlattened.length - executedCommands.length;
|
|
252
|
+
this.pendingConfigChangeMap = new Map();
|
|
253
|
+
let i = 0;
|
|
254
|
+
for (const command of allCommands) {
|
|
255
|
+
try {
|
|
256
|
+
if (typeof command.getCommands === 'function') {
|
|
257
|
+
const subCommands = command.getCommands();
|
|
258
|
+
for (const subCommand of subCommands) {
|
|
259
|
+
await this.handleCommand(subCommand, activeCommandCount, i, pendingChanges);
|
|
260
|
+
i++;
|
|
261
|
+
}
|
|
262
|
+
} else {
|
|
263
|
+
await this.handleCommand(command, activeCommandCount, i, pendingChanges);
|
|
264
|
+
i++;
|
|
268
265
|
}
|
|
266
|
+
} catch (error) {
|
|
267
|
+
Log.error('CPE: Change creation Failed', getError(error));
|
|
268
|
+
}
|
|
269
269
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
270
|
+
const eventIndex = this.eventStack.indexOf(event);
|
|
271
|
+
if (this.eventStack.length - 1 === eventIndex) {
|
|
272
|
+
this.pendingChanges = pendingChanges.filter(change => !!change);
|
|
273
|
+
const changesRequiringReload = this.pendingChanges.reduce((sum, change) => isGenericConfigChange(change) ? sum + 1 : sum, 0);
|
|
274
|
+
if (changesRequiringReload > this.changesRequiringReload) {
|
|
275
|
+
await sendInfoCenterMessage({
|
|
276
|
+
title: {
|
|
277
|
+
key: 'CHANGES_VISIBLE_AFTER_SAVE_AND_RELOAD_TITLE'
|
|
278
|
+
},
|
|
279
|
+
description: {
|
|
280
|
+
key: 'CHANGES_VISIBLE_AFTER_SAVE_AND_RELOAD_DESCRIPTION'
|
|
281
|
+
},
|
|
282
|
+
type: MessageBarType.info
|
|
283
|
+
});
|
|
284
|
+
this.sendAction(setApplicationRequiresReload(changesRequiringReload > 0));
|
|
285
|
+
}
|
|
286
|
+
this.changesRequiringReload = changesRequiringReload;
|
|
278
287
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
if (!changeType) {
|
|
285
|
-
return undefined;
|
|
286
|
-
}
|
|
287
|
-
const changeDefinition = change.getDefinition ? change.getDefinition() : change.getJson();
|
|
288
|
-
const {fileName} = changeDefinition;
|
|
289
|
-
const handler = GENERIC_CHANGE_HANDLER[changeType];
|
|
290
|
-
if (handler) {
|
|
291
|
-
const {
|
|
292
|
-
properties,
|
|
293
|
-
changeTitle,
|
|
294
|
-
controlId,
|
|
295
|
-
changeType: type,
|
|
296
|
-
subtitle
|
|
297
|
-
} = await handler(changeDefinition, {
|
|
298
|
-
textBundle,
|
|
299
|
-
appComponent: this.options.rta.getRootControlInstance(),
|
|
300
|
-
configPropertyControlIdMap: this.configPropertyControlIdMap
|
|
301
|
-
});
|
|
302
|
-
const genericChange = {
|
|
303
|
-
kind: GENERIC_CHANGE_KIND,
|
|
304
|
-
type: 'pending',
|
|
305
|
-
changeType: type ?? changeType,
|
|
306
|
-
...subtitle && { subtitle },
|
|
307
|
-
isActive: index >= inactiveCommandCount,
|
|
308
|
-
title: textBundle.getText(changeTitle),
|
|
309
|
-
fileName,
|
|
310
|
-
...controlId && { controlId },
|
|
311
|
-
properties
|
|
312
|
-
};
|
|
313
|
-
if (changeType === 'appdescr_fe_changePageConfiguration') {
|
|
314
|
-
this.trackPendingConfigChanges(genericChange);
|
|
315
|
-
}
|
|
316
|
-
return genericChange;
|
|
317
|
-
} else {
|
|
318
|
-
const title = TITLE_MAP[changeType] ?? '';
|
|
319
|
-
let result = {
|
|
320
|
-
type: PENDING_CHANGE_TYPE,
|
|
321
|
-
kind: UNKNOWN_CHANGE_KIND,
|
|
322
|
-
...title && { title },
|
|
323
|
-
changeType,
|
|
324
|
-
isActive: index >= inactiveCommandCount,
|
|
325
|
-
fileName
|
|
326
|
-
};
|
|
327
|
-
if (selectorId) {
|
|
328
|
-
result = {
|
|
329
|
-
...result,
|
|
330
|
-
kind: 'control',
|
|
331
|
-
controlId: selectorId
|
|
332
|
-
};
|
|
333
|
-
}
|
|
334
|
-
return result;
|
|
335
|
-
}
|
|
288
|
+
this.eventStack.splice(eventIndex, 1);
|
|
289
|
+
if (Array.isArray(allCommands) && allCommands.length === 0) {
|
|
290
|
+
this.pendingChanges = [];
|
|
291
|
+
this.pendingConfigChangeMap = new Map();
|
|
292
|
+
await this.fetchSavedChanges();
|
|
336
293
|
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
294
|
+
|
|
295
|
+
// Notify to update the ui for configuration changes.
|
|
296
|
+
const configurationChanges = this.pendingChanges?.filter(isGenericConfigChange);
|
|
297
|
+
if (configurationChanges.length) {
|
|
298
|
+
const stackChangeEvent = new CustomEvent(STACK_CHANGE_EVENT, {
|
|
299
|
+
detail: {
|
|
300
|
+
controls: configurationChanges.reduce((acc, item) => {
|
|
301
|
+
const controls = [...(item.controlId ?? [])].map(id => {
|
|
302
|
+
return getControlById(id);
|
|
303
|
+
}).filter(ui5Element => isA('sap.ui.core.Element', ui5Element));
|
|
304
|
+
acc.push(...controls);
|
|
305
|
+
return acc;
|
|
306
|
+
}, [])
|
|
348
307
|
}
|
|
349
|
-
|
|
350
|
-
|
|
308
|
+
});
|
|
309
|
+
this.dispatchEvent(stackChangeEvent);
|
|
310
|
+
}
|
|
311
|
+
this.updateStack();
|
|
312
|
+
handleStackChange();
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Cached configuration commands to set reset value during stack change event.
|
|
317
|
+
*
|
|
318
|
+
* @param controlId - control id of the config property.
|
|
319
|
+
* @param propertyName - config property name.
|
|
320
|
+
* @returns Configuration property value.
|
|
321
|
+
*/
|
|
322
|
+
getConfigurationPropertyValue(controlId, propertyName) {
|
|
323
|
+
const pendingChanges = this.pendingConfigChangeMap?.get(controlId);
|
|
324
|
+
return (pendingChanges || []).find(item => item.isActive && item.properties[0].label === propertyName)?.properties[0].value;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Update config changes with associated controls.
|
|
329
|
+
*
|
|
330
|
+
* @param {Map<string, string[]>} configPropertyControlIdMap - config property path control id map.
|
|
331
|
+
*/
|
|
332
|
+
async updateConfigurationProps(configPropertyControlIdMap) {
|
|
333
|
+
this.configPropertyControlIdMap = configPropertyControlIdMap;
|
|
334
|
+
await this.fetchSavedChanges();
|
|
335
|
+
this.updateStack();
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Handles a command by preparing a pending change and adding it to the list of pending changes.
|
|
340
|
+
*
|
|
341
|
+
* @param {FlexCommand} command - The command to process.
|
|
342
|
+
* @param {number} inactiveCommandCount - The number of inactive commands.
|
|
343
|
+
* @param {number} index - The index of the current command being processed.
|
|
344
|
+
* @param {PendingChange[]} pendingChanges - The list of pending changes to update.
|
|
345
|
+
* @returns {Promise<void>} A promise that resolves when the command is handled.
|
|
346
|
+
*/
|
|
347
|
+
async handleCommand(command, inactiveCommandCount, index, pendingChanges) {
|
|
348
|
+
setAdditionalChangeInfo(command?.getPreparedChange?.());
|
|
349
|
+
const pendingChange = await this.prepareChangeType(command, inactiveCommandCount, index);
|
|
350
|
+
if (pendingChange) {
|
|
351
|
+
pendingChanges.push(pendingChange);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
trackPendingConfigChanges(result) {
|
|
355
|
+
for (const id of result?.controlId ?? []) {
|
|
356
|
+
if (!this.pendingConfigChangeMap.get(id)) {
|
|
357
|
+
this.pendingConfigChangeMap.set(id, []);
|
|
351
358
|
}
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
359
|
+
const pendingChanges = this.pendingConfigChangeMap.get(id);
|
|
360
|
+
pendingChanges?.push(result);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Prepares the type of change based on the command and other parameters.
|
|
366
|
+
*
|
|
367
|
+
* @param {FlexCommand} command - The command to process.
|
|
368
|
+
* @param {number} inactiveCommandCount - The number of inactive commands.
|
|
369
|
+
* @param {number} index - The index of the current command being processed.
|
|
370
|
+
* @returns {Promise<PendingChange | undefined>} - A promise that resolves to a `PendingChange` or `undefined`.
|
|
371
|
+
*/
|
|
372
|
+
async prepareChangeType(command, inactiveCommandCount, index) {
|
|
373
|
+
const change = command?.getPreparedChange?.();
|
|
374
|
+
const textBundle = await getTextBundle();
|
|
375
|
+
const selectorId = typeof change?.getSelector === 'function' ? await getControlIdByChange(change, this.options.rta.getRootControlInstance()) : this.getCommandSelectorId(command);
|
|
376
|
+
const changeType = this.getCommandChangeType(command);
|
|
377
|
+
if (!changeType) {
|
|
378
|
+
return undefined;
|
|
379
|
+
}
|
|
380
|
+
const changeDefinition = change.getDefinition ? change.getDefinition() : change.getJson();
|
|
381
|
+
const {
|
|
382
|
+
fileName
|
|
383
|
+
} = changeDefinition;
|
|
384
|
+
const handler = GENERIC_CHANGE_HANDLER[changeType];
|
|
385
|
+
if (handler) {
|
|
386
|
+
const {
|
|
387
|
+
properties,
|
|
388
|
+
changeTitle,
|
|
389
|
+
controlId,
|
|
390
|
+
changeType: type,
|
|
391
|
+
subtitle
|
|
392
|
+
} = await handler(changeDefinition, {
|
|
393
|
+
textBundle,
|
|
394
|
+
appComponent: this.options.rta.getRootControlInstance(),
|
|
395
|
+
configPropertyControlIdMap: this.configPropertyControlIdMap
|
|
396
|
+
});
|
|
397
|
+
const genericChange = {
|
|
398
|
+
kind: GENERIC_CHANGE_KIND,
|
|
399
|
+
type: 'pending',
|
|
400
|
+
changeType: type ?? changeType,
|
|
401
|
+
...(subtitle && {
|
|
402
|
+
subtitle
|
|
403
|
+
}),
|
|
404
|
+
isActive: index >= inactiveCommandCount,
|
|
405
|
+
title: textBundle.getText(changeTitle),
|
|
406
|
+
fileName,
|
|
407
|
+
...(controlId && {
|
|
408
|
+
controlId
|
|
409
|
+
}),
|
|
410
|
+
properties
|
|
411
|
+
};
|
|
412
|
+
if (changeType === 'appdescr_fe_changePageConfiguration') {
|
|
413
|
+
this.trackPendingConfigChanges(genericChange);
|
|
357
414
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
415
|
+
return genericChange;
|
|
416
|
+
} else {
|
|
417
|
+
const title = TITLE_MAP[changeType] ?? '';
|
|
418
|
+
let result = {
|
|
419
|
+
type: PENDING_CHANGE_TYPE,
|
|
420
|
+
kind: UNKNOWN_CHANGE_KIND,
|
|
421
|
+
...(title && {
|
|
422
|
+
title
|
|
423
|
+
}),
|
|
424
|
+
changeType,
|
|
425
|
+
isActive: index >= inactiveCommandCount,
|
|
426
|
+
fileName
|
|
427
|
+
};
|
|
428
|
+
if (selectorId) {
|
|
429
|
+
result = {
|
|
430
|
+
...result,
|
|
431
|
+
kind: 'control',
|
|
432
|
+
controlId: selectorId
|
|
433
|
+
};
|
|
365
434
|
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
435
|
+
return result;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Retry operations.
|
|
441
|
+
*
|
|
442
|
+
* @param operations to be executed
|
|
443
|
+
* @returns first successfull operation result or undefined
|
|
444
|
+
*/
|
|
445
|
+
retryOperations(operations) {
|
|
446
|
+
for (const operation of operations) {
|
|
447
|
+
try {
|
|
448
|
+
const result = operation();
|
|
449
|
+
if (!result) {
|
|
450
|
+
continue;
|
|
451
|
+
}
|
|
452
|
+
return result;
|
|
453
|
+
} catch (error) {
|
|
454
|
+
continue;
|
|
374
455
|
}
|
|
375
|
-
|
|
376
|
-
|
|
456
|
+
}
|
|
457
|
+
Log.error('All retry operations failed');
|
|
458
|
+
return undefined;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Get command change type.
|
|
463
|
+
*
|
|
464
|
+
* @param command to be executed for creating change
|
|
465
|
+
* @returns command change type or undefined
|
|
466
|
+
*/
|
|
467
|
+
getCommandChangeType(command) {
|
|
468
|
+
return this.retryOperations([() => command.getChangeType(), () => command.getPreparedChange().getDefinition().changeType]);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Get command selector id.
|
|
473
|
+
*
|
|
474
|
+
* @param command to be executed for creating change
|
|
475
|
+
* @returns command selector id or undefined
|
|
476
|
+
*/
|
|
477
|
+
getCommandSelectorId(command) {
|
|
478
|
+
return this.retryOperations([() => command.getSelector().id,
|
|
479
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
480
|
+
() => command.getElement().getProperty('persistencyKey'), () => command.getElement().getId(), () => command.getParent()?.getElement().getId()]);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Sync outline changes to place modification markers when outline is changed.
|
|
485
|
+
*
|
|
486
|
+
* @returns void
|
|
487
|
+
*/
|
|
488
|
+
async syncOutlineChanges() {
|
|
489
|
+
for (const change of this.savedChanges) {
|
|
490
|
+
if (change.kind !== 'unknown' && change.changeType !== 'configuration') {
|
|
491
|
+
const flexObject = await getFlexObject(this.changedFiles[change.fileName]);
|
|
492
|
+
change.controlId = (await getControlIdByChange(flexObject, this.options.rta.getRootControlInstance())) ?? '';
|
|
377
493
|
}
|
|
494
|
+
}
|
|
495
|
+
this.updateStack();
|
|
378
496
|
}
|
|
379
|
-
|
|
380
|
-
|
|
497
|
+
onStackChange(handler) {
|
|
498
|
+
this.addEventListener(STACK_CHANGE_EVENT, handler);
|
|
381
499
|
}
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
500
|
+
}
|
|
501
|
+
function isGenericConfigChange(change) {
|
|
502
|
+
return change.kind === GENERIC_CHANGE_KIND && change.changeType === 'configuration';
|
|
503
|
+
}
|
|
504
|
+
var __exports = {
|
|
505
|
+
__esModule: true
|
|
506
|
+
};
|
|
507
|
+
__exports.STACK_CHANGE_EVENT = STACK_CHANGE_EVENT;
|
|
508
|
+
__exports.ChangeService = ChangeService;
|
|
509
|
+
return __exports;
|
|
510
|
+
});
|
|
511
|
+
//# sourceMappingURL=service.js.map
|