@sap-ux/preview-middleware 0.19.41 → 0.19.43
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/add-fragment.js +46 -46
- package/dist/client/adp/api-handler.js +159 -159
- package/dist/client/adp/command-executor.js +75 -75
- package/dist/client/adp/control-utils.js +44 -44
- package/dist/client/adp/controllers/ControllerExtension.controller.js +210 -210
- package/dist/client/adp/controllers/ExtensionPoint.controller.js +139 -139
- package/dist/client/adp/controllers/FileExistsDialog.controller.js +66 -66
- package/dist/client/adp/dialog-factory.js +135 -135
- package/dist/client/adp/init-dialogs.js +163 -163
- package/dist/client/adp/quick-actions/add-new-subpage-quick-action-base.js +96 -96
- package/dist/client/adp/quick-actions/common/add-controller-to-page.js +60 -60
- package/dist/client/adp/quick-actions/common/create-page-action.js +54 -54
- package/dist/client/adp/quick-actions/common/op-add-custom-section.js +39 -39
- package/dist/client/adp/quick-actions/common/op-add-header-field.js +67 -67
- package/dist/client/adp/quick-actions/common/utils.js +18 -18
- package/dist/client/adp/quick-actions/control-types.js +23 -23
- package/dist/client/adp/quick-actions/dialog-enablement-validator.js +24 -24
- package/dist/client/adp/quick-actions/enablement-validator.js +4 -4
- package/dist/client/adp/quick-actions/fe-v2/add-new-subpage.js +81 -81
- package/dist/client/adp/quick-actions/fe-v2/change-table-actions.js +67 -67
- package/dist/client/adp/quick-actions/fe-v2/change-table-columns.js +101 -101
- package/dist/client/adp/quick-actions/fe-v2/create-table-action.js +107 -107
- package/dist/client/adp/quick-actions/fe-v2/create-table-custom-column.js +99 -99
- package/dist/client/adp/quick-actions/fe-v2/lr-enable-semantic-date-range-filter-bar.js +78 -78
- package/dist/client/adp/quick-actions/fe-v2/lr-enable-table-filtering.js +77 -77
- package/dist/client/adp/quick-actions/fe-v2/lr-enable-variant-management.js +69 -69
- package/dist/client/adp/quick-actions/fe-v2/lr-toggle-clear-filter-bar.js +59 -59
- package/dist/client/adp/quick-actions/fe-v2/op-enable-empty-row-mode.js +93 -93
- package/dist/client/adp/quick-actions/fe-v2/op-enable-variant-management.js +84 -84
- package/dist/client/adp/quick-actions/fe-v2/registry.js +77 -77
- package/dist/client/adp/quick-actions/fe-v2/utils.js +116 -116
- package/dist/client/adp/quick-actions/fe-v4/add-new-subpage.js +138 -138
- package/dist/client/adp/quick-actions/fe-v4/change-table-actions.js +79 -79
- package/dist/client/adp/quick-actions/fe-v4/change-table-columns.js +75 -75
- package/dist/client/adp/quick-actions/fe-v4/create-table-action.js +53 -53
- package/dist/client/adp/quick-actions/fe-v4/create-table-custom-column.js +49 -49
- package/dist/client/adp/quick-actions/fe-v4/enable-variant-management.js +81 -81
- package/dist/client/adp/quick-actions/fe-v4/lr-enable-semantic-date-range-filter-bar.js +56 -56
- package/dist/client/adp/quick-actions/fe-v4/lr-enable-table-filtering.js +84 -84
- package/dist/client/adp/quick-actions/fe-v4/lr-toggle-clear-filter-bar.js +53 -53
- package/dist/client/adp/quick-actions/fe-v4/op-enable-empty-row-mode.js +89 -89
- package/dist/client/adp/quick-actions/fe-v4/registry.js +60 -60
- package/dist/client/adp/quick-actions/fe-v4/utils.js +72 -72
- package/dist/client/adp/quick-actions/load.js +44 -44
- package/dist/client/adp/quick-actions/quick-action-base.js +64 -64
- package/dist/client/adp/utils.js +218 -218
- package/dist/client/cpe/additional-change-info/add-xml-additional-info.js +75 -75
- package/dist/client/cpe/changes/generic-change.js +328 -0
- package/dist/client/cpe/changes/generic-change.ts +462 -0
- package/dist/client/cpe/changes/index.js +10 -10
- package/dist/client/cpe/changes/service.js +75 -237
- package/dist/client/cpe/changes/service.ts +141 -403
- package/dist/client/cpe/changes/validator.js +39 -39
- package/dist/client/cpe/documentation.js +164 -164
- package/dist/client/cpe/feature-service.js +36 -36
- package/dist/client/cpe/logger.js +30 -30
- package/dist/client/cpe/outline/editable.js +37 -37
- package/dist/client/cpe/outline/nodes.js +203 -203
- package/dist/client/cpe/outline/service.ts +0 -1
- package/dist/client/cpe/quick-actions/quick-action-definition.js +4 -4
- package/dist/client/cpe/quick-actions/registry.js +143 -143
- package/dist/client/cpe/quick-actions/utils.js +92 -92
- package/dist/client/cpe/types.js +4 -4
- package/dist/client/cpe/ui5-utils.js +33 -33
- package/dist/client/cpe/utils.js +111 -111
- package/dist/client/flp/WorkspaceConnector.js +92 -92
- package/dist/client/flp/common.js +28 -28
- package/dist/client/flp/enableFakeConnector.js +89 -89
- package/dist/client/flp/homepage/Component.js +14 -14
- package/dist/client/flp/initCdm.js +117 -117
- package/dist/client/flp/initConnectors.js +28 -28
- package/dist/client/flp/initRta.js +178 -178
- package/dist/client/i18n.js +56 -56
- package/dist/client/messagebundle.properties +21 -0
- package/dist/client/thirdparty/@sap-ux-private/control-property-editor-common.js +2 -4
- package/dist/client/utils/additional-change-info.js +54 -54
- package/dist/client/utils/application.js +32 -32
- package/dist/client/utils/core.js +84 -84
- package/dist/client/utils/error.js +19 -19
- package/dist/client/utils/fe-v2.js +56 -56
- package/dist/client/utils/fe-v4.js +140 -140
- package/dist/client/utils/version.js +104 -104
- package/package.json +4 -4
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
ExternalAction,
|
|
3
3
|
PendingChange,
|
|
4
|
-
SavedPropertyChange,
|
|
5
4
|
UnknownSavedChange,
|
|
6
5
|
SavedControlChange,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
ConfigurationValue,
|
|
7
|
+
SavedGenericChange,
|
|
8
|
+
SavedChange,
|
|
9
|
+
PendingGenericChange
|
|
10
10
|
} from '@sap-ux-private/control-property-editor-common';
|
|
11
11
|
import {
|
|
12
12
|
changeProperty,
|
|
@@ -17,11 +17,9 @@ import {
|
|
|
17
17
|
reloadApplication,
|
|
18
18
|
setApplicationRequiresReload,
|
|
19
19
|
save,
|
|
20
|
-
CONFIGURATION_CHANGE_KIND,
|
|
21
|
-
PropertyType,
|
|
22
20
|
PENDING_CHANGE_TYPE,
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
UNKNOWN_CHANGE_KIND,
|
|
22
|
+
GENERIC_CHANGE_KIND
|
|
25
23
|
} from '@sap-ux-private/control-property-editor-common';
|
|
26
24
|
import { applyChange } from './flex-change';
|
|
27
25
|
import type { ActionSenderFunction, SubscribeFunction, UI5AdaptationOptions } from '../types';
|
|
@@ -29,108 +27,33 @@ import type Event from 'sap/ui/base/Event';
|
|
|
29
27
|
import type FlexCommand from 'sap/ui/rta/command/FlexCommand';
|
|
30
28
|
import Log from 'sap/base/Log';
|
|
31
29
|
import { modeAndStackChangeHandler } from '../rta-service';
|
|
32
|
-
import
|
|
33
|
-
import FlexChange from 'sap/ui/fl/Change';
|
|
30
|
+
import { ChangeDefinition } from 'sap/ui/fl/Change';
|
|
34
31
|
import { getError } from '../../utils/error';
|
|
35
|
-
import { isLowerThanMinimalUi5Version, getUi5Version } from '../../utils/version';
|
|
36
32
|
import MessageToast from 'sap/m/MessageToast';
|
|
37
33
|
import { getTextBundle } from '../../i18n';
|
|
38
34
|
import { getControlById, isA } from '../../utils/core';
|
|
39
35
|
import UI5Element from 'sap/ui/core/Element';
|
|
40
|
-
import { getConfigMapControlIdMap } from '../../utils/fe-v4';
|
|
41
36
|
import { setAdditionalChangeInfo } from '../../utils/additional-change-info';
|
|
37
|
+
import {
|
|
38
|
+
ChangeHandler,
|
|
39
|
+
changeType,
|
|
40
|
+
ConfigChange,
|
|
41
|
+
GENERIC_CHANGE_HANDLER,
|
|
42
|
+
getControlIdByChange,
|
|
43
|
+
getFlexObject,
|
|
44
|
+
type GenericChange
|
|
45
|
+
} from './generic-change';
|
|
42
46
|
|
|
43
47
|
const TITLE_MAP: { [key: string]: string } = {
|
|
44
48
|
appdescr_app_addAnnotationsToOData: 'Add New Annotation File'
|
|
45
49
|
};
|
|
46
50
|
|
|
47
|
-
interface ChangeContent {
|
|
48
|
-
property: string;
|
|
49
|
-
newValue: string;
|
|
50
|
-
newBinding: string;
|
|
51
|
-
}
|
|
52
51
|
export const STACK_CHANGE_EVENT = 'STACK_CHANGED';
|
|
53
52
|
export interface StackChangedEventDetail {
|
|
54
53
|
controls: UI5Element[];
|
|
55
54
|
}
|
|
56
55
|
|
|
57
|
-
|
|
58
|
-
page: string;
|
|
59
|
-
entityPropertyChange: {
|
|
60
|
-
propertyPath: string;
|
|
61
|
-
operation: 'UPSERT' | 'DELETE' | 'INSERT' | 'UPDATE';
|
|
62
|
-
propertyValue: string;
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
interface ChangeSelector {
|
|
67
|
-
id: string;
|
|
68
|
-
type: string;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
interface BaseChange {
|
|
72
|
-
fileName: string;
|
|
73
|
-
timestamp: string;
|
|
74
|
-
creation: string;
|
|
75
|
-
value: string;
|
|
76
|
-
selector: ChangeSelector;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const PROPERTY_CHANGE = 'propertyChange';
|
|
80
|
-
const PROPERTY_BINDING_CHANGE = 'propertyBindingChange';
|
|
81
|
-
const MANIFEST_V4_CHANGE = 'appdescr_fe_changePageConfiguration';
|
|
82
|
-
|
|
83
|
-
interface PropertyChange extends BaseChange {
|
|
84
|
-
changeType: typeof PROPERTY_CHANGE | typeof PROPERTY_BINDING_CHANGE;
|
|
85
|
-
controlId: string;
|
|
86
|
-
propertyName: string;
|
|
87
|
-
content: ChangeContent;
|
|
88
|
-
}
|
|
89
|
-
interface ConfigChange extends BaseChange {
|
|
90
|
-
changeType: typeof MANIFEST_V4_CHANGE;
|
|
91
|
-
propertyName: string;
|
|
92
|
-
content: ConfigurationChangeContent;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
type SavedChangesResponse = Record<string, PropertyChange | ConfigChange>;
|
|
96
|
-
|
|
97
|
-
type Properties<T extends object> = { [K in keyof T]-?: K extends string ? K : never }[keyof T];
|
|
98
|
-
/**
|
|
99
|
-
* Assert change for its validity. Throws error if no value found in saved changes.
|
|
100
|
-
*
|
|
101
|
-
* @param properties array of property name
|
|
102
|
-
* @param target object which will be checked
|
|
103
|
-
*/
|
|
104
|
-
function assertProperties<T extends object>(properties: Properties<T>[], target: T): void {
|
|
105
|
-
for (const property of properties) {
|
|
106
|
-
const value = target[property];
|
|
107
|
-
if (value === null || value === undefined) {
|
|
108
|
-
throw new Error(`Invalid change, missing ${property} in the change file`);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Assert change for its validity. Throws error if no value found in saved changes.
|
|
115
|
-
*
|
|
116
|
-
* @param change Change object
|
|
117
|
-
*/
|
|
118
|
-
function assertChange(change: PropertyChange): void {
|
|
119
|
-
assertProperties(['fileName', 'selector', 'content', 'creation'], change);
|
|
120
|
-
assertProperties(['id'], change.selector);
|
|
121
|
-
assertProperties(['property'], change.content);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Assert v4 manifest change for its validity. Throws error if no value found in saved changes.
|
|
126
|
-
*
|
|
127
|
-
* @param change Change object
|
|
128
|
-
*/
|
|
129
|
-
function assertManifestChange(change: ConfigChange): void {
|
|
130
|
-
assertProperties(['fileName', 'content', 'creation'], change);
|
|
131
|
-
assertProperties(['page', 'entityPropertyChange'], change.content);
|
|
132
|
-
assertProperties(['propertyPath', 'operation', 'propertyValue'], change.content.entityPropertyChange);
|
|
133
|
-
}
|
|
56
|
+
type SavedChangesResponse = Record<string, ConfigChange | GenericChange>;
|
|
134
57
|
|
|
135
58
|
/**
|
|
136
59
|
* Modify rta message.
|
|
@@ -144,34 +67,17 @@ function modifyRTAErrorMessage(errorMessage: string, id: string, type: string):
|
|
|
144
67
|
return errorMessage.replace('Error: Applying property changes failed:', '').replace(`${type}#${id}`, '');
|
|
145
68
|
}
|
|
146
69
|
|
|
147
|
-
/**
|
|
148
|
-
* Returns a shortened version of the given configuration path segments by removing excess segments,
|
|
149
|
-
* leaving only the most relevant parts for display. For example, the configuration path
|
|
150
|
-
* `controlConfiguration/com.sap.UI.v1.LineItem/tableSettings` will be shortened to
|
|
151
|
-
* `LineItem/tableSettings`.
|
|
152
|
-
*
|
|
153
|
-
* @param propertyPathSeg string[]
|
|
154
|
-
* @returns string
|
|
155
|
-
*/
|
|
156
|
-
function getCompactV4ConfigPath(propertyPathSeg: string[]): string {
|
|
157
|
-
return propertyPathSeg.join('/').replace(/^controlConfiguration\/(?:([^/]+\/))?@[^/]+\.v1\./, '$1');
|
|
158
|
-
}
|
|
159
|
-
|
|
160
70
|
/**
|
|
161
71
|
* A Class of ChangeService
|
|
162
72
|
*/
|
|
163
73
|
export class ChangeService extends EventTarget {
|
|
164
|
-
private savedChanges:
|
|
165
|
-
| SavedPropertyChange[]
|
|
166
|
-
| UnknownSavedChange[]
|
|
167
|
-
| SavedControlChange[]
|
|
168
|
-
| SavedConfigurationChange[] = [];
|
|
74
|
+
private savedChanges: SavedChange[] = [];
|
|
169
75
|
private changesRequiringReload = 0;
|
|
170
76
|
private sendAction: (action: ExternalAction) => void;
|
|
171
77
|
private pendingChanges: PendingChange[] = [];
|
|
172
78
|
private changedFiles: Record<string, object> = {};
|
|
173
79
|
private readonly eventStack: object[] = [];
|
|
174
|
-
private pendingConfigChangeMap: Map<string,
|
|
80
|
+
private pendingConfigChangeMap: Map<string, PendingGenericChange[]> = new Map();
|
|
175
81
|
private configPropertyControlIdMap: Map<string, string[]> = new Map();
|
|
176
82
|
/**
|
|
177
83
|
*
|
|
@@ -242,25 +148,17 @@ export class ChangeService extends EventTarget {
|
|
|
242
148
|
);
|
|
243
149
|
}
|
|
244
150
|
|
|
245
|
-
private
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
kind: 'configuration',
|
|
257
|
-
fileName: change.fileName,
|
|
258
|
-
controlIds,
|
|
259
|
-
propertyPath: getCompactV4ConfigPath(propertyPathSegments) || change.content.page,
|
|
260
|
-
propertyName: propertyName ?? '',
|
|
261
|
-
value: change.content.entityPropertyChange.propertyValue,
|
|
262
|
-
timestamp: new Date(change.creation).getTime()
|
|
263
|
-
};
|
|
151
|
+
private isGenericChange(change: GenericChange): change is GenericChange {
|
|
152
|
+
return (
|
|
153
|
+
change.changeType === 'appdescr_app_addAnnotationsToOData' ||
|
|
154
|
+
change.changeType === 'rename' ||
|
|
155
|
+
change.changeType === 'moveControls' ||
|
|
156
|
+
change.changeType === 'addXML' ||
|
|
157
|
+
change.changeType === 'propertyChange' ||
|
|
158
|
+
change.changeType === 'propertyBindingChange' ||
|
|
159
|
+
change.changeType === 'appdescr_fe_changePageConfiguration' ||
|
|
160
|
+
change.changeType === 'appdescr_ui_generic_app_changePageConfiguration'
|
|
161
|
+
);
|
|
264
162
|
}
|
|
265
163
|
|
|
266
164
|
/**
|
|
@@ -270,90 +168,80 @@ export class ChangeService extends EventTarget {
|
|
|
270
168
|
this.changedFiles = {};
|
|
271
169
|
const savedChangesResponse = await fetch(FlexChangesEndPoints.changes + `?_=${Date.now()}`);
|
|
272
170
|
const savedChanges = (await savedChangesResponse.json()) as SavedChangesResponse;
|
|
171
|
+
const textBundle = await getTextBundle();
|
|
273
172
|
const changes = (
|
|
274
|
-
(
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
173
|
+
await Promise.all(
|
|
174
|
+
Object.keys(savedChanges ?? {}).map(
|
|
175
|
+
async (key): Promise<UnknownSavedChange | SavedControlChange | SavedGenericChange | undefined> => {
|
|
176
|
+
const change = savedChanges[key];
|
|
177
|
+
try {
|
|
178
|
+
const handler = GENERIC_CHANGE_HANDLER[
|
|
179
|
+
change.changeType
|
|
180
|
+
] as unknown as ChangeHandler<GenericChange>;
|
|
181
|
+
if (this.isGenericChange(change)) {
|
|
182
|
+
const {
|
|
183
|
+
properties,
|
|
184
|
+
changeTitle,
|
|
185
|
+
controlId,
|
|
186
|
+
changeType: type,
|
|
187
|
+
subtitle
|
|
188
|
+
} = await handler(change as unknown as GenericChange, {
|
|
189
|
+
textBundle,
|
|
190
|
+
appComponent: this.options.rta.getRootControlInstance(),
|
|
191
|
+
configPropertyControlIdMap: this.configPropertyControlIdMap
|
|
192
|
+
});
|
|
193
|
+
this.changedFiles[change.fileName] = change;
|
|
194
|
+
return {
|
|
195
|
+
kind: GENERIC_CHANGE_KIND,
|
|
196
|
+
type: 'saved',
|
|
197
|
+
fileName: change.fileName,
|
|
198
|
+
...(subtitle && { subtitle }),
|
|
199
|
+
changeType: type ?? change.changeType,
|
|
200
|
+
timestamp: new Date(change.creation).getTime(),
|
|
201
|
+
...(controlId && { controlId }),
|
|
202
|
+
properties,
|
|
203
|
+
title: textBundle.getText(changeTitle)
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
throw new Error('Unknown change type');
|
|
207
|
+
} catch (error) {
|
|
208
|
+
// Gracefully handle change files with invalid content
|
|
209
|
+
const flexObject = await getFlexObject(change);
|
|
210
|
+
const selectorId = await getControlIdByChange(
|
|
211
|
+
flexObject,
|
|
212
|
+
this.options.rta.getRootControlInstance()
|
|
213
|
+
);
|
|
214
|
+
if (change.fileName) {
|
|
215
|
+
this.changedFiles[change.fileName] = change;
|
|
216
|
+
const unknownChange: UnknownSavedChange = {
|
|
217
|
+
type: 'saved',
|
|
218
|
+
kind: 'unknown',
|
|
219
|
+
changeType: change.changeType,
|
|
220
|
+
fileName: change.fileName,
|
|
221
|
+
timestamp: new Date(change.creation).getTime()
|
|
222
|
+
};
|
|
223
|
+
if (change.creation) {
|
|
224
|
+
unknownChange.timestamp = new Date(change.creation).getTime();
|
|
322
225
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
const unknownChange: UnknownSavedChange = {
|
|
329
|
-
type: 'saved',
|
|
330
|
-
kind: 'unknown',
|
|
331
|
-
changeType: change.changeType,
|
|
332
|
-
fileName: change.fileName,
|
|
333
|
-
timestamp: new Date(change.creation).getTime(),
|
|
334
|
-
...(title && { title })
|
|
226
|
+
if (selectorId) {
|
|
227
|
+
const controlChange: SavedControlChange = {
|
|
228
|
+
...unknownChange,
|
|
229
|
+
kind: 'control',
|
|
230
|
+
controlId: selectorId
|
|
335
231
|
};
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
}
|
|
339
|
-
if (selectorId) {
|
|
340
|
-
const controlChange: SavedControlChange = {
|
|
341
|
-
...unknownChange,
|
|
342
|
-
kind: 'control',
|
|
343
|
-
controlId: selectorId
|
|
344
|
-
};
|
|
345
|
-
|
|
346
|
-
return controlChange;
|
|
347
|
-
}
|
|
348
|
-
return unknownChange;
|
|
232
|
+
|
|
233
|
+
return controlChange;
|
|
349
234
|
}
|
|
350
|
-
return
|
|
235
|
+
return unknownChange;
|
|
351
236
|
}
|
|
237
|
+
return undefined;
|
|
352
238
|
}
|
|
353
|
-
|
|
239
|
+
}
|
|
354
240
|
)
|
|
355
|
-
)
|
|
356
|
-
)
|
|
241
|
+
)
|
|
242
|
+
)
|
|
243
|
+
.filter((change) => !!change)
|
|
244
|
+
.sort((a, b) => b.timestamp - a.timestamp);
|
|
357
245
|
this.savedChanges = changes;
|
|
358
246
|
}
|
|
359
247
|
|
|
@@ -370,10 +258,6 @@ export class ChangeService extends EventTarget {
|
|
|
370
258
|
return fileName === change.fileName;
|
|
371
259
|
}
|
|
372
260
|
|
|
373
|
-
if (change.kind === 'property') {
|
|
374
|
-
return change.controlId === controlId && change.propertyName === propertyName;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
261
|
if (change.kind === 'control') {
|
|
378
262
|
return change.controlId === controlId;
|
|
379
263
|
}
|
|
@@ -436,12 +320,7 @@ export class ChangeService extends EventTarget {
|
|
|
436
320
|
if (this.eventStack.length - 1 === eventIndex) {
|
|
437
321
|
this.pendingChanges = pendingChanges.filter((change): boolean => !!change);
|
|
438
322
|
const changesRequiringReload = this.pendingChanges.reduce(
|
|
439
|
-
(sum, change) =>
|
|
440
|
-
change.kind === CONFIGURATION_CHANGE_KIND ||
|
|
441
|
-
change.changeType === 'appdescr_ui_generic_app_changePageConfiguration' ||
|
|
442
|
-
change.changeType === 'appdescr_app_addAnnotationsToOData'
|
|
443
|
-
? sum + 1
|
|
444
|
-
: sum,
|
|
323
|
+
(sum, change) => (isGenericConfigChange(change) ? sum + 1 : sum),
|
|
445
324
|
0
|
|
446
325
|
);
|
|
447
326
|
if (changesRequiringReload > this.changesRequiringReload) {
|
|
@@ -460,12 +339,12 @@ export class ChangeService extends EventTarget {
|
|
|
460
339
|
}
|
|
461
340
|
|
|
462
341
|
// Notify to update the ui for configuration changes.
|
|
463
|
-
const configurationChanges = this.pendingChanges?.filter(
|
|
342
|
+
const configurationChanges: PendingGenericChange[] = this.pendingChanges?.filter(isGenericConfigChange);
|
|
464
343
|
if (configurationChanges.length) {
|
|
465
344
|
const stackChangeEvent = new CustomEvent(STACK_CHANGE_EVENT, {
|
|
466
345
|
detail: {
|
|
467
346
|
controls: configurationChanges.reduce((acc: UI5Element[], item) => {
|
|
468
|
-
const controls = (item.
|
|
347
|
+
const controls = ([...(item.controlId ?? [])] as string[])
|
|
469
348
|
.map((id: string) => {
|
|
470
349
|
return getControlById(id);
|
|
471
350
|
})
|
|
@@ -490,7 +369,8 @@ export class ChangeService extends EventTarget {
|
|
|
490
369
|
*/
|
|
491
370
|
public getConfigurationPropertyValue(controlId: string, propertyName: string): ConfigurationValue | undefined {
|
|
492
371
|
const pendingChanges = this.pendingConfigChangeMap?.get(controlId);
|
|
493
|
-
return (pendingChanges || []).find((item) => item.isActive && item.
|
|
372
|
+
return (pendingChanges || []).find((item) => item.isActive && item.properties[0].label === propertyName)
|
|
373
|
+
?.properties[0].value;
|
|
494
374
|
}
|
|
495
375
|
|
|
496
376
|
/**
|
|
@@ -526,91 +406,14 @@ export class ChangeService extends EventTarget {
|
|
|
526
406
|
}
|
|
527
407
|
}
|
|
528
408
|
|
|
529
|
-
private
|
|
530
|
-
|
|
531
|
-
value: ConfigurationValue,
|
|
532
|
-
fileName: string,
|
|
533
|
-
index: number,
|
|
534
|
-
inactiveCommandCount: number
|
|
535
|
-
): PendingConfigurationChange {
|
|
536
|
-
const { entityPropertyChange, page } = command.getProperty('parameters') as {
|
|
537
|
-
entityPropertyChange: {
|
|
538
|
-
propertyPath: string;
|
|
539
|
-
};
|
|
540
|
-
page: string;
|
|
541
|
-
};
|
|
542
|
-
const controlId = this.getCommandSelectorId(command) ?? '';
|
|
543
|
-
const propertyPathSegments = entityPropertyChange.propertyPath.split('/');
|
|
544
|
-
const propName = propertyPathSegments.pop() as string;
|
|
545
|
-
const key = getConfigMapControlIdMap(page, propertyPathSegments);
|
|
546
|
-
|
|
547
|
-
const isActive = index >= inactiveCommandCount;
|
|
548
|
-
const controlIds = this.configPropertyControlIdMap?.get(key) || [controlId];
|
|
549
|
-
const result: PendingConfigurationChange = {
|
|
550
|
-
type: PENDING_CHANGE_TYPE,
|
|
551
|
-
kind: CONFIGURATION_CHANGE_KIND,
|
|
552
|
-
controlIds,
|
|
553
|
-
propertyPath: getCompactV4ConfigPath(propertyPathSegments) || page,
|
|
554
|
-
propertyName: propName,
|
|
555
|
-
isActive,
|
|
556
|
-
value,
|
|
557
|
-
fileName
|
|
558
|
-
};
|
|
559
|
-
for (const id of result.controlIds) {
|
|
560
|
-
if (!this.pendingConfigChangeMap.get(id)) {
|
|
561
|
-
this.pendingConfigChangeMap.set(id, []);
|
|
562
|
-
}
|
|
563
|
-
const pendingChanges = this.pendingConfigChangeMap.get(id);
|
|
564
|
-
pendingChanges?.push(result);
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
return result;
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
private prepareV2ConfigurationChange(
|
|
571
|
-
command: FlexCommand,
|
|
572
|
-
fileName: string,
|
|
573
|
-
index: number,
|
|
574
|
-
inactiveCommandCount: number
|
|
575
|
-
): PendingConfigurationChange {
|
|
576
|
-
const { entityPropertyChange, page } = command.getProperty('parameters') as {
|
|
577
|
-
entityPropertyChange: {
|
|
578
|
-
propertyPath: string;
|
|
579
|
-
propertyValue: Record<string, string>;
|
|
580
|
-
};
|
|
581
|
-
page: string;
|
|
582
|
-
};
|
|
583
|
-
const propertyPathSegments = entityPropertyChange.propertyPath.split('/');
|
|
584
|
-
const propertyName =
|
|
585
|
-
Object.keys(entityPropertyChange.propertyValue)?.[0] ??
|
|
586
|
-
propertyPathSegments[propertyPathSegments.length - 1];
|
|
587
|
-
const propertyValue = entityPropertyChange.propertyValue?.[propertyName] ?? entityPropertyChange.propertyValue;
|
|
588
|
-
const controlId = this.getCommandSelectorId(command) ?? '';
|
|
589
|
-
|
|
590
|
-
const key = getConfigMapControlIdMap(page, propertyPathSegments);
|
|
591
|
-
|
|
592
|
-
const isActive = index >= inactiveCommandCount;
|
|
593
|
-
const controlIds = this.configPropertyControlIdMap?.get(key) || [controlId];
|
|
594
|
-
|
|
595
|
-
const result: PendingConfigurationChange = {
|
|
596
|
-
type: PENDING_CHANGE_TYPE,
|
|
597
|
-
kind: CONFIGURATION_CHANGE_KIND,
|
|
598
|
-
controlIds,
|
|
599
|
-
propertyPath: getCompactV4ConfigPath(propertyPathSegments) || page,
|
|
600
|
-
propertyName,
|
|
601
|
-
isActive,
|
|
602
|
-
value: propertyValue,
|
|
603
|
-
fileName
|
|
604
|
-
};
|
|
605
|
-
for (const id of result.controlIds) {
|
|
409
|
+
private trackPendingConfigChanges(result: PendingGenericChange): void {
|
|
410
|
+
for (const id of result?.controlId ?? []) {
|
|
606
411
|
if (!this.pendingConfigChangeMap.get(id)) {
|
|
607
412
|
this.pendingConfigChangeMap.set(id, []);
|
|
608
413
|
}
|
|
609
414
|
const pendingChanges = this.pendingConfigChangeMap.get(id);
|
|
610
415
|
pendingChanges?.push(result);
|
|
611
416
|
}
|
|
612
|
-
|
|
613
|
-
return result;
|
|
614
417
|
}
|
|
615
418
|
|
|
616
419
|
/**
|
|
@@ -627,10 +430,10 @@ export class ChangeService extends EventTarget {
|
|
|
627
430
|
index: number
|
|
628
431
|
): Promise<PendingChange | undefined> {
|
|
629
432
|
const change = command?.getPreparedChange?.();
|
|
630
|
-
|
|
433
|
+
const textBundle = await getTextBundle();
|
|
631
434
|
const selectorId =
|
|
632
435
|
typeof change?.getSelector === 'function'
|
|
633
|
-
? await this.
|
|
436
|
+
? await getControlIdByChange(change, this.options.rta.getRootControlInstance())
|
|
634
437
|
: this.getCommandSelectorId(command);
|
|
635
438
|
|
|
636
439
|
const changeType = this.getCommandChangeType(command);
|
|
@@ -639,37 +442,36 @@ export class ChangeService extends EventTarget {
|
|
|
639
442
|
return undefined;
|
|
640
443
|
}
|
|
641
444
|
|
|
642
|
-
const
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
445
|
+
const changeDefinition = change.getDefinition ? change.getDefinition() : (change.getJson() as ChangeDefinition);
|
|
446
|
+
const { fileName } = changeDefinition;
|
|
447
|
+
const handler = GENERIC_CHANGE_HANDLER[changeType as changeType] as unknown as ChangeHandler<GenericChange>;
|
|
448
|
+
if (handler) {
|
|
449
|
+
const {
|
|
450
|
+
properties,
|
|
451
|
+
changeTitle,
|
|
452
|
+
controlId,
|
|
453
|
+
changeType: type,
|
|
454
|
+
subtitle
|
|
455
|
+
} = await handler(changeDefinition as unknown as GenericChange, {
|
|
456
|
+
textBundle,
|
|
457
|
+
appComponent: this.options.rta.getRootControlInstance(),
|
|
458
|
+
configPropertyControlIdMap: this.configPropertyControlIdMap
|
|
459
|
+
});
|
|
460
|
+
const genericChange: PendingGenericChange = {
|
|
461
|
+
kind: GENERIC_CHANGE_KIND,
|
|
462
|
+
type: 'pending',
|
|
463
|
+
changeType: type ?? changeType,
|
|
464
|
+
...(subtitle && { subtitle }),
|
|
661
465
|
isActive: index >= inactiveCommandCount,
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
466
|
+
title: textBundle.getText(changeTitle),
|
|
467
|
+
fileName,
|
|
468
|
+
...(controlId && { controlId }),
|
|
469
|
+
properties
|
|
665
470
|
};
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
return this.prepareV4ConfigurationChange(command, value, fileName, index, inactiveCommandCount);
|
|
671
|
-
} else if (changeType === 'appdescr_ui_generic_app_changePageConfiguration') {
|
|
672
|
-
return this.prepareV2ConfigurationChange(command, fileName, index, inactiveCommandCount);
|
|
471
|
+
if (changeType === 'appdescr_fe_changePageConfiguration') {
|
|
472
|
+
this.trackPendingConfigChanges(genericChange);
|
|
473
|
+
}
|
|
474
|
+
return genericChange;
|
|
673
475
|
} else {
|
|
674
476
|
const title = TITLE_MAP[changeType] ?? '';
|
|
675
477
|
let result: PendingChange = {
|
|
@@ -743,59 +545,6 @@ export class ChangeService extends EventTarget {
|
|
|
743
545
|
]) as string | undefined;
|
|
744
546
|
}
|
|
745
547
|
|
|
746
|
-
/**
|
|
747
|
-
* Get element id by change.
|
|
748
|
-
*
|
|
749
|
-
* @param change to be executed for creating change
|
|
750
|
-
* @returns element id or empty string
|
|
751
|
-
*/
|
|
752
|
-
private async getControlIdByChange(change: FlexChange<ChangeContent>): Promise<string | undefined> {
|
|
753
|
-
const appComponent = this.options.rta.getRootControlInstance();
|
|
754
|
-
const selector = typeof change.getSelector === 'function' ? change.getSelector() : undefined;
|
|
755
|
-
const changeType = change.getChangeType();
|
|
756
|
-
const layer = change.getLayer();
|
|
757
|
-
|
|
758
|
-
if (!selector?.id) {
|
|
759
|
-
return;
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
try {
|
|
763
|
-
let control = JsControlTreeModifier.bySelector(selector, appComponent);
|
|
764
|
-
if (!control) {
|
|
765
|
-
return selector.id;
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
const changeHandlerAPI = (await import('sap/ui/fl/write/api/ChangesWriteAPI')).default;
|
|
769
|
-
|
|
770
|
-
if (typeof changeHandlerAPI?.getChangeHandler !== 'function') {
|
|
771
|
-
return selector.id;
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
const changeHandler = await changeHandlerAPI.getChangeHandler({
|
|
775
|
-
changeType,
|
|
776
|
-
element: control,
|
|
777
|
-
modifier: JsControlTreeModifier,
|
|
778
|
-
layer
|
|
779
|
-
});
|
|
780
|
-
|
|
781
|
-
if (changeHandler && typeof changeHandler.getChangeVisualizationInfo === 'function') {
|
|
782
|
-
const result: { affectedControls?: [string] } = await changeHandler.getChangeVisualizationInfo(
|
|
783
|
-
change,
|
|
784
|
-
appComponent
|
|
785
|
-
);
|
|
786
|
-
return JsControlTreeModifier.getControlIdBySelector(
|
|
787
|
-
result?.affectedControls?.[0] ?? selector,
|
|
788
|
-
appComponent
|
|
789
|
-
);
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
return JsControlTreeModifier.getControlIdBySelector(selector, appComponent);
|
|
793
|
-
} catch (error) {
|
|
794
|
-
Log.error('Getting element ID from change has failed:', getError(error));
|
|
795
|
-
return selector.id;
|
|
796
|
-
}
|
|
797
|
-
}
|
|
798
|
-
|
|
799
548
|
/**
|
|
800
549
|
* Sync outline changes to place modification markers when outline is changed.
|
|
801
550
|
*
|
|
@@ -803,9 +552,10 @@ export class ChangeService extends EventTarget {
|
|
|
803
552
|
*/
|
|
804
553
|
public async syncOutlineChanges(): Promise<void> {
|
|
805
554
|
for (const change of this.savedChanges) {
|
|
806
|
-
if (change.kind !== 'unknown' && change.
|
|
807
|
-
const flexObject = await
|
|
808
|
-
change.controlId =
|
|
555
|
+
if (change.kind !== 'unknown' && change.changeType !== 'configuration') {
|
|
556
|
+
const flexObject = await getFlexObject(this.changedFiles[change.fileName]);
|
|
557
|
+
change.controlId =
|
|
558
|
+
(await getControlIdByChange(flexObject, this.options.rta.getRootControlInstance())) ?? '';
|
|
809
559
|
}
|
|
810
560
|
}
|
|
811
561
|
this.updateStack();
|
|
@@ -814,20 +564,8 @@ export class ChangeService extends EventTarget {
|
|
|
814
564
|
public onStackChange(handler: (event: CustomEvent<StackChangedEventDetail>) => void | Promise<void>): void {
|
|
815
565
|
this.addEventListener(STACK_CHANGE_EVENT, handler as EventListener);
|
|
816
566
|
}
|
|
567
|
+
}
|
|
817
568
|
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
*
|
|
821
|
-
* @param change change object
|
|
822
|
-
* @returns FlexChange
|
|
823
|
-
*/
|
|
824
|
-
private async getFlexObject(change: object): Promise<FlexChange<ChangeContent>> {
|
|
825
|
-
if (isLowerThanMinimalUi5Version(await getUi5Version(), { major: 1, minor: 109 })) {
|
|
826
|
-
const Change = (await import('sap/ui/fl/Change')).default;
|
|
827
|
-
return new Change(change);
|
|
828
|
-
}
|
|
829
|
-
|
|
830
|
-
const FlexObjectFactory = (await import('sap/ui/fl/apply/_internal/flexObjects/FlexObjectFactory')).default;
|
|
831
|
-
return FlexObjectFactory.createFromFileContent(change) as FlexChange<ChangeContent>;
|
|
832
|
-
}
|
|
569
|
+
function isGenericConfigChange(change: PendingChange): change is PendingGenericChange {
|
|
570
|
+
return change.kind === GENERIC_CHANGE_KIND && change.changeType === 'configuration';
|
|
833
571
|
}
|